Skip to content

fix(megatron): preserve diffusion resume state - #970

Draft
gphuang wants to merge 16 commits into
mainfrom
fix/megatron/energon-resume-state
Draft

fix(megatron): preserve diffusion resume state#970
gphuang wants to merge 16 commits into
mainfrom
fix/megatron/energon-resume-state

Conversation

@gphuang

@gphuang gphuang commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Supports Issue #220, Task 9 Option 6.

Preserves rank-local Energon state during Megatron diffusion resume and fails closed when a required state file is absent or malformed. Resets warmup RNG accounting and adds opt-in batch-fingerprint plus instantiated-linear-class audit markers so checkpoint continuity and MXFP4-to-FP8 routing can be proven before a full run.

Test plan

  • Changed Primus modules and both new unit-test files compile
  • tests/unit_tests/backends/megatron/test_dataloader_checkpoint.py passes in pinned v26.5
  • tests/unit_tests/backends/megatron/test_diffusion_audit_markers.py passes in pinned v26.5
  • Combined pinned-image run: 25 tests passed
  • Build the pinned Flux model and exercise the four-leg 5+5 resume smoke after review

Guangpu Huang and others added 4 commits August 11, 2026 07:07
Restore rank-local Energon state and reset warmup RNG accounting so resumed diffusion runs continue the same data and seed sequence. Add opt-in runtime fingerprints and precision census for validation.
Apply the repository's pinned isort and Black formatting so the resume-state PR can pass its pre-commit gate.
Reject empty or topology-incompatible Energon state, avoid mutating resumed runs during synthetic warmup, and keep validation batches out of continuity fingerprints.
Comment thread primus/backends/megatron/data/energon_dataset_provider.py Fixed
The batch-fingerprint and linear-class-census markers were written with a bare
print, but the training process reaches the run log through a path that keeps
only fd 2, so every marker was discarded. The audit then reported zero markers
on a healthy run and no continuity check could ever pass. Route both through
the module logger, which the same run demonstrably preserves.
The comment asserted that the launcher filters fd 1, which the probe never
showed. It showed that fd 1 does not reach the run log on this path while
logging and fd 2 do, which is all the fix relies on.
@gphuang

gphuang commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Note: audit markers were dropped on stdout

The batch-fingerprint and linear-class-census markers introduced in this PR were initially emitted with bare print(). On the training path, the run log preserves fd 2 and Python logging but not fd 1, so markers were discarded and the continuity audit reported zero markers on an otherwise healthy run (10 steps, finite loss, rc=0).

A probe that emitted the same token to stdout, stderr, and logging from both callsites confirmed this path behavior: logging and stderr were preserved, stdout was not. Routing both markers through the module logger moved a Flux 12B MXFP4 smoke from 0 markers to 8 census and 80 fingerprints, and the continuity gate passed. Pushed as 7a7e4f07 and 7e4810a5.

Two follow-ups for the next runner:

  • The runner hardcodes --local-ranks-filter 0, so only rank 0 reaches the log while the audit needs fingerprints from all ranks. Because it appends $LOCAL_RANKS after its own flag and torchrun honors the last occurrence, LOCAL_RANKS='--local-ranks-filter 0,1,2,3,4,5,6,7' re-admits all ranks without patching the runner.
  • Once the marker gate passed, the smoke reached first checkpoint save and hit an unrelated pre-existing failure: torch_dist save asserts on adaLN_modulation because Flux's 19 double-stream and 38 single-stream blocks register different global shapes under one stacked key. That blocks resume testing but is out of scope for this PR.

gphuang and others added 4 commits August 11, 2026 16:48
The optional warning path in the missing dataloader_save branch was dead code
because this block is reachable only when require_dataloader_restore is true.
Raise unconditionally to keep exact-resume behavior explicit and remove the
unreachable branch flagged by code-quality review.
## Summary

Stacked on PR #970 for [Issue
\#220](AMD-AGI/tiger-training-internal#220).

Flux combines 19 joint and 38 single transformer blocks whose parameter
schemas
differ. The homogeneous distributed-checkpoint path collapses them into
one
layer-stacked namespace, so checkpoint validation sees both 6-chunk and
3-chunk
adaLN tensors under the same key and aborts before writing a checkpoint.

- Require Megatron's supported non-homogeneous, per-layer checkpoint
namespace
  for every `FluxConfig`.
- Fail closed if a caller tries to select the invalid homogeneous
layout.
- Add regression coverage for distinct adaLN keys and a real
`torch_dist`
  save/load round trip.

## Test plan

- [x] `black --check` on all changed files.
- [x] Config regressions: default enables heterogeneous checkpointing;
explicit
  disable is rejected (`2 passed` in the pinned v26.5 image).
- [ ] Tiny joint+single Flux `torch_dist` save/load round trip (GPU
window
  pending; n15-09 currently has a foreign eight-GPU tenant).
- [ ] Issue 220 Option 6 `stage1` checkpoint save, then resumed
`control`
  continuity smoke after review.
Capture batch-fingerprint markers from the forward-step logger instead of stdout so tests validate the current fail-closed logging path. Add an explicit CUDA-only Flux torch_dist round-trip test to make GPU runtime coverage first-class while keeping the existing CPU/CUDA fallback test.
@gphuang

gphuang commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Note: review follow-ups landed

Pushed 1a272bc4 to the PR branch with two review-gap follow-ups:

  • Updated tests/unit_tests/backends/megatron/test_diffusion_audit_markers.py to assert PRIMUS_BATCH_FINGERPRINT via caplog (logger capture) instead of capsys stdout, matching the current implementation in forward_step.py.
  • Added explicit CUDA runtime coverage in tests/unit_tests/backends/megatron/diffusion/test_flux_dist_checkpoint.py via test_torch_dist_save_load_round_trip_cuda (@pytest.mark.skipif(not torch.cuda.is_available(), reason=\"Requires CUDA\")) while keeping the existing CPU/CUDA fallback round-trip test.

Validation in this shell:

  • python3 -m compileall on both updated test files passes.
  • Full pytest remains blocked in this shell (No module named pytest, and this host also lacks torch).

Remaining non-blocking integration gaps are unchanged: GPU execution of the checkpoint round-trip path and the end-to-end stage1->control continuity smoke.

gphuang and others added 5 commits August 11, 2026 09:37
Use TemporaryDirectory-backed paths inside TestFluxDistCheckpoint methods instead of tmp_path parameters, which unittest-style test cases cannot receive from pytest. This keeps the GPU torch_dist round-trip coverage runnable in CI and local container validation.
## Summary

Allow the precision-class audit to report an all-zero MXFP4/FP8 census
for native BF16 models. This keeps the audit fail-closed in the
experiment validator while avoiding an unconditional model-startup
failure for Option 7.

## Test plan

- [x] Added a unit test for the native BF16 zero-count payload
- [x] Python compilation passes
- [ ] Targeted unit test passes in the pinned runtime container
- [ ] Option 7 BF16-resume smoke passes

---------

Co-authored-by: Guangpu Huang <guangphu@crs-m2m-cpu-spur-012.us-east2-a.compute.internal>
## Summary

Tracks [Issue
220](AMD-AGI/tiger-training-internal#220).

Add independent MXFP4 forward precision selection so late recovery runs
can use FP8 or BF16 forward GEMMs while keeping MXFP4 data- and
weight-gradient GEMMs.

- Add fail-closed `mxfp4_forward_precision` config plumbing and runtime
mode census.
- Reuse existing FP8 and BF16 operators; no new kernel implementation.
- Cover direct autograd, compile, Flux integration, config validation,
and audit modes.

## Test plan

- [x] Python compile check
- [x] `git diff --check`
- [ ] Targeted CPU-safe unit tests in the v26.5 container
- [ ] MI355X direct linear and Flux 535M forward/backward tests
- [ ] Option 6/7 resume smoke with exact mode census

---------

Co-authored-by: Guangpu Huang <guangphu@crs-m2m-cpu-spur-012.us-east2-a.compute.internal>
## Summary

Closes the post-merge review gap from PR #986.

Adds regression coverage for FP8/BF16 forward with MXFP4 backward
through `torch.compile`, including exact eager/compiled output and
gradient comparisons. It also covers YAML-to-`FluxConfig` precision
propagation and runtime mode-census emission.

## Test plan

- [x] 35 config and audit tests passed
- [x] Compiled-backward checks passed for FP8 and BF16 forward modes
- [x] Flux 535M forward-only integration test passed
- [x] `black` formatting verified
- [x] GPU memory returned to idle

Co-authored-by: Guangpu Huang <guangphu@crs-m2m-cpu-spur-012.us-east2-a.compute.internal>
## Summary

Tracks [Issue
\#220](AMD-AGI/tiger-training-internal#220),
Task 9 Option 9.

Add an opt-in Flux audit that records deterministic rank-zero parameter
samples after selected completed training iterations. This lets early
MXFP4, FP8, and BF16 forks compare model drift without extra full
optimizer checkpoints or changes to Torch RNG state.

- Sample after the model forward so overlapped distributed-optimizer
gathers have refreshed every parameter buffer.
- Record per-parameter shape, dtype, finite counts, sampled moments, and
SHA256.
- Publish one strict JSON file per completed iteration using atomic,
no-overwrite semantics; identical restarts are idempotent and
conflicting output fails closed.
- Skip validation and synthetic warmup, and explicitly record
completed-iteration, next-iteration, forward-counter, and microbatch
coordinates.

## Test plan

- [x] Changed modules compile with `py_compile`
- [x] `git diff --check`
- [ ] CI formatting and dependency checks
- [ ] Targeted audit-marker tests in the pinned v26.5 container
- [ ] Real Megatron wrapper smoke verifies post-gather step-5,120 and
step-8,192 snapshots

---------

Co-authored-by: Guangpu Huang <13152353+gphuang@users.noreply.github.com>
Comment thread tests/unit_tests/backends/megatron/test_diffusion_audit_markers.py Fixed
Use Exception instead of BaseException in the concurrent publication test helper so the test still captures expected runtime failures without swallowing system-level termination signals.
@gphuang

gphuang commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Pushed commit 67e52597 to address the review note: _publish_and_capture now catches Exception instead of BaseException, so test failures are still captured without swallowing system-level exits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant