Skip to content

fix(parallelizer): resolve NemotronH decoder blocks for Nemotron-V3#2638

Merged
akoumpa merged 1 commit into
mainfrom
akoumpa/fix/am-448-nemotronh-backbone
Jun 19, 2026
Merged

fix(parallelizer): resolve NemotronH decoder blocks for Nemotron-V3#2638
akoumpa merged 1 commit into
mainfrom
akoumpa/fix/am-448-nemotronh-backbone

Conversation

@akoumpa

@akoumpa akoumpa commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

What does this PR do ?

Fixes AttributeError: 'NemotronHForCausalLM' object has no attribute 'backbone' that crashes FSDP2 parallelization for the native Nemotron-V3 model (e.g. nemotron_nano_v3_singlegpu_lora).

Two distinct classes share the name NemotronHForCausalLM:

  • the HF model keeps decoder blocks at model.backbone.layers (an nn.ModuleList), while
  • the native Nemotron-V3 model (NemotronV3Model) keeps them at model.model.layers (an nn.ModuleDict keyed "0".."N-1").

NemotronHParallelizationStrategy (selected by the class-name string) and the LLM_MODEL_CLS_TO_LAYERS registry assumed the HF layout, so the native model raised at layers = model.backbone.layers.

Changelog

  • Add _nemotronh_decoder_blocks(model) resolving the decoder-block container for both layouts (backbone.layers ModuleList vs model.layers ModuleDict) and returning the ordered block list.
  • Use it in NemotronHParallelizationStrategy.parallelize (TP iteration, CP setup, FSDP wrap), and make the activation-checkpointing rewrap write back into the real container by ModuleDict key / ModuleList index.
  • Add "model.layers" to the NemotronHForCausalLM entry of LLM_MODEL_CLS_TO_LAYERS. _reduce_attrs already skips the absent backbone.layers via getattr(..., None), so both paths are covered and neither raises.
  • Add regression tests (TestNemotronHLayoutResolution) for both layouts (helper + _extract_model_layers).

Before your PR is "Ready for review"

  • Did you write any new necessary tests? — tests/unit_tests/distributed/test_parallelization_strategies.py::TestNemotronHLayoutResolution (10 NemotronH tests pass locally)

Additional Information

  • Affected recipe: nemotron_nano_v3_singlegpu_lora (single-GPU LoRA), surfaced in nemo-ci job 343744282.
  • Scope note: for native Nemotron-V3 with tp>1/ep>1, this strategy's TP plan does not shard MoE experts; proper multi-GPU native-v3 parallelism should use the MoE parallelizer. This PR fixes the single-GPU / DP-only crash.
  • Fixes AM-448.

…on-V3 layout

Two classes share the name NemotronHForCausalLM: the HF model keeps its decoder
blocks at model.backbone.layers (a ModuleList), while the native Nemotron-V3
model (NemotronV3Model) keeps them at model.model.layers (a ModuleDict). The
parallelizer registry routes by class name, so the native model reached
NemotronHParallelizationStrategy, which hard-coded model.backbone.layers ->
AttributeError: 'NemotronHForCausalLM' object has no attribute 'backbone'
(nemotron_nano_v3_singlegpu_lora, single GPU LoRA).

- Add _nemotronh_decoder_blocks() resolving blocks for both layouts (iterating
  ModuleDict values); use it in the strategy incl. the activation-checkpointing
  write-back (by ModuleDict key / ModuleList index).
- Add model.layers to the NemotronHForCausalLM entry in LLM_MODEL_CLS_TO_LAYERS
  (_reduce_attrs already skips the absent backbone.layers via getattr).
- Add regression tests for both layouts.

Fixes AM-448.

Signed-off-by: Alexandros Koumparoulis <akoumparouli@nvidia.com>
@akoumpa akoumpa requested a review from a team as a code owner June 19, 2026 03:13
@copy-pr-bot

copy-pr-bot Bot commented Jun 19, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@akoumpa akoumpa added the r0.5.0 Auto-cherrypick to release branch. Apply before merge; cherrypick happens after merge. label Jun 19, 2026
@akoumpa akoumpa changed the title fix(parallelizer): resolve NemotronH decoder blocks for native Nemotron-V3 layout fix(parallelizer): resolve NemotronH decoder blocks for Nemotron-V3 Jun 19, 2026
@akoumpa

akoumpa commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 3b32a53

Comment thread nemo_automodel/components/distributed/parallelizer.py
@akoumpa akoumpa merged commit 2a6491e into main Jun 19, 2026
80 of 82 checks passed
@akoumpa akoumpa deleted the akoumpa/fix/am-448-nemotronh-backbone branch June 19, 2026 11:49
akoumpa added a commit that referenced this pull request Jun 19, 2026
…-V3 (2638)` into `r0.5.0` (#2642)

fix(parallelizer): resolve NemotronH decoder blocks for Nemotron-V3 (#2638)

fix(parallelizer): resolve NemotronH decoder blocks for native Nemotron-V3 layout

Two classes share the name NemotronHForCausalLM: the HF model keeps its decoder
blocks at model.backbone.layers (a ModuleList), while the native Nemotron-V3
model (NemotronV3Model) keeps them at model.model.layers (a ModuleDict). The
parallelizer registry routes by class name, so the native model reached
NemotronHParallelizationStrategy, which hard-coded model.backbone.layers ->
AttributeError: 'NemotronHForCausalLM' object has no attribute 'backbone'
(nemotron_nano_v3_singlegpu_lora, single GPU LoRA).

- Add _nemotronh_decoder_blocks() resolving blocks for both layouts (iterating
  ModuleDict values); use it in the strategy incl. the activation-checkpointing
  write-back (by ModuleDict key / ModuleList index).
- Add model.layers to the NemotronHForCausalLM entry in LLM_MODEL_CLS_TO_LAYERS
  (_reduce_attrs already skips the absent backbone.layers via getattr).
- Add regression tests for both layouts.

Fixes AM-448.

Signed-off-by: Alexandros Koumparoulis <akoumparouli@nvidia.com>
Signed-off-by: NeMo Bot <nemo-bot@nvidia.com>
Co-authored-by: Alexandros Koumparoulis <153118171+akoumpa@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r0.5.0 Auto-cherrypick to release branch. Apply before merge; cherrypick happens after merge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants