offline-token-counter
offline-token-counter 是一个轻量级 Python 库,专为需要完全离线、精确计数大语言模型 Token 的场景而设计。将所有主流模型的 tokenizer 数据直接打包在安装包内,无需联网、无需额外下载,开箱即用。支持对字符串(str)、对话消息(messages)和工具调用(tools)三种输入格式进行精确 Token 计数,全面覆盖大模型应用开发中的各类使用场景。
特性
- 完全离线 — tokenizer 文件随包分发,无需联网下载
- 多模型支持 — 支持 429 个模型别名,覆盖 47 个独立 tokenizer(含 DeepSeek、Qwen、GLM、MiniMax、JiuTian、Janus 等系列)
- 多种输入格式 — 纯文本、对话消息、工具调用
- 智能解析 — 支持组织前缀剥离、大小写容错、模糊拼写纠错
- 无
transformers依赖 — 仅依赖轻量tokenizers、jinja2、sentencepiece
支持的模型
DeepSeek 系列
| 模型名称 | 数据目录 | 词表大小 |
|---|---|---|
| deepseek-llm-7b-base | deepseek-llm-7b-base | 100,015 |
| deepseek-coder-33b-base | deepseek-coder-33b-base | 32,022 |
| deepseek-coder-7b-base-v1.5 | deepseek-coder-7b-base-v1.5 | 100,016 |
| deepseek-v2 | deepseek-v2 | 100,002 |
| deepseek-v2.5 | deepseek-v2.5 | 100,018 |
| deepseek-v3 | deepseek-v3 | 128,818 |
| deepseek-v3.1 | deepseek-v3.1 | 128,818 |
| deepseek-v3.2 | deepseek-v3.2 | 128,818 |
| deepseek-v4 | deepseek-v4 | 129,283 |
| deepseek-r1 | deepseek-r1 | 128,818 |
| deepseek-r1-0528-qwen3-8b | deepseek-r1-0528-qwen3-8b | 151,671 |
| deepseek-r1-distill-llama-8b | deepseek-r1-distill-llama-8b | 128,256 |
| deepseek-r1-distill-qwen-7b | deepseek-r1-distill-qwen-7b | 151,665 |
| deepseek-vl-7b-base | deepseek-vl-7b-base | 100,016 |
| deepseek-vl2 | deepseek-vl2 | 128,826 |
| deepseek-vl2-small | deepseek-vl2-small | 100,011 |
| deepseek-ocr | deepseek-ocr | 128,830 |
Qwen 系列
| 模型名称 | 数据目录 | 词表大小 |
|---|---|---|
| qwen-2.5 | qwen-2.5 | 151,665 |
| qwen-3 | qwen-3 | 151,669 |
| qwen-3.5 | qwen-3.5 | 248,070 |
| qwen-3.6 | qwen-3.5 | 248,070 |
| qwen-vl | qwen-2.5 | 151,665 |
| qwen2-vl-2b | qwen2-vl-2b | 151,655 |
| qwen2-vl-2b-instruct-awq | qwen2-vl-2b-instruct-awq | 151,657 |
| qwen2.5-72b-instruct-awq | qwen2.5-72b-instruct-awq | 151,665 |
| qwen2.5-math-prm-7b | qwen2.5-math-prm-7b | 151,652 |
| qwen2.5-omni-3b | qwen2.5-omni-3b | 151,665 |
| qwen2.5-omni-7b-awq | qwen2.5-omni-7b-awq | 151,665 |
| qwen2.5-vl-3b-instruct-awq | qwen2.5-vl-3b-instruct-awq | 151,665 |
| qwen3-235b-a22b-mlx-4bit | qwen3-235b-a22b-mlx-4bit | 151,670 |
| qwq-32b | qwq-32b | 151,669 |
GLM 系列
| 模型名称 | 数据目录 | 词表大小 |
|---|---|---|
| glm-4 | glm-4 | 151,343 |
| glm-4v | glm-4 | 151,343 |
| glm-4-32b-0414 | glm-4-32b-0414 | 151,343 |
| glm-4-9b-0414 | glm-4-32b-0414 | 151,343 |
| glm-z1-9b-0414 | glm-4-32b-0414 | 151,343 |
| glm-z1-32b-0414 | glm-4-32b-0414 | 151,343 |
| glm-4.5v | glm-4.5v | 151,365 |
| glm-4.6v | glm-4.5v | 151,365 |
| glm-4.6v-flash | glm-4.5v | 151,365 |
| glm-4.7-flash | glm-4.7-flash | 154,856 |
| glm-5 | glm-4.7-flash | 154,856 |
| glm-5.1 | glm-4.7-flash | 154,856 |
| glm-5.2 | glm-4.7-flash | 154,856 |
MiniMax 系列
| 模型名称 | 数据目录 | 词表大小 |
|---|---|---|
| minimax | minimax | ~200,054 |
| minimax-m1-40k | minimax-m1-40k | ~200,036 |
| minimax-m3 | minimax-m3 | ~200,061 |
| minimax-text-01 | minimax-text-01 | ~200,026 |
JiuTian 系列
| 模型名称 | 数据目录 | 词表大小 |
|---|---|---|
| jt-coder-8b-base | jt-coder-8b-base | 151,667 |
| jt-math-8b-instruct | jt-math-8b-instruct | 151,665 |
| jt-da-8b | jt-da-8b | 151,665 |
| jiutian-139moe-chat | jiutian-139moe-chat | 69,120 |
Janus 系列
| 模型名称 | 数据目录 | 词表大小 |
|---|---|---|
| janus-1.3b | janus-1.3b | 100,594 |
| janus-pro-1b | janus-pro-1b | 100,590 |
| janus-pro-7b | janus-pro-7b | 100,603 |
| janusflow-1.3b | janusflow-1.3b | 100,008 |
SynLogic 系列
| 模型名称 | 数据目录 | 词表大小 |
|---|---|---|
| synlogic-32b | qwen-2.5 | 151,665 |
| synlogic-7b | qwen-2.5 | 151,665 |
| synlogic-mix-3-32b | qwen-2.5 | 151,665 |
快速别名参考
| 别名 | 解析为 |
|---|---|
v3 |
deepseek-v3 |
v4 |
deepseek-v4-pro |
r1 |
deepseek-r1 |
qwen2.5 |
qwen-2.5 |
qwen3 |
qwen-3 |
glm4 |
glm-4 |
glm4v |
glm-4v |
安装
pip install offline-token-counter
本地开发:
pip install -e ".[test]"
用法
from offline_token_counter import count_tokens
# 纯文本计数
count_tokens("Hello, world!")
# => 4 (deepseek-v4)
# 指定模型
count_tokens("你好", model="qwen-2.5")
# 对话消息
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"},
]
count_tokens(messages, model="glm-4")
# 带工具定义
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"},
},
"required": ["location"],
},
},
},
]
count_tokens(messages, tools=tools, model="deepseek-r1")
API
count_tokens(messages, tools=None, model="deepseek-v4")
| 参数 | 类型 | 说明 |
|---|---|---|
| messages | str 或 list[dict] |
文本字符串或消息字典列表 |
| tools | list[dict] | None |
工具定义(OpenAI function-calling 格式) |
| model | str |
模型名称或别名(默认 "v3") |
返回: int — Token 数量。
异常: 不抛异常。失败时自动降级为启发式估算。
版本记录
v0.1.1
- 修复:30 个模型的
chat_template.jinja文件内容为"Entry not found"(下载工具错误),删除后改用tokenizer_config.json中的合法模板 - 修复:
qwen2.5-72b-instruct-awq的tokenizer.json与qwen-2.5完全一致,删除重复文件 - 修复:
jiutian-139moe-chatSentencePiece 模型从未被用于 token 计数(回落 heuristic),现转换为独立tokenizer.json.zip(Unigram, 69120 vocab) - 修复:synlogic / qwen2.5-vl 系列模型映射错误(指向
jt-math-8b-instruct→ 修正为qwen-2.5) - 修复:
count_tokens()中_get_tokenizer与_render_messages调用顺序错误,导致chat_template/bos_token加载时机不确定 - 新增:多模态图像 token 计数支持(Qwen2.5-VL、GLM-4V、DeepSeek-VL2 等视觉模型)
- 新增:全模型回归测试用例(strings / messages / tools / vision),锁定每个 canonical 模型的精确 token 计数
- 修复:
qwen2-vl-2b和qwen2-vl-2b-instruct-awq的tokenizer_config.json中 chat_template 损坏(仅处理视觉 content 数组,不支持标准消息格式),删除后回落 fallback 格式
v0.1.0
- 首个正式发布版本
- 支持 DeepSeek、Qwen、GLM、MiniMax、JiuTian、Janus 六大系列共 47 个独立 tokenizer(429 个模型别名)
- 支持纯文本、对话消息、工具调用三种输入格式
- 支持组织前缀剥离、大小写容错、模糊拼写纠错
- 失败时自动降级为启发式估算
许可证
MIT
Metadata
Release files for offline-token-counter 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| offline_token_counter-0.1.1.tar.gz | 89.9 MB | Without provenance | Details for offline_token_counter-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| offline_token_counter-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for offline_token_counter-0.1.1-py3-none-any.whl |
Total release size: 179.8 MB
Release files / offline_token_counter-0.1.1.tar.gz
| Download URL | offline_token_counter-0.1.1.tar.gz |
|---|---|
| Size | 89.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9c0f4edb2b8498a6fe047cbdddc16133cd7b63f280c1533ba67b7fa02efac48f
|
|
BLAKE2b-256 checksum How to use checksums |
970b66d27d3f550fad9df3a69036d940df45ecac72b7ccc294b8d4387ab83af3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / offline_token_counter-0.1.1-py3-none-any.whl
| Download URL | offline_token_counter-0.1.1-py3-none-any.whl |
|---|---|
| Size | 89.9 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8bc4475625b3942689ca9a8333c5a2277bb304c595520ebe078894f65dd33138
|
|
BLAKE2b-256 checksum How to use checksums |
6f1375e7677f6e5980a3b1f3496da6ffe649cf15ffa5ba614298751e8d73bb22
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Security for offline-token-counter 0.1.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.