- 推理引擎
- 大模型
【免费下载链接】FlexGen
Running large language models on a single GPU for throughput-oriented scenarios.
导读
本指南以仓库benchmark/third_party/transformers/templates/adding_a_missing_tokenization_test/目录下的官方模板为绝对核心,系统讲解如何通过 Cookiecutter 为一个尚缺分词测试的新模型一键生成test_tokenization_Xxx.py测试骨架。你将掌握模板的交互式变量配置(模型命名、慢/快分词器组合、SentencePiece 依赖)、生成后测试文件的结构与关键实现点,以及如何把生成文件安置到对应模型的测试子目录并接入TokenizerTesterMixin公共测试体系,最终用pytest驱动验证。文中全部证据来自仓库内模板、cookiecutter.json配置与tests/test_tokenization_common.py、tests/models/bert/test_tokenization_bert.py等源码。
一、模板是什么:为“缺失的分词测试”补课
在 Hugging Face Transformers 中,每个模型(BERT、RoBERTa、DeBERTa 等)在tests/models/<model>/下都应有一份test_tokenization_*.py,用来回归验证该模型分词器的行为。当社区提交一个新模型或发现某模型缺少分词测试时,最规范的做法不是手写重复的样板代码,而是使用本目录提供的 Cookiecutter 模板生成标准骨架。
仓库中该模板由三个部分组成(相对仓库根目录):
- 模板说明文档:即本指南依据的主文档,交代 fork、clone、安装与调用方式;
- cookiecutter.json:定义模板的全部交互变量及默认值;
- Jinja 模板源文件:用
{{cookiecutter.xxx}}占位符生成最终测试文件。
从源码结构看,这是 transformers 官方templates/目录被完整随仓库收录的开发者工具,属于“给库本身做贡献”的流程组件,与 FlexGen 的推理基准脚本无直接耦合,可以独立使用。
二、环境准备:fork、clone 与 dev 依赖安装
模板说明文档给出的第一步是准备开发环境。注意:本仓库为只读镜像,以下命令面向你在 GitHub 上的 fork 副本执行,不修改当前仓库:
git clone https://github.com/YOUR-USERNAME/transformers cd transformers pip install -e ".[dev]"要点说明:
pip install -e ".[dev]"以可编辑模式安装 transformers 及其全部开发依赖。cookiecutter 属于 dev 依赖之一,因此文档强调“使用 cookiecutter 需要先装齐所有 dev 依赖”;- 若你的环境是 Conda,官方文档一般建议先创建独立环境再执行上述安装,避免污染系统 Python;
- 安装完成后可用
cookiecutter --version验证工具可用。
三、生成模板:一条命令 + 一轮问答
安装就绪后,在 transformers 仓库根目录下运行:
cookiecutter path-to-the folder/adding_a_missing_tokenization_test/即指向本目录的路径(在本仓库中为benchmark/third_party/transformers/templates/adding_a_missing_tokenization_test/)。运行后:
- Cookiecutter 会在当前工作目录新建一个以
{{cookiecutter.modelname}}命名的文件夹(例如BrandNewBERT/); - 依次弹出变量问答(见下一节变量表);
- 模板引擎把 Jinja 占位符替换成你回答的值,最终在新建文件夹内生成唯一一个文件:
test_tokenization_{{cookiecutter.lowercase_modelname}}.py。
文档特别提醒:模板生成位置是当前工作目录下的新文件夹,生成完成后需要手动把它移动到tests/models/<对应模型名>/子目录。
四、交互变量详解:一份 cookiecutter.json 的完整拆解
模板变量配置 定义了 8 个变量,下面逐个给出含义、默认值与影响:
| 变量 | 默认值 | 可选值 | 作用与注意事项 |
|---|---|---|---|
modelname | BrandNewBERT | 任意字符串 | 模型显示名,按纯文本大小写书写,如BERT、RoBERTa、DeBERTa。文档明确要求按模型原文大小写填写,它同时决定新建文件夹名 |
uppercase_modelname | BRAND_NEW_BERT | 任意 | 全大写蛇形名,用于在注释、常量等场景引用模型 |
lowercase_modelname | brand_new_bert | 任意 | 全小写蛇形名,直接决定生成文件名test_tokenization_brand_new_bert.py |
camelcase_modelname | BrandNewBert | 任意 | 驼峰名,用于生成测试类名BrandNewBertTokenizationTest及导入BrandNewBertTokenizer/BrandNewBertTokenizerFast |
has_slow_class | True | True/False | 模型是否提供 Python 慢分词器。为True时测试类绑定tokenizer_class并开启test_slow_tokenizer |
has_fast_class | True | True/False | 模型是否提供基于 🤗 Tokenizers 的快分词器。为True时绑定rust_tokenizer_class并开启test_rust_tokenizer |
slow_tokenizer_use_sentencepiece | True | True/False | 慢分词器是否基于 SentencePiece。为True时测试类追加test_sentencepiece = True,并自动加上@require_sentencepiece装饰器 |
authors | The HuggingFace Team | 任意 | 写入生成文件版权头的作者名 |
变量之间的组合关系(由 Jinja 模板源文件 的{% if %}逻辑决定):
- 导入语句:仅慢类时导入
XxxTokenizer;仅快类时导入XxxTokenizerFast;两者都有时同时导入; - 装饰器:慢类用 SentencePiece → 加
@require_sentencepiece;含快类 → 加@require_tokenizers;两者都有且用 SentencePiece → 两个装饰器都加;都不用 → 无装饰器。
这两个装饰器定义在 transformers/testing_utils.py:require_sentencepiece在 SentencePiece 未安装时跳过测试,require_tokenizers在 🤗 Tokenizers 未安装时跳过测试。也就是说,生成文件的“可运行性”由你的环境决定——只有安装对应依赖才能跑这些用例。
五、生成的测试文件长什么样
以默认值(BrandNewBERT、双类、用 SentencePiece)生成后,文件核心结构如下:
""" Testing suite for the BrandNewBERT tokenizer. """ import unittest from transformers import BrandNewBertTokenizer, BrandNewBertTokenizerFast from transformers.testing_utils import require_sentencepiece, require_tokenizers from ...test_tokenization_common import TokenizerTesterMixin @require_sentencepiece @require_tokenizers class BrandNewBertTokenizationTest(TokenizerTesterMixin, unittest.TestCase): tokenizer_class = BrandNewBertTokenizer test_slow_tokenizer = True rust_tokenizer_class = BrandNewBertTokenizerFast test_rust_tokenizer = True test_sentencepiece = True # TODO: Check in `TokenizerTesterMixin` if other attributes need to be changed def setUp(self): super().setUp() raise NotImplementedError( "Here you have to implement the saving of a toy tokenizer in " "`self.tmpdirname`." ) # TODO: add tests with hard-coded target values5.1 类级属性:声明被测对象
tokenizer_class/rust_tokenizer_class:指定被测的慢、快分词器类,供 mixin 的get_tokenizer()/get_rust_tokenizer()加载(见 公共测试基类);test_slow_tokenizer/test_rust_tokenizer:开关对应慢/快分词器的公共用例;test_sentencepiece:开关 SentencePiece 专属用例;setUp中的self.tmpdirname由 mixin 的setUp创建(tempfile.mkdtemp(),见 test_tokenization_common.py),测试结束由tearDown清理。
5.2 模板留白:两个 TODO 是“必答题”
模板刻意留下两处raise NotImplementedError/ TODO,这是新增测试的核心工作量所在:
setUp必须被重写:你要在self.tmpdirname中保存一个“玩具分词器”(toy tokenizer),例如写一份 vocab 文件。参考 BERT 的真实实现——test_tokenization_bert.py 在setUp里构造了含[UNK]、[CLS]、[SEP]、[PAD]、[MASK]及若干子词(want、##want、##ed、wa、un、runn、##ing等)的词表并写入self.vocab_file,还实现了get_input_output_texts返回一对文本/期望输出;- 补充硬编码目标值的用例:模板的
# TODO: add tests with hard-coded target values提示你仿照test_full_tokenizer(见 test_tokenization_bert.py)写出确定性的 token→id 断言,而不是只依赖 mixin 的通用检查。
5.3 mixin 带来的“免费”测试集
TokenizerTesterMixin是约 4000 行的公共测试基类(tests/test_tokenization_common.py),子类仅需配置少量属性即可自动继承大量用例,主要包括:
- 基础行为:
test_tokenize_special_tokens(L338)、test_sentencepiece_tokenize_and_convert_tokens_to_string(L365)、test_rust_and_python_full_tokenizers(L494)验证 Python/Rust 分词结果一致性; - 编解码:
test_save_and_load_tokenizer(L610)、test_pickle_tokenizer(L700)、test_internal_consistency(L868)、test_conversion_reversible(L1915); - 特殊 token:
test_add_tokens_tokenizer(L795)、test_add_special_tokens(L846)、test_special_tokens_mask(L1415); - 长度/填充/截断:
test_maximum_encoding_length_single_input(L993)、test_right_and_left_padding(L1535)、test_padding_to_max_length(L1655); - 批处理与模型输入:
test_batch_encode_plus_tensors(L2244)、test_torch_encode_plus_sent_to_model(L2339)、test_offsets_mapping(L2883); - 对齐与保存:
test_tokenization_python_rust_equals(L2768)、test_save_pretrained(L3390)。
另有从tests/fixtures/sample_text.txt读取样本文本驱动慢/快一致性检查的逻辑(L171-L172)。
六、把生成文件归位并运行测试
生成完成后按文档说明执行归位与验证:
# 1. 将新生成的文件夹移动到对应模型的测试子目录 # 例如 tests/models/brand_new_bert/test_tokenization_brand_new_bert.py # 2. 运行该测试文件 pytest tests/models/brand_new_bert/test_tokenization_brand_new_bert.py若在仓库内查看现成范例,可对照 tests/models/bert/test_tokenization_bert.py(BERT)、tests/models/albert/test_tokenization_albert.py(ALBERT)等十余个模型的分词测试,它们都是从同一 mixin 体系派生并各自补齐setUp与硬编码断言的成熟样例。注意在仓库中运行此类测试前,需确认已安装sentencepiece(@require_sentencepiece依赖)与tokenizers(@require_tokenizers依赖),否则相关用例会被unittest.skipUnless跳过而不是失败(装饰器语义见 testing_utils.py)。
七、最佳实践清单
- 命名三件套保持一致:
modelname(原样大小写)、camelcase_modelname(类名/导入名)、lowercase_modelname(文件名)三者必须对应同一模型,避免类名与文件名错位; - 如实申报类与依赖:
has_slow_class/has_fast_class/slow_tokenizer_use_sentencepiece必须与模型实际实现一致,否则生成的 import 或装饰器会让测试误跳过或误失败; - 必改
setUp:不实现玩具分词器的保存,get_tokenizer()/get_rust_tokenizer()会因from_pretrained(self.tmpdirname)找不到文件而失败(加载逻辑见 test_tokenization_common.py); - 补硬编码断言:mixin 只保证通用契约,模型特有的分词边界(如 BERT 的
##子词切分)必须靠自定义测试固定下来; - 提交前跑通全套:先单跑生成文件,再跑
tests/test_tokenization_common.py中与test_slow_tokenizer/test_rust_tokenizer开关相关的公共用例,确保与既有模型测试风格一致。
八、关联文件索引
- 模板说明:README.md
- 变量配置:cookiecutter.json
- 生成骨架:test_tokenization_{{cookiecutter.lowercase_modelname}}.py
- 公共测试基类:tests/test_tokenization_common.py
- 成熟范例:tests/models/bert/test_tokenization_bert.py
- 依赖装饰器:src/transformers/testing_utils.py
- 推理引擎
- 大模型
【免费下载链接】FlexGen
Running large language models on a single GPU for throughput-oriented scenarios.
相关推荐
开源项目 Mantle 亮点深度解析:Objective-C模型层的革命性简化
开源项目 Mantle 亮点深度解析:Objective C模型层的革命性简化 引言:Objective C模型开发的痛点 在iOS/macOS开发中,处理JS
推理引擎大模型FlexGen 基准测试仓库中的 Hugging Face Transformers:预训练模型加载、pipeline 推理与多框架实践指南
FlexGen 基准测试仓库中的 Hugging Face Transformers:预训练模型加载、pipeline 推理与多框架实践指南 本篇技术指南以当前
推理引擎大模型FlexGen 仓库中的 Hugging Face transformers 混合 INT8 量化测试指南:基于 bitsandbytes 的 8-bit 模型加载、调试与验证
FlexGen 仓库中的 Hugging Face transformers 混合 INT8 量化测试指南:基于 bitsandbytes 的 8 bit 模型
推理引擎大模型
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考