Model or dataset
chtmp223/topicGPT avatar
chtmp223/topicGPT

TopicGPT: Prompt-Based Topic Modeling With an Auditable Topic List

TopicGPT: A Prompt-Based Framework for Topic Modeling [NAACL'24]

418 stars65 forksPythonMIT

At a glance

What is it?
TopicGPT replaces the word distributions of LDA with an LLM-generated, editable topic list, then grounds every document assignment in a supporting quote. It is a research framework with a Python package, and the cost model is API tokens rather than CPU time.
Who is it for?
Adopt TopicGPT when you need topic labels a human can read, edit and defend, and when you can pay per-token API costs or run vLLM on your own GPUs. Do not adopt it when you need a deterministic model that reproduces bit-for-bit across runs, or when no external model call is acceptable.
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 93 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 TopicGPT solves: topics you can read and edit

Classical topic models return numbered topics and weighted word lists. Someone still has to look at topic 7, decide it means something, and write the label. TopicGPT inverts that. The model writes the topic labels first, in natural language, and then assigns documents to them. The paper is titled "TopicGPT: Topic Modeling by Prompting Large Language Models" and appeared at NAACL'24, so the intended audience is researchers and practitioners who want an inspectable topic list rather than a matrix of probabilities.

The package exposes five functions, and the split matters. generate_topic_lvl1 produces high-level, generalizable topics. generate_topic_lvl2 produces low-level topics specific to each high-level topic, building a hierarchy. refine_topics merges near-duplicate topics and removes low-frequency ones. assign_topics maps the generated topics onto the input text, and correct_topics reprompts the model so the final assignment is grounded in the topic list. That last step is the interesting design choice: the framework assumes the first assignment pass can drift, and spends extra tokens to pull it back.

How the pipeline moves data from jsonl to a grounded topic list

The data flow is file-based. Input is a .jsonl file where each line has an optional id, a text field, and an optional label field for ground-truth comparison. The README says to put that file in data/input, and ships data/input/sample.jsonl for debugging. Outputs land in data/output.

Each pipeline stage takes a prompt file, a topic file, and an output file. The prompts live in the prompt/ directory at the top level of the repository, which means you can read and edit the instructions the model receives without touching Python. That is the mechanism behind the name: the topic model is a prompt, and the prompt is a file you can diff.

Generation and assignment are deliberately separable. The README advises using a weaker model for assignment when working with paid APIs, because assignment runs over every document while topic generation runs over a sample. If you have GPUs, vLLM is supported as a deployment path; setup.py declares it as an extra, vllm>=0.6.3.post1,<1.0.0, so it is not pulled in by a plain install. The metrics module, topicgpt_python.metrics, computes Adjusted Rand Index, Harmonic Purity, and Normalized Mutual Information against the label field, which is how the paper's comparisons are made.

Installing topicgpt_python and running one stage

The README asks for a Python 3.9+ environment made with virtualenv or conda, and setup.py confirms python_requires=">=3.9". The package name on PyPI is topicgpt_python, which is not the same string as the repository name, so pip install topicgpt is not the documented command.

bash
pip install topicgpt_python

Before any call, the provider credentials have to be in the environment. The README lists one variable set per deployment, and you only need the block for the provider you use.

bash
export OPENAI_API_KEY={your_openai_api_key}
export GEMINI_API_KEY={your_gemini_api_key}
export AZURE_OPENAI_API_KEY={your_azure_api_key}
export AZURE_OPENAI_ENDPOINT={your_azure_endpoint}

For Vertex AI the two variables are VERTEX_PROJECT and VERTEX_LOCATION. With credentials set, the first real use is generating high-level topics over the sample file. The README shows the call signature with positional arguments, and the optional config.yml at the repository root is loaded with yaml.safe_load to define I/O paths.

python
import yaml
from topicgpt_python import *

with open("config.yml", "r") as f:
    config = yaml.safe_load(f)

generate_topic_lvl1(api, model, data, prompt_file, seed_file, out_file, topic_file, verbose)

What you should see is a topic file containing the generated high-level topics and an output file for the generation run. The README points to demo.ipynb for the complete pipeline and to the data/output folder for sample outputs, so compare against those before scaling up. The README also advises running on a subset with cheaper or open-source models first.

Where TopicGPT is the wrong tool

The honest limitation is that this is not a statistical model. There is no likelihood, no convergence criterion, and no posterior. Two runs with the same data can produce different topic lists because the generator is a language model, and the framework's answer to that is correct_topics, an extra reprompting pass, not a determinism guarantee. If your work needs a reproducible artifact that a reviewer can regenerate exactly, that is a real problem, and the README does not document a seeding or caching mechanism that would fix it.

Cost is the second constraint. The README links to OpenAI and Vertex pricing pages rather than quoting numbers, which is the right call given how often those change, but it means you have to estimate yourself. Assignment and correction touch every document, so a corpus of a few hundred thousand texts is a token bill, not a compute bill. The vLLM path avoids per-token charges but needs GPUs, and the extra is version-pinned, so you are managing CUDA-level dependencies.

There is also a data-shape constraint. Input is text documents in jsonl with an optional label. If your unit of analysis is a short phrase, a time series, or an image, the pipeline has nothing to say. And the prompt files are English-language instructions; the README does not describe a multilingual path.

TopicGPT compared with LDA and BERTopic

LDA is the baseline this work is positioned against, and the difference is structural. LDA infers latent distributions over a fixed vocabulary and returns words per topic; you interpret afterward. TopicGPT asks a model to state topics in words and then assigns documents to those stated topics, with the assignment carrying a supporting quote. The quote is the part LDA cannot give you: a span of the original document that justifies the label.

BERTopic sits between them. It embeds documents, clusters the embeddings, and derives topic representations from the clusters, typically with a class-based TF-IDF or a language model for labeling. The clustering step is deterministic given the embedding model, so BERTopic gives you stable cluster membership and an unstable label, while TopicGPT gives you a stable label vocabulary and model-dependent membership. The README's metrics module, with Adjusted Rand Index, Harmonic Purity, and Normalized Mutual Information, is designed for exactly this kind of comparison against ground-truth labels, which is how the paper evaluates the approach.

If your corpus has a label field and you want to measure topic quality against it, TopicGPT ships the measurement. If you want speed on a large corpus with no external API, BERTopic's local embedding pipeline is the more direct fit.

Maintenance, licence and the upgrade surface

The repository is not archived, and the last push was on 2026-06-15. The release history shows v0.2.0 introducing the topicgpt_python package in November 2024, v0.2.2 removing redundant parameters, and v0.2.7 adding Ollama support in March 2025. setup.py declares version 0.2.8, one step past the newest release listed, which is normal for a repository that ships from source as well as PyPI.

The dependency list is where upgrade cost lives. requirements.txt pins upper bounds on openai (<2.0.0), anthropic (<1.0.0), vertexai (<2.0.0), numpy (<2.0.0), pandas (<3.0.0), and sentence-transformers (<4.0.0), among others. Those caps protect you from breaking changes but also mean the package will lag behind major provider SDK releases until the maintainers widen them. The vllm extra is capped below 1.0.0. Upgrading the package is therefore a coordinated move, not a drop-in.

The licence is MIT, which is permissive and places few obligations on redistribution. Note that the licence covers this code; the model you call through it carries its own terms, and the README defers pricing and usage questions to the provider pages. That is a distinction worth checking before you route a proprietary corpus through a hosted API.

Editorial conclusion

Adopt TopicGPT when you need topic labels a human can read, edit and defend, and when you can pay per-token API costs or run vLLM on your own GPUs. Do not adopt it when you need a deterministic model that reproduces bit-for-bit across runs, or when no external model call is acceptable. Before committing, verify two things yourself: whether your provider and model are actually supported by the api argument you pass, and what a full pass over your corpus costs at the assign and correct stages, since those run over every document.

Frequently asked questions

What is TopicGPT and what does it do?

It is a prompt-based topic modeling framework, published as the NAACL'24 paper "TopicGPT: Topic Modeling by Prompting Large Language Models." The topicgpt_python package generates high-level and low-level topics, refines them, assigns them to documents with a supporting quote, and corrects the assignments.

How do I install TopicGPT?

Create a Python 3.9+ environment with virtualenv or conda, then run pip install topicgpt_python. After that, export the API key for your provider, such as OPENAI_API_KEY or GEMINI_API_KEY, before calling any pipeline function.

Which model providers does TopicGPT support?

The README lists OpenAI API, Vertex AI, Azure API, Gemini API, and vLLM, the last requiring GPUs for inference. Ollama support was added in release v0.2.7. Credentials are supplied through environment variables named per provider.

What input format does TopicGPT expect?

A .jsonl file with an optional id, a text field for the document, and an optional label field for ground-truth labels. The README says to place it in data/input, and a sample.jsonl file is included for debugging.

How do I evaluate the topics TopicGPT produces?

The topicgpt_python.metrics module provides Adjusted Rand Index, Harmonic Purity, and Normalized Mutual Information to compare generated topics against ground-truth labels. Those metrics require the optional label field in your input data.

Is TopicGPT free to use?

The code is MIT licensed, but the README points to the OpenAI and Vertex AI pricing pages for model costs. Running the pipeline through a hosted API is billed per token, while the vLLM path requires your own GPUs.

Official sources

  1. chtmp223/topicGPT on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes