small-text: Active Learning for Text Classification, and When Labeling Budgets Are the Real Constraint
Active Learning for Text Classification in Python
At a glance
- What is it?
- small-text is an MIT-licensed Python library that wraps sklearn, PyTorch and transformers classifiers behind one active learning loop with swappable query strategies. The current release line is a 2.0.0 development series, so the interfaces you build on today are not frozen yet.
- Who is it for?
- Adopt small-text if you already have a text classifier you trust and the bottleneck is how many labels you can afford, not which model to use. Skip it if you need a stable API today or if your labels arrive in bulk anyway, since the loop adds a pool management layer for no benefit.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 114 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The Problem small-text Solves Is Label Cost, Not Model Quality
Most text classification tutorials assume you have a labeled corpus. In practice you often have a large pool of unlabeled documents and a person who can annotate a few hundred of them. The question small-text addresses is which few hundred. Its README states the library "allows you to efficiently label training data for supervised learning when you have little to no labeled data." That framing matters, because it means the library is not competing with your classifier. It sits on top of one.
The audience is therefore narrow and specific. You are a researcher or engineer who has already chosen a classifier, whether that is a scikit-learn estimator, a PyTorch module, or a transformer model, and you want to reduce the number of annotations needed to reach a given accuracy. The README lists applications in biomedical research, social science, information science, computer science, and political communication, including systematic literature reviews and detecting employment status disclosures on social media. Those are settings where annotation requires domain expertise and cannot be crowdsourced cheaply.
If your labels are already collected, or if you are annotating everything regardless, small-text is overhead. It adds a pool, a strategy, and a stopping decision to a pipeline that would otherwise be a single fit call.
Query Strategies, Initialization Strategies and Stopping Criteria as Interchangeable Parts
The architecture the README describes is a composition model. The library provides "several pre-implemented query strategies, initialization strategies, and stopping criteria" that can be "easily mixed and matched." Those three component types map onto the three decisions an active learning loop has to make.
Initialization decides what to label first, before any model exists to score the pool. Query strategies decide which unlabeled instances to request next, given a trained model and the remaining pool. Stopping criteria decide when the marginal gain no longer justifies another annotation round. Keeping these separate is the design choice that makes the library useful for experiments: you can hold the classifier fixed and vary only the query strategy, which is exactly the comparison an active learning paper needs.
The README states the library "provides unified interfaces for Active Learning, allowing you to easily mix and match query strategies with classifiers provided by sklearn, PyTorch, or transformers." That is the actual mechanism. The classifier is wrapped rather than replaced, so a scikit-learn linear model and a transformer can be driven by the same loop. The 2.0.0.dev4 release notes mention "new functionality such as vector indices," which suggests the pool representation is being reworked, but the changelog is the place to confirm what that means in code. The README does not describe the vector index mechanism, so I cannot say more about it here.
Installation: Two Extras and a Python Floor
The README gives the base install as pip install small-text, described as "a slim installation with only the necessary dependencies." The full install adds the transformers extra: pip install small-text[transformers]. There is also a conda-forge package, referenced by the badge at the top of the README, though the README does not give the conda command itself.
Two constraints are stated explicitly. The library "requires Python 3.10 or newer," and GPU use requires "CUDA 10.1 or newer." The README also notes that a GPU "is supported but not required," and that CPU-only use cases "require only a lightweight installation with minimal dependencies." That is a real deployment advantage: if your query strategy works with a scikit-learn classifier, you can run the loop on a laptop or a small CI runner without pulling in the transformers stack.
The README points to three runnable examples rather than inline code: examples/examplecode/binary_classification.py, examples/examplecode/pytorch_multiclass_classification.py, and examples/examplecode/transformers_multiclass_classification.py. It also references a notebook series, with the first entry titled "Intro: Active Learning for Text Classification with Small-Text." I have not run any of these. If you want to evaluate the library, those three files are the cheapest starting point because each one targets a different classifier backend, and comparing them shows you what the unified interface actually abstracts.
The 2.0.0 Development Series Is the Main Adoption Risk
The most recent release is v2.0.0.dev4, dated May 23rd, 2026. The release notes call it "a development release with the most changes so far" and say you "can consider it an alpha release, which does not guarantee you stable interfaces yet, but is otherwise ready to use." That sentence contains both the opportunity and the problem. You get "refined interfaces, new query strategies, improved classifiers, and new functionality such as vector indices," but the project is telling you directly that the API may move.
The release cadence reinforces this. v2.0.0.dev2 landed in May 2025, dev3 in August 2025, and dev4 in May 2026. The last stable line mentioned in the README is v1.4.1 from August 2024, described as a bugfix release. So there is a roughly two-year gap between the last stable release and the current development work. Anyone adopting today is choosing between a stable but older API and a newer API that the maintainers describe as alpha.
For a research codebase where you control the environment, that trade-off is usually acceptable. For a production service that needs to survive a dependency bump, it is not, unless you pin the version and budget time for migration. The README does not state a timeline for a stable 2.0.0, and I would not assume one.
When Active Learning Is the Wrong Tool
Active learning assumes labels are expensive and unlabeled data is abundant. If either assumption fails, the loop costs more than it saves. A team that has already labeled 50,000 documents does not need a query strategy; it needs a better classifier or better features. A team whose annotation is done in one batch by an external vendor has no way to interleave model training with labeling, so the sequential loop never closes.
There is a second failure mode that the README does not address: the loop depends on the model's uncertainty or diversity estimates being meaningful. A poorly calibrated classifier will nominate the wrong examples, and the library cannot detect that for you. The stopping criteria help here, but they are heuristics. If your query strategy consistently selects outliers or annotation artifacts rather than informative examples, you will spend labels confirming that. The README lists stopping criteria as a feature but does not describe how any of them decide to stop, so you should read that part of the documentation before trusting a run to terminate sensibly.
Finally, the library is scoped to text classification. Sequence labeling, generation, and ranking are outside what the README describes. The topics list includes language-models and llms, but the description stays on classification.
Compared with modAL: Pool-Based Wrapping Versus a General Framework
The closest comparison in the Python ecosystem is modAL, a general-purpose active learning framework built around scikit-learn. Both libraries let you swap query strategies and both wrap an existing estimator. The difference is scope and dependency surface.
modAL is not tied to text. It works with any scikit-learn compatible estimator and any feature matrix, which means it fits tabular, image, and text problems through the same interface. small-text is narrower: it targets text classification specifically, and its distinguishing feature is that it integrates transformers so you can drive a pretrained language model through the loop. If you are working with text and want to use a transformer as the classifier, modAL gives you less out of the box because the wrapping and fine-tuning path is not its focus. If you are working with text but using a bag-of-words model, modAL is a reasonable substitute and has a wider user base outside NLP.
The README does not name modAL or any other alternative, so this comparison is based on what each library describes about itself rather than on a benchmark. I have not run either against the other. The practical way to decide is to look at the classifier you intend to use: if it is a transformer, small-text's transformers extra and its example file are the shorter path.
Licence, Maintenance and the Cost of Keeping Up
small-text is MIT licensed, which is permissive and places few obligations on how you use or redistribute it. The repository is not archived, and the README carries a "Maintained Yes" badge alongside a "Contributions Welcome" badge and a CONTRIBUTING.md file. The topics list includes "looking-for-contributors," which is a signal about the project's own view of its capacity. A Zenodo DOI is present, pointing to a citable archive of the software, which matters if you need to reference a specific version in a paper.
The maintenance cost you should plan for is version migration, not bug fixes. Because the current line is a development series, upgrading from dev3 to dev4 is not guaranteed to be drop-in. The README directs readers to the changelog for "a full list of changes" in v2.0.0.dev4. The practical step is to pin small-text to an exact version in your requirements file, record which one your experiments used, and read the changelog before moving. If you are publishing results, cite the Zenodo DOI for the version you ran rather than the project generally.
This is not legal advice. The MIT licence text in the LICENSE file is what governs your use, and if you are redistributing the library or a modified version, read it rather than relying on the one-line summary above.
Editorial conclusion
Adopt small-text if you already have a text classifier you trust and the bottleneck is how many labels you can afford, not which model to use. Skip it if you need a stable API today or if your labels arrive in bulk anyway, since the loop adds a pool management layer for no benefit. Before committing, pin the exact version you evaluated and re-run your baseline after any upgrade, because the 2.0.0 development series is documented as not guaranteeing stable interfaces.
Community notes