Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gpt_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def gpt_builder(args, pre_process, post_process, vp_stage=None, config=None, pg_
rotary_percent=args.rotary_percent,
rotary_base=args.rotary_base,
rope_scaling=args.use_rope_scaling,
rope_scaling_factor=args.rope_scaling_factor,
mtp_block_spec=mtp_block_spec,
vp_stage=vp_stage,
pg_collection=pg_collection,
Expand Down
1 change: 1 addition & 0 deletions megatron/post_training/model_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ def modelopt_gpt_hybrid_builder(
"rotary_percent": args.rotary_percent,
"rotary_base": args.rotary_base,
"rope_scaling": args.use_rope_scaling,
"rope_scaling_factor": args.rope_scaling_factor,
"mtp_block_spec": mtp_block_spec,
"pg_collection": pg_collection,
}
Expand Down
1 change: 1 addition & 0 deletions megatron/training/argument_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ def gpt_config_from_args(
kwargs["rotary_base"] = args.rotary_base
kwargs["make_vocab_size_divisible_by"] = args.make_vocab_size_divisible_by
kwargs["rope_scaling"] = args.use_rope_scaling
kwargs["rope_scaling_factor"] = args.rope_scaling_factor

kwargs["seq_len_interpolation_factor"] = args.rotary_seq_len_interpolation_factor
kwargs["seq_length"] = args.max_position_embeddings
Expand Down
35 changes: 35 additions & 0 deletions tests/unit_tests/models/test_gpt_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,3 +615,38 @@ def test_get_transformer_layer_spec_forwards_use_te_activation_func():
assert (
call_kwargs.get('use_te_activation_func') is True
), "use_te_activation_func must be forwarded from config"


def test_gpt_builder_forwards_rope_scaling_factor():
"""Test that gpt_builder forwards rope_scaling_factor to GPTModel.

Regression test for https://github.com/NVIDIA/Megatron-LM/issues/6305
The --rope-scaling-factor flag was silently ignored because gpt_builder
passed rope_scaling but not rope_scaling_factor, so GPTModel always fell
back to its default factor of 8.0.
"""
mock_config = MagicMock()

mock_args = MagicMock()
mock_args.spec = None
mock_args.transformer_impl = "transformer_engine"
mock_args.experimental_attention_variant = None
mock_args.num_experts = None
mock_args.heterogeneous_layers_config_path = None
mock_args.mtp_num_layers = None
mock_args.use_rope_scaling = True
mock_args.rope_scaling_factor = 32.0

with (
patch('gpt_builders.GPTModel') as mock_gpt_model,
patch('gpt_builders._get_transformer_layer_spec'),
):
from gpt_builders import gpt_builder

gpt_builder(mock_args, pre_process=True, post_process=True, config=mock_config)

mock_gpt_model.assert_called_once()
_, call_kwargs = mock_gpt_model.call_args
assert (
call_kwargs.get('rope_scaling_factor') == 32.0
), "rope_scaling_factor must be forwarded from args"
38 changes: 38 additions & 0 deletions tests/unit_tests/training/models/test_gpt_builder.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.

import inspect
import sys
from unittest.mock import Mock, call, patch

import pytest
Expand All @@ -12,6 +13,8 @@
HeterogeneousTransformerConfig,
)
from megatron.core.transformer.transformer_config import TransformerConfig
from megatron.training.argument_utils import gpt_config_from_args
from megatron.training.arguments import parse_args, validate_args
from megatron.training.models.gpt import (
GPTModelBuilder,
GPTModelConfig,
Expand Down Expand Up @@ -898,3 +901,38 @@ def test_use_transformer_engine_false_when_impl_not_te(self, mock_get_mtp):
mtp_block_spec(config, spec)

assert mock_get_mtp.call_args.kwargs["use_transformer_engine"] is False


# =============================================================================
# Section 5 — gpt_config_from_args
# =============================================================================


class TestGPTConfigFromArgs:
"""Tests for argument propagation through ``gpt_config_from_args``."""

def _make_args(self, **overrides):
sys.argv = ['test_gpt_builder.py']
args = parse_args()
args.num_layers = 2
args.hidden_size = 128
args.num_attention_heads = 8
args.micro_batch_size = 1
args.seq_length = 128
args.max_position_embeddings = 131072
args.padded_vocab_size = 32000
args.position_embedding_type = 'rope'
args.apply_rope_fusion = False
for name, value in overrides.items():
setattr(args, name, value)
validate_args(args)
return args

def test_forwards_rope_scaling_factor_from_args(self):
"""--rope-scaling-factor must reach the model config instead of the default."""
args = self._make_args(use_rope_scaling=True, rope_scaling_factor=32.0)

config = gpt_config_from_args(args)

assert config.rope_scaling is True
assert config.rope_scaling_factor == 32.0