Skip to content

Commit a53d9a6

Browse files
HJSangclaude
andcommitted
Fail loudly on a None group; drop the last Megatron import from the log-prob path
- The torch kernel took dist.get_rank(None), i.e. the world group, where callers elsewhere mean no tensor parallelism by None: with 8 ranks and no TP every rank but 0 masked its targets and the SUM mixed data-parallel ranks. It now takes group.rank(), as Megatron's kernel did, so None or a non-member group raises. Every caller passes a group. - The tensor-parallel true-on-policy gather imported Megatron's dist_all_gather_func, which is torch.distributed.all_gather_into_tensor; call that directly, so a wheel install can use it. - --debug-unified-grad-fused-logprob's help no longer mentions a fused kernel. Found by an adversarial review of this PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 5eda13c commit a53d9a6

3 files changed

Lines changed: 7 additions & 11 deletions

File tree

‎miles/backends/training_utils/loss/hub/math_utils.py‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -315,15 +315,16 @@ class _VocabParallelCrossEntropy(torch.autograd.Function):
315315
"""
316316

317317
@staticmethod
318-
def forward(ctx, logits: torch.Tensor, target: torch.Tensor, group: dist.ProcessGroup | None) -> torch.Tensor:
318+
def forward(ctx, logits: torch.Tensor, target: torch.Tensor, group: dist.ProcessGroup) -> torch.Tensor:
319319
ctx.input_dtype = logits.dtype
320320
logits = logits.float()
321321
logits_max = logits.max(dim=-1)[0]
322322
dist.all_reduce(logits_max, op=dist.ReduceOp.MAX, group=group)
323323
logits.sub_(logits_max.unsqueeze(-1))
324324

325325
partition_vocab_size = logits.size(-1)
326-
vocab_start = dist.get_rank(group) * partition_vocab_size
326+
# group.rank(), as Megatron: None or a rank outside the group fails here instead of reducing over the world
327+
vocab_start = group.rank() * partition_vocab_size
327328
target_mask = (target < vocab_start) | (target >= vocab_start + partition_vocab_size)
328329
masked_target = (target - vocab_start).masked_fill(target_mask, 0)
329330
predicted_logits = logits.gather(-1, masked_target.unsqueeze(-1)).squeeze(-1).masked_fill(target_mask, 0.0)
@@ -347,7 +348,7 @@ def backward(ctx, grad_output: torch.Tensor):
347348
return grad_input.mul_(grad_output.unsqueeze(-1)).to(ctx.input_dtype), None, None
348349

349350

350-
def vocab_parallel_cross_entropy(logits: torch.Tensor, target: torch.Tensor, group: dist.ProcessGroup | None):
351+
def vocab_parallel_cross_entropy(logits: torch.Tensor, target: torch.Tensor, group: dist.ProcessGroup):
351352
return _VocabParallelCrossEntropy.apply(logits, target, group)
352353

353354

@@ -439,12 +440,10 @@ def forward(ctx, input_: torch.Tensor, group: dist.ProcessGroup) -> torch.Tensor
439440
if world_size == 1:
440441
return input_.contiguous()
441442

442-
from megatron.core.tensor_parallel.mappings import dist_all_gather_func
443-
444443
gather_shape = list(input_.shape)
445444
gather_shape[0] *= world_size
446445
gathered = torch.empty(gather_shape, dtype=input_.dtype, device=input_.device)
447-
dist_all_gather_func(gathered, input_.contiguous(), group=group)
446+
dist.all_gather_into_tensor(gathered, input_.contiguous(), group=group)
448447
return torch.cat(gathered.chunk(world_size, dim=0), dim=-1).contiguous()
449448

450449
@staticmethod

‎miles/utils/arguments.py‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2456,9 +2456,8 @@ def add_debug_arguments(parser):
24562456
"--debug-unified-grad-fused-logprob",
24572457
action="store_true",
24582458
default=False,
2459-
help="Debug/test only: compute the stored log probabilities through the same grad-enabled fused "
2460-
"cross entropy the training step uses, then detach the result, so the two invocations of the "
2461-
"fused kernel take one execution path instead of two.",
2459+
help="Debug/test only: compute the stored log probabilities through the same grad-enabled "
2460+
"cross entropy the training step uses, then detach the result.",
24622461
)
24632462
parser.add_argument(
24642463
"--debug-deterministic-collective",

‎tests/fast/backends/training_utils/loss_hub/test_vocab_parallel_cross_entropy.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ def _check_compute_log_probs(group: dist.ProcessGroup) -> None:
7474
expected = torch.log_softmax(logits, dim=-1).gather(-1, tokens.unsqueeze(-1))
7575

7676
torch.testing.assert_close(compute_log_probs(logits.clone(), tokens, group), expected, atol=1e-6, rtol=1e-6)
77-
# None: the default group
78-
torch.testing.assert_close(compute_log_probs(logits.clone(), tokens, None), expected, atol=1e-6, rtol=1e-6)
7977

8078

8179
def _run_checks(rank: int, world_size: int, port: int) -> None:

0 commit comments

Comments
 (0)