ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Megatron-LM CI/CD 全指南:流水线结构、PR 测试标签与内部 GitLab CI 触发排查

Megatron-LM CI/CD 全指南:流水线结构、PR 测试标签与内部 GitLab CI 触发排查 Megatron-LM CI/CD 全指南流水线结构、PR 测试标签与内部 GitLab CI 触发排查【免费下载链接】Megatron-LMOngoing research training transformer models at scale项目地址: https://gitcode.com/GitHub_Trending/me/Megatron-LMMegatron-LMNVIDIA 的 Megatron Core 大规模 Transformer 训练框架在仓库内维护了一套完整的分层 CI/CD 体系GitHub Actions 工作流根据 PR 标签动态决定测试范围、重复次数与容器镜像同时提供tools/trigger_internal_ci.py把本地分支推送到内部 GitLab 并触发功能测试流水线。本文以 skills/mcore-cicd/SKILL.md 为主线结合 .github/workflows/cicd-main.yml、tools/trigger_internal_ci.py 及 tools/trigger_internal_ci.md 等源码级证据系统讲解CI 流水线如何分层、各 PR 标签究竟控制什么参数、如何安全触发内部 GitLab CI、以及 CI 失败时如何从日志 artifact 中定位根因。读完本文你将能正确地为自己的 PR 选择测试标签、安全地触发内部流水线并独立完成一次 CI 失败的排查闭环。一、Answer-First先记住这套 CI 事实速查表Megatron-LM 的 CI 对“该跑什么测试”的决策完全由PR 标签label驱动。SKILL 文档要求在任何涉及标签或触发的问题上优先给出精确值而非长篇解释。速查如下场景scopen_repeatlightweight无任何标签mr-github-slim2falseRun testsmr-github1trueRun functional testsmr-github5false合并队列merge groupmr-github1false自动无需标签三个正交附加标签标签作用container::lts仅把容器镜像路径切换为 LTS长期支持版NGC PyTorch 基础镜像而非 dev 最新版——它是一次向后兼容性检查不改变测试集可与任意 scope 标签组合。必须显式 opt-in只有当用户明确要求做 LTS 验证时才附加即使是容器或依赖变更也不要主动添加Run MBridge tests额外触发 MBridgeMegatron-BridgeL1 测试套件Run NeMoRL tests额外触发 NeMo RL 的 Megatron 功能测试套件⚠️破坏性远程写入警告tools/trigger_internal_ci.py会把当前分支**强推force-push**到内部 GitLab 远端上的pull-request/branch引用。任何情况下都必须先以--dry-run运行并确认目标引用才能不带该标志调用绝不针对共享分支或受保护分支运行只允许指向你自己的 PR 分支。安全预检命令python tools/trigger_internal_ci.py --gitlab-origin gitlab --dry-run只有在 dry-run 输出与预期目标一致后才可添加可选的--functional-test-*标志。二、CI 流水线结构从 PR push 到最终 Gate主工作流位于 .github/workflows/cicd-main.yml其on触发器第 16-23 行包括push 到pull-request/[0-9]分支即 CI 分支见下文第四节push 到deploy-release/*分支merge_group事件合并队列校验每日schedule手动workflow_dispatch同时工作流设置了concurrency组与cancel-in-progress: true保证同一 head ref 的新 run 会取消旧 run。整个流水线的 job 拓扑源自 SKILL.md 的文本树结合源码验证如下is-not-external-contributor # SSO / 成员资格检查决定 runner 与 maintainer 身份 └─ pre-flight # 复用 NVIDIA-NeMo FW-CI-templates 的预检判定 docs_only / ci_workload 等 └─ configure # 核心决策节点读取 PR 标签产出 scope / container tag / n_repeat / cadence ├─ linting # autoformat.sh 检查 golden values 校验 内核变更确定性覆盖检查 ├─ cicd-container-build │ ├─ cicd-parse-unit-tests → cicd-unit-tests-latest # 单元测试矩阵 │ ├─ cicd-parse-integration-tests-h100 → cicd-integration-tests-latest-h100 │ └─ cicd-parse-integration-tests-gb200 → cicd-integration-tests-latest-gb200 (仅 maintainer) └─ Nemo_CICD_Test # 最终 pass/fail 汇总门汇总所有测试 job 结果并决定整体状态2.1configure流水线的“大脑”configurejobcicd-main.yml是理解整套机制的关键。它用一次gh pr view调用拉取 PR 的全部标签然后按first match wins顺序决定参数if [ $IS_MERGE_GROUP true ]; then SCOPEL1; N_REPEAT1; LIGHTWEIGHTfalse elif [ $HAS_RUN_TESTS true ]; then SCOPEL1; N_REPEAT1; LIGHTWEIGHTtrue elif [ $HAS_RUN_FUNCTIONAL true ]; then SCOPEL1; N_REPEAT5; LIGHTWEIGHTfalse elif [ $IS_CI_WORKLOAD true ] || [ $EVENT_NAME workflow_dispatch ]; then SCOPEL1; N_REPEAT5; LIGHTWEIGHTfalse else SCOPEL0; N_REPEAT2; LIGHTWEIGHTfalse fi这里有一个值得注意的映射SKILL.md 中出现的mr-github-slim/mr-github是GitHub 侧的 legacy scope 名在 tests/test_utils/python_scripts/recipe_parser.py 中被统一别名到新的L-tier 成本分级词汇表L-tier含义legacy 别名L0精简 PR 测试最便宜mr-github-slimL1完整 PR / 合并队列测试mr-githubL2夜间测试nightlyL3周测试weeklyL0-smoke则是 GitLab 侧专用的亚 L0 层用于轻量 smoke 测试只做2步训练。scope 是成本/套件标签而触发轴由cadencepr/nightly/mergegroup/weekly单独承担——测试 recipe 默认挂[pr, nightly, mergegroup]三种 cadence。configure还会输出一套决策树摘要到 step summary内容与 SKILL.md 的表格完全一致并附上术语表lightweight训练 4 步而非 100 步跳过 golden values 对比——反馈更快但不保证数值正确性lts使用 LTS 容器基础镜像替代最新的 dev 镜像dev默认使用最新开发容器镜像cadence按触发事件过滤测试的维度recipe 中的cadence:字段run_mbridge是否触发 Megatron-Bridge 下游 CIPR push 默认关闭加Run MBridge tests标签开启run_nemo_rl是否触发 NeMo RL 下游 CI合并队列校验默认跳过PR 作者可加Run NeMoRL tests标签 opt-in2.2 镜像构建与测试矩阵cicd-container-build通过 .github/workflows/_build_ci_container.yml 复用构建镜像容器镜像推送到AWS ECR766267172432.dkr.ecr.us-east-1.amazonaws.com/…GCP Artifact Registryus-east4-docker.pkg.dev/nv-projdgxchipp-20260113193621/megatron-lm/…单元测试与集成测试都是典型的parse → matrix模式cicd-parse-*先用yq读取 tests/test_utils/recipes/h100/unit-tests.yaml 等 recipe 文件生成 JSON 矩阵再由cicd-unit-tests-latest/cicd-integration-tests-latest-h100用matrix.include并行展开。集成测试的 recipe 覆盖了 gpt、moe、mamba、hybrid、bert、t5、mimo、multimodal-llava、各类 inference server 等数十个用例见 tests/test_utils/recipes/h100 目录。GB200 测试cicd-*-gb200额外受双重门控is_maintainer true且vars.ENABLE_GB200_TESTING true——非 maintainer 的 PR 默认不会触发 GB200 测试。2.3Nemo_CICD_Test最终状态汇总Nemo_CICD_Test是整体 pass/fail 的收口 jobdocs-only 与部署工作流直接放行否则汇总单元测试、H100/GB200 集成测试结果并用gh run view做全 job 扫描排除merge-queue-notification、cicd-mbridge-testing、cicd-nemo-rl-testing任何 failure/cancelled job 都会导致整体失败。2.4 单元测试划分与 cadence 过滤单元测试矩阵来自 recipe 中的unit-tests.yaml每个测试被切分为多个 bucket 并行执行功能测试则通过 tests/test_utils/python_scripts/generate_jet_trigger_job.py 生成 GitLab 子流水线配置其中--cadence参数透传给 tests/test_utils/python_scripts/recipe_parser.py 的load_workloads()按pr/nightly/mergegroup过滤 recipe 行。Run tests/Run functional tests标签会置cadence_bypasstrue让贡献者可以绕过 cadence 过滤获得手动覆盖能力。三、PR 测试标签选择指南一张表搞定SKILL.md 提供了按“变更性质”选标签的权威对照表开 PR 时直接对号入座变更路径 / 性质应附加的标签仅文档docs/、*.md、docstring无仅 CI/工具链.github/、tools/、Makefile无仅测试文件tests/——修改已有测试未新增 golden valuesRun tests新增测试用例尚无 golden valuesRun functional tests重新启用被禁用的测试scope-broken→ activeRun functional tests非数值类库代码日志、错误处理、CLI 标志、重构Run tests可能影响训练数值模型结构、attention、优化器、分布式、MoE 路由Run functional tests容器或依赖变更docker/、pyproject.toml、uv.lockRun tests仅在用户明确要求 LTS 验证时再加container::lts涉及 MBridge 集成追加Run MBridge tests可能影响 NeMo RL 的 Megatron 集成追加Run NeMoRL tests经验法则默认使用Run tests当 PR 新增测试用例必须生成 golden values或变更可能引起 loss 曲线偏移时一律使用Run functional tests。这套决策与源码完全一致linting job 中 cicd-main.yml 会对tests/functional_tests/test_cases/**/golden_values*.json的变更运行 tools/check_golden_values.py 校验同时用 tools/check_kernel_determinism_coverage.py 强制内核kernel变更必须附带确定性测试——这正是“新增测试用例必须跑Run functional tests”在流水线层的体现。四、触发内部 GitLab CI先 dry-run再触发4.1 前置条件tools/trigger_internal_ci.py的目标用户是 NVIDIA 内部成员SKILL 文档注明仅对 NVIDIAN 有用它可以在不触碰 GitLab UI 的情况下完成“推分支 触发流水线”。完整配置步骤见 tools/trigger_internal_ci.md1. 添加内部 GitLab 为 git remotegit remote add gitlab gitgitlab-hostname:ADLR/Megatron-LM.git git remote -v # 检查已有 remote注意这个 origin 名之后会作为参数传入2. 获取 Personal Access Token打开内部 GitLab 个人资料User menu → Edit profile → Access tokens点击Add new token填写描述、设置过期时间并勾选apiscope创建后复制生成的 token以glpat-开头存入环境变量避免每次手动传参export GITLAB_TOKENglpat-your-token建议将该变量写入.env或.bashrc。4.2 安装依赖与用法python -m pip install python-gitlab python tools/trigger_internal_ci.py \ --gitlab-origin gitlab \ [--access-token glpat-your-token] \ [--functional-test-scope mr] \ [--functional-test-repeat 5] \ [--functional-test-cases all] \ [--functional-test-name release-testing/mcore-vX.Y.Z] \ [--functional-test-time-limit 14400] \ [--dry-run]参数对照表来自 tools/trigger_internal_ci.md参数默认值说明--gitlab-origin必填指向内部 GitLab 的 git remote 名--access-token$GITLAB_TOKEN带apiscope 的 Personal Access Token--functional-test-scopemrFUNCTIONAL_TEST_SCOPE流水线变量--functional-test-repeat5FUNCTIONAL_TEST_REPEAT流水线变量--functional-test-casesallFUNCTIONAL_TEST_CASES流水线变量--functional-test-namecommit SHAFUNCTIONAL_TEST_NAME流水线变量——为pre-release/releasescope 的 run 命名用作 run 名与 WB 实验名--functional-test-time-limit随 scope 而定FUNCTIONAL_TEST_TIME_LIMIT流水线变量秒。release/weekly长时运行 scope 默认144004 小时其余 scope 不设置--dry-run关闭只打印将要执行的操作不推送、不触发release 测试请使用--functional-test-scope release并用release-testing/mcore-vX.Y.Z约定命名 run例如release-testing/mcore-v0.17.0。4.3 脚本真实执行流程从 tools/trigger_internal_ci.py 源码可以看到完整调用链main()第 136-255 行校验 token--access-token或GITLAB_TOKEN缺失则直接报错退出第 209-211 行获取当前分支git rev-parse --abbrev-ref HEAD第 89-97 行解析 GitLab 主机名从 remote URL 中提取兼容gitSSH 与 HTTPS 两种格式第 80-86 行构造目标引用pull-request/branch常量GITLAB_BRANCH_PREFIX pull-request第 36 行强推分支git push origin HEAD:pull-request/branch --force第 100-110 行--dry-run时只打印日志组装流水线变量并触发固定写入UNIT_TESTno与INTEGRATION_TESTno再叠加FUNCTIONAL_TEST_SCOPE/REPEAT/CASES以及可选的FUNCTIONAL_TEST_NAME、FUNCTIONAL_TEST_TIME_LIMIT、CLUSTER_A100/H100/GB200最终通过python-gitlab在项目 19378 上创建 pipeline第 113-133 行脚本内部还包含一个细节resolve_time_limit()第 51-66 行只在release/weekly两个长时 scope 下自动注入 4 小时上限其余 scope 保持默认避免为短时测试施加不必要的超时限制。4.4 预期输出Current branch: my-feature-branch Everything up-to-date Triggering pipeline on https://gitlab-hostname project 19378 pull-request/my-feature-branch Pipeline triggered: https://gitlab-hostname/namespace/project/-/pipelines/123456对应 SKILL.md 的约束只针对你自己的 PR 分支操作绝不触碰共享/受保护分支。当触发 GitLab 功能测试时子流水线由generate_jet_trigger_job.py生成它读取 recipe、按 model 分 stage、为每个 test_case 生成一个 GitLab job并支持--enable-lightweight-mode2 步 smoke 测试、--enable-warmup首个 job 作为后续 job 的缓存预热依赖等开关。五、CI 失败排查从分支名到根因的完整链路CI 分支永远遵循pull-request/number命名模式这是所有排查的起点。5.1 从 CI 分支定位 PR# 从当前分支提取 PR 号 PR_NUMBER$(git rev-parse --abbrev-ref HEAD | grep -oP (?pull-request/)\d) # 查看 PR 元数据标题、标签、作者、基础分支 gh pr view $PR_NUMBER --repo NVIDIA/Megatron-LM # 查看该 PR 的变更集 gh pr diff $PR_NUMBER --repo NVIDIA/Megatron-LM5.2 读取 CI Job 日志# 列出该 PR 最近的 workflow run gh run list --repo NVIDIA/Megatron-LM --branch pull-request/$PR_NUMBER # 流式输出失败 job 的日志 gh run view run-id --repo NVIDIA/Megatron-LM --log-failed关键点各 rank 的完整日志不在runner 的 stdout 里而是作为 GitHub artifacts 上传命名格式为logs-test_case-run_id-uuid# 1. 先查出 artifact 名称 gh run view run-id --repo NVIDIA/Megatron-LM --json artifacts \ --jq .artifacts[].name # 2. 下载 artifact zip gh run download run-id --repo NVIDIA/Megatron-LM \ --name logs-artifact-name -D ./ci-logs # 3. 定位哪些 rank 日志含有错误 grep -r -l ERROR\|Traceback\|FAILED\|fatal ./ci-logs/ # 4. 日志文件可能超过 10000 行——永远不要一次性读完整份日志 wc -l ./ci-logs/test/attempt/attempt_0/rank/stderr.log sed -n 1,200p ./ci-logs/.../stderr.log # 分段读取5.3 按失败类型定位根因SKILL.md 给出五类典型失败的处理路径Linting 失败—— 本地重跑tools/autoformat.shdiff 会精确显示需要修改的内容该脚本在 linting job 中以CHECK_ONLYtrue运行见 cicd-main.yml容器构建失败—— 检查cicd-container-buildjob 日志单元测试失败—— 失败的 bucket 位于cicd-unit-tests-latestjob 的 matrix 中功能测试失败—— 查看cicd-integration-tests-*job从rank 0 的stdout.log开始Flaky 测试—— runner 会自动重试至多 3 次若重试耗尽且错误模式匹配已知的瞬时问题NCCL、ECC、segfault则属于基础设施噪声5.4 将失败与 PR 变更集关联# 找出覆盖了被改源码文件的单元测试 grep -r from megatron.core.transformer.attention tests/unit_tests/ -l # 查看 CODEOWNERS 确认 reviewer 分配 cat .github/CODEOWNERS | grep changed-path.github/CODEOWNERS位于仓库 .github 目录下是确认各路径责任人的权威来源结合gh pr diff输出的变更文件清单即可快速圈定最可能受影响的测试模块与需要拉入 review 的人。六、实践要点与避坑清单先答事实再讲道理问标签选什么、触发什么参数时直接给出第一节速查表中的精确值这是仓库 CI 文档的第一原则。container::lts是 opt-in无论改动是否涉及容器/依赖都不应主动附加该标签除非用户明确要求做 LTS 兼容性验证。dry-run 是铁律tools/trigger_internal_ci.py每次真实执行都是一次对pull-request/branch的 force-push务必先跑--dry-run核对目标引用且只作用于自己的 PR 分支。数值型变更默认Run functional tests凡是可能影响 loss 曲线的改动模型结构、attention、优化器、分布式、MoE 路由都应触发 5 次重复 golden values 对比的完整功能测试仅日志/CLI/重构等非数值变更用Run tests1 次重复、轻量模式即可。日志分段读取单份 rank 日志可能超过一万行务必先用wc -l探明规模再sed分段查看避免一次读取吞掉上下文。理解参数在源码中的落点scope/n_repeat/lightweight三个值最终经由 recipe_parser.py 的 scope 别名与 cadence 过滤映射到具体的 recipe 测试行阅读 tests/test_utils/recipes/h100 下的 YAML 可以精确预判“这个标签组合实际会跑哪些用例”。参考文件速览技能文档skills/mcore-cicd/SKILL.md主工作流.github/workflows/cicd-main.yml容器构建工作流.github/workflows/_build_ci_container.yml触发脚本tools/trigger_internal_ci.py 与配置说明 tools/trigger_internal_ci.mdrecipe 解析tests/test_utils/python_scripts/recipe_parser.pyGitLab 任务生成tests/test_utils/python_scripts/generate_jet_trigger_job.py测试 recipetests/test_utils/recipes/h100含 unit-tests.yaml 与各模型功能测试用例校验工具tools/check_golden_values.py、tools/check_kernel_determinism_coverage.py、tools/autoformat.sh代码归属.github/CODEOWNERS【免费下载链接】Megatron-LMOngoing research training transformer models at scale项目地址: https://gitcode.com/GitHub_Trending/me/Megatron-LM创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表