Transformers v5 分词更新
Transformers v5 引入了其分词系统的重大重新设计,将分词器的架构设计与已训练的词表分离。此变化使开发者能够将分词器视为可配置的模板,而不是不透明的黑盒,类似于 PyTorch 将神经网络架构与学习到的权重分离的方式。
架构与参数的分离
在 Transformers v5 中,分词器架构——包括 normalizer、pre-tokenizer、model type、post-processor 和 decoder——现在与已训练的参数(如词表和合并规则)分离。这与第 4 版不同,后者的分词器与预训练检查点文件紧密耦合,难以确定使用的具体规范化或预分词策略。
通过这种模块化方法,分词器类现在显式声明其结构。例如,v5 中的 LlamaTokenizer 明确指出它使用 Byte Pair Encoding (BPE),不对输入文本进行规范化,并在解码时将元空间字符 ☁ 替换为空格。
统一后端与简化层次结构
Transformers v5 消除了之前的双实现系统,即每个模型同时拥有 “slow” Python 分词器和 “fast” Rust 支持的分词器。
统一文件结构
- 每个模型单文件:库现在对每个模型使用一个文件(例如
tokenization_llama.py),而不是两个。 - 首选后端:通过
TokenizersBackend的 Rust 支持分词现在是首选默认,减少代码重复并消除慢速和快速版本之间的行为差异。
类层次结构
PreTrainedTokenizerBase:定义所有分词器通用接口的抽象基类,处理特殊标记、编码/解码接口、序列化和聊天模板。TokenizersBackend:主要后端,封装基于 Rust 的tokenizers库以实现高性能分词。PythonBackend:用于自定义逻辑或遗留兼容性的纯 Python mixin。SentencePieceBackend:专门处理使用 Google 的 SentencePiece 库的模型。
从头训练特定模型的分词器
由于架构与参数现在分离,用户可以实例化一个 “空白” 分词器架构并在特定领域语料上进行训练。以前,这需要使用低层原语手动重建流水线。在 v5 中,开发者只需初始化模型特定的类(如 LlamaTokenizer),并调用 train_new_from_iterator 来填充自定义词表和合并规则,同时保持模型原有的空格处理和特殊标记约定。
分词流水线与包装层
Transformers 中的分词分为五个独立阶段:
- Normalizer:标准化文本(例如小写化)。
- Pre-tokenizer:将文本拆分为初步块。
- Model:应用算法(BPE、Unigram 或 WordPiece)。
- Post-processor:添加特殊标记(BOS、EOS、填充)。
- Decoder:将 token ID 转回文本。
虽然底层的 tokenizers Rust 库处理这些机制,transformers 包装层则添加了关键的模型感知功能,包括通过 apply_chat_template 应用聊天模板、自动插入特殊标记、截断至上下文长度以及带填充的批量编码。
对比:Transformers v4 与 v5
| 方面 | V4 | V5 |
|---|---|---|
| 每个模型的文件数 | Two (tokenization_X.py, tokenization_X_fast.py) |
One (tokenization_X.py) |
| 默认后端 | Split between Python and Rust | Rust (TokenizersBackend) preferred |
| 架构可见性 | Hidden in serialized files | Explicit in class definition |
| 从头训练 | Required manual pipeline construction | tokenizer.train(files=[...]) |
| 组件检查 | Difficult, undocumented | Direct properties (tokenizer.normalizer, etc.) |
| 父类 | PreTrainedTokenizer, PreTrainedTokenizerFast |
TokenizersBackend, SentencePieceBackend, PythonBackend |