☰
Transformers 的 Pull Request 检查机制详解:四类 CI 校验与本地调试方法
2026/10/11 7:56:41 网站建设 项目流程

Transformers 的 Pull Request 检查机制详解:四类 CI 校验与本地调试方法

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

本文以 Transformers 仓库的官方文档 pr_checks.md 为主体,系统讲解在仓库中提交 Pull Request 后会被触发的四类检查——测试执行、文档构建、代码风格、仓库一致性——它们各自对应的 CI 任务与本地调试命令。读完后,你将能够在本地完整复现 CI 的每一步校验,当 PR 检查失败时快速定位原因并用make命令自动修复。

一、检查体系总览与前置准备

当你在 Transformers 仓库打开一个 Pull Request 时,会自动执行一系列校验,目的是确保你提交的补丁不会破坏任何既有功能。这些校验共分为四种类型:

  1. 常规测试(pruebas regulares)
  2. 文档构建(creación de la documentación)
  3. 代码与文档风格(estilo del código y documentación)
  4. 仓库一致性(consistencia del repositorio)

理解这四种校验背后“为什么存在”,是排查 CI 失败的基础。所有本地调试都以拥有开发环境安装为前提:

pip install transformers[dev]

或者采用可编辑安装:

pip install -e ".[dev]"

安装的是 Transformers 仓库本身。从 setup.py 的依赖定义看,devextra 的组合方式是extras["dev"] = extras["all"] + extras["testing"] + extras["ja"] + extras["sklearn"],即包含了全部可选依赖加测试工具链,这与 CI 检查所需的完整环境相匹配。

注意:当前仓库的 CI 已演进为双入口结构。从 .circleci/config.yml 的 workflow 定义看,公开仓库的 CI 已迁移到 GitHub Actions(CircleCI 对公开仓库为 no-op),CircleCI 配置主要用于私有仓库(如新模型接入)的完整流水线;但两类检查任务(check_code_quality、check_repository_consistency)以及fetch_tests测试抓取任务仍在该配置中定义,本文后续以这些任务为线索说明。

二、测试:run_tests_* 系列任务与 tests_fetcher 测试抓取

2.1 测试任务的划分方式

所有以ci/circleci: run_tests_开头的过程都执行 Transformers 测试集的一部分。每个过程聚焦于库的某一部分、在某一特定环境中运行:例如ci/circleci: run_tests_pipelines_tf就在只安装了 TensorFlow 的环境中执行 pipelines 模块的测试。

2.2 为什么只跑一部分测试:tests_fetcher 的四步机制

为了避免在“被测模块实际没有变化”时仍执行全部测试,CI 只运行测试集的一个子集:先运行一个辅助任务,确定 PR 前后库的差异(即 GitHub “Files changed” 页签展示的内容),再挑选受该差异影响的测试。该辅助任务可以本地运行:

python utils/tests_fetcher.py

(在 Transformers 仓库根目录下执行)其内部执行以下四个步骤:

  1. 过滤真实代码变更:对diff中的每个文件,检查改动是发生在真实代码、还是仅发生在注释或 docstring 中。只有包含真实代码改动的文件会被保留。
  2. 构建影响地图:为库中每个源码文件建立一张内部映射表,给出它递归影响的所有文件。定义上,模块 A 影响模块 B,当且仅当模块 B 导入了模块 A;而递归影响需要一条从 A 到 B 的模块链,链上每个模块导入前一个模块。
  3. 应用影响地图:将这张地图作用于第 1 步收集到的文件,得到受该 PR 影响的模型文件列表。
  4. 映射到测试文件:把每个受影响文件分配到其对应的测试文件,最终得到待执行的测试列表。

本地运行该脚本后,你会看到第 1、3、4 步的结果被打印出来,从而知道哪些测试将会被运行。脚本同时会生成一个名为test_list.txt的文件,其中包含待执行测试列表,可以直接本地执行:

python -m pytest -n 8 --dist=loadfile -rA -s $(cat test_list.txt)

2.3 源码层面的补充:tests_fetcher 的边界策略

深入 utils/tests_fetcher.py 可以看到更多实现细节:

  • 模块 docstring 自述为 “tests_fetcher V2”,核心逻辑分为两个 Stage:Stage 1 识别被修改的文件(PR 场景取从分支点到当前 commit 的全部变更,并排除仅 docstring/注释的修改);Stage 2 通过解析各模块与测试文件的 import 关系,构建“反向依赖图”以找出所有受影响的模块与测试。
  • 从源码结构看,脚本内置了两类“兜底”机制:一是CORE_FILES常量,列出了改动即会触发全量测试的核心文件(如src/transformers/modeling_utils.py、src/transformers/core_model_loading.py、src/transformers/cache_utils.py、src/transformers/generation/utils.py等,因为这些文件几乎影响库的每一个角落);二是NUM_MODELS_TO_TRIGGER_FULL_CI = 15这一启发式阈值——当受影响的模型数量过多时,不再逐一挑选,而是退化为只运行核心模型的测试,避免单次 PR 触发无法承受的运行量。
  • 脚本还支持--diff_with_last_commit参数,用于在 main 分支上(而非 PR 场景)以“与上一次 commit 的 diff”来确定受影响的测试。
  • 两个已声明的注意点:该模块按“文件”粒度过滤测试(而非单个测试函数),因此不同用途的测试放在不同文件里效果最佳;它假设__init__.py只做导入而不构建对象。

如果某次 PR 漏抓了受影响的测试也不用担心:全套测试仍会每日执行一次作为兜底。

三、文档构建:build_pr_documentation 与本地预览

build_pr_documentation任务会编译并生成文档预览,确保你的 PR 合并后文档呈现正常。一个机器人会在你的 PR 中追加一条评论,附上文档预览链接;你对 PR 的任何修改都会自动反映到预览中。

如果文档构建失败,点击失败任务旁的Detalles(Details)查看出错位置。一个常见的错误其实非常简单——toctree中缺少了某个文件(即新建的文档页面没有被登记进目录树)。

如果想本地编译或预览文档,参见 docs/README.md。其中说明:文档位于docs/source/<lang>/目录下、由 doc-builder 构建;通常不必本地构建文档(PR 触发的机器人预览已足够),但为了更快的迭代循环或开 PR 前自查,可以本地构建,安装[quality]extra 依赖即可满足仅改文档的场景([dev]则覆盖完整开发依赖)。

四、代码与文档风格:make style、ruff 与 Makefile 检查器

4.1 格式化工具链

代码格式化应用于所有源码文件、示例和测试,原文档所述工具为black与ruff;此外还有处理 docstring 与 rst 文件格式的专用工具(原文档指向utils/style_doc.py),以及处理 Transformers 各__init__.py中 lazy import 排序的 utils/custom_init_isort.py。

make style

可以一次性应用上述格式化。CI 在check_code_quality任务(即原文档所指的ci/circleci: check_code_quality)中验证这些格式已应用。

需要说明的是:从当前仓库的 utils/ 目录结构看,docstring 格式化与“自动表格”相关的脚本已演进——原utils/style_doc.py、utils/check_table.py不再存在,相应职责由 ruff 规则、utils/check_docstrings.py、utils/update_metadata.py 等检查器承接。理解这一点有助于对照 CI 报错信息定位对应的现行脚本。

make style在 Makefile 中的定义是:

STYLE_CHECKERS := ruff_check, ruff_format, init_isort, sort_auto_mappings, noisy_comments style: @python utils/checkers.py $(STYLE_CHECKERS) --fix

即当前由统一入口 utils/checkers.py 驱动ruff检查、ruff格式化、__init__.pylazy import 排序、Auto-mappings 排序与噪音注释检查。

4.2 ruff 静态检查与 make check-repo

CI 同时运行ruff,它会对代码做基础静态检查,发现未定义变量或未使用变量时会报错。本地运行该检查:

make check-repo

这个命令还会执行全部“仓库一致性”附加检查(见下一节)。从 Makefile 看,check-repo实际是:

ALL_CHECKERS := $(CODE_QUALITY_CHECKERS), $(REPO_CONSISTENCY_CHECKERS) check-repo: @python utils/checkers.py $(ALL_CHECKERS) --keep-going

即代码质量检查(types、modeling_structure、ruff_check、ruff_format、init_isort、sort_auto_mappings、noisy_comments)加仓库一致性检查,--keep-going表示单个检查失败不中断,便于一次收集所有问题。

五、仓库一致性:make check-repo 检查清单与 make fix-repo 自动修复

5.1 一致性校验项

make check-repo聚合了所有“确保 PR 提交后仓库仍处于健康状态”的检查,CI 中对应check_repository_consistency任务(原文档写作ci/circleci: check_repository_consistency)。原文档列出的检查项与负责脚本如下:

检查内容负责脚本
所有加入__init__的对象都有文档utils/check_repo.py
所有__init__.py文件的两个 section 内容一致utils/check_inits.py
所有标记为“拷贝自其他模块”的代码与原件保持一致utils/check_copies.py
所有配置类至少在 docstring 中提及一个有效 checkpointutils/check_config_docstrings.py
README 翻译版与文档索引中的模型列表与主 README 一致utils/check_copies.py
文档中自动生成的表格保持最新原文档指向utils/check_table.py(现行仓库中由 utils/update_metadata.py 等元数据检查器承接)
即使未安装全部可选依赖,库的所有对象依然可用utils/check_dummies.py

几个脚本的实现要点值得展开:

  • utils/check_inits.py 的 docstring 解释了“两个 section 一致”的动机:src/transformers/models/__init__.py的TYPE_CHECKING半区只为类型检查器提供_LazyModule运行时导出内容的静态视图;手写这一半会导致新模型丢失、已删模型残留,而运行时不受影响、imports检查器又捕获不到,因此它直接从磁盘上的 import 结构重新生成该文件——检查模式直接运行,--fix_and_overwrite模式则自动重写。
  • utils/check_copies.py 覆盖三类一致性:所有# Copied from注释标记的代码副本、主 README 与本地化 README 中的模型列表、以及脚本内FULL_COPIES常量注册的整文件级副本;同样支持--fix_and_overwrite自动补齐缺失的 README 模型行。

5.2 当前 Makefile 中的完整一致性检查器清单

当前 Makefile 中REPO_CONSISTENCY_CHECKERS的完整列表比原文档所列更细,反映了仓库检查体系的增长:

REPO_CONSISTENCY_CHECKERS := \ auto_mappings, imports, import_complexity, copies, modular_conversion, \ inits, doc_toc, reviewers, modeling_rules_doc, docstrings, dummies, repo, \ pipeline_typing, config_docstrings, config_attributes, doctest_list, \ update_metadata, add_dates, deps_table

Makefile 注释还特别说明了一个工程细节:CI 的两个任务(make check-code-quality与make check-repository-consistency)持有检查器集合的权威定义,本地便捷目标check-repo/fix-repo由它们派生,从而保证两者永不漂移(注释中引用了历史上本地目标悄悄漏掉auto_mappings的真实事故)。

5.3 自动修复:make fix-repo

如果一致性检查失败,上表所列前两项(init 对象文档、README 列表类)需要人工修复,其余各项可以运行以下命令自动修复:

make fix-repo

对应 Makefile 定义:

fix-repo: @python utils/checkers.py $(ALL_CHECKERS) --fix --keep-going

5.4 可选依赖下的可导入性验证

“库在缺少可选依赖时仍全部可用”这条检查在 CI 中有直接的实证环节。从 .circleci/config.yml 的check_repository_consistency任务看,CI 会在四种依赖组合下分别执行python -c "from transformers import *":全部后端(torch + PIL + torchvision)、仅 torch(卸载 Pillow 与 torchvision)、仅 PIL(卸载 torch 全家)、torch + PIL 但无 torchvision——任何一组导入失败都会以 “Fix unprotected imports!!” 报错终止。这与 utils/check_dummies.py 的 dummy 对象机制互为表里:dummy 保证未装可选依赖时属性访问不炸,而 CI 的多次导入测试则端到端验证了这一点。

5.5 面向“新增模型 PR”的附加检查

针对新增模型的 PR,原文档还列出两类附加检查:

  • 所有新增模型都出现在 Auto-mapping 中(由 utils/check_repo.py 完成;现行 Makefile 清单中的auto_mappings检查器对应 utils/sort_auto_mappings.py 与 utils/check_auto.py);
  • 所有模型都能被正确校验(由 utils/check_repo.py 完成)。

六、底层机制:checkers.py 的统一检查器插件体系

上述make style/make check-repo/make fix-repo之所以能一行命令驱动几十个脚本,源于 utils/checkers.py 的统一插件体系,值得单独理解:

  • 声明式注册:每个检查器模块(如 utils/check_copies.py、utils/check_inits.py)在文件顶层声明一个CHECKER_CONFIG字典,含五个键:name(注册名,如copies、inits)、label(人类可读标签)、cache_globs(缓存失效用的文件模式)、check_args(检查模式追加参数)、fix_args(修复模式追加参数)。
  • AST 发现而非导入:checkers.py通过ast.parse+ast.literal_eval扫描utils/*.py提取CHECKER_CONFIG,不导入检查器代码本身——这既保证发现阶段速度快,也避免扫描期执行检查器逻辑。
  • 基于内容哈希的缓存:cache_globs所列文件的内容被哈希,决定某个检查器能否跳过;docstring 明确提示某些检查器(如check_repo、check_config_docstrings)会内省实时的transformers模块,其 globs 只是依赖集的近似;某些检查器(如add_dates、imports)依赖网络/git 历史等外部状态,缓存无法完全覆盖。不确定时可加--no-cache强制全量运行。
  • 三种常用运行模式:python utils/checkers.py copies,doc_toc(指定检查)、加--fix(自动修复)、加--keep-going(失败不中断),以及python utils/checkers.py all全量执行。

理解了这一层,再读 CI 日志时就能把任务名(如check_code_quality执行make check-code-quality)直接映射到具体检查器脚本,快速定位失败源头。

七、本地调试速查表

场景本地命令CI 对应任务
复现 PR 将运行哪些测试python utils/tests_fetcher.py,再python -m pytest -n 8 --dist=loadfile -rA -s $(cat test_list.txt)run_tests_*系列
应用代码/文档格式化make stylecheck_code_quality
基础静态检查 + 全部仓库一致性make check-repocheck_code_quality+check_repository_consistency
自动修复一致性项make fix-repo—(人工本地操作)
文档预览依赖 PR 机器人自动构建,本地方法见 docs/README.mdbuild_pr_documentation

适用前提与限制:本文所有命令以当前仓库(pyproject.toml/setup.py定义的devextra、utils/checkers.py插件体系、CircleCI 配置文件现状)为准;公开仓库的实际测试任务经 GitHub Actions 触发,CircleCI 配置中的ci/circleci:任务名对应原文档时期与私有仓库流水线的命名,本地调试命令不受此影响。若你新增的是模型模块,还需额外确认 Auto-mapping 与tests_fetcher核心文件清单的触发行为,避免测试抓取范围与预期不符。

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询