refactor(train): drive SFT/RL training through AutoModel's DeepSpeed-style Engine - #92
Draft
HuiyingLi wants to merge 58 commits into
Draft
refactor(train): drive SFT/RL training through AutoModel's DeepSpeed-style Engine#92HuiyingLi wants to merge 58 commits into
HuiyingLi wants to merge 58 commits into
Conversation
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
…mments Merge the duplicated packing/HF-fallback/aux-loss/routing-replay validation from the two BaseModel construction branches into one shared _finalize_model_setup, drop the dead get_flat_mesh import fallback, make the cross-module debug helper public, and cut war-story comments down to concise why-only notes per AGENTS.md. Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
…itic docs Experience's two hand-rolled recursive tensor walkers collapse into a single _map_tensors helper, and the Critic/value-head docstrings shrink to the why-only form AGENTS.md asks for. Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
… consumer pack_padded_batch/unpack_to_padded serve BaseModel's input preparation, not the FSDP strategy layer; molt/trainer/fsdp/packing.py becomes molt/models/packing.py. Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
BaseModel now owns only the runtime forward contract (padded/packed/VLM/CP/R3 input preparation, backbone forward, dense output restore). Everything about turning a path into a distributed AutoModel module — registry probing, MoE detection, kernel-backend selection, MTP disabling, fail-fast validation, and post-load configuration — moves to molt/models/loading.py behind two entry points: load_automodel() and configure_loaded_model(). Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Actor/Critic now return an ordinary dict of tensors and every consumer uses subscript access, removing the dual attribute/mapping magic. _forward_backbone returns the logits tensor directly (nothing consumed the rest of the backbone output, including the dead output_hidden_states knob), and the VLM placeholder-id probe is inlined where it runs. Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
- promote agents.base._first_scalar to first_scalar; drop the cross-module private import alias in samples_generator - inline the single-call _iter_nemo_moe_gates and critic hidden-size probe - freeze_moe_router imports Gate directly: nemo_automodel is a hard dependency, and the ImportError fallback silently skipped a requested freeze - drop SFTTrainer.save_logs_and_checkpoints's unused step_bar parameter Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
_get_automodel_group folds into _get_dp_group, and _get_automodel_mesh drops its dead try/except: 'required' was always true past the device_mesh early return, so the except branch could only re-raise. Pin nemo-automodel to the matching Engine commit. Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
The AutoModel HybridEP dispatcher now equalizes and aligns per-rank token counts itself (padded rows route to no expert and are sliced off after combine), so BaseModel no longer probes dispatcher internals or pads packed, padded, and VLM inputs to an EP-group width; pack_padded_batch loses its pad_to_tokens escape hatch. Pin nemo-automodel to the dispatcher-fix commit. Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
pack_vlm_batch is the VLM counterpart of pack_padded_batch (dense RL batch -> model-native packed layout + restore indices), so it belongs in molt/models/packing.py; BaseModel passes its model-derived state (token ids, layout, cp_size, module) explicitly. Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
--fsdp.attn_implementation gains choices=, so loading.py's duplicate validator and its three choice-set constants go away (only the transformer-engine importability check remains, which argparse cannot do). Also drop _will_use_hf_model's never-passed default parameter and a single-use dtype variable. Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
HuiyingLi
force-pushed
the
huiyingl/feat/sft-automodel-engine-integration
branch
from
August 24, 2026 09:39
f451772 to
e25ce7e
Compare
…load Restore molt/trainer/fsdp/optimizer_offload.py: CpuOptimizerOffloader runs the AdamW step on CPU with params resident on GPU, now wrapping the optimizer with the step()/zero_grad() surface the AutoModel Engine drives (checkpointing and the LR scheduler keep the wrapped optimizer). --fsdp.offload choices become none/optimizer; the AM FSDP2 CPUOffloadPolicy 'full' mode, its gloo backend, the refit CPU-staging hunk, and its tests are removed. Checkpoint resume pages Adam moments back to CPU as before. Pin nemo-automodel to the matching revert commit. 8-GPU SFT smoke with --fsdp.offload optimizer converges identically to the GPU-step run (numerically equivalent, not bit-identical). Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Restore the pre-integration design: the value head is a plain replicated _ValueHead module installed after AutoModel's FSDP wrap (rank-0 broadcast for identical replicas, tie_word_embeddings cleared), and the critic trainer DP-all-reduces its gradient before each optimizer step via the restored FsdpStrategy.sync_replicated_grads. The pre_fsdp_hook plumbing through load_automodel is removed. Pin nemo-automodel to the matching revert commit. Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
This was referenced Aug 25, 2026
Merged
…el pin The AutoModel branch dropped its unused datasets.vlm package re-exports; import pack_vlm_samples, merge_media_values, and the collaters from their defining modules. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Molt stops maintaining its own training-execution loop and drives SFT and RL through AutoModel's DeepSpeed-style eager
Engine, following the OpenRLHF↔DeepSpeed boundary:The
Engineis a thinnn.Modulewrapper (forward/backward(loss)/step()/zero_grad()/get_global_grad_norm()) around an already-distributed model. There is no Datum, loss callback, output envelope, or packing protocol at this boundary — AutoModel stays RL-oblivious.Net diff: +2594 / −2936 across 49 files.
Main changes
FsdpStrategyloses its duplicate backward / gradient-sync / clip / optimizer / accumulation loop; SFT, policy, and critic trainers callengine.backward(loss)+engine.step()directly, with the RL formula staying in the trainer.models/base.py(918 → ~330 lines) keeps only the runtime forward contract; checkpoint-loading policy moves tomodels/loading.py, THD/VLM packing tomodels/packing.py, and the critic value head tomodels/critic.py.trainer/fsdp/packing.pyis deleted; under TP the lm-head output is a vocab-sharded DTensor and log-prob/entropy come from AutoModel'stoken_log_probs/token_entropy, which handle dense and vocab-sharded logits without gathering the vocabulary.Ownership boundary
Molt owns:
sync_replicated_gradsbefore the step)CpuOptimizerOffloader: AdamW step on CPU, params stay on GPU;--fsdp.offload none|optimizer)AutoModel owns:
Engine: backward, gradient finalization, clipping, optimizer update, gradient clearingDetails:
docs/automodel-engine-integration.md.Validation
tests/unitgreen (234) in the 26.06 molt container; ruff + compileall clean.Known gaps
nemo-automodellacks the Engine API; requirements.txt pins the AutoModel source revision (78cac7159).🤖 Generated with Claude Code