fasttext-threaded
fasttext-threaded is a Python package for running fastText supervised model
inference with one model loaded in memory and a native C++ thread pool doing
parallel batch prediction.
The package is designed to preserve the official Python fastText predict
interface while fixing the high-throughput inference case where Python threads
do not provide useful model-level parallelism and Python processes multiply
model memory.
Install
Install from PyPI:
pip install fasttext-threaded
For local development:
uv sync --all-extras
uv run pre-commit install
You need a C++17 compiler and CMake.
Usage
from fasttext_threaded import load_model
model = load_model("model.bin", threads=16)
labels, probs = model.predict("some text", k=1, threshold=0.0)
batch_labels, batch_probs = model.predict(
["first document", "second document"],
k=1,
threshold=0.0,
)
The public prediction signature intentionally matches official fastText:
predict(text, k=1, threshold=0.0, on_unicode_error="strict")
predict(list[str], ...) is the high-throughput path. It sends one batch into
C++, releases the GIL, and partitions rows across native worker threads while
using one loaded model.
predict_batch(texts, k=1, threshold=0.0, on_unicode_error="strict") is also
available as a convenience alias for predict(texts, ...). It does not have
different semantics.
Compatibility
The goal is API and behavior parity with official Python fastText for prediction:
predict(str)returns(tuple[str, ...], numpy.ndarray).predict(list[str])returns(list[list[str]], list[numpy.ndarray]).- newline-containing inputs are rejected with the same message shape as official fastText.
k,threshold, and labels/probabilities are tested against official fastText.
Why This Exists
Official fastText supports predict(list[str]), but the binding processes that
batch with a serial C++ loop. Python-side ThreadPoolExecutor is not a reliable
solution for throughput, and Python-side ProcessPoolExecutor loads one model
copy per process.
This package targets the common production inference shape:
- one model object in one Python process
- one native C++ thread pool
- large batches passed through
predict(list[str], ...) - no TCP, pickle, JSON, or multiprocessing serialization on the hot path
Error Handling
The package exposes custom exceptions:
from fasttext_threaded import (
FastTextThreadedError,
InvalidInputError,
ModelLoadError,
PredictionError,
)
Input validation errors happen before worker threads are launched where possible. If a C++ worker fails during batch prediction, the first exception is captured, already-running workers finish, and the entire batch raises a Python exception. Partial predictions are not returned silently.
Benchmarks
Prepare a realistic language-identification benchmark using the official
fastText lid.176.bin supervised model:
uv run python benchmarks/prepare_lid_benchmark.py --model-kind bin --repeat 5000
This downloads the 126 MB lid.176.bin model into .cache/ and writes a
multilingual input corpus. The compressed lid.176.ftz model is also supported
for quick smoke checks, but lid.176.bin is the meaningful default for
performance measurements.
Run:
uv run python benchmarks/benchmark_inference.py \
--model .cache/fasttext-threaded/lid/lid.176.bin \
--input .cache/fasttext-threaded/lid/lid_input.txt \
--threads 16 \
--batch-size 4096
The benchmark compares:
- official fastText single-thread
predict(str)loop - official fastText
predict(list[str]) - official fastText with
ThreadPoolExecutor - official fastText with
ProcessPoolExecutor fasttext_threaded.predict(list[str])
Reported metrics include throughput, latency percentiles, model load time, RSS memory, model-copy count, worker count, and a small parity sample.
For scaling plots across native threads, Python threads, and Python processes:
uv run python benchmarks/benchmark_scaling.py \
--model .cache/fasttext-threaded/lid/lid.176.bin \
--input .cache/fasttext-threaded/lid/lid_input.txt \
--workers 1,2,4,8,16 \
--process-workers 1,2,4 \
--batch-size 4096 \
--repeat 3
This writes:
.cache/fasttext-threaded/scaling/scaling_results.csv.cache/fasttext-threaded/scaling/scaling_metadata.json.cache/fasttext-threaded/scaling/scaling_plot.png
The scaling benchmark records wall time, parent-plus-child CPU time, RSS, model-copy count, machine metadata, and a four-panel plot. Each measured scenario runs in a fresh subprocess, and RSS is captured as peak parent-plus-child memory for that scenario.
Example result from a local Apple Silicon run with lid.176.bin, 54k documents,
batch size 2048, and 5 repeats:
| Method | Workers | Model copies | Docs/s | Peak RSS |
|---|---|---|---|---|
| official fastText batch | 1 | 1 | 284,996 | 192 MB |
| official fastText + Python threads | 16 | 1 | 178,204 | 200 MB |
fasttext_threaded native threads |
8 | 1 | 815,628 | 194 MB |
fasttext_threaded native threads |
16 | 1 | 880,588 | 196 MB |
| official fastText + Python processes | 4 | 4 | 998,273 | 811 MB |
| official fastText + Python processes | 8 | 8 | 1,298,549 | 1,544 MB |
| official fastText + Python processes | 16 | 16 | 685,018 | 2,993 MB |
The important tradeoff is that multiprocessing can win peak throughput at 8 processes on this machine, but it does so by loading many model copies. The native-thread path keeps one model copy and has a much smaller memory footprint.
Stress Test
Run:
uv run python stress/stress_inference.py \
--model /path/to/model.bin \
--input /path/to/input.txt \
--threads 16 \
--callers 32 \
--duration 60
The stress test repeatedly calls one shared model from many Python threads and checks for crashes, exceptions, output count mismatches, order corruption, and RSS growth.
Development
uv sync --all-extras
uv run pre-commit run --all-files
uv run pytest
Native C++ tests can be run with:
uv run cmake -S . -B build -DFASTTEXT_THREADED_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release
uv run cmake --build build
uv run ctest --test-dir build --output-on-failure
Runtime-safety checks are available through sanitizer builds:
uv run cmake -S . -B build-asan \
-DFASTTEXT_THREADED_BUILD_TESTS=ON \
-DFASTTEXT_THREADED_ENABLE_ASAN=ON \
-DCMAKE_BUILD_TYPE=Debug
uv run cmake --build build-asan
uv run ctest --test-dir build-asan --output-on-failure
Use FASTTEXT_THREADED_ENABLE_TSAN=ON instead of ASAN for ThreadSanitizer.
Run the full stress tool locally for concurrency and memory-pressure testing.
Ruff and mypy are mandatory quality gates.
Release
Releases are published by GitHub Actions using PyPI Trusted Publishing. No long-lived PyPI token is required.
- Configure the PyPI project trusted publisher for this repository,
.github/workflows/release.yaml, and thepypiGitHub environment. - Require manual approval on the
pypienvironment. - Push a SemVer tag:
git tag v0.1.0
git push origin v0.1.0
The release workflow builds the source distribution plus Linux and macOS wheels
with cibuildwheel, validates all artifacts, and publishes them with PyPI
Trusted Publishing.
Limitations
- v1 targets Linux and macOS.
- Windows wheels are not part of the initial release.
- The primary speedup comes from batching. Per-row calls still pay Python call overhead and should not be used for throughput measurements.
Metadata
Release files for fasttext-threaded 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fasttext_threaded-0.1.0.tar.gz | 176.6 kB | Details |
Built distributions (wheels)
Total release size: 2.1 MB
Release files / fasttext_threaded-0.1.0.tar.gz
| Download URL | fasttext_threaded-0.1.0.tar.gz |
|---|---|
| Size | 176.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6b784f1c668a2f680875fdb2cbac7a65944fd4137e8cfd9b76e86274a8f72997
|
|
BLAKE2b-256 checksum How to use checksums |
0ce588bde8b12b17ccea551ce015501931fefdb110bbf46fb26c0ed1fea5ce5f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / fasttext_threaded-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | fasttext_threaded-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 241.0 kB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
88f7debaeca4c8c47d79e663561f2f1c1d4a90c64c42b7ee8f7d798fed54a9cb
|
|
BLAKE2b-256 checksum How to use checksums |
bf17dca321513f371f7161933f11fd7d32eb78babe6f8fa202302553a64cc730
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / fasttext_threaded-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | fasttext_threaded-0.1.0-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 202.8 kB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
cf4ab774ed9990fb3b6c98005b172a7e61512cbda79c685948719d2b14463151
|
|
BLAKE2b-256 checksum How to use checksums |
a2c9172f03d029661c8c0f32074124dfde019781deb31042210192b9023697ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / fasttext_threaded-0.1.0-cp312-cp312-macosx_10_13_x86_64.whl
| Download URL | fasttext_threaded-0.1.0-cp312-cp312-macosx_10_13_x86_64.whl |
|---|---|
| Size | 215.0 kB |
| Tags | CPython 3.12 macOS 10.13+ x86-64 |
|
SHA-256 checksum How to use checksums |
317cac8965b450ce54a73ed200f8c3689a31d44e38b1d2b6e70d833e1ee59c0b
|
|
BLAKE2b-256 checksum How to use checksums |
4407362998c159d52c1654aaf5598883c7037001b58441f3335426cde03fbec4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / fasttext_threaded-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | fasttext_threaded-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 236.8 kB |
| Tags | CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
d20d050511625ef213b821462cc08194a55c159dc238e10f3385b1f5c1ae9664
|
|
BLAKE2b-256 checksum How to use checksums |
26d5bdf1bd9b7eb963cca78d536c92a222ead59927bc768126fb3934a1d2bd69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / fasttext_threaded-0.1.0-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | fasttext_threaded-0.1.0-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 198.8 kB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
f542d9471f236b34b4fdb97d6a9a6118d20d1cc7ffa65cc523e0f855f42b6d6e
|
|
BLAKE2b-256 checksum How to use checksums |
ecb15098b956f0d4a81cf7db730b6a57681e3c8ce5013341dd54e8e4862e27ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / fasttext_threaded-0.1.0-cp311-cp311-macosx_10_9_x86_64.whl
| Download URL | fasttext_threaded-0.1.0-cp311-cp311-macosx_10_9_x86_64.whl |
|---|---|
| Size | 211.8 kB |
| Tags | CPython 3.11 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
edab6e957a7ca35e963c909b0a071b6389028e7981a2a72cdbdddd6d62802fb6
|
|
BLAKE2b-256 checksum How to use checksums |
e021480feac3d8c418b8286db89fb70790829f8abbd9e4e1155a741c3b9af2b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / fasttext_threaded-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | fasttext_threaded-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 236.4 kB |
| Tags | CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
1618434e82f513fd8fc51a5ea372a5ee30e0acfd7f38c0a199e228cadb86848c
|
|
BLAKE2b-256 checksum How to use checksums |
e9be307b3ce95fcbbd6f327e86ad57ee815f128ffd9e7f39c7c7ac574888dcc4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / fasttext_threaded-0.1.0-cp310-cp310-macosx_11_0_arm64.whl
| Download URL | fasttext_threaded-0.1.0-cp310-cp310-macosx_11_0_arm64.whl |
|---|---|
| Size | 197.7 kB |
| Tags | CPython 3.10 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
dba860a54c2a4d326847000bdd9ab55e32394c49db961bcab43d7bb471d8744c
|
|
BLAKE2b-256 checksum How to use checksums |
aaf58304f715fd023a6bfd58bfdd096c3b0cc5499cc9dee68a65ec07c3e32878
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / fasttext_threaded-0.1.0-cp310-cp310-macosx_10_9_x86_64.whl
| Download URL | fasttext_threaded-0.1.0-cp310-cp310-macosx_10_9_x86_64.whl |
|---|---|
| Size | 210.6 kB |
| Tags | CPython 3.10 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
10fa8788488bee94d8c1c16e8d88baef9bdcb3eddbf8b599a0bdc1d1aa38c8d1
|
|
BLAKE2b-256 checksum How to use checksums |
eab28bd322dc85f6ae4d871847fd9393c9a64ac5ed029fe10f61b9beb63713fd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency log