跳至内容
人工智能
大语言模型

Transformers v5 分词:架构与迁移指南

升级到 Transformers v5。关于统一 Rust 后端、API 变更,以及编码与聊天在 v4 与 v5 之间的并排迁移范式的实用指南。
Aashi Dutt's photo
Aashi Dutt
已更新 · 8分钟 阅读

使用 AI 探索

ChatGPTClaudePerplexity

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。

分词(Tokenization)是 HuggingFace Transformer 技术栈中我们常常不太在意的一环,直到它开始“泄漏”进您的输出。一个简单的空白字符怪癖就可能改变分词边界,解码可能生成意料之外的字符串,而在模板化时聊天提示也可能无声崩溃。

Transformers v5 通过分词重构来解决这些痛点:在不同实现间标准化行为、简化 API 表面,并在需要调试时让分词器内部更易检查。

在本教程中,我将先讲解分词会产生什么以及流水线如何工作,然后从务实、迁移为主的角度带您逐步了解 v5 实际发生了哪些变化。您将看到编码、解码、聊天模板和序列化的 v4 与 v5 并排代码模式,便于更新您的代码库。

如果您刚接触分词,建议先看看 Python 自然语言处理入门课程。

什么是分词(Tokenization)?

一种非常常见的 分词 定义是将文本转换为 token ID,这没错但不完整。在生产环境中,更好的理解是把分词看作一份契约。给定原始文本,分词器必须产出模型可以安全消费的结构化编码。

至少,这份契约包括:

  • input_ids,即整型 token ID,用于索引模型的嵌入表。
  • 还包括 attention_mask,用于指示哪些位置是真实 token,哪些是填充。
  • 偏移/对齐(如可用)将 token 跨度映射回原文中的字符或词级跨度,这在高亮、命名实体识别(NER)和归因中是必须的。
  • 必须保留特殊 token 的语义,即 BOS/EOS/PAD/UNK 的放置和 ID 要与模型训练时的约定一致。
  • 对于聊天模型,聊天格式也是契约的一部分,因此我们通常在运行分词前应用模型的聊天模板。

在 Transformers 中,这些职责位于分词器层(不在模型的前向传递内部),这就是为什么 AutoTokenizer 是标准入口。如下是一个简单示例:

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM3-3B")
enc = tokenizer("Hello world")
print(enc["input_ids"])
print(tokenizer.convert_ids_to_tokens(enc["input_ids"]))

预期输出如下:

[9906, 1917]
['Hello', 'Ġworld']

这里,enc 是一个 BatchEncoding 对象(类字典容器),用于保存分词器生成的、可直接输入模型的字段(如 input_ids,以及常见的 attention_mask)。输出返回 [9906, 1917],即输入字符串对应的整型 token ID,同时还有 ['Hello', 'Ġworld'],展示了对应的 token 字符串。

注意: Ġ 前缀是一个常见约定,表示该 token 包含前导空格,因此 Ġworld 表示的是“ world”而非不含空白的“world”。

将分词视为流水线:v5 如何让它可调试

分词问题通常表现为一些小毛病,比如多余的空格、奇怪的 Unicode 切分、token 数量突然暴涨,或者聊天提示未按角色正确组织。

调试这些问题的最简单方式是把分词当作由多个阶段组成的流水线。一旦明确各阶段各司其职,您就能快速定位问题来源,而不是盲目猜测。请记住以下要点:

分词是可组合的流水线

首先要打破“分词器只是一个 WordPiece”的常见误解。实际上,它是一连串独立的变换阶段,包括规范化、预分词、子词建模、后处理和解码。每个阶段控制最终行为的不同部分。

可调试的心智模型

将分词拆分为多个阶段为我们提供了可靠的排障地图:

  • 空白字符的怪癖通常来自预分词器或解码器
  • Unicode 问题通常起源于规范化器
  • token“爆炸”往往由子词模型及其词表/合并规则引起
  • 聊天格式错误主要来自模板或后处理

天生显式且可检查

Transformers v5 让分词器更易于检查,尤其是由 Rust tokenizers 引擎驱动的分词器。

当使用 Rust 后端时,我们可以通过 tokenizer._tokenizer 查看底层组件(规范化器、预分词器、模型、后处理器、解码器)。我们不需要每天都用 _tokenizer,但在 v5 发布时它非常有用,因为在需要调试时可以让内部实现“看得见”。

这也自然引出了引擎与包装器的区分:

  • 引擎(tokenizers):低级的 Rust 实现,执行规范化、分割、子词切分等核心机制,并生成 token ID(以及在可用时生成偏移)。
  • 包装器(transformers): 面向模型的层,将这些机制转化为模型可用的 输入,执行诸如特殊 token 处理、聊天模板、填充/截断规则以及特定框架张量输出等约定。

Transformers v5 有哪些变化?

Transformers v5 是一次重要的标准化版本,分词是其中对用户可见的变化领域之一。该版本减少了重复实现,使分词器行为在不同模型之间更一致,并让分词器更易检查,某些情况下也更易从零训练。以下是对日常用户影响最大的变化。

每个模型仅保留一个分词器实现

在此前的版本中,许多模型同时拥有:

  • 一个慢速的 Python 分词器
  • 一个基于 Rust 的快速分词器实现

在 v5 中,Transformers 合并为每个模型仅一个分词器文件,并优先选择基于 Rust 的路径。为什么基于 Rust 的分词器行之有效:

  • 去除了慢速与快速实现的重复。
  • 减少了由这些实现间细微行为差异导致的一致性缺陷。
  • 该分词器实现缩小并简化了测试面,因为只有一个主要代码路径需要验证。
  • 同时为跨模型的分词器行为建立了唯一的“事实来源”。

编码 API 迁移

v4 的 encode_plus() API 已弃用,推荐直接调用分词器。本例展示 v4 与 v5 的差异:

v4 版本

enc = tokenizer.encode_plus(
    text,
    truncation=True,
    padding="max_length",
    max_length=128,
    return_tensors="pt",
)

v5 版本

enc = tokenizer(
    text,
    truncation=True,
    padding="max_length",
    max_length=128,
    return_tensors="pt",
)

从 encode_plus() 迁移到单一的 tokenizer() 入口可以减少生产代码中真实会遇到的失败模式。

在 v4 中,存在多种编码方法,意味着填充、截断、批处理或张量转换上可能出现细微差异,取决于您使用的路径,且往往只在从单样本切换到批量工作负载时才暴露出来。

v5 将一切标准化为一个始终返回 BatchEncoding 的编码路径,使行为更可预测,既减少边界情况的 Bug,也减少保持分词流水线一致所需的代码量。

解码 API 迁移

v5 统一了解码,使 decode() 同时处理单样本与批处理输入,使解码行为与编码保持一致。

v4 版本

texts = tokenizer.batch_decode(batch_ids, skip_special_tokens=True)

v5 版本

texts = tokenizer.decode(batch_ids, skip_special_tokens=True)

在 v5 中,解码被设计为镜像编码。就像 tokenizer() 可接受单个字符串或字符串批,decode() 也可接受单个 token ID 序列或一批序列。

关键在于返回类型:如果您传入一个序列,会返回一个字符串;如果传入一批(如 list[list[int]]),则返回字符串列表。整体上这让 API 更简洁,但也意味着任何假设 decode() 总是返回字符串的代码都应更新,以处理两种情况。

聊天模板

在 v4 中,apply_chat_template 为了向后兼容会返回原始的 input_ids。在 v5 中,它会像其他分词器方法一样返回一个 BatchEncoding。

v4 版本

input_ids = tokenizer.apply_chat_template(messages, return_tensors="pt")

v5 版本

enc = tokenizer.apply_chat_template(messages, return_tensors="pt")
input_ids = enc["input_ids"]
attention_mask = enc["attention_mask"]

在 v5 中,apply_chat_template() 被视为一个正式的分词器入口点,而非特殊的辅助函数。它不再只返回 input_ids,而是返回完整的 BatchEncoding 对象(包含 input_ids 与 attention_mask 等字段)。

这很重要,因为聊天格式的输入现在能接入与常规分词相同的批处理、填充、截断以及张量返回工作流。我们无需额外代码去重建 mask 或在送入模型前手动对齐格式。

分词器序列化

在 v5 中,分词器序列化被简化:将特殊 token 与新增 token 的元数据整合为更少的工件,同时仍支持旧文件以保持向后兼容。这降低了多个“事实来源”文件不同步的风险,并让分词器资产更易在 Transformers 之外的下游工具中加载与复用。

将分词器视为可配置的架构

在 v5 中,关键转变在于:分词器被视为一个定义好的流水线与已学习工件的组合,而非只是从序列化文件加载的某个东西。

  • 分词器类定义了文本如何被规范化、拆分为片段、转换为子词 token,并最终解码回文本。
  • 词表与合并规则是已学习的工件,即它们是经过训练得到的部分,决定了存在哪些 token 以及文本如何被压缩为 token ID。
  • 这种分离支持“架构优先”的工作流。对于受支持的分词器,您可以实例化一个遵循某模型设计的分词器,然后单独加载或训练词表/合并规则,这让定制与再训练更为直接。

总结思考

Transformers v5 的分词在标准化与简化方面迈出了重要一步。现在有了更规范的行为路径(减少慢/快实现分歧)、更简化的 API 表面、聊天模板也会像常规分词一样返回结构化的 BatchEncoding 对象,并通过整合序列化降低了脆弱的文件级假设。

同时,它也推动了“架构优先”的心智模型,使分词器更易检查,并在受支持的场景下可从零训练。要顺利从 v4 迁移:用 tokenizer() 替换 encode_plus(),用 decode() 替换 batch_decode(),更新 apply_chat_template() 的调用以配合 BatchEncoding,在保存时避免硬编码旧的分词器文件名,并预期慢速分词器的一些怪癖会向基于 tokenizers 的行为收敛。

如果您想进一步了解近期发布,这里有 发布说明。我也推荐 Hugging Face 基础技能路线来进行实操练习。

Tokenization v5 常见问答

我还需要在“Fast”(Rust)与“Slow”(Python)分词器类之间做选择吗?

不需要。Transformers v5 将这些整合为每个模型一个实现。库现在默认对所有受支持的模型使用高度优化的 Rust 后端(tokenizers 库),无需手动在 LlamaTokenizerFast 与 LlamaTokenizer 之间选择。

我现有的 encode_plus 代码会马上失效吗?

不会立刻停止,但它已被弃用。尽管 v5 目前可能仍支持带警告的 encode_plus,强烈建议切换到直接的 tokenizer(__call__) 方法。这样可以获得统一的新批处理行为,并让您的代码更具前瞻性。

为什么 apply_chat_template 现在返回 BatchEncoding 字典而不是字符串?

是为了将聊天输入当作普通模型输入来处理。通过返回一个字典(包含 input_ids 和 attention_mask),v5 允许聊天格式数据无需第二次分词即可直接批处理、填充与截断。

我还能使用 return_tensors="tf" 或 return_tensors="jax" 吗?

不能。作为 v5 架构变更的一部分,Transformers 已弃用对 TensorFlow 与 Flax/JAX 后端的官方支持,专注于 PyTorch。您需要依赖 PyTorch 后端,或将模型导出为 ONNX/GGUF 等格式以供其他框架使用。

如何在 v5 中调试“无声”的分词错误?

使用可检查的内部结构。在 v5 中,您可以通过 tokenizer._tokenizer 访问底层 Rust 流水线。这使您可以单独检查特定阶段——如规范化器或预分词器——以准确查看字符串是在何处被意外拆分或修改的。


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

我是一名 Google Developers 机器学习(生成式 AI)领域的专家、Kaggle 三项专家,以及 Women Techmakers 大使,拥有 3 年以上的技术从业经验。2020 年我共同创办了一家健康科技初创公司,目前在佐治亚理工学院攻读计算机科学硕士,专攻机器学习。

主题
人工智能
大语言模型

热门 DataCamp 课程

课程

Python 中的自然语言处理(NLP)

4 小时
10.3K
掌握文本分析:从预处理到高级 Transformer 模型,精通核心 NLP 技术。
查看详情开始课程

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。
查看更多