Transformers 文档

Pull Request 检查

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始

Pull Request 检查

当你在 🤗 Transformers 上打开一个 pull request 时,会运行相当多的检查,以确保你添加的补丁不会破坏任何已有的东西。这些检查分为四种类型

  • 常规测试
  • 文档构建
  • 代码和文档风格
  • 一般仓库一致性

在本文档中,我们将尝试解释这些不同的检查是什么以及它们背后的原因,以及如果其中一个检查在你的 PR 上失败时如何在本地调试它们。

请注意,理想情况下,它们需要你进行开发安装

pip install transformers[dev]

或者用于可编辑安装

pip install -e .[dev]

在 Transformers 仓库中。由于 Transformers 的可选依赖项数量已大幅增长,你可能无法全部安装它们。如果开发安装失败,请确保安装你正在使用的深度学习框架(PyTorch、TensorFlow 和/或 Flax),然后执行

pip install transformers[quality]

或者用于可编辑安装

pip install -e .[quality]

测试

所有以 ci/circleci: run_tests_ 开头的任务都运行 Transformers 测试套件的一部分。这些任务中的每一个都专注于库的某个部分在特定环境中的测试:例如 ci/circleci: run_tests_pipelines_tf 在仅安装 TensorFlow 的环境中运行 pipelines 测试。

请注意,为了避免在被测模块没有实际更改时运行测试,每次只运行测试套件的一部分:运行一个实用程序来确定 PR 前后库中的差异(GitHub 在“文件更改”选项卡中显示的内容),并选择受该差异影响的测试。该实用程序可以使用以下命令在本地运行

python utils/tests_fetcher.py

从 Transformers 仓库的根目录。它将

  1. 检查 diff 中的每个文件,看更改是在代码中还是仅在注释或文档字符串中。仅保留具有实际代码更改的文件。
  2. 构建一个内部映射,该映射为库源代码的每个文件提供它递归影响的所有文件。如果模块 B 导入模块 A,则称模块 A 影响模块 B。对于递归影响,我们需要一个从模块 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)

为了防止任何疏漏,完整的测试套件也会每天运行。

文档构建

build_pr_documentation 任务构建并生成文档预览,以确保你的 PR 合并后一切看起来正常。一个机器人将在你的 PR 中添加一个链接以预览文档。你对 PR 所做的任何更改都会在预览中自动更新。如果文档构建失败,请单击失败任务旁边的“Details”以查看哪里出错了。通常,错误就像 toctree 中缺少文件一样简单。

如果你有兴趣在本地构建或预览文档,请查看 docs 文件夹中的 README.md

代码和文档风格

代码格式化应用于所有源文件、示例和测试,使用 blackruff。我们还有一个自定义工具,用于处理文档字符串和 rst 文件的格式化 (utils/style_doc.py),以及在 Transformers __init__.py 文件中执行的延迟导入的顺序 (utils/custom_init_isort.py)。所有这些都可以通过执行以下命令启动

make style

CI 检查这些是否已在 ci/circleci: check_code_quality 检查中应用。它还运行 ruff,它将基本查看你的代码,如果发现未定义的变量或未使用的变量,则会发出警告。要在本地运行该检查,请使用

make quality

这可能需要很长时间,因此要在当前分支中仅对你修改的文件运行相同的操作,请运行

make fixup

最后一个命令还将运行所有用于仓库一致性的附加检查。让我们看看它们。

仓库一致性

这重新组合了所有测试,以确保你的 PR 使仓库保持良好状态,并由 ci/circleci: check_repository_consistency 检查执行。你可以通过执行以下命令在本地运行该检查

make repo-consistency

这检查了

  • 添加到 init 的所有对象都已文档化(由 utils/check_repo.py 执行)
  • 所有 __init__.py 文件在其两个部分中都具有相同的内容(由 utils/check_inits.py 执行)
  • 所有标识为从另一个模块复制的代码都与原始代码一致(由 utils/check_copies.py 执行)
  • 所有配置类在其文档字符串中都至少提到了一个有效的检查点(由 utils/check_config_docstrings.py 执行)
  • 所有配置类仅包含在相应的建模文件中使用的属性(由 utils/check_config_attributes.py 执行)
  • README 的翻译和文档索引与主 README 具有相同的模型列表(由 utils/check_copies.py 执行)
  • 文档中的自动生成表格是最新的(由 utils/check_table.py 执行)
  • 即使未安装所有可选依赖项,库也拥有所有可用对象(由 utils/check_dummies.py 执行)
  • 所有文档字符串都正确记录了对象签名中的参数(由 utils/check_docstrings.py 执行)

如果此检查失败,前两项需要手动修复,后四项可以通过运行以下命令为你自动修复

make fix-copies

附加检查涉及添加新模型的 PR,主要是

  • 添加的所有模型都在 Auto-mapping 中(由 utils/check_repo.py 执行)
  • 所有模型都经过适当的测试(由 utils/check_repo.py 执行)

检查副本

由于 Transformers 库在模型代码方面非常有主见,并且每个模型都应完全在一个文件中实现,而不依赖于其他模型,因此我们添加了一种机制,用于检查给定模型层的代码副本是否与原始代码保持一致。这样,当出现 bug 修复时,我们可以看到所有其他受影响的模型,并选择向下传递修改或中断副本。

如果文件是另一个文件的完整副本,则应将其注册在 utils/check_copies.py 的常量 FULL_COPIES 中。

此机制依赖于 # Copied from xxx 形式的注释。xxx 应包含正在复制的类或函数的完整路径。例如,RobertaSelfOutputBertSelfOutput 类的直接副本,因此你可以在此处看到它有一个注释

# Copied from transformers.models.bert.modeling_bert.BertSelfOutput

请注意,你可以将其应用于从其复制的相关方法,而不是将其应用于整个类。例如,在这里你可以看到 RobertaPreTrainedModel._init_weights 如何从 BertPreTrainedModel 中的相同方法复制而来,并带有注释

# Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights

有时,副本除了名称外完全相同:例如在 RobertaAttention 中,我们使用 RobertaSelfAttention 而不是 BertSelfAttention,但除此之外,代码完全相同。这就是为什么 # Copied from 支持使用以下语法进行简单的字符串替换:Copied from xxx with foo->bar。这意味着代码被复制,所有 foo 实例都被 bar 替换。你可以在 RobertaAttention 中看到它是如何使用的,并带有注释

# Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->Roberta

请注意,箭头周围不应有任何空格(除非该空格是要替换的模式的一部分)。

你可以添加多个以逗号分隔的模式。例如,CamemberForMaskedLMRobertaForMaskedLM 的直接副本,其中有两个替换:Roberta 替换为 CamembertROBERTA 替换为 CAMEMBERT。你可以在此处看到这是如何完成的,并带有注释

# Copied from transformers.models.roberta.modeling_roberta.RobertaForMaskedLM with Roberta->Camembert, ROBERTA->CAMEMBERT

如果顺序很重要(因为其中一个替换可能与之前的替换冲突),则替换从左到右执行。

如果替换更改了格式(例如,如果你用一个很长的名称替换一个短名称),则在应用自动格式化程序后检查副本。

当模式只是同一替换的不同大小写(带有大写和小写变体)时,另一种方法是添加选项 all-casing。这是 MobileBertForSequenceClassification 中的一个示例,带有注释

# Copied from transformers.models.bert.modeling_bert.BertForSequenceClassification with Bert->MobileBert all-casing

在这种情况下,代码是从 BertForSequenceClassification 复制而来,通过替换

  • Bert 替换为 MobileBert(例如,在 init 中使用 MobileBertModel 时)
  • bert 替换为 mobilebert(例如,在定义 self.mobilebert 时)
  • BERT 替换为 MOBILEBERT(在常量 MOBILEBERT_INPUTS_DOCSTRING 中)
< > 在 GitHub 上更新