Skip to content

Commit 4db2cf9

Browse files
HJSangclaude
andcommitted
accelerator: bind CUDA before init_process_group; compile_dynamic -> compile_fused
The CUDA device is bound before init_process_group again, with main's exact torch.cuda.set_device("cuda:<local_rank>") call, so the GPU path keeps main's call order. TPU still binds after init: touching its one visible device earlier breaks the rendezvous. The two phases are two named calls in _init_common. compile_dynamic becomes compile_fused, whose docstring names its three callers: each is elementwise/reduction math, where compiling only fuses kernels, so the uncompiled function TPU gets computes the same values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 2fee0a1 commit 4db2cf9

3 files changed

Lines changed: 20 additions & 10 deletions

File tree

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def hook(grad: torch.Tensor) -> torch.Tensor:
136136
tensor.register_hook(hook)
137137

138138

139-
@accelerator.compile_dynamic
139+
@accelerator.compile_fused
140140
def compute_approx_kl(
141141
log_probs: torch.Tensor,
142142
log_probs_base: torch.Tensor,
@@ -251,7 +251,7 @@ def compute_gspo_kl(
251251
return ppo_kl
252252

253253

254-
@accelerator.compile_dynamic
254+
@accelerator.compile_fused
255255
def compute_policy_loss(
256256
ppo_kl: torch.Tensor,
257257
advantages: torch.Tensor,
@@ -426,7 +426,7 @@ class _VocabParallelEntropy(torch.autograd.Function):
426426
@staticmethod
427427
def forward(ctx, vocab_parallel_logits: torch.Tensor, process_group: dist.ProcessGroup) -> torch.Tensor:
428428

429-
@accelerator.compile_dynamic
429+
@accelerator.compile_fused
430430
def mul_reduce(a, b):
431431
return (a * b).sum(dim=-1, keepdim=True)
432432

‎miles/ray/train_actor.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ def _init_common(self, args: Namespace, role: str, with_ref: bool = False, with_
153153

154154
torch.serialization.add_safe_globals([miles.utils.eval_config.EvalDatasetConfig])
155155

156+
accelerator.bind_device_before_process_group(int(os.environ.get("LOCAL_RANK", 0)))
157+
156158
if args.debug_deterministic_collective:
157159
register_det_nccl_backend()
158160
args.distributed_backend = DET_NCCL_BACKEND_NAME
@@ -169,7 +171,7 @@ def _init_common(self, args: Namespace, role: str, with_ref: bool = False, with_
169171
backend=backend,
170172
timeout=timedelta(minutes=args.distributed_timeout_minutes),
171173
)
172-
accelerator.bind_local_device(int(os.environ.get("LOCAL_RANK", 0)))
174+
accelerator.bind_device_after_process_group()
173175
init_gloo_group()
174176

175177
args.rank = dist.get_rank()

‎miles/utils/accelerator.py‎

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,16 @@
1818
import torch_tpu # noqa: F401 registers the tpu device with torch
1919

2020

21-
def bind_local_device(local_rank: int) -> None:
22-
"""Bind this process to its device. Call after init_process_group: TPU binds its one visible device at
23-
process-group init (touching it earlier breaks the rendezvous), CUDA binds lazily."""
24-
torch.accelerator.set_device_index(0 if IS_TPU else local_rank)
21+
def bind_device_before_process_group(local_rank: int) -> None:
22+
# CUDA binds before init_process_group, as it always has; a TPU touched this early breaks the rendezvous
23+
if not IS_TPU:
24+
torch.cuda.set_device(f"cuda:{local_rank}")
25+
26+
27+
def bind_device_after_process_group() -> None:
28+
# TPU binds its one visible device once the process group is up
29+
if IS_TPU:
30+
torch.accelerator.set_device_index(0)
2531

2632

2733
def current_device() -> torch.device:
@@ -36,6 +42,8 @@ def device_name() -> str | None:
3642
return torch.cuda.get_device_name()
3743

3844

39-
def compile_dynamic(fn):
40-
# the TPU compile backend rejects dynamic shapes; these helpers only fuse kernels
45+
def compile_fused(fn):
46+
"""`torch.compile(dynamic=True)` on CUDA, the function itself on TPU, whose compile backend rejects dynamic
47+
shapes. Only for elementwise/reduction helpers, where compiling only fuses kernels and eager gives the same
48+
values: `compute_approx_kl`, `compute_policy_loss` and the entropy's `mul_reduce`."""
4149
return fn if IS_TPU else torch.compile(dynamic=True)(fn)

0 commit comments

Comments
 (0)