Appearance
分词 (Tokenization) 将输入文本拆分为模型能处理的 token ID 序列,是 LLM 推理的第一步。
为什么需要 tokenization
模型不能直接处理原始文本,需要将文本转换为固定词表中的 token ID 序列。分词算法的质量直接影响模型的处理效率和能力(如多语言支持、代码处理等)。
核心原理
llama.cpp 支持多种分词算法:
| 类型 | 模型 | 算法 |
|---|---|---|
| SPM | LLaMA, Mistral | SentencePiece (BPE + byte fallback) |
| BPE | GPT-2, Qwen | Byte Pair Encoding |
| WPM | BERT | WordPiece |
| UGM | T5 | Unigram |
| RWKV | RWKV | Greedy tokenization |
| HybridDNA | Carbon-3B | BPE + DNA k-mer(6-base 固定长度)混合分词 |
分词流程:
- 文本预处理(Unicode 规范化,含
lowercase/strip_accents等normalizer_options) - 预分词(按规则分割为词)
- 子词编码(BPE 合并 / SPM 查找)
- 映射为 token ID
- 添加特殊 token(BOS 等;HuggingFace
TemplateProcessing的 leading 特殊 token 会被自动采纳为 BOS)
Chat 模板用 Jinja 渲染,支持 call 语句({% call %} 调用宏);工具调用(tool call)由各模型的 PEG parser 解析(如新增的 MiniCPM5 XML tool parser,并修复 min/max 对齐 Jinja2);--reasoning-preserve 控制输出是否保留推理内容,--dump-prog(仅存在于测试用例 tests/test-chat-template.cpp,非通用 CLI 选项)用于导出模板编译后的 AST 便于调试。语法约束生成(grammar)则由 PEG ac parser / json-schema-to-grammar 生成解析器,间距规则与各 parser 对齐(已移除未使用的 common/regex-partial)。
在源码中的实现
src/llama-vocab.cpp— 分词器实现(所有算法)src/unicode.cpp— Unicode 处理src/unicode-data.cpp— Unicode 数据表include/llama.h—llama_tokenize()API
相关概念
- gguf — 词表数据存储在 GGUF 文件中
- sampler-chain — 分词是逆过程(token → text = detokenization)