Hugging Face 中tokenizer.json 和vocab.json 有区别?
在使用 Hugging Facetransformers库时。
tokenizer.json是Fast Tokenizer的核心文件,它包含了分词器运行所需的所有信息(词表、合并规则、配置),可以直接加载用于推理。vocab.json(通常配合merges.txt或special_tokens_map.json存在) 是Slow Tokenizer(传统 Python 实现) 使用的文件,它只包含词汇映射关系,不包含分词逻辑。
以下是详细的对比和解释:
1.tokenizer.json
- 定义:这是一个 JSON 格式的文件,它是SentencePiece或BPE (Byte-Pair Encoding)等 Fast Tokenizer 引擎的序列化配置。
- 包含内容:
- Vocabulary (词表):所有的 token 到 ID 的映射。
- Merging Rules (合并规则):如果是 BPE 算法,这里存储了所有合并步骤(例如 “a” + “b” -> “ab” 的规则)。
- Configuration (配置):包括 normalizer(归一化器)、pre_tokenizer(预分词器)、post_processor(后处理器)等完整流水线配置。
- Added Tokens:模型在训练过程中额外添加的特殊 token(如
<s>,</s>,[UNK]等)。
- 特点:
- 完整且独立:它包含了一个分词器能正常工作所需的一切。
- 极速加载:使用 Rust 编写的
tokenizers库(Hugging Face 的底层引擎)直接读取此文件,速度比 Python 实现的 Slow Tokenizer 快几十倍。 - 用于 Fast Tokenizer当你使用
AutoTokenizer.from_pretrained()时,如果仓库里有tokenizer.json,transformers库会优先加载 Fast Tokenizer。
2.vocab.json(和merges.txt)
- 定义:这是传统的、基于 Python 实现的 Slow Tokenizer 所需的文件。通常与
merges.txt(BPE 的合并规则) 或sentencepiece.model(SentencePiece 的模型文件) 一起出现。 - 包含内容:
- 仅词表映射:
vocab.json通常只是一个字典,格式为{"token_string": integer_id}。 - 不包含逻辑:它不包含如何将文本切分成 token 的规则(即不包含 BPE 的合并步骤或 SentencePiece 的子词切割逻辑)。
- 仅词表映射:
- 特点:
- 不完整:仅有
vocab.json无法完成分词,必须配合merges.txt或其他规则文件。 - 较慢:在 Python 中通过循环或正则表达式实现分词逻辑,速度较慢,尤其不适合批量处理大量数据。
- 用于 Slow Tokenizer:如果仓库里没有
tokenizer.json,transformers会自动使用 Slow Tokenizer 来读取vocab.json和merges.txt。
- 不完整:仅有
3. 关键区别总结
| 特性 | tokenizer.json | vocab.json(+merges.txt) |
|---|---|---|
| 对应类 | PreTrainedTokenizerFast | PreTrainedTokenizer(Slow) |
| 底层引擎 | Hugging Facetokenizers(Rust) | 纯 Python 实现 |
| 包含信息 | 词表 +分词规则/流水线+ 配置 | 仅词表映射(不包含分词逻辑) |
| 加载速度 | 极快(毫秒级) | 慢 (秒级,尤其是大模型) |
| 序列化状态 | 可持久化(Save 后直接加载即可用) | 通常用于训练或旧版兼容,加载后可能需要重新构建流水线 |
| 是否必需 | 对于 Fast Tokenizer 是核心 | 对于 Slow Tokenizer 是必要但非充分条件 |
4. 为什么会有这两个文件?
- 历史原因:早期的 NLP 模型(如 BERT 原始版本)主要使用 Python 实现的分词器,依赖
vocab.txt或vocab.json+merges.txt。 - 性能需求:随着模型变大和数据量增加,分词器的速度成为瓶颈。Hugging Face 开发了基于 Rust 的
tokenizers库,并引入了tokenizer.json来封装整个分词流水线,实现了“一次保存,到处快速加载”。 - 兼容性:
transformers库同时支持两者,以保证向后兼容。但官方强烈推荐使用tokenizer.json。
5. 实际操作建议
保存/上传:
- 当你训练完一个分词器并调用
tokenizer.save_pretrained("path")时,transformers会自动生成tokenizer.json。 - 如果你想上传到 Hugging Face Hub,确保包含
tokenizer.json,这样其他用户加载时会自动使用 Fast Tokenizer。
- 当你训练完一个分词器并调用
加载:
AutoTokenizer.from_pretrained("model_name")会自动检测。如果有tokenizer.json,就用 Fast Tokenizer;否则 fallback 到 Slow Tokenizer。- 你可以强制使用 Fast Tokenizer:
fromtransformersimportAutoTokenizer tokenizer=AutoTokenizer.from_pretrained("model_name",use_fast=True) - 你可以强制使用 Slow Tokenizer:
tokenizer=AutoTokenizer.from_pretrained("model_name",use_fast=False)
转换:
- 如果你只有
vocab.json和merges.txt,想生成tokenizer.json,可以使用:fromtransformersimportAutoTokenizer tokenizer=AutoTokenizer.from_pretrained("model_name",use_fast=False)# 先加载慢的tokenizer.save_pretrained("new_path")# 这会自动生成 tokenizer.json
- 如果你只有
结论:tokenizer.json是现代 LLM 分词的标准和首选,它包含了完整的分词逻辑;而vocab.json只是词表映射,通常作为 Slow Tokenizer 的一部分,性能较差且功能不完整。
