TorchTitan 测试体系详解:Fake PG / Real PG 集成测试、数值守卫与单元/集成测试运行指南
2026/9/17 8:00:45 网站建设 项目流程

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.pymodels.pyh100.pyb200.py等)。这种"清单与配置分离"的设计使得同一套硬件套件可以同时被 CI 的 A10G 通道与 ROCm 等可复用工作流引用。

CI 设计:集成测试(目标:E2E 组合性)

原则:尽可能使用 Fake PG

torchtitan 的 CI 遵循一个核心原则:在 pull request 上尽可能使用 Fake PG,以获得快速而广泛的功能覆盖。每一个启用的测试都会在代码合入前执行:

  • 与 Fake PG 兼容的测试只使用1 块物理 GPUtorch.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 - featuresrequired subset - models两个独立作业运行。给 PR 打上ciflow/8gpu标签会创建ciflow/8gpu/*标签,并以 Real PG 运行full suite - featuresfull 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 通道则运行完整选定套件。硬件通过套件编码:featuresmodels运行在 A10G 通道,h100b200仅在其各自的工作流中以 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_degreetensor_parallel_degreecontext_parallel_degreeexpert_parallel_degreepipeline_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 3FSDP 2 x TP 2 x CP 2
Llama 3 SFTFSDP 2
DeepSeek V3FSDP 8, EP 8
DeepSeek V4FSDP 2 x TP 2, EP 2(仅 Real-PG)
GPT-OSSFSDP 4 x TP 2, EP 4
Qwen3FSDP 2 x TP 2 x CP 2, EP 8
Muse Glimmer textFSDP 8
Qwen3.5 MoE multimodalFSDP 4 x TP 2, EP 4
Kimi K2.5 DistMuonFSDP 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 V3FSDP 2 x CP 2 x PP 2, EP 4, Interleaved1F1B
Llama 3FSDP 2 x TP 2 x PP 2, 1F1B
GPT-OSSFSDP 2 x CP 2 x PP 2, EP 4, Interleaved1F1B
Kimi K2.7 DistMuonFSDP 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:(可选)cudarocm(默认cuda),ROCm 上会跳过标记skip_rocm_test的用例;
  • --parallel/--no-parallel:(可选)并发执行(默认开启),测试按"最大需求优先"装箱到 GPU 池,任一时刻最多占用--ngpu块 GPU。

每个测试为其每次运行(run)指定完整配置,runner 把它们作为MODULECONFIG环境变量传给 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 时需要);
  • timeoutdisabledskip_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_modelhash_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),仅供参考

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

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

立即咨询