Skip to content

分词与词表 — 练习

练习 1:使用 llama-cli 测试分词

使用 llama-cli --verbose-prompt 查看一段中文文本的分词结果,分析哪些 token 是完整的汉字,哪些被拆分。

参考答案

运行命令:

bash
./llama-cli -m model.gguf -p "你好世界" --verbose-prompt

输出会显示 token 序列和对应的文本。对于 LLaMA 模型,中文通常被编码为多个 byte-fallback token,因为 SPM 词表中中文字符覆盖有限。

练习 2:追踪 BPE 编码过程

llama-vocab.cpp 中找到 BPE 编码的实现,画出从输入 "hello" 到 token IDs 的完整流程。

参考答案

流程:

  1. llama_tokenize() 调用内部 llama_vocab::tokenize()
  2. 文本 "hello" 经过预分词(GPT-2 风格正则分割)
  3. "hello" 执行 BPE 编码:
    • 初始: [h, e, l, l, o]
    • 合并 ll["h", "e", "ll", "o"]
    • 查找词表得到对应的 token IDs
  4. 返回 [token_id_h, token_id_e, token_id_ll, token_id_o]

练习 3:比较不同模型的词表

下载两个不同架构的 GGUF 模型,用 gguf-py 分别查看它们的词表大小和类型。

参考答案
python
from gguf import GGUFReader

for model_path in ["llama.gguf", "gpt2.gguf"]:
    reader = GGUFReader(model_path)
    vocab_type = reader.fields.get("tokenizer.ggml.model")
    n_tokens = reader.fields.get("tokenizer.ggml.n_tokens")
    print(f"{model_path}: type={vocab_type}, n_tokens={n_tokens}")

典型结果:

  • LLaMA 2: SPM, 32000 tokens
  • GPT-2: BPE, 50257 tokens
  • Qwen2: BPE, 151936 tokens

拓展挑战

  • 阅读 Unicode 处理代码 (unicode.cpp),理解 byte-fallback 机制
  • 实现一个简单的 BPE 分词器(Python),与 llama.cpp 的结果对比
  • 分析 chat template 如何影响分词结果