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 中的分词分为五个独立阶段:

  1. Normalizer:标准化文本(例如小写化)。
  2. Pre-tokenizer:将文本拆分为初步块。
  3. Model:应用算法(BPE、Unigram 或 WordPiece)。
  4. Post-processor:添加特殊标记(BOS、EOS、填充)。
  5. 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

Sources