Topica: fast, all-purpose topic modeling for Python — a Rust core for LDA, STM, and more
Project description
Topica: fast, all-purpose topic modeling for Python
topica is a fast topic-modeling library for Python with more than a dozen models, built for social scientists who want to move from text data to publishable results in a single workflow. It brings together models and tools usually split across JVM software like MALLET and R packages like stm, and runs them on a parallel Rust core competitive with the standard implementations, with reproducible fits: the variational models are identical to the bit, and the samplers reproduce from a fixed seed and thread count. Each model comes with the validation, covariate-effect, and reporting tools to meet the standards reviewers expect.
pip install topica
The core needs only NumPy. Optional extras add features without weighing the core
down: topica[viz] (matplotlib plots), topica[formula] (R-style formulas),
topica[polars] (Polars frames), and topica[llm] (LLM labels and embeddings,
OpenAI or local via ollama). PyTorch is never required.
from topica import LDA
model = LDA(num_topics=2, seed=42)
model.fit([["cat", "dog", "fish"]] * 15 + [["planet", "star", "moon"]] * 15, iters=1000)
for i, words in enumerate(model.top_words(3)):
print(f"Topic {i}:", " ".join(w for w, _ in words))
See the getting-started guide and the worked examples for end-to-end analyses.
Models
Count-based models learn topics from word counts (collapsed Gibbs, variational EM, or an amortized VAE):
| Model | What it's for |
|---|---|
LDA |
Classic topics via fast collapsed-Gibbs (SparseLDA); optional multi-threaded and LightLDA alias samplers |
STM |
The Structural Topic Model: correlated topics with prevalence and content covariates |
STS |
Structural Topic and Sentiment-Discourse: covariate-driven topic sentiment/tone on top of STM |
CTM |
Correlated topics (logistic-normal) |
DMR |
Topics conditioned on document metadata (Dirichlet-multinomial regression) |
DTM |
Dynamic topics that evolve across time slices |
HDP |
Nonparametric LDA that infers the number of topics |
keyATM / seededlda |
Guided topics steered by seed words |
ProdLDA |
Sharper, more coherent topics via a product-of-experts word model, fit as an amortized VAE (no PyTorch) |
PT / GSDMM |
Short-text models for tweets, survey answers, headlines |
SupervisedLDA |
Topics shaped to predict a per-document response |
LabeledLDA |
Supervised topics tied to document labels |
SAGE |
Content-covariate topics: the same topic worded differently across groups |
PA / HLDA |
Topic hierarchies (Pachinko, nested-CRP) |
Embedding-based models start from document embeddings you supply (no PyTorch, no UMAP/numba in the wheel):
| Model | What it's for |
|---|---|
BERTopic |
Cluster document embeddings, label topics by class-TF-IDF; topic reduction and a soft per-document distribution |
Top2Vec |
Topics as points in the embedding space; topic words are the nearest word vectors |
ETM |
Generative LDA with the topic-word distribution factored through embeddings (β = softmax(ρ·α)); per-document EM or an amortized VAE (inference="vae") |
FASTopic |
Topics read off two optimal-transport plans between document, topic, and word embeddings |
Every model exposes the same shape: fit(docs, …), then topic_word (φ), doc_topic (θ), top_words(n), and save/load. The count-based variational models (CTM/STM/STS/SupervisedLDA/DTM) parallelize across cores while staying bit-for-bit deterministic. The embedding models split into two kinds: BERTopic and Top2Vec run the reduce → cluster → represent pipeline, while ETM and FASTopic are generative and mixed-membership; all of them take vectors from any embedder (sentence-transformers, an API, a local model such as ollama). Full guides: the models and embedding topics.
Diagnostics & analysis
Model-agnostic: they work on any fitted model's topic_word/doc_topic:
- Quality:
coherence(u_mass,c_v,c_uci,c_npmi; computed in the Rust core),exclusivity,topic_diversity,quality_frontier - Labeling:
label_topics(prob / FREX / lift / score),frex,relevance,find_thoughts,topic_table,summary - Validation:
word_intrusion,document_intrusion,bootstrap_stability,search_k - Reliability:
select_model(fit many seeds) andensemble(combine runs into a consensus more reliable than any single fit — cluster/align/stable methods, the last a gensimEnsembleLdaport) - Comparison:
fighting_words(weighted log-odds) for contrasting corpora - Covariate effects:
estimate_effect(method of composition, cluster-robust SEs, GLM links),topic_correlation, and the design helpersone_hot(top level) plusstm.spline/stm.interaction(anstm-style API);posterior_theta_samplesdraws θ for the logistic-normal models (STM/CTM) - Preprocessing:
tokenize,learn_phrases/apply_phrases,split_documents, theCorpusclass
See diagnostics and covariate effects.
Performance
topica runs on a parallel Rust core. It is several times faster than R stm — the single-threaded field standard — for the structural and other variational models, and it matches the hand-tuned compiled samplers core for core: parity with Java MALLET on plain LDA and with the C++ keyATM on keyword models. On the political-blog corpus (2,000 documents, fit time only, same iterations on both sides):
| Model | Reference | topica speedup |
|---|---|---|
| STM | R stm |
3–6× single-threaded, ~10–22× multithreaded |
| LDA | Java MALLET | parity single-threaded; multithread speedup grows with corpus size |
| keyATM | R keyATM |
parity single-threaded, ~2× multithreaded |
For the approximate parallel Gibbs samplers the multithreaded speedup grows with corpus size: the per-sweep count-table merge is fixed overhead, so larger corpora amortize it over more sampling work. LDA's eight-core speedup over MALLET runs about 3× at 2,000 documents and reaches ~4× at 5,000, so the small-corpus figures above understate what large-corpus users see.
Every fit is reproducible from a fixed seed and validated against its reference. See Benchmarks for the full methodology; reproduce the 2,000-document table with python benchmarks/speed_vs_r.py and the size-varying curve with python benchmarks/speed_vs_size.py.
Install from source
pip install maturin
git clone https://github.com/nealcaren/topica && cd topica
python -m venv .venv && source .venv/bin/activate
maturin develop --release --features python
Requires numpy >= 1.21. Use --release (the debug build is much slower).
Acknowledgements
Topica stands on a generation of open topic-modeling research and code. Each entry below lists the reference, its authors and year, and the topica class(es) it underlies; the other models are Rust ports or reimplementations, validated against these reference implementations.
- MALLET (McCallum, 2002) —
LDA,DMR,LabeledLDA: the SparseLDA sampler, Dirichlet-multinomial regression, and hyperparameter optimization.LDAbinds David Mimno's RustMallet (Apache-2.0), reproducing itstrainCLI byte-for-byte; against Java MALLET (a different RNG) it recovers the same topics (cosine 1.000) - stm (Roberts, Stewart & Tingley, 2019) —
STM,CTM,SAGE: variational EM,estimateEffect,searchK, FREX, spectral initialization, and the method of composition - sts (Chen & Mankad, 2024) —
STS: the Structural Topic and Sentiment-Discourse model — the joint prevalence/sentiment Laplace E-step and the Poisson topic-word M-step, validated against the package - lda-c / ctm-c / dtm and hdp (Blei lab, 2006–2007) —
CTM,DTM,HDP: the CTM, Dynamic Topic Model, and HDP samplers - gensim (Řehůřek & Sojka, 2010) —
DTM,ensemble: coherence measures, theLdaSeqModelDTM reference, and theEnsembleLda(CBDBSCAN stable-topic) method ported forensemble(method="stable") - tomotopy (bab2min, 2020) — API conventions (
summary, the short-text models) - keyATM (Eshima, Imai & Sasaki, 2024) —
KeyATM: the base, covariate, and dynamic models, the information-theory token weighting, and the Chib (1998) change-point HMM, validated against the package - seededlda (Watanabe, 2023) —
SeededLDA: the seeded-prior scheme - LightLDA (Yuan et al., 2015) —
LDA: the alias-table Metropolis-Hastings sampler - GSDMM (Yin & Wang, 2014) —
GSDMM: the movie-group-process mixture for short text - ProdLDA / AVITM (Srivastava & Sutton, 2017) —
ProdLDA: autoencoding variational inference and the product-of-experts word model - BERTopic (Grootendorst, 2022) and Top2Vec (Angelov, 2020) —
BERTopic,Top2Vec: the embedding-clustering pipeline, class-based TF-IDF, and thereduce → cluster → representdesign - ETM (Dieng, Ruiz & Blei, 2020) —
ETM: the Embedded Topic Model (per-document variational EM and an amortized VAE) - FASTopic (Wu et al., 2024) —
FASTopic: the optimal-transport topic model
The embedding-native models build on two pure-Rust crates: petal-clustering for HDBSCAN and umap-rs for the optional UMAP reducer, both BLAS-free.
Full citations for every model and reference implementation, and how to cite topica, are on the Citing page.
License
Apache-2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file topica-0.16.2.tar.gz.
File metadata
- Download URL: topica-0.16.2.tar.gz
- Upload date:
- Size: 3.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ecbed06f7424ca822a247fb4df932d22b1fc6732e58a12e1ee148af3a4ce365
|
|
| MD5 |
376fadb427ba5d74196c826abe87a6ff
|
|
| BLAKE2b-256 |
8b72fa05834faa486de64b6d4ce4b2f1daeb8df3dd723cd06322a1582bded638
|
Provenance
The following attestation bundles were made for topica-0.16.2.tar.gz:
Publisher:
CI.yml on nealcaren/topica
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
topica-0.16.2.tar.gz -
Subject digest:
8ecbed06f7424ca822a247fb4df932d22b1fc6732e58a12e1ee148af3a4ce365 - Sigstore transparency entry: 1809367852
- Sigstore integration time:
-
Permalink:
nealcaren/topica@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Branch / Tag:
refs/tags/v0.16.2 - Owner: https://github.com/nealcaren
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file topica-0.16.2-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: topica-0.16.2-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
695ced2e76725304ba880a9561178e84c842f9f8fbcec44bd3216a768901c670
|
|
| MD5 |
60486184aadec7ede29d9d0088b21d19
|
|
| BLAKE2b-256 |
dfddfb109d32f1a56ab2dca2450b2cb5311d5df7b7f2b7c930898feb1db90981
|
Provenance
The following attestation bundles were made for topica-0.16.2-cp39-abi3-win_amd64.whl:
Publisher:
CI.yml on nealcaren/topica
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
topica-0.16.2-cp39-abi3-win_amd64.whl -
Subject digest:
695ced2e76725304ba880a9561178e84c842f9f8fbcec44bd3216a768901c670 - Sigstore transparency entry: 1809368235
- Sigstore integration time:
-
Permalink:
nealcaren/topica@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Branch / Tag:
refs/tags/v0.16.2 - Owner: https://github.com/nealcaren
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file topica-0.16.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: topica-0.16.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bf7a58038e829fcca921ea56a3364cd5ba2ab2d995e656d587c6030da334ca5
|
|
| MD5 |
40547ebd153e969461325b741889a85a
|
|
| BLAKE2b-256 |
9d989c4f3013b6d93934f3e8e5138afb4d9ece9e507f0fbcc4c51f7989207f92
|
Provenance
The following attestation bundles were made for topica-0.16.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
CI.yml on nealcaren/topica
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
topica-0.16.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
3bf7a58038e829fcca921ea56a3364cd5ba2ab2d995e656d587c6030da334ca5 - Sigstore transparency entry: 1809368039
- Sigstore integration time:
-
Permalink:
nealcaren/topica@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Branch / Tag:
refs/tags/v0.16.2 - Owner: https://github.com/nealcaren
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file topica-0.16.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: topica-0.16.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.5 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
330de4803742fa763ccddc04605bef51bc10295301565357b925c3ba750a377e
|
|
| MD5 |
12435cbdcb36a4d77968b5219fdf019a
|
|
| BLAKE2b-256 |
60b0eaa9ebe0f4c37fdb2c4b641491bc2157ecbbafd442ddd5a6376b8e2de506
|
Provenance
The following attestation bundles were made for topica-0.16.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
CI.yml on nealcaren/topica
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
topica-0.16.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
330de4803742fa763ccddc04605bef51bc10295301565357b925c3ba750a377e - Sigstore transparency entry: 1809367951
- Sigstore integration time:
-
Permalink:
nealcaren/topica@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Branch / Tag:
refs/tags/v0.16.2 - Owner: https://github.com/nealcaren
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file topica-0.16.2-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: topica-0.16.2-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.4 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11cbee1386206189bb5daed2f911ccc2ca856929b2785f386af2d43d21eb5f2f
|
|
| MD5 |
6de1069831c81b3a1ca3e98ddbe49637
|
|
| BLAKE2b-256 |
aed5cbe7dbfc5704bcb5cba8a72f74944de6f828818af9ad6df9c69ecf9084c6
|
Provenance
The following attestation bundles were made for topica-0.16.2-cp39-abi3-macosx_11_0_arm64.whl:
Publisher:
CI.yml on nealcaren/topica
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
topica-0.16.2-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
11cbee1386206189bb5daed2f911ccc2ca856929b2785f386af2d43d21eb5f2f - Sigstore transparency entry: 1809368141
- Sigstore integration time:
-
Permalink:
nealcaren/topica@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Branch / Tag:
refs/tags/v0.16.2 - Owner: https://github.com/nealcaren
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file topica-0.16.2-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: topica-0.16.2-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.5 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96b0dc981fef3b9301438c2fdec40b194ec5e1ddb1b7fbee0ccec2e7c95a49cf
|
|
| MD5 |
b170b2b0a8018767fb4bc4762ba4d687
|
|
| BLAKE2b-256 |
e25a60199d26f3811018fc6cc3459993d2f5979ed165a687c93bae056333507e
|
Provenance
The following attestation bundles were made for topica-0.16.2-cp39-abi3-macosx_10_12_x86_64.whl:
Publisher:
CI.yml on nealcaren/topica
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
topica-0.16.2-cp39-abi3-macosx_10_12_x86_64.whl -
Subject digest:
96b0dc981fef3b9301438c2fdec40b194ec5e1ddb1b7fbee0ccec2e7c95a49cf - Sigstore transparency entry: 1809368313
- Sigstore integration time:
-
Permalink:
nealcaren/topica@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Branch / Tag:
refs/tags/v0.16.2 - Owner: https://github.com/nealcaren
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@0cad27a9b9d3e5a3e392458b444d50c9efcf0ad2 -
Trigger Event:
push
-
Statement type: