Skip to content

Commit d24d98c

Browse files
committed
fix(model): detach grouped HF export tensors
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
1 parent fded99b commit d24d98c

2 files changed

Lines changed: 109 additions & 1 deletion

File tree

‎src/megatron/bridge/models/conversion/model_bridge.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ def stream_weights_megatron_to_hf(
12911291
)
12921292
if merged_result is not None:
12931293
for hf_name, tensor in merged_result.items():
1294-
yield HFWeightTuple(hf_name, tensor.cpu() if cpu else tensor)
1294+
yield HFWeightTuple(hf_name, tensor.detach().cpu() if cpu else tensor.detach())
12951295
continue
12961296

12971297
# --- Standard export path ---

‎tests/unit_tests/models/test_model_bridge_lora.py‎

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,114 @@ def _raise_on_build(*_args, **_kwargs):
15961596
return weights
15971597

15981598

1599+
def _patch_stream_weights_megatron_to_hf_basics(monkeypatch, *, num_moe_experts: int = 0):
1600+
monkeypatch.setattr(
1601+
DummyBridge,
1602+
"_with_progress_tracking",
1603+
lambda self, tasks, *_args, **_kwargs: tasks,
1604+
)
1605+
monkeypatch.setattr(
1606+
DummyBridge,
1607+
"_share_embeddings_and_output_weights",
1608+
lambda self, *_args, **_kwargs: False,
1609+
)
1610+
monkeypatch.setattr(
1611+
"megatron.bridge.models.conversion.model_bridge.unwrap_model",
1612+
lambda *_args, **_kwargs: [
1613+
SimpleNamespace(config=SimpleNamespace(num_moe_experts=num_moe_experts, pipeline_model_parallel_size=1))
1614+
],
1615+
)
1616+
1617+
1618+
@pytest.mark.parametrize("cpu", [False, True])
1619+
def test_stream_weights_megatron_to_hf_detaches_standard_export_tensors(monkeypatch, cpu):
1620+
bridge = DummyBridge()
1621+
source_tensor = torch.ones(1, requires_grad=True)
1622+
1623+
class DummyMapping:
1624+
def megatron_to_hf(self, weight, module):
1625+
return {"hf.weight": weight}
1626+
1627+
task = WeightConversionTask(
1628+
param_name="decoder.layers.0.mlp.linear_fc1.weight",
1629+
global_param_name="decoder.layers.0.mlp.linear_fc1.weight",
1630+
mapping=DummyMapping(),
1631+
pp_rank=0,
1632+
vp_stage=0,
1633+
megatron_module=None,
1634+
param_weight=source_tensor,
1635+
)
1636+
1637+
_patch_stream_weights_megatron_to_hf_basics(monkeypatch)
1638+
monkeypatch.setattr(
1639+
DummyBridge,
1640+
"maybe_modify_converted_hf_weight",
1641+
lambda self, *_args, **_kwargs: _args[1],
1642+
)
1643+
1644+
weights = list(
1645+
bridge.stream_weights_megatron_to_hf(
1646+
[Mock()],
1647+
SimpleNamespace(),
1648+
cpu=cpu,
1649+
show_progress=False,
1650+
conversion_tasks=[task],
1651+
merge_adapter_weights=False,
1652+
)
1653+
)
1654+
1655+
assert len(weights) == 1
1656+
assert weights[0].param_name == "hf.weight"
1657+
assert weights[0].weight.requires_grad is False
1658+
assert weights[0].weight.grad_fn is None
1659+
1660+
1661+
@pytest.mark.parametrize("cpu", [False, True])
1662+
def test_stream_weights_megatron_to_hf_detaches_grouped_export_tensors(monkeypatch, cpu):
1663+
bridge = DummyBridge()
1664+
grouped_tensor = torch.ones(1, 1, requires_grad=True)
1665+
1666+
class GroupedMapping:
1667+
is_grouped_export = True
1668+
group_key = "hf.grouped"
1669+
1670+
def megatron_to_hf(self, weight, module):
1671+
return {self.group_key: weight}
1672+
1673+
task = WeightConversionTask(
1674+
param_name="decoder.layers.0.mlp.experts.linear_fc2.weight0",
1675+
global_param_name="decoder.layers.0.mlp.experts.linear_fc2.weight0",
1676+
mapping=GroupedMapping(),
1677+
pp_rank=0,
1678+
vp_stage=0,
1679+
megatron_module=None,
1680+
param_weight=grouped_tensor,
1681+
)
1682+
1683+
_patch_stream_weights_megatron_to_hf_basics(monkeypatch, num_moe_experts=1)
1684+
monkeypatch.setattr(
1685+
DummyBridge,
1686+
"_accumulate_grouped_export",
1687+
lambda *_args, **_kwargs: {"hf.grouped": grouped_tensor},
1688+
)
1689+
1690+
weights = list(
1691+
bridge.stream_weights_megatron_to_hf(
1692+
[Mock()],
1693+
SimpleNamespace(),
1694+
cpu=cpu,
1695+
show_progress=False,
1696+
conversion_tasks=[task],
1697+
merge_adapter_weights=False,
1698+
)
1699+
)
1700+
1701+
assert len(weights) == 1
1702+
assert weights[0].param_name == "hf.grouped"
1703+
assert weights[0].weight.requires_grad is False
1704+
assert weights[0].weight.grad_fn is None
1705+
1706+
15991707
@pytest.mark.parametrize(
16001708
("converted_name", "expected_name"),
16011709
[

0 commit comments

Comments
 (0)