Skip to content

Fix IndexError in get_num_experts_per_layer for dense models under pipeline parallelism #486

Description

@hipa211a

Problem

get_num_experts_per_layer (megatron/model/transformer.py) raises an
IndexError for dense models (num_experts=[1]) whenever pipeline
parallelism is enabled (--pipeline-model-parallel-size > 1).

The function expands the single-element num_experts list using the
local per-stage layer count:

num_experts = num_experts * (num_layers // expert_interval)

but then indexes it using the global layer number, which includes the
pipeline stage offset:

layer_num = i + 1 + offset
n_e = num_experts[(layer_num-1) // expert_interval] if ...

For any pipeline stage past the first (offset > 0), the global index
exceeds the length of the locally-sized list, causing an out-of-bounds
access.

Reproduction

Any dense GPT run with PP > 1, e.g.:
--num-layers 32 --pipeline-model-parallel-size 2
--tensor-model-parallel-size 2

Stage 1 (offset=16) computes (30-1)//2 = 14 as an index into a
list of length 16//2 = 8 → IndexError.

TP-only and DP-only configurations are unaffected because offset is
always 0 there, which is why this only surfaces once PP is used.

Fix

Short-circuit the dense case before the MoE indexing logic. A dense
model has exactly one expert per layer regardless of stage offset:

In ./megatron/model/transformer.py adding these lines in function def get_num_experts_per_layer(num_experts: list, num_layers: int, expert_interval: int, offset: int = 0) -> list: solves the issue

if len(num_experts) == 1 and num_experts[0] == 1:
    return [1] * num_layers

This leaves the genuine MoE path (num_experts > 1, or an explicit
per-layer list) completely untouched.

Notes

The deeper issue is that the expansion is sized by the local layer
count while indexing uses global layer numbers; a more complete fix
would reconcile the two for the MoE-with-PP case as well. This issue
addresses only the dense-model regression, which is the common path and
currently breaks all pipeline-parallel dense training.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions