首页
/ Transformers 中的 tiktoken 集成:加载与转换 PreTrainedTokenizerFast 的完整指南

Transformers 中的 tiktoken 集成:加载与转换 PreTrainedTokenizerFast 的完整指南

2026-09-04 17:49:36作者:卓艾滢Kingsley

本篇技术指南聚焦于 🤗 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.modeltiktoken.modeltekken.json 等文件,且没有现成的 fast 分词器文件,Transformers 就会将其登记为 vocab_file(或 SentencePiece 的 spm_file),从而触发后续的 tiktoken / tekken 转换路径。这也解释了为什么「把 tokenizer.model 放到模型仓库里」就足够让 from_pretrained 自动接管。

文档同时明确列出了已随 tiktoken 词表发布、且已被验证可加载的知名模型

  • gpt2
  • llama3

适用前提:自动转换依赖安装了 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 / decodePreTrainedTokenizerFast 实例。

从仓库的转换脚本可以看到,llama3llama4mllamagpt_oss 等模型的官方转换脚本都继承或复用了 TikTokenConverter(例如 llama/convert_llama_weights_to_hf.py 中的 Llama3Convertergpt_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 的实现):

  1. 准备目录结构output_dir 不存在则创建;tiktoken 词表文件被写入 output_dir/tiktoken/tokenizer.model(由 TIKTOKEN_VOCAB_FILE 常量决定),fast 分词器输出到 output_dir/tokenizer.jsonTOKENIZER_FILE)。
  2. dump 词表:若 encoding 是字符串,先 tiktoken.get_encoding(encoding) 加载;随后 dump_tiktoken_bpe(encoding._mergeable_ranks, save_file_absolute) 把可合并词元(mergeable ranks)写成标准 tiktoken 文件。
  3. 转换并保存:调用 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

因此运行该函数前,需要确保 tiktokenblobfile 均可用;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_tokenizerSequence[ Split(Regex(pattern), behavior="isolated"), ByteLevel(add_prefix_space=...) ],其中 pattern 默认是 GPT-2 风格的字节级正则;
  • decoderByteLevel 解码器;
  • 若提供了 extra_special_tokens,逐个以 AddedToken(normalized=False, special=True) 加入特殊符号;
  • post_processorByteLevel(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)的判定顺序为:

  1. 若分词器类名命中 SLOW_TO_FAST_CONVERTERS 且未指定 from_tiktoken,走对应的专用转换器;
  2. 否则若 vocab_file 是 tekken 文件名,走 Mistral 的 MistralConverter
  3. 否则记录 Converting from Tiktoken,回退到 TikTokenConverter(vocab_file=..., extra_special_tokens=...)
  4. 若以上都失败,抛出带可用转换器列表的 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 转成 PreTrainedTokenizerFastgpt2llama3 等模型已验证可用);生成侧通过 convert_tiktoken_to_fastTikTokenConverter,把任意 tiktoken 编码(含 pattern 与特殊符号)落盘为标准 tokenizer.json,供 fast 分词器直接复用。理解 TIKTOKEN_VOCAB_FILE = "tokenizer.model"VOCAB_FILES_NAMES 的映射关系,以及 TikTokenConverter 对 vocab / merges / pre·post-processor 的装配方式,是掌握这一集成、并在自定义场景中正确落地 tiktoken 分词器的关键。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
903
1.82 K
docsdocs
暂无描述
Markdown
888
5.78 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.51 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.17 K
341