11.1 Tokenizer、特殊符号与长文切片:模型读到的是 Token ID,不是原始文字
Checkpoint 约定了 tokenizer 协议:Vocabulary ID、归一化、边界符号和 chat format。只换 tokenizer 而不换权重,同一句话就可能被模型读成另一组输入。
本课目标
- 拆开 normalization、pre-tokenization、subword model 与 post-processing;
- 区分 BPE、WordPiece、Unigram 和 byte-level 设计;
- 正确处理 special tokens、padding、truncation 与 loss mask;
- 为长文设计 document-aware chunking;
- 评估多语言/领域 token 效率与字符对齐。
1. Tokenization 是一条 Pipeline
常见阶段:
raw text
-> Unicode / case / whitespace normalization
-> pre-tokenization(空白、标点、byte 边界等)
-> subword segmentation
-> vocabulary IDs
-> BOS/EOS/SEP/role 等 special tokens
-> padding / truncation / attention mask不同 tokenizer 可能保留大小写,也可能 lower-case;可能使用 Unicode normalization,也可能保留原 byte。不可假设 decode 后逐字符等于原文:规范化、未知字符、空白清理都会影响 round trip。
做 span labeling 或引用定位时,保留原文并核对 backend 的 offset 约定。例如开启小写和去重音的 tokenizer 可把 Café 编成 cafe,offset 仍指向原文片段。归一化不一定可逆;special tokens 还可能使用 (0, 0) 这类空区间。
2. 为什么不用“一个词一个 ID”
Word vocabulary 对形态变化、拼写、代码标识符和开放词表很脆弱;character/byte vocabulary 小,但序列更长。Subword 在 vocabulary size 与 sequence length 间折中。
BPE
从小单元开始,迭代合并频繁相邻 pair。实际实现还受 pre-tokenizer、byte-level mapping 和 merge tie rule 影响。
WordPiece
也构建 subwords,但 vocabulary 学习准则和编码细节与 BPE 不同。## 只是某些 BERT tokenizer 的 continuation 表示,不是 WordPiece 的普遍外观。
Unigram LM
从候选 vocabulary 出发,按 probabilistic segmentation likelihood 剪除/选择 pieces;同一文本可存在多种分段候选。
Byte-level
完整覆盖 256 个 byte 值,或提供相应 byte fallback,才能把有效 Unicode 文本按 UTF-8 字节表示而不丢未知字符。仅有“byte-level”名称不能证明覆盖完整;一个字符仍可能消耗多个 bytes/tokens。
“GPT 都用一种 BPE、BERT 都用同一种 WordPiece”过于笼统。必须检查具体 checkpoint 的 tokenizer files。
3. Vocabulary ID 没有数值顺序
ID 50257 不比 ID 100 “语义更大”。Embedding table 以 ID 索引 learned vector;重排 vocabulary 却不同时重排 embedding/output head,就彻底改变模型。
很多 causal LM tie input embedding 与 output projection weights。新增 tokens 后要:
- 更新 tokenizer;
- resize model embeddings/output head;
- 初始化并训练新增 rows;
- 保存 tokenizer 与 model 同一版本;
- 检查 serving engine 是否加载新 vocabulary。
仅调用 add_tokens 不会让新 token 自动获得语义。
4. Special Tokens 是协议控制符
常见:
- BOS/EOS:序列开始/结束;
- PAD:批量补齐;
- MASK:masked objective corruption;
- SEP/CLS:特定 encoder 输入组织;
- role/control tokens:system/user/assistant/tool 边界;
- sentinel tokens:span corruption 或 infilling。
未注册为 special token 的可见字符串可能被拆成普通 pieces。重复 BOS/EOS 或遗漏 assistant-start token 都会改变序列。有些 causal model 有意共用 PAD 与 EOS ID,此时必须按位置区分补齐与真正的结束监督。
不要把 user 可输入的普通字符串直接当不可伪造权限边界;控制 token 解析和消息角色应由应用层构造。
5. Padding Mask 与 Loss Mask 不是一回事
Tokenizer 的 attention_mask 通常说明哪些 input positions 是有效 token;模型/架构再转换为实际 attention mask。Training labels 还需单独决定哪些 positions 计算 loss。
Instruction tuning 中可能:
system/user tokens: 可被 assistant attend,labels = -100(不计 loss)
assistant tokens: 可被 attend,labels = token IDs(计 loss)
padding tokens: 不应被 attend,labels = -100是否只训练 assistant response 由 objective 决定。这里的 -100 是 loss 实现约定的 ignore index,不是 tokenizer ID,也不是通用 mask 协议。Attention 可见性与 loss 监督仍要分别设置。
Left/right padding 影响 position IDs、cache 和 generation batching,必须遵循 checkpoint/serving implementation。
6. Truncation 可能删除问题或答案
truncation=True 让输入不超过上限,却未说明删哪一端/哪一段。Pair input 的 longest_first、only_first、only_second 语义不同;对聊天若从右侧截断,可能恰好删掉最新用户问题。
记录:
- 原 token count 与截断后 count;
- 被截断样本比例;
- 各字段保留策略;
- BOS/EOS/role tokens 是否仍完整;
- label 是否被截掉;
- train/serve 的 truncation_side 是否一致。
模型 context limit、tokenizer model_max_length 与 serving 配置可能不一致;配置中的极大占位数也不应当作真实可用窗口。
7. 长文先按 Document Split,再切 Chunks
正确顺序:
documents -> train/valid/test by source/time/entity -> tokenize/chunk within each split若先切 chunk 再随机分,重叠窗口或同文相邻段会跨 train/test,产生近重复泄漏。
Chunk 设计包括:
- boundary:句子、段落、代码单元还是固定 token;
- max tokens 与 special-token 预算;
- overlap/stride;
- document ID、offset、timestamp、license metadata;
- 短文 packing 是否跨 document;
- causal LM 的 EOS/document boundary。
Overlap 提高边界召回,也增加重复 compute 与评估相关性。Metric/bootstrap 应按 document/source,而非把 overlapping chunks 当独立样本。
EOS 标记边界,却不会阻止 packed 文档之间的 attention。若要求文档独立,应使用框架支持的分块对角 attention mask 或分开序列;允许跨文档上下文则是另一种明确的训练选择。
8. 一个可审计的编码示例
片段需要先把 tokenizer_dir 设为已固定版本的本地 tokenizer 目录。接口已用 Transformers 5.16.1 和本地小词表核对;输出随词表而变。
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(
tokenizer_dir, local_files_only=True, use_fast=True,
)
if not tokenizer.is_fast:
raise ValueError("this example requires a fast tokenizer with offsets")
encoded = tokenizer(
"第一段任务日志。第二段包含告警。",
add_special_tokens=True,
truncation=True,
max_length=32,
return_attention_mask=True,
return_offsets_mapping=True,
return_special_tokens_mask=True,
)
print({
"tokens": tokenizer.convert_ids_to_tokens(encoded["input_ids"]),
"ids": encoded["input_ids"],
"attention_mask": encoded["attention_mask"],
"special_mask": encoded["special_tokens_mask"],
"offsets": encoded["offset_mapping"],
})Fast tokenizer 常支持 offset mapping,具体 backend/checkpoint 要验证。Production 不应运行时用浮动 model ID 下载最新文件;固定 revision、hash、license 和本地 artifact。
9. Token 效率要实测
同一句话在不同 tokenizer 下的 tokens/character、tokens/byte 差异会影响:
- 可放入 context 的信息量;
- pretraining/fine-tuning compute;
- API/serving token cost;
- 跨语言响应长度与 latency;
- code、数字、URL、罕见术语的碎片化。
不存在“英文每词 1–2 token、中文每字 1 token”的稳定规律。用真实语言、领域和混合文本 corpus 统计 length quantiles、unknown/byte fallback、compression ratio 和 truncation rate。
10. Tokenizer Training 也是数据治理
Vocabulary 频率会编码训练 mixture。若数据含 PII、secret、恶意控制字符串或大量某语言,token pieces 与效率会受影响。
训练/选择 tokenizer 时记录:
- normalization/pre-tokenizer/config;
- corpus source、license、consent 与时间;
- per-language/domain sampling weights;
- dedup/filter;
- vocabulary size 与 reserved tokens;
- stability/compatibility policy。
Tokenizer vocabulary 中出现字符串不等于模型记住事实;但 artifact 本身也可能泄露敏感片段,需要审计。
常见误区
- Tokenizer 只是部署前处理:它是 checkpoint 输入协议的一部分。
- Subword 能无损还原任何原文:normalization/unknown/cleanup 可改变文本。
- PAD mask 自动屏蔽 training loss:attention 与 label mask 分开。
- 开启 truncation 就安全:可能删掉最新问题或监督答案。
- 中文一字一个 token:效率取决于具体 vocabulary 与文本。
练习
- 比较两个 pinned tokenizers 在中文、英文、代码、URL 上的长度分布。
- 检查 encode→decode 与 offsets 在空白/Unicode normalization 下的变化。
- 为 pair/chat 输入设计不会删掉问题与答案的截断策略。
- 先 chunk 后 split,观察重叠泄漏;再改为 document-first split。
- 新增 domain token 后检查 embedding resize、保存与 serving compatibility。
小结
Tokenizer 把原始文本变成模型真正接收的 IDs,并通过 special tokens、mask、padding 和 truncation 定义输入协议。它决定序列长度、字符对齐和部署兼容性,也会继承训练 corpus 的治理问题。
下一课讨论这些 token sequences 怎样产生监督信号:causal、masked 与 denoising objectives 从同一批原始文本构造出不同的信息流和模型能力。