[PyTorch] Support distributed weights in GroupedLinear's grouped-tensor path - #3517
fanshiqing wants to merge 1 commit into
Conversation
|
…or path The DistributedWeight protocol (NVIDIA#3005) materializes weights upstream of the split-quantize / grouped-tensor fork, but only updated the former: * Grouped-tensor closed its wgrad callables over the transient gathered copies, so backward read .main_grad off a plain tensor (AttributeError). Save the shards instead, take main_grad from grad_buffer, re-gather in backward, and finalize through finalize_weight_grads. * Backward re-gathers at the shards' own precision, so bf16 shards under an fp8 recipe fail the dgrad GEMM's scaling-mode check. Re-quantize those; natively-fp8 shards are unaffected. Adds test_module_grouped_linear_distributed_weight.py, covering both paths in bf16 and MXFP8. Signed-off-by: Shiqing Fan <shiqingf@nvidia.com>
b1f3a52 to
f88b71f
Compare
| # | ||
| # See LICENSE for license information. | ||
|
|
||
| """DistributedWeight dispatch in ``module.GroupedLinear``, on both of its execution paths. |
There was a problem hiding this comment.
Nit: can we put it in the distributed folder of tests and following the programming pattern there?
| ctx.weight_quantizers, | ||
| None, | ||
| num_gemms=N, | ||
| single_grouped_weight=ctx.single_grouped_weight, |
There was a problem hiding this comment.
will single weight be working in this case? Mcore can disable it for other reasons (like Muon), but TE should have single weight supported well
| IN_F, OUT_F, TOKENS = 256, 512, 128 | ||
| DTYPE, DEVICE = torch.bfloat16, "cuda" | ||
|
|
||
| PATHS = pytest.mark.parametrize( |
There was a problem hiding this comment.
grouped tensor and single weights are orthogonal, we should include single weight as part of the test case, otherwise we should assert with clear error messages
Description
#3005 added the
DistributedWeightprotocol and materializes weights upstreamof
module.GroupedLinear's split-quantize / grouped-tensor fork, but wired uponly the split-quantize side. Two bugs followed:
Grouped-tensor path crashes. It closed its wgrad callables over the
transient gathered copies, so backward read
.main_gradoff a plaintensor:
AttributeError: 'Tensor' object has no attribute 'main_grad'Re-gathering drops fp8 quantization. Forward discards the quantized
weights (the gathered buffer is transient) and backward re-gathers at the
shards' own precision, so bf16 shards under an fp8 recipe fail the dgrad
GEMM's scaling-mode check. Natively-fp8 shards are unaffected — which is why
this went unnoticed.
Why #3005 missed it:
NVTE_GROUPED_LINEAR_USE_FUSED_GROUPED_GEMM, default offDistributedWeight; wires the split-quantize path only — reasonable, the other was opt-inuse_grouped_tensorconstructor arg, making the unwired path reachable from the normal APIKnown gap: bug 2 also affects
ops/basic/grouped_linear.py, which feedsre-gathered weights into
general_grouped_gemmthe same way(
a_is_low_precision == b_is_low_precision). This PR fixes the module paths;the ops path is left for a follow-up.
Type of change
Changes
main_gradfromgrad_buffer(),re-gather in backward, finalize via
finalize_weight_grads.weight_requires_gradfrom the parameters, not the materialized copy —the protocol does not require materialize to propagate it, and a
Falsesilently skipped the whole wgrad path.
_fp8_workspaces(both paths): it would pin anunsharded weight for the module's lifetime.
delay_wgrad_compute+ distributed weight, matching the existing guardin
ops/fused/grouped_mlp.py.tests/pytorch/test_module_grouped_linear_distributed_weight.py(8/8),registered in
qa/L0_pytorch_unittest. Existing grouped/dist-weight suites:2023 passed, 624 skipped.
Checklist: