Skip to main content

fastNLTK

NLTK with a Rust engine.
Drop-in replacement. Same API, Same data, 10× faster.

PyPI Python CI Rust License


NLTK is the standard Python NLP library — teaching, research, prototyping. It works great, but it's pure Python. Tokenizing a 50K-word document takes ~40 ms in NLTK. That's fine for one-offs, but in a pipeline it adds up fast.

fastNLTK wraps the same API calls in Rust. Change your import, get the same results. No new dependency tree — the Rust engine lives in a single .pyd/.so file shipped with the wheel.

# Before
import nltk
tokens = nltk.word_tokenize("The quick brown fox.")

# After
import fastnltk as nltk
tokens = nltk.word_tokenize("The quick brown fox.")  # same call, 5–50× faster

All your NLTK data (corpora, models, pickles) still works. Nothing to re-download.

Benchmarks

366 Python drop-in compatibility tests against NLTK. 6 skipped (chat stdin). 3 expected failures.

Benchmarked on release builds against NLTK 3.10. Full results →

Operation NLTK fastNLTK Speedup
TextTiling tokenizer 22237 ms 32 ms 704×
Maxent classifier training 31.93 ms 0.08 ms 425×
edit_distance 2.48 ms 0.01 ms 176×
windowdiff 2.35 ms 0.01 ms 172×
pk (segmentation) 2.19 ms 0.02 ms 90×
Treebank detokenizer 6.70 ms 0.12 ms 55×
VADER sentiment 67.06 ms 1.75 ms 38×
sentence tokenizer (Punkt) 14.65 ms 0.44 ms 33×
S-expression tokenizer 0.36 ms 0.01 ms 30×
Expression parser 16.47 ms 0.55 ms 30×
Tweet tokenizer 83.96 ms 3.31 ms 25×
CFG grammar parser 0.05 ms 0.002 ms 25×
Lancaster stemmer 32.81 ms 1.41 ms 23×
quadgram collocations 101.04 ms 4.94 ms 21×
Earley parser 6.55 ms 0.51 ms 13×
Snowball stemmer 21.84 ms 1.79 ms 12×
word tokenizer (Treebank) 42.18 ms 4.27 ms 10×

Geometric mean across 49 benchmarks: 10.1×. Module-level breakdown:

Module Geo Mean Top single
metrics 146× 176×
sentiment 38× 38×
sem 30× 30×
parse 18× 25×
tokenize 18× 704×
collocations 14× 21×
tree 11× 11×
translate
stem 23×
chunk
classify 425×
cluster
chat
tag
probability
ccg

What's accelerated

Every module that has a Rust-backed engine:

Module What's in Rust
tokenize Treebank, Toktok, Tweet, Regexp, Space, MWE, TextTiling, Punkt, SExpr, Logos DFA
stem Porter, Lancaster (full 124 rules), Snowball, Regexp, WordNet, ARLSTem, Cistem, ISRI, RSLP
tag PerceptronTagger, TnT (integer Viterbi), HMM, Default/Unigram/Bigram/Trigram/Regexp/Affix taggers
classify NaiveBayes, Maxent (GIS), TextCat
probability FreqDist, ConditionalFreqDist, MLE/Laplace/Lidstone prob dists
lm MLE, Lidstone, Laplace, Kneser-Ney interpolated, Witten-Bell, StupidBackoff
collocations Bigram/Trigram/Quadgram finders
metrics edit_distance, jaccard, windowdiff, pk, BLEU, association, agreement, Spearman
parse CFG, Earley chart parser
tree Tree (bracket parse, subtrees, productions, leaves)
chunk RegexpParser (NP/VP IOB extraction)
sentiment VADER
sem FOL expression parser, model evaluation
inference Tableau prover, Resolution prover, Discourse
cluster K-means
chat Eliza-style chatbot
translate BLEU score

Not in Rust yet? Those calls fall through to NLTK automatically. Your code still works.

Install

pip install fastnltk

Pre-built wheels for Linux (x86_64, aarch64), macOS (x86_64, arm64), Windows (x64). Python 3.10–3.13.

Make sure you have the NLTK data you need:

python -m nltk.downloader punkt averaged_perceptron_tagger wordnet

Usage

Everything lives under fastnltk with the same names and signatures as nltk.

from fastnltk import word_tokenize, pos_tag, sent_tokenize

# Sentence segmentation (Punkt, Rust)
sents = sent_tokenize("Dr. Smith left at 5 p.m. He went home.")
# → ['Dr. Smith left at 5 p.m.', 'He went home.']

# Word tokenization (Treebank, Rust)
tokens = word_tokenize("The quick brown fox jumps over the lazy dog.")
# → ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog', '.']

# POS tagging (Perceptron, Rust)
tagged = pos_tag(tokens)
# → [('The', 'DT'), ('quick', 'JJ'), ...]

Drop it in as a direct NLTK replacement:

import fastnltk as nltk
# All your existing nltk.* calls now run through Rust
nltk.word_tokenize("Hello, world!")
nltk.pos_tag(["Hello", "world"])
nltk.ne_chunk(nltk.pos_tag(["John", "lives", "in", "Boston"]))

For module-level imports:

from fastnltk.stem import PorterStemmer, LancasterStemmer
from fastnltk.tag import PerceptronTagger
from fastnltk.parse import CFG, EarleyChartParser
from fastnltk.probability import FreqDist, ConditionalFreqDist
from fastnltk.lm import MLE, KneserNeyInterpolated
from fastnltk.metrics import edit_distance, jaccard_distance
from fastnltk.collocations import BigramCollocationFinder
from fastnltk.tree import Tree

# Same API as NLTK everywhere
stemmer = LancasterStemmer()
stemmer.stem("maximum")          # → 'maxim'
stemmer.stem("presumably")       # → 'presum'

fd = FreqDist("hello world")
fd["l"]                           # → 3
fd.max()                          # → 'l'

tagger = PerceptronTagger()
tagger.tag(["I", "love", "NLP"])  # → [('I', 'PRP'), ('love', 'VBP'), ('NLP', 'NNP')]

tree = Tree.from_string("(S (NP I/PRP) (VP love/VBP NLP/NNP))")
tree.leaves()                     # → ['I/PRP', 'love/VBP', 'NLP/NNP']
tree.productions()                # → ['S -> NP VP', 'NP -> I/PRP', 'VP -> love/VBP NLP/NNP']

From source

git clone https://github.com/wyattferguson/fastnltk
cd fastnltk
pip install maturin
maturin develop --release

Development

pip install -e ".[dev]"
maturin develop --release

cargo test          # Rust unit tests
pytest tests/       # 375 Python tests (366 pass, 6 skip, 3 xfail)

cargo fmt --all -- --check
cargo clippy --lib
ruff check fastnltk/ tests/

See CONTRIBUTING.md for full setup and PR workflow.

Compatibility

The goal is 100% drop-in. Right now 366 of 375 tests pass (6 skipped — chat bots read stdin), with only 3 expected failures:

  • Earley parse tree extraction — Rust Earley finds parses but the tree structure differs from NLTK's chart-printing format (WIP)
  • ConditionalFreqDist clone semanticsfreqdist() returns a copy, so mutations don't propagate back the way NLTK's reference-sharing does (design limitation)
  • CCG fromstring — NLTK 3.10's ccg.chart.fromstring is broken (upstream bug)

Every critical-path API (tokenize, tag, stem, metrics, prob, parse, chunk, sentiment, classify, collocations, tree, cluster, translate, chat) is verified byte-identical to NLTK across all tested inputs.

Platform

Platform Arch Wheel
Linux x86_64, aarch64
macOS x86_64, arm64
Windows x64

License

Apache 2.0. Not affiliated with NLTK or its maintainers.

Contact + Support

Created by Wyatt Ferguson

For any questions or comments heres how you can reach me:

:octopus: Follow me on Github @wyattferguson

:mailbox_with_mail: Email me at wyattxdev@duck.com

:tropical_drink: Follow on BlueSky @wyattf

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastnltk-0.5.2.tar.gz (266.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fastnltk-0.5.2-cp310-abi3-win_amd64.whl (1.4 MB view details)

Uploaded CPython 3.10+Windows x86-64

fastnltk-0.5.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

fastnltk-0.5.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

File details

Details for the file fastnltk-0.5.2.tar.gz.

File metadata

  • Download URL: fastnltk-0.5.2.tar.gz
  • Upload date:
  • Size: 266.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fastnltk-0.5.2.tar.gz
Algorithm Hash digest
SHA256 9d03f8595acf15be838d4a14c4340dde21bf9e83cb7b981748ac00be29fbb430
MD5 787a4a42773b0520acd0059a45b82709
BLAKE2b-256 5afe6921f9a83ef88e0dd82bfcf2649f94efebd7bc4b896726363d948cb27ff4

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastnltk-0.5.2.tar.gz:

Publisher: release.yml on wyattferguson/fastNLTK

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastnltk-0.5.2-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: fastnltk-0.5.2-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fastnltk-0.5.2-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 ee7a004d75e8da50bc8bedaff79fa1579deeab962a90080744fb2f648b86c74f
MD5 85357c04fa4ef80a6eaa820337834cce
BLAKE2b-256 ff35ab4b486560a3d6180e99d80ed54107717c15ccdbcccb255f49231aaffc66

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastnltk-0.5.2-cp310-abi3-win_amd64.whl:

Publisher: release.yml on wyattferguson/fastNLTK

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastnltk-0.5.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fastnltk-0.5.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 10460183ba0eeb888e56870e5614ca8234ec9b1439dc0dc0d67c016dd038f41d
MD5 3f9cd5d211f7981c3a7539b887e5fe9b
BLAKE2b-256 b848f53d7639c2fe952bc802574237111efd480f5ea461f2bd4d1e6c8bbed188

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastnltk-0.5.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on wyattferguson/fastNLTK

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastnltk-0.5.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for fastnltk-0.5.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 daa3fbb20c6ed7afa815274a682cb40ef361ae25d5e55d7f473953b75c5faf3b
MD5 a56273cc9ee4d455aee3f77d03e702a2
BLAKE2b-256 b28e56bf2dde277a338de2883712745f2f381789af708f40f5127331ae26d716

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastnltk-0.5.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on wyattferguson/fastNLTK

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.5.5

4 files

0.5.4

4 files

0.5.3

4 files

This release

0.5.2 This release

4 files

0.5.0

4 files

0.4.1

6 files

0.4.0

4 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page