[PyTorch] 2.21 regression: NVFP4 sequence-parallel all-gather of 3-D grad_output with B=1 crashes in swap_first_dims ("Input is not allocated"); please backport fix to release_v2.21
Maintainer thường phản hồi trong vòng 2 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 52/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Lĩnh vực
- backend, performance
Hướng nghiên cứu
Read _all_gather_nvfp4 in transformer_engine/pytorch/distributed.py and compare its columnwise shape calculation with NVFP4Quantizer::create_tensor and the get_columnwise_shape change in #3628. Start by reproducing the two-rank sequence-parallel case with a [S, 1, H] input. Done means backward completes and the gathered columnwise shape is correct; add the regression test described in the issue and verify it fails before and passes after the fix.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Describe the bug
In TE 2.21.0, backward through a row-parallel te.Linear with sequence_parallel=True crashes under the NVFP4 recipe. It happens when grad_output is 3-D [S/TP, B, H] with B == 1, which is the usual Megatron [seq, micro_batch, hidden] layout at micro-batch size 1:
File ".../transformer_engine/pytorch/module/linear.py", line 1259, in _linear_backward_impl
) = TransformerEngineBaseModule.grad_output_preprocess(
File ".../transformer_engine/pytorch/module/base.py", line 1803, in grad_output_preprocess
grad_output, _ = gather_along_first_dim(
File ".../transformer_engine/pytorch/distributed.py", line 1795, in gather_along_first_dim
return _all_gather_nvfp4(
File ".../transformer_engine/pytorch/distributed.py", line 1536, in _all_gather_nvfp4
_post_process_nvfp4_gather(out, out_columnwise_data, out_scale_inv, world_size, handle)
File ".../transformer_engine/pytorch/distributed.py", line 1313, in _post_process_nvfp4_gather
out._columnwise_scale_inv = _swap_first_dims(columnwise_scale_inv_interleaved, world_size)
File ".../transformer_engine/pytorch/distributed.py", line 1296, in _swap_first_dims
tensor = tex.swap_first_dims(tensor, out=None)
RuntimeError: .../transformer_engine/common/transpose/swap_first_dims.cu:130 in function swap_first_dims: Assertion failed: input.data.dptr != nullptr. Input is not allocated.
The same training configuration works on TE 2.20.2 (6ea2a74a).
Root cause (source at d77ef88c, the current release_v2.21 HEAD)
- #3523 (ac544de1, "Remove the view() calls from Linear/LNLinear/LNMLP modules") removed
grad_output = grad_output.reshape((-1, grad_output.shape[-1]))fromTransformerEngineBaseModule.grad_output_preprocess. The SP gather now receives the 3-D gradient. _all_gather_nvfp4has not changed since 2.20. It computes the columnwise shape for a high-precision input within_shape_t = convert_shape_for_fp4(get_columnwise_shape(inp.size())).- On 2.21,
get_columnwise_shapekeeps the input rank ([S, B, H] -> [H, S, B]), andconvert_shape_for_fp4halves the last dim. - For
B == 1this gives[H, S, 0], sounpadded_dim1 = 0and the gathered columnwise scale-inv is a zero-element tensor with a null data pointer.tex.swap_first_dimsthen asserts. - For odd
B > 1the scale width is silently wrong. For(4096, 3, 8192)it is 512 instead of 768.
- On 2.21,
- The C++
NVFP4Quantizer::create_tensoralready forces this shape to 2-D for exactly this case. The bug is only in the Python all-gather shape bookkeeping.
Fix status
#3628 (f0b10961, merged to main on 2026-10-20) changes NVFP4Quantizer.get_columnwise_shape to return (shape[-1], prod(shape[:-1])). For the _all_gather_nvfp4 call this gives the same shapes as the 2-D flatten tested below. It was motivated by torch.compile (#3626), though, and is not on release_v2.21. Please backport a fix for this path to 2.21. Either cherry-pick the get_columnwise_shape change from #3628 or apply this minimal one-hunk patch:
--- a/transformer_engine/pytorch/distributed.py
+++ b/transformer_engine/pytorch/distributed.py
@@ -1365,8 +1365,12 @@ def _all_gather_nvfp4(
if isinstance(inp, torch.Tensor) and not isinstance(inp, NVFP4TensorStorage):
# High-precision tensor.
in_shape = NVFP4Quantizer.convert_shape_for_fp4(inp.size())
+ # Columnwise NVFP4 data is always 2D [K, M/2] with M = prod(leading dims),
+ # matching NVFP4Quantizer::create_tensor. Using the N-D shape here would
+ # give [K, d0, ..., d_{n-2}//2], which is zero-width for e.g. [S, 1, H].
+ flat_shape = (math.prod(inp.shape[:-1]), inp.shape[-1])
in_shape_t = NVFP4Quantizer.convert_shape_for_fp4(
- NVFP4Quantizer.get_columnwise_shape(inp.size())
+ NVFP4Quantizer.get_columnwise_shape(flat_shape)
)
A regression test with te.Linear(parallel_mode="row", sequence_parallel=True), NVFP4, and a [S, 1, H] input would cover this path.
Validation of the one-hunk patch on 2.21.0 (d77ef88c)
I applied the patch to the installed 2.21.0 package in an otherwise unchanged container. That is the same image that crashes without the patch. Results:
- Llama 3 70B (Megatron-Bridge NVFP4 pretraining: TP=2, PP=4, VP=5, SP, micro-batch 1, seq 8192, 64x GB200): the crash is gone. All 30 steps completed with no skipped or NaN iterations. Steady-state step time was 8.50 s, versus 8.52 s on TE 2.20.2. The loss at step 1 is identical to 2.20.2 (13.402) and stays close afterwards.
- Nemotron-3 Super (NVFP4, TP=2, SP, micro-batch 1, 64x GB200): the crash is gone and all 30 steps completed.
- Caveat: both runs then hit a separate segfault at process exit. It occurs in cudnn-frontend 1.31.0 while TE's fused-attention
GraphCacheis being destroyed. That is the known teardown issue NVIDIA/cudnn-frontend#1486 and is unrelated to this bug.
Steps/Code to reproduce bug
The full-scale reproduction is the Megatron-Bridge Llama 3 70B NVFP4 pretraining run above. TP=1 NVFP4 runs on the same container pass, because they have no SP gather.
Minimal sketch, run with torchrun --nproc_per_node=2. It has not been executed standalone:
import torch, torch.distributed as dist
import transformer_engine.pytorch as te
from transformer_engine.common import recipe
dist.init_process_group("nccl")
torch.cuda.set_device(dist.get_rank())
tp = dist.new_group([0, 1])
S, B, H = 4096, 1, 8192
lin = te.Linear(H, H, parallel_mode="row", sequence_parallel=True, tp_group=tp, tp_size=2,
params_dtype=torch.bfloat16, device="cuda")
x = torch.randn(S, B, H // 2, dtype=torch.bfloat16, device="cuda", requires_grad=True)
with te.autocast(recipe=recipe.NVFP4BlockScaling()):
y = lin(x)
y.sum().backward() # RuntimeError: swap_first_dims ... Input is not allocated
Expected behavior
Backward of an SP row-parallel NVFP4 Linear should work for any leading-dimension layout, as it does in 2.20.2.
Actual behavior
On TE 2.21.0 every rank fails in the first backward pass with RuntimeError: ... swap_first_dims.cu:130 in function swap_first_dims: Assertion failed: input.data.dptr != nullptr. Input is not allocated. (stack above). The run aborts before the first optimizer step.
Environment overview
- Environment location: Docker (NVIDIA PyTorch-based container), Slurm multi-node
- Method of Transformer Engine install: preinstalled in the NVIDIA PyTorch container
Environment details
- OS version: Ubuntu 24.04
- PyTorch version: 2.15.0a0 (NVIDIA internal nightly)
- Python version: 3.12.3
- Transformer Engine version: 2.21.0+d77ef88c (bad); 2.20.2+6ea2a74a (good)
- CUDA version: 13.5
- CUDNN version: 9.28.0
Device details
- GPU model: GB200 NVL (driver 580.196)
Additional context
- Regression bracket: last good 2.20.2 (6ea2a74a), first bad 2.21.0 (d77ef88c).
- ac544de1 (#3523) is the only change between those versions that alters the shape reaching
_all_gather_nvfp4._all_gather_nvfp4andconvert_shape_for_fp4are unchanged. - Related: #3626 / #3628.
This issue was drafted with assistance from the opus AI model.
- Ngôn ngữ chính
- Python
- Star
- 3.6k
- Fork
- 872
- Merge trung bình
- 4 ngày 12 giờ
- Pull request đã merge (30 ngày)
- 60
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của NVIDIA/TransformerEngine
-
[PyTorch] fp8_cs_quantize fake implementation returns a vector inverse scale instead of a scalarCó thể làm lại được @sanjana658 đã nhận 14 ngày trước và không có pull request nào đang mở. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
NVIDIA/TransformerEngine#3636 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[Bug] Backend selection picks FA3 for training with head_dim_qk=192 / v_head_dim=128, but FA3 backward cannot run itCó thể làm lại được @modelpath-dev đã nhận 48 ngày trước và không có pull request nào đang mở. Đang mởattention
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
NVIDIA/TransformerEngine#3481 · 4 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Increase MAX_TENSOR_NUMĐang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
NVIDIA/TransformerEngine#2189 · 7 bình luận · 5 reaction ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[Feature] Fused gated RMSNorm (RMSNorm(x) * SiLU(gate)) for GDN output normCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
NVIDIA/TransformerEngine#3724 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[PyTorch] torch.compile fails on FusedAttnBackend IntEnum comparisonsCó thể đã có người làm @pggPL đã nhận 2 ngày trước. Đang mởbug
NVIDIA/TransformerEngine#3716 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của NVIDIA/TransformerEngine
Issue tương tự
-
follow-up
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Download helper still uses huggingface_hub arguments removed in 1.0: USE_SYMLINKS is silently ignored and every download ends with a WinError 3 lineCó thể đã có người làm @li-lizhe đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
IPv6 node addresses produce an invalid request URLCó thể đã có người làm @RaphaelFakhri đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
typesense/typesense-python#154 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
elastic/elasticsearch-py#3592 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
developmentseed/titiler-cmr#250 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày