Repository navigation
refactor(model): build Ling MoE V2 and EXAONE 4.0 from builder-backed model configs - #6401
kamran-nvidia wants to merge 3 commits into
Conversation
|
/ok to test e0d514e |
cuichenx
left a comment
There was a problem hiding this comment.
One concern with tied-weight conversion when enabling the builder path; details inline.
|
|
||
| def provider_bridge(self, hf_pretrained: PreTrainedCausalLM) -> GPTModelProvider: | ||
| """Convert HuggingFace EXAONE 4.0 config to Megatron GPTModelProvider. | ||
| USE_MODEL_CONFIG_FOR_CONVERSION = True |
There was a problem hiding this comment.
Tied embeddings with PP > 1 lose the conversion tie flag
Enabling the builder path here puts share_embeddings_and_output_weights on the outer BridgeGPTModelConfig, while the runtime model's .config is only the nested TransformerConfig. build_conversion_tasks() reads the nested config, and _share_embeddings_and_output_weights() defaults the missing field to False.
For tied EXAONE at PP > 1, the last pipeline stage materializes output_layer.weight. It is consequently no longer filtered from conversion, but EXAONE's mapping registry has no mapping for this parameter, so conversion fails. The post-import shared-embedding broadcast also reads the missing flag and is skipped. Previously the provider's .config carried the flag. PP=1 avoids allocating the duplicate output parameter, so the reported TP2 checks do not cover this case.
Could we fix tie-flag resolution in the shared conversion helpers and add a tied EXAONE PP2 import/export test, including output-stage weights and synchronization? The same issue is noted on #6379, so one shared fix should cover both. HF initialization for training via load_hf_weights() also reaches this path.
This is separate from the pre-existing EXAONE architecture/parity limitations listed in the PR. The finding is based on pinned source inspection and source-level probes; I have not run a distributed checkpoint reproduction.
There was a problem hiding this comment.
Thanks, confirmed. A tied tiny EXAONE 4.0 at PP=2 through the builder path fails on this branch with ValueError: No mapping found for the following Megatron parameter(s): output_layer.weight.
One shared fix covers this and #6379: #6460 makes _share_embeddings_and_output_weights() fall back to the flag on the built language model when the nested TransformerConfig doesn't declare it. With it, the last-stage output_layer.weight equals the HF embed_tokens, and the export reproduces all 46 HF tensors exactly with no lm_head.weight. #6460 adds a tied PP=2 builder-path functional test (Qwen3, since its toy checkpoint is tied and already in L0). I'll rebase this PR onto it once it merges.
Move Bailing/Ling MoE V2 onto the ModelConfig/ModelBuilder path, following Muse Glimmer. BailingMoeV2Bridge maps Hugging Face configs in hf_config_to_model_config_kwargs(); the builder's default MoE layer spec is the GPT decoder block spec, which honors the dense-first moe_layer_freq, and the deprecated provider path keeps its explicit decoder block spec. USE_MODEL_CONFIG_FOR_CONVERSION = True. Signed-off-by: Kamran Jafari <kjafarisadeg@nvidia.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move EXAONE 4.0 onto the ModelConfig/ModelBuilder path, following Muse Glimmer: - Exaone4Bridge maps Hugging Face configs in hf_config_to_model_config_kwargs(), including its Post-LN layer spec; the deprecated provider path reuses the same kwargs. USE_MODEL_CONFIG_FOR_CONVERSION = True. - llama3 RoPE scaling maps rope_scaling and rope_scaling_factor, the only values Megatron Core uses. The undeclared low/high-frequency and original context attributes are no longer set; export writes Megatron Core's fixed values, and a warning is logged when a checkpoint's values differ from them. - The EXAONE 4.0 recipes use get_model_config(). Signed-off-by: Kamran Jafari <kjafarisadeg@nvidia.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…configs After #6305, MODEL_CONFIG_CLASS defaults to None and each family opts in. Set MODEL_CONFIG_CLASS = BridgeGPTModelConfig on the bridges this PR migrates, matching Qwen3 and Llama, and assert it in their tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kamran Jafari <kjafarisadeg@nvidia.com>
e0d514e to
8ceb812
Compare
|
/ok to test 8ceb812 |
|
Automatic Claude reviews have been retired. To request a pull-request review, post a comment containing: Add |
What does this PR do ?
Moves Ling MoE V2 (Bailing) and EXAONE 4.0 onto the builder-backed
ModelConfig/ModelBuilderpath, for recipes and checkpoint conversion, following Muse Glimmer.Changelog
MODEL_CONFIG_CLASSnow defaults toNone, so each migrated bridge setsMODEL_CONFIG_CLASS = BridgeGPTModelConfignext toUSE_MODEL_CONFIG_FOR_CONVERSION = True(as Qwen3 and Llama do), and its tests assert it.BailingMoeV2Bridge:provider_bridge()is replaced byhf_config_to_model_config_kwargs(), and the provider path reuses the same kwargs. The builder config leavestransformer_layer_specunset because MCore's builder default for MoE models is alreadyget_gpt_decoder_block_spec, which honors the dense-firstmoe_layer_freq. The deprecated provider path keeps its explicit decoder block spec inhf_config_to_provider_kwargs().USE_MODEL_CONFIG_FOR_CONVERSION = True.Exaone4Bridge: same kwargs migration. The builder config carries the Post-LNexaone4_layer_spec, which does not read its config.USE_MODEL_CONFIG_FOR_CONVERSION = True. The EXAONE 4.0 recipes useget_model_config().low_freq_factor,high_freq_factorandoriginal_max_position_embeddingsas undeclared attributes on the provider. Megatron Core never reads them:RotaryEmbeddingcalls_apply_scaling(inv_freq, factor=rope_scaling_factor)with fixed 1 / 4 / 8192. They were only echoed back on export, and a strict builder config cannot carry undeclared fields.rope_scalingandrope_scaling_factorare mapped. Export writes Megatron Core's fixed values (asLlamaBridgedoes), and a warning is logged when a checkpoint's values differ from what Megatron applies.Verification
Each family was validated separately on tiny random-weight checkpoints (single GB200 node, NeMo 26.10 container; Bailing uses the HF modeling code vendored in this repo, EXAONE uses transformers 5.15).
Conversion paths:
scripts/conversionGPU import at TP2 and export.AutoBridge.import_ckpt/export_ckpt.compare.py.roundtrip_checkpoint.Each was run on this branch and on
main.mainvs this branchget_model_config()vs providermain)main)main-imported checkpoint)main, and this branch on amain-imported checkpointroundtrip_checkpointTP2Regression: 11 Bailing/EXAONE recipe factories and 312 tests (1 skipped) across
models/bailing,models/exaone, the EXAONE 4.0 recipe test,test_auto_bridge.py,test_gpt_model_config.py, the AutoBridge registration matrix,conversion/anddoc_consistency.Lint:
ruff checkandruff format --checkare clean (ruff 0.16.7;pre-commititself not run).Pre-existing, identical on
main; not changed by this PR:maingives the same value. The HF-side value varies slightly between runs while the Megatron logits are bit-identical.maintoo. It persists with all-global attention and with no RoPE scaling, so it is structural rather than RoPE- or sliding-window-related.lm_headmapping), and HF's hybrid sliding-window attention (global layers without RoPE) is not modeled.These are worth separate investigation against real checkpoints.
After rebasing onto
mainwith #6305 (Megatron Core a98aed553): 193 passed, 1 skipped, including #6305's all-bridges opt-in check intest_gpt_model_config.py;ruffclean.Before your PR is "Ready for review"
Pre checks:
Additional Information
exaone4_bridge.py; the overlap with this PR is a trivial docstring merge.maindirectly.🤖 Generated with Claude Code