Skip to content

Commit ae40713

Browse files
committed
[peft] test: strengthen grouped LoRA scaling coverage
Signed-off-by: Chen Cui <chcui@nvidia.com>
1 parent 9b9444b commit ae40713

1 file changed

Lines changed: 28 additions & 15 deletions

File tree

tests/unit_tests/peft/test_utils.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1996,18 +1996,17 @@ def test_grouped_expert_scales_bottleneck_before_grouped_output_projection(self)
19961996
in_features=2,
19971997
out_features=2,
19981998
dim=2,
1999-
alpha=4,
2000-
num_local_experts=2,
1999+
alpha=3,
2000+
num_local_experts=3,
20012001
base_linear_name="decoder.layers.0.mlp.experts.linear_fc2",
20022002
activation="identity",
20032003
input_is_parallel=False,
20042004
model_parallel_config=MockModelParallelConfig(),
20052005
)
20062006
with torch.no_grad():
2007-
adapter.linear_in.weight[0].copy_(torch.eye(2))
2008-
adapter.linear_in.weight[1].copy_(torch.eye(2))
2009-
adapter.linear_out.weight[0].copy_(torch.eye(2))
2010-
adapter.linear_out.weight[1].copy_(torch.eye(2))
2007+
for expert_idx in range(3):
2008+
adapter.linear_in.weight[expert_idx].copy_(torch.eye(2))
2009+
adapter.linear_out.weight[expert_idx].copy_(torch.eye(2))
20112010

20122011
projection_inputs = {}
20132012
original_projection = GroupedExpertLinearAdapter._forward_grouped_projection
@@ -2034,10 +2033,10 @@ def fake_grouped_mm(inputs, weights, *, offs):
20342033
create=True,
20352034
),
20362035
):
2037-
output = adapter(x, [1, 2])
2036+
output = adapter(x, [1, 0, 2])
20382037

20392038
scale = adapter.alpha / adapter.dim
2040-
assert scale == 2.0
2039+
assert scale == 1.5
20412040
# The output projection consumes the already-scaled bottleneck, so no
20422041
# full-width temporary is needed to apply the scale afterwards.
20432042
torch.testing.assert_close(projection_inputs["linear_out"], projection_inputs["linear_in"] * scale)
@@ -2049,7 +2048,7 @@ def test_grouped_expert_per_expert_fallback_still_applies_lora_scaling(self):
20492048
in_features=2,
20502049
out_features=2,
20512050
dim=2,
2052-
alpha=4,
2051+
alpha=3,
20532052
num_local_experts=2,
20542053
base_linear_name="decoder.layers.0.mlp.experts.linear_fc2",
20552054
activation="identity",
@@ -2062,11 +2061,17 @@ def test_grouped_expert_per_expert_fallback_still_applies_lora_scaling(self):
20622061
adapter.linear_out.weight[0].copy_(torch.eye(2))
20632062
adapter.linear_out.weight[1].copy_(torch.eye(2))
20642063

2065-
x = torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
2064+
x = torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], requires_grad=True)
20662065
with patch.object(GroupedExpertLinearAdapter, "_can_use_grouped_mm", return_value=False):
20672066
output = adapter(x, [1, 2])
20682067

2069-
torch.testing.assert_close(output, x * (adapter.alpha / adapter.dim))
2068+
scale = adapter.alpha / adapter.dim
2069+
assert scale == 1.5
2070+
torch.testing.assert_close(output, x * scale)
2071+
output.sum().backward()
2072+
torch.testing.assert_close(x.grad, torch.full_like(x, scale))
2073+
assert torch.isfinite(adapter.linear_in.weight.grad).all()
2074+
assert torch.isfinite(adapter.linear_out.weight.grad).all()
20702075

20712076
def test_grouped_expert_linear_adapter_fp8_without_te_uses_fallback(self):
20722077
"""An unsupported FP8 layout should not silently run the public BF16 grouped backend."""
@@ -2253,6 +2258,7 @@ def test_grouped_expert_linear_adapter_public_grouped_mm_forward_backward(self):
22532258
in_features=16,
22542259
out_features=16,
22552260
dim=8,
2261+
alpha=12,
22562262
num_local_experts=2,
22572263
base_linear_name="decoder.layers.0.mlp.experts.linear_fc2",
22582264
activation="identity",
@@ -2272,6 +2278,7 @@ def test_grouped_expert_linear_adapter_public_grouped_mm_forward_backward(self):
22722278
expected_chunks = []
22732279
for expert_idx, expert_input in enumerate(reference_x.split([2, 3])):
22742280
hidden = nn.functional.linear(expert_input, reference_linear_in[expert_idx])
2281+
hidden = hidden * (adapter.alpha / adapter.dim)
22752282
expected_chunks.append(nn.functional.linear(hidden, reference_linear_out[expert_idx]))
22762283
expected = torch.cat(expected_chunks)
22772284
expected.float().sum().backward()
@@ -2298,6 +2305,7 @@ def test_grouped_expert_linear_adapter_te_fp8_forward_backward_and_inference(sel
22982305
in_features=16,
22992306
out_features=16,
23002307
dim=16,
2308+
alpha=24,
23012309
num_local_experts=2,
23022310
base_linear_name="decoder.layers.0.mlp.experts.linear_fc2",
23032311
activation="identity",
@@ -2316,6 +2324,7 @@ def test_grouped_expert_linear_adapter_te_fp8_forward_backward_and_inference(sel
23162324
expected_chunks = []
23172325
for expert_idx, expert_input in enumerate(reference_x.split([2, 3])):
23182326
hidden = nn.functional.linear(expert_input, reference_linear_in[expert_idx])
2327+
hidden = hidden * (adapter.alpha / adapter.dim)
23192328
expected_chunks.append(nn.functional.linear(hidden, reference_linear_out[expert_idx]))
23202329
expected = torch.cat(expected_chunks)
23212330
expected.float().sum().backward()
@@ -2872,12 +2881,16 @@ def linear_out(x, *args):
28722881
def test_scales_bottleneck_before_output_projection(self, is_fc1):
28732882
"""Scaling must land on the rank-sized bottleneck for both fc1 and fc2 wiring."""
28742883
recorded = {}
2875-
adapter = self._stub_adapter(is_fc1=is_fc1, alpha=4, dim=2, recorded=recorded)
2876-
x = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
2884+
adapter = self._stub_adapter(is_fc1=is_fc1, alpha=3, dim=2, recorded=recorded)
2885+
x = torch.tensor([[1.0, 2.0], [3.0, 4.0]], requires_grad=True)
28772886

28782887
output = SharedOuterGroupedExpertAdapter.forward(adapter, x, m_splits=[1, 1])
28792888

28802889
# The output projection receives the scaled bottleneck, so applying the
28812890
# scale never allocates a second full-width tensor.
2882-
torch.testing.assert_close(recorded["linear_out_input"], x * 2.0)
2883-
torch.testing.assert_close(output, x * 2.0)
2891+
scale = adapter.alpha / adapter.dim
2892+
assert scale == 1.5
2893+
torch.testing.assert_close(recorded["linear_out_input"], x * scale)
2894+
torch.testing.assert_close(output, x * scale)
2895+
output.sum().backward()
2896+
torch.testing.assert_close(x.grad, torch.full_like(x, scale))

0 commit comments

Comments
 (0)