Transformers 中的 tiktoken 集成:加载与转换 PreTrainedTokenizerFast 的完整指南
本篇技术指南聚焦于 🤗 Transformers 对 tiktoken 分词器的原生支持:如何在 from_pretrained 阶段自动识别并转换 Hub 上的 tiktoken tokenizer.model 文件,以及如何用 convert_tiktoken_to_fast 把任意 tiktoken 编码落地为标准 tokenizer.json。读完后,你将掌握 tiktoken 分词器在 Transformers 中的加载链路、TikTokenConverter 的底层转换原理,以及从 tiktoken 生成 fast 分词器并可被 PreTrainedTokenizerFast 直接复用的实操方案。
一、集成机制:tiktoken 文件如何被自动识别
Transformers 与 tiktoken 的集成核心在于:当使用 from_pretrained 加载带有 tiktoken tokenizer.model 文件的模型时,该文件会被自动转换为 fast 分词器(即 PreTrainedTokenizerFast),无需用户手动干预。这一机制在仓库中已有两处关键支撑。
其一,文件名常量的统一。在 tokenization_utils_tokenizers.py 中,tiktoken 的默认词表文件名被固定为:
TOKENIZER_FILE = "tokenizer.json"
TIKTOKEN_VOCAB_FILE = "tokenizer.model"
VOCAB_FILES_NAMES = {"tokenizer_file": TOKENIZER_FILE, "vocab_file": TIKTOKEN_VOCAB_FILE}
也就是说,Transformers 把 tokenizer.model 视为 tiktoken 词表(vocab_file),而把 tokenizer.json 视为 fast 分词器的单文件序列化结果(tokenizer_file)。
其二,在解析远程/本地词表文件时的回退匹配。在 tokenization_utils_base.py 中,当仓库里找不到 tokenizer_file 时,加载逻辑会用一段正则去匹配仓库文件列表中是否存在可转换的词表:
other_pattern = r"tekken\.json|tokenizer\.model\.*|tiktoken\.model" + "|".join(
getattr(cls, "VOCAB_FILES_NAMES", {}).keys()
)
if match := re.search(other_pattern, "\n".join(remote_files)):
if "spm_file" in vocab_files:
vocab_files["spm_file"] = match.group()
else:
vocab_files["vocab_file"] = match.group()
从源码结构看,这段逻辑意味着:只要仓库里存在 tokenizer.model、tiktoken.model 或 tekken.json 等文件,且没有现成的 fast 分词器文件,Transformers 就会将其登记为 vocab_file(或 SentencePiece 的 spm_file),从而触发后续的 tiktoken / tekken 转换路径。这也解释了为什么「把 tokenizer.model 放到模型仓库里」就足够让 from_pretrained 自动接管。
文档同时明确列出了已随 tiktoken 词表发布、且已被验证可加载的知名模型:
gpt2llama3
适用前提:自动转换依赖安装了
tiktoken(部分路径还依赖blobfile)。若未安装,加载相关词表会抛出带安装提示的异常,后文会给出具体报错信息。
二、加载 tiktoken 分词器的实操示例
要把 tiktoken 文件加载进 Transformers,关键前提是:确保 tokenizer.model 确实是 tiktoken 格式的文件,之后在 from_pretrained 时它会被自动加载并转换。官方示例以 meta-llama/Meta-Llama-3-8B-Instruct 为例,使用 subfolder 定位到原始子目录:
from transformers import AutoTokenizer
model_id = "meta-llama/Meta-Llama-3-8B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_id, subfolder="original")
这里的 subfolder="original" 指定了在模型仓库中存放原始 tiktoken 词表的子目录。AutoTokenizer 会根据模型配置自动解析出对应的 fast 分词器类型,并走上面第一节的词表回退匹配逻辑,最终返回一个可直接 encode / decode 的 PreTrainedTokenizerFast 实例。
从仓库的转换脚本可以看到,llama3、llama4、mllama、gpt_oss 等模型的官方转换脚本都继承或复用了 TikTokenConverter(例如 llama/convert_llama_weights_to_hf.py 中的 Llama3Converter、gpt_oss/convert_gpt_oss_weights_to_hf.py 中的 GptOssConverter),印证了 tiktoken 是这批 LLaMA 系模型词表的标准格式。
三、从 tiktoken 生成 fast 分词器:convert_tiktoken_to_fast
需要特别注意的一点是:原始 tokenizer.model 文件本身并不包含关于特殊符号(special tokens)或额外正则 pattern 的信息。如果这些信息对你的场景很重要,就应该把分词器转换成 tokenizer.json——这才是 PreTrainedTokenizerFast 所适配的标准格式。
推荐流程是:先用 tiktoken 拿到一个 encoding,再用 Transformers 提供的 convert_tiktoken_to_fast 把它转成 tokenizer.json 并落盘:
from transformers.integrations.tiktoken import convert_tiktoken_to_fast
from tiktoken import get_encoding
# 可以加载你自定义的编码,也可以是 OpenAI 提供的编码
encoding = get_encoding("gpt2")
convert_tiktoken_to_fast(encoding, "config/save/dir")
生成的 tokenizer.json 会被保存在指定目录,随后即可用 PreTrainedTokenizerFast 直接加载:
tokenizer = PreTrainedTokenizerFast.from_pretrained("config/save/dir")
源码级解析:convert_tiktoken_to_fast 做了什么
该函数位于 integrations/tiktoken.py,其签名与行为如下:
def convert_tiktoken_to_fast(encoding, output_dir: str):
"""
Args:
encoding (`str` or `tiktoken.Encoding`):
Tokenizer from `tiktoken` library. If `encoding` is `str`, the tokenizer will be loaded with
`tiktoken.get_encoding(encoding)`.
output_dir (`str`):
Save path for converted tokenizer configuration file.
"""
它执行的核心步骤(结合 integrations/tiktoken.py 的实现):
- 准备目录结构:
output_dir不存在则创建;tiktoken 词表文件被写入output_dir/tiktoken/tokenizer.model(由TIKTOKEN_VOCAB_FILE常量决定),fast 分词器输出到output_dir/tokenizer.json(TOKENIZER_FILE)。 - dump 词表:若
encoding是字符串,先tiktoken.get_encoding(encoding)加载;随后dump_tiktoken_bpe(encoding._mergeable_ranks, save_file_absolute)把可合并词元(mergeable ranks)写成标准 tiktoken 文件。 - 转换并保存:调用
TikTokenConverter(vocab_file=..., pattern=encoding._pat_str, extra_special_tokens=encoding._special_tokens).converted(),最后tokenizer.save(output_file_absolute)输出tokenizer.json。
这里有个容易被忽略的细节:它会把 tiktoken 编码自带的正则 pattern(encoding._pat_str)和特殊符号(encoding._special_tokens)一并带入转换,从而弥补了裸 tokenizer.model 缺少 pattern / special tokens 信息的短板。
关于依赖与报错,源码显式区分了两类缺失:
if "blobfile" in error_msg.lower():
raise ValueError(
"`blobfile` is required to save a `tiktoken` file. Install it with `pip install blobfile`."
) from e
raise ValueError(
"`tiktoken` is required to save a `tiktoken` file. Install it with `pip install tiktoken`."
) from e
因此运行该函数前,需要确保 tiktoken 与 blobfile 均可用;tiktoken 已列入 Transformers 的可选依赖表(见 dependency_versions_table.py)。
四、底层转换原理:TikTokenConverter
真正完成「tiktoken 词表 → fast 分词器」转换的是 convert_slow_tokenizer.py 中的 TikTokenConverter 类,它把 tiktoken 的 BPE 表示映射到 HuggingFace tokenizers 库的 Tokenizer 对象。
1)词表与 merges 的提取。extract_vocab_merges_from_model(tiktoken_url)(L1923-L1952)先用 load_tiktoken_bpe 读入 BPE 排名,再用 bytes_to_unicode 把字节串转成字符串构造 vocab;对长度大于 1 的词元,枚举其所有合法左右切分组合,生成按 rank 排序的 merges。这一过程解释了 tiktoken 的「可合并排名」如何被拆解成 fast 分词器所需的 (vocab_scores, merges)。
2)构造 BPE 模型。tokenizer()(L1954-L1959)用 Tokenizer(BPE(vocab_scores, merges, fuse_unk=False)) 建立模型,并开启 ignore_merges = True,保证解码行为与 tiktoken 原始语义一致。
3)预/后处理与解码器。converted()(L1961-L1978)为模型装配:
pre_tokenizer:Sequence[ Split(Regex(pattern), behavior="isolated"), ByteLevel(add_prefix_space=...) ],其中pattern默认是 GPT-2 风格的字节级正则;decoder:ByteLevel解码器;- 若提供了
extra_special_tokens,逐个以AddedToken(normalized=False, special=True)加入特殊符号; post_processor:ByteLevel(trim_offsets=False)。
默认的预分词正则在构造函数里被显式定义(L1911),与 GPT-2 系分词器一致,这也是 gpt2 能开箱即用的原因。
五、加载链路中的 tiktoken 回退
除了主动调用 convert_tiktoken_to_fast,Transformers 在「慢分词器 → 快分词器」的统一入口里也内置了 tiktoken 回退。入口函数 convert_slow_tokenizer(transformer_tokenizer, from_tiktoken=False)(convert_slow_tokenizer.py)的判定顺序为:
- 若分词器类名命中
SLOW_TO_FAST_CONVERTERS且未指定from_tiktoken,走对应的专用转换器; - 否则若
vocab_file是 tekken 文件名,走 Mistral 的MistralConverter; - 否则记录
Converting from Tiktoken,回退到TikTokenConverter(vocab_file=..., extra_special_tokens=...); - 若以上都失败,抛出带可用转换器列表的
ValueError。
从源码结构看,这意味着:当一个分词器没有专用转换器、但其 vocab_file 指向 tiktoken 词表时,Transformers 会自动尝试用 TikTokenConverter 完成转换,与第二节 from_pretrained 的自动加载行为形成呼应。
六、测试验证:如何确认可复现
仓库在 tests/models/gpt2/test_tokenization_gpt2.py 提供了 test_tokenization_tiktoken 测试,可作为功能是否生效的直接验证依据:
@require_tiktoken
def test_tokenization_tiktoken(self):
from tiktoken import encoding_name_for_model
from transformers.integrations.tiktoken import convert_tiktoken_to_fast
encoding = encoding_name_for_model("gpt2")
convert_tiktoken_to_fast(encoding, self.tmpdirname)
tiktoken_fast_tokenizer = GPT2Tokenizer.from_pretrained(self.tmpdirname)
rust_tokenizer = GPT2Tokenizer.from_pretrained("openai-community/gpt2")
sequence = "lower newer"
self.assertEqual(
rust_tokenizer.decode(rust_tokenizer.encode(sequence)),
tiktoken_fast_tokenizer.decode(rust_tokenizer.encode(sequence)),
)
该测试用 convert_tiktoken_to_fast 生成 fast 分词器后,对比其 decode 结果与官方 gpt2 fast 分词器是否一致,从而证明转换后的分词器在行为上与原实现等价。@require_tiktoken 装饰器确保在未安装 tiktoken 的环境自动跳过该用例。
七、小结
Transformers 的 tiktoken 支持可以归纳为两条互补路径:加载侧通过词表文件名回退匹配,让 from_pretrained 自动把 Hub 上的 tokenizer.model 转成 PreTrainedTokenizerFast(gpt2、llama3 等模型已验证可用);生成侧通过 convert_tiktoken_to_fast 与 TikTokenConverter,把任意 tiktoken 编码(含 pattern 与特殊符号)落盘为标准 tokenizer.json,供 fast 分词器直接复用。理解 TIKTOKEN_VOCAB_FILE = "tokenizer.model"、VOCAB_FILES_NAMES 的映射关系,以及 TikTokenConverter 对 vocab / merges / pre·post-processor 的装配方式,是掌握这一集成、并在自定义场景中正确落地 tiktoken 分词器的关键。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00