Skip to content

Commit 6e3f912

Browse files
committed
Fix ZeRO parameter alignment for grouped_mm
1 parent 24402c3 commit 6e3f912

2 files changed

Lines changed: 59 additions & 1 deletion

File tree

deepspeed/runtime/zero/stage_1_and_2.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,14 @@ def _configure_moe_settings(self):
795795
def _update_model_bit16_weights(self, group_index):
796796
updated_params = self.unflatten(self.bit16_groups_flat[group_index], self.round_robin_bit16_meta[group_index])
797797
for p, q in zip(self.round_robin_bit16_groups[group_index], updated_params):
798-
p.data = q.data
798+
# Some kernels, including torch grouped_mm, require 16-byte aligned parameter pointers.
799+
if q.data_ptr() % 16 == 0:
800+
p.data = q.data
801+
elif (p.data.shape == q.shape and p.data.dtype == q.dtype and p.data.device == q.device
802+
and p.data.data_ptr() % 16 == 0):
803+
p.data.copy_(q.data)
804+
else:
805+
p.data = q.data.clone()
799806

800807
# set model fp16 weight to slices of reordered flattened buffer
801808
for param_index, param in enumerate(self.bit16_groups[group_index]):

tests/unit/v1/zero/test_stage2_flatten_on_gpu.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@
1818
_DTYPE_MAP = {"fp32": torch.float32, "fp16": torch.float16, "bf16": torch.bfloat16}
1919

2020

21+
class _MisalignedParamModel(torch.nn.Module):
22+
23+
def __init__(self):
24+
super().__init__()
25+
self.offset = torch.nn.Parameter(torch.ones(1))
26+
self.weight = torch.nn.Parameter(torch.ones(8, 8))
27+
28+
def forward(self, x):
29+
return (x @ self.weight).sum() + self.offset.sum()
30+
31+
2132
def _apply_dtype_to_config(config_dict, dtype):
2233
"""Set bf16/fp16 in config_dict based on dtype; skip if not supported."""
2334
if dtype == "bf16":
@@ -31,6 +42,46 @@ def _apply_dtype_to_config(config_dict, dtype):
3142
# fp32: no half-precision block
3243

3344

45+
class TestStage1ParamAlignment(DistributedTest):
46+
world_size = 1
47+
48+
def test_model_params_remain_16_byte_aligned(self):
49+
if not get_accelerator().is_bf16_supported():
50+
pytest.skip("bf16 is not supported on this accelerator")
51+
52+
config_dict = {
53+
"train_micro_batch_size_per_gpu": 1,
54+
"bf16": {
55+
"enabled": True
56+
},
57+
"zero_optimization": {
58+
"stage": 1
59+
},
60+
}
61+
model = _MisalignedParamModel()
62+
optimizer = torch.optim.AdamW(model.parameters(), lr=0.1)
63+
engine, _, _, _ = deepspeed.initialize(config=config_dict,
64+
model=model,
65+
optimizer=optimizer,
66+
model_parameters=model.parameters())
67+
68+
opt = engine.optimizer
69+
flat_views = opt.unflatten(opt.bit16_groups_flat[0], opt.round_robin_bit16_meta[0])
70+
assert flat_views[1].data_ptr() % 16 != 0
71+
assert engine.module.weight.data_ptr() % 16 == 0
72+
weight_before_step = engine.module.weight.detach().clone()
73+
74+
data = torch.ones(1, 8, device=engine.device, dtype=torch.bfloat16)
75+
loss = engine(data)
76+
engine.backward(loss)
77+
engine.step()
78+
79+
assert engine.module.weight.data_ptr() % 16 == 0
80+
assert not torch.equal(engine.module.weight, weight_before_step)
81+
flat_views = opt.unflatten(opt.bit16_groups_flat[0], opt.round_robin_bit16_meta[0])
82+
assert torch.equal(engine.module.weight, flat_views[1])
83+
84+
3485
@pytest.mark.parametrize("zero_stage", [1, 2])
3586
@pytest.mark.parametrize("dtype", ["fp32", "fp16", "bf16"], ids=["fp32", "fp16", "bf16"])
3687
class TestStage2FlattenOnGPU(DistributedTest):

0 commit comments

Comments
 (0)