TorchTitan 测试体系详解:Fake PG / Real PG 集成测试、数值守卫与单元/集成测试运行指南
【免费下载链接】torchtitanA PyTorch native platform for training generative AI models项目地址: https://gitcode.com/GitHub_Trending/to/torchtitan
本篇指南围绕 torchtitan 仓库的 测试体系文档 展开,系统讲解其"单元测试 + 集成测试 + 数值测试"三层测试架构、基于 Fake PG(FakeProcessGroup)与 Real PG(真实进程组)的 CI 设计原则,以及各类测试的完整运行命令。读完本文,你将能够在本机或 CI 环境中复现 torchtitan 的 A10G 完整测试矩阵、理解 golden 数值文件的校验机制,并掌握如何为项目新增一个集成测试用例。
测试目录结构
torchtitan 的全部测试位于tests/目录下,按硬件需求与测试粒度分层组织:
tests/unit_tests/cpu/:无需 GPU 即可运行的单元测试;tests/unit_tests/gpu/:需要 GPU 的测试,其中多卡测试使用 pytest 的multi_gpu标记(marker);tests/integration_tests/:组合多个组件进行端到端验证的集成测试:- features.py:torchtitan 核心特性与组合性(composability)测试;
- flux.py:FLUX 模型测试;
- h100.py:H100 GPU 上的测试用例;
- b200.py:需要 SM100 或 SM103 GPU(B200 级别)的测试用例;
- models.py:各模型架构的测试;
tests/assets/:测试资产与 fixture:losses/:数值守卫(numerics guards)用的 golden 损失与梯度范数曲线,按fake_pg/与real_pg/两个模式目录存放;tokenizer/:测试用的分词器配置与词表文件;custom_schedule.csv:测试用的自定义 PP(流水线并行)调度表。
每个集成测试套件的测试条目定义(OverrideDefinitions列表)与对应的Trainer.Config构建函数分离存放:套件清单在tests/integration_tests/下,而配置本体位于 torchtitan_recipes/tests/ 目录,每个套件对应一个模块(features.py、models.py、h100.py、b200.py等)。这种"清单与配置分离"的设计使得同一套硬件套件可以同时被 CI 的 A10G 通道与 ROCm 等可复用工作流引用。
CI 设计:集成测试(目标:E2E 组合性)
原则:尽可能使用 Fake PG
torchtitan 的 CI 遵循一个核心原则:在 pull request 上尽可能使用 Fake PG,以获得快速而广泛的功能覆盖。每一个启用的测试都会在代码合入前执行:
- 与 Fake PG 兼容的测试只使用1 块物理 GPU(
torch.distributed的 FakeProcessGroup 在单卡上模拟任意 world size 的通信); - 标记了
use_real_pg=True的测试使用8 块物理 GPU; - 定期调度(schedule)与合入后(post-merge)运行则以 Real PG 执行完整测试套件。
从源码看,这一机制在 run_tests.py 中落地:当use_fake_pg为真时,runner 通过环境变量COMM_MODE=fake_backend切换通信后端,并将NGPU设为测试声明的逻辑卡数,而实际只占用 1 块物理 GPU(见run_single_test中的base_env["COMM_MODE"] = "fake_backend"分支)。
同时,init.py 中的validate_fake_pg_compatibility会对每个配置做兼容性校验:如果配置启用了 checkpointing、流水线并行(pipeline_parallel_degree > 1)或显式非 Fake 通信后端等已知不兼容项,而测试又未标记use_real_pg=True,校验会直接抛出ValueError。这保证了"哪些测试能在 Fake PG 上跑"这一约束由代码强制执行,而非依赖约定。
CI 触发节奏(Cadence)
- 1 GPU Fake PG 节奏:pull request 的 open、update、reopen 或 ready-for-review 事件均触发。可复用工作流(reusable workflow)的调用方默认运行 Fake PG;
- 8 GPU Real PG 节奏:上述任一 PR 事件都会将标记
use_real_pg=True的测试拆分为required subset - features与required subset - models两个独立作业运行。给 PR 打上ciflow/8gpu标签会创建ciflow/8gpu/*标签,并以 Real PG 运行full suite - features与full suite - models两个完整套件作业。向main的推送与合并、每 6 小时的计划任务以及手动 dispatch 也会运行这两个完整套件作业。可复用工作流调用方可以显式请求execution_mode: real_pg,ROCm 工作流即采用这种方式; - 8 GPU H100 节奏:携带
ciflow/h100.8标签的自选 PR。该通道始终使用 Real PG;标签保留期间,update 与 reopen 事件会重新运行; - B200 节奏:携带
ciflow/b200标签的自选 PR,以及main上影响 Kimi K3 的推送。该通道使用 Real PG,目前运行 Kimi K3 多模态 FSDP 测试(对应 b200.py 中的kimi_k3_mm_fsdp用例)。
功能测试(features 套件)提供基础设施组合性的深度:Fake PG 运行验证特性组合能够正确配置、变换并完成训练,Real PG 运行则额外覆盖真实集合通信与分布式状态。模型测试(models 套件)提供跨受支持实现的广度。两类定义保持分离以便区分。每个 8 GPU Real PG 套件作为独立 CI 作业运行并拥有独立超时;模型作业同时运行 FLUX 集成测试。
在 PR 上,Fake PG 通道与real_pg_requiredReal PG 范围对启用的 A10G 测试做无重叠切分;合入后与计划调度的 Real PG 通道则运行完整选定套件。硬件通过套件编码:features与models运行在 A10G 通道,h100与b200仅在其各自的工作流中以 Real PG 运行(run_tests.py 的main中也会强制校验h100/b200套件不允许fake_pg模式)。
数值测试(目标:确定性回归覆盖)
部分模型集成测试通过设置golden_numerics_path来检查数值确定性。运行器从该文件推导出指标列与步数(_read_golden_spec解析 golden 文件的# step loss grad_norm表头),为 A10G Real PG 执行创建种子 checkpoint(seed checkpoint),并通过 loss_compare.py 执行集成用例。Fake PG 执行跳过种子 checkpoint 创建,走其固定的初始化路径。
具体规则:
A10G 用例在 PR 上以 1 块物理 GPU + Fake PG 运行,在合入后、计划调度或
ciflow/8gpu标签触发时以 8 块物理 A10G + Real PG 运行。golden 路径可以用{execution_mode}占位符选择fake_pg/或real_pg/目录;共享数值用例在两种模式下使用相同配置;Fake PG golden 守卫的是 PyTorch FakeProcessGroup 的确定性合成数值契约,并不校验远端 rank 数值或 EP 负载均衡;
Fake PG 下较大的梯度范数在该合成契约下仍可能是确定性的。非有限(non-finite)梯度不会被接受——训练会在优化器更新前停止。golden 能捕获对有限合成值的改动,但不证明模拟梯度在数值上具有代表性;
golden 目录标识 PG 模式,文件名标识模型与硬件档位,而精确的并行计划记录在文件头中。例如 tests/assets/losses/fake_pg/llama3_a10g.txt 的文件头为:
# config: llama3_debugmodel_fsdp2_tp2_cp2 # ngpu: 8 # parallelism: FSDP=2, TP=2, CP=2 # step loss grad_norm 1 3.742710590362549 847769.4375 ...其中
# parallelism:这一行由 runner 在导出数值时自动插入(_add_parallelism_header依据配置中的data_parallel_shard_degree、tensor_parallel_degree、context_parallel_degree、expert_parallel_degree、pipeline_parallel_degree生成摘要),保证每个 golden 文件自描述其并行拓扑。Qwen3.5 MoE FSDP 4 x TP 2, EP 4没有数值 golden:其 A10G Real PG 结果非按位确定性,因此该用例只提供端到端覆盖;
DeepSeek V4 FSDP 2 x TP 2, EP 2 仅为端到端覆盖,没有数值 golden。它只在真实进程组上运行(
use_real_pg=True):在 Fake PG 下,其序列并行集合通信返回与输入别名(alias)的激活值,会破坏 saved-for-backward 张量并使第 1 步的 grad_norm 爆炸;同一配置在真实的 4 卡 PG 上训练正常。
A10G 数值用例拓扑
| A10G 模型 | 拓扑(Fake-PG 与 Real-PG) |
|---|---|
| Llama 3 | FSDP 2 x TP 2 x CP 2 |
| Llama 3 SFT | FSDP 2 |
| DeepSeek V3 | FSDP 8, EP 8 |
| DeepSeek V4 | FSDP 2 x TP 2, EP 2(仅 Real-PG) |
| GPT-OSS | FSDP 4 x TP 2, EP 4 |
| Qwen3 | FSDP 2 x TP 2 x CP 2, EP 8 |
| Muse Glimmer text | FSDP 8 |
| Qwen3.5 MoE multimodal | FSDP 4 x TP 2, EP 4 |
| Kimi K2.5 DistMuon | FSDP 8, EP 8 |
Kimi K2.5 DistMuon FSDP+EP 与 Kimi K2.7 DistMuon PP+FSDP+EP 均在 A10G 上运行。由于 K2.5 多模态反向传播使用双三次上采样(bicubic upsampling),其 CUDA 反向没有确定性实现,因此 FSDP+EP 用例不携带数值 golden。手工对比时,loss_compare.py可以用模型等价的 AdamW 配置创建仅模型的种子 checkpoint,而被测运行继续保留 DistMuon(对应OverrideDefinitions.loss_compare_seed_config字段)。
仅 Real-PG 的 CP / 流水线通信用例
| A10G 模型 | 流水线并行拓扑 |
|---|---|
| DeepSeek V3 | FSDP 2 x CP 2 x PP 2, EP 4, Interleaved1F1B |
| Llama 3 | FSDP 2 x TP 2 x PP 2, 1F1B |
| GPT-OSS | FSDP 2 x CP 2 x PP 2, EP 4, Interleaved1F1B |
| Kimi K2.7 DistMuon | FSDP 2 x PP 2, EP 2, Interleaved1F1B |
单元测试(目标:模块功能)
- CPU 与 GPU 需求通过
tests/unit_tests/cpu/与tests/unit_tests/gpu/两个目录编码; - 需要多块物理设备的 GPU 测试使用
multi_gpupytest 标记;1 GPU 通道选择not multi_gpu,多卡通道选择multi_gpu,两者取自同一 GPU 目录。
运行测试
前置条件
确保已安装全部开发依赖:
pip install -r requirements-dev.txt pip install -r requirements.txt运行集成测试
python -m tests.integration_tests.run_tests <output_dir> [--test_suite TEST_SUITE[,TEST_SUITE...]] [--execution_mode {fake_pg,real_pg}] [--test_scope {all,real_pg_required}] [--test_name TEST_NAME] [--ngpu NGPU]参数说明(含 run_tests.py 中解析的全部选项):
output_dir:(必填)存放测试输出的目录,必须为空目录,否则 runner 直接报错;--test_suite:(可选)逗号分隔的测试套件列表(默认features),可选值为features, models, h100, b200;多套件时输出目录按套件名分子目录;--execution_mode:(可选)使用 Fake PG 或 Real PG 运行(默认real_pg);h100/b200套件仅支持real_pg;--test_scope:(可选)运行全部选定测试或仅use_real_pg=True的测试(默认all);real_pg_required要求--execution_mode real_pg;--test_name:(可选)按名称运行特定测试(默认all);--ngpu:(可选)测试可用的 GPU 数量(默认 8)。Runner 用 GPU 池把各测试固定到互不相交的物理 GPU 子集上并发执行,每个测试通过CUDA_VISIBLE_DEVICES/HIP_VISIBLE_DEVICES固定其分片;--export-numerics:(可选)对带golden_numerics_path的测试导出数值结果,而不是与其 golden 文件比对;--exclude:(可选)逗号分隔的、需要跳过的测试名列表;--gpu_arch_type:(可选)cuda或rocm(默认cuda),ROCm 上会跳过标记skip_rocm_test的用例;--parallel/--no-parallel:(可选)并发执行(默认开启),测试按"最大需求优先"装箱到 GPU 池,任一时刻最多占用--ngpu块 GPU。
每个测试为其每次运行(run)指定完整配置,runner 把它们作为MODULE与CONFIG环境变量传给 run_train.sh。这些配置位于 torchtitan_recipes/tests/,每个套件对应一个模块。要运行别的内容,只需在那里添加一个配置,再添加一个引用它的测试条目。
示例:
# 运行全部功能集成测试(features 是默认套件) python -m tests.integration_tests.run_tests test_output # 用 Fake PG 在 1 块物理 GPU 上运行完整 A10G 矩阵 python -m tests.integration_tests.run_tests test_output --test_suite features,models --execution_mode fake_pg --ngpu 1 # 用真实进程组运行完整 A10G 矩阵 python -m tests.integration_tests.run_tests test_output --test_suite features,models --execution_mode real_pg --ngpu 8 # 只运行显式要求真实进程组的用例 python -m tests.integration_tests.run_tests test_output --test_suite features,models --execution_mode real_pg --test_scope real_pg_required --ngpu 8 # 用真实进程组运行 H100 专属用例 python -m tests.integration_tests.run_tests test_output --test_suite h100 --execution_mode real_pg --ngpu 8 # 用真实进程组运行 B200 专属用例 python -m tests.integration_tests.run_tests test_output --test_suite b200 --execution_mode real_pg --ngpu 8运行单元测试
# CPU 单元测试 pytest -s tests/unit_tests/cpu/ # 单卡 GPU 测试 pytest -s tests/unit_tests/gpu/ -m "not multi_gpu" # 多卡 GPU 测试 pytest -s tests/unit_tests/gpu/ -m multi_gpu运行指定测试文件与指定测试函数:
# 指定测试文件 pytest -s tests/unit_tests/cpu/test_config_manager.py # 指定测试函数 pytest -s tests/unit_tests/cpu/test_config_manager.py::TestConfigManager::test_cli_overrides源码深潜:Runner 与测试工具
测试条目:OverrideDefinitions
所有集成测试共用 tests/integration_tests/init.py 中的OverrideDefinitions数据类,其关键字段包括:
configs:每次运行一个Trainer.Config构建函数,runner 通过其__module__/__name__设置MODULE/CONFIG环境变量;override_args:兼容旧式"基础配置 + 覆盖参数"形式的命令行片段(保留给torchtitan/experiments下的套件);ngpu:逻辑 world size;use_real_pg:是否需要真实通信语义;golden_numerics_path:数值 golden 路径(可含{execution_mode}占位符),并约束此类测试必须恰好定义一个配置;loss_compare_seed_config:供loss_compare.py单卡种子运行使用的模型等价配置(当测试配置应用了并行 transform 时需要);timeout、disabled、skip_rocm_test:超时、禁用与 ROCm 跳过控制。
以 features.py 中的full_checkpoint条目为例,它依次引用"保存"与"加载"两个配置(llama3_debugmodel_full_checkpoint_save/..._load),并标记use_real_pg=True——因为 checkpointing 属于 Fake PG 不兼容项,这正是validate_fake_pg_compatibility强制要求的用法。
数值校验流水线
当测试设置了golden_numerics_path时,run_tests.py 的run_single_test不会直接调用run_train.sh,而是拼装一条scripts/loss_compare.py命令:以同一配置的"baseline"与"test"双跑(保证种子一致),用--assert-equal断言 loss/grad_norm 与 golden 完全相等;--export-numerics模式则改为--export-result写出新结果并由 runner 补写# parallelism:头行。Real PG 模式使用--baseline-ngpus/--test-ngpus与种子 checkpoint,Fake PG 模式追加--no-seed-checkpoint走固定初始化。loss_compare.py的模块 docstring(scripts/loss_compare.py)给出了同一脚本的手工用法全集,包括跨 commit 对比、--import-result基线模式与--seed-config种子配置。
确定性哈希工具
tests/utils.py 提供hash_model与hash_gradient两个函数,用于跨运行对比模型状态/梯度以验证确定性训练:
- 对
DTensor先调用to_local()再哈希,天然适配 FSDP/TP 切分后的分布式参数; - 分布式环境下仅 rank 0 计算哈希,其余 rank 返回空字符串;
per_tensor=True时返回"张量名 → 十六进制哈希"的 JSON 字典,便于精确定位第一个发散张量;默认对整个模型输出单一 sha256;- 实现上使用
t.numpy().tobytes()生成字节流(按代码注释,这是张量化为字节最快的方式)。
这些工具与 golden 数值文件、loss_compare.py的--assert-equal一起,构成了 torchtitan 从"单卡合成数值契约"到"8 卡真实通信逐位确定性"的完整回归防线。
小结
torchtitan 的测试体系用三层防线保障一个 PyTorch 原生训练平台的正确性:CPU/GPU 单元测试覆盖模块功能;集成测试以"Fake PG 单卡快速全覆盖 + Real PG 八卡真实通信"的双节奏保证 E2E 组合性;数值测试则以 golden loss/grad_norm 曲线加上loss_compare.py的逐位断言,对确定性回归形成守卫。其工程要点——测试清单与Trainer.Config分离存放、Fake PG 兼容性由代码强制校验、golden 文件自描述并行拓扑、测试输出目录强制为空——都值得在自建分布式训练项目的 CI 时参考。
【免费下载链接】torchtitanA PyTorch native platform for training generative AI models项目地址: https://gitcode.com/GitHub_Trending/to/torchtitan
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考