Skip to content

Commit cf172db

Browse files
Merge pull request baidu-baige#158 from NeosZhang/feat/ddp-comm-hook-v2
[train] feat: add ddp_comm_hook for gradient compression
2 parents f4f62fe + f8441ed commit cf172db

4 files changed

Lines changed: 106 additions & 1 deletion

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright 2026 The LoongForge Authors.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
"""DDP utilities package: gradient communication hook resolution."""
5+
6+
from .ddp_comm_hook import resolve_comm_hook
7+
8+
__all__ = ["resolve_comm_hook"]
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Copyright 2026 The LoongForge Authors.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
"""DDP gradient communication hooks."""
5+
6+
import logging
7+
from typing import Callable
8+
9+
from torch.distributed.algorithms.ddp_comm_hooks.default_hooks import (
10+
allreduce_hook,
11+
bf16_compress_hook,
12+
fp16_compress_hook,
13+
)
14+
15+
from ..utils import is_rank_zero
16+
17+
logger = logging.getLogger(__name__)
18+
19+
# Comm hooks eligible to be resolved by ``resolve_comm_hook``. All of them
20+
# share the ``(process_group, bucket) -> Future`` signature.
21+
_SUPPORTED_COMM_HOOKS = {
22+
"allreduce_hook": allreduce_hook,
23+
"fp16_compress_hook": fp16_compress_hook,
24+
"bf16_compress_hook": bf16_compress_hook,
25+
}
26+
27+
28+
def resolve_comm_hook(hook: Callable | str, use_logging: bool = False) -> Callable:
29+
"""Resolve a comm hook name/callable, optionally wrapped with logging.
30+
31+
Args:
32+
hook: Either a DDP comm hook callable (e.g. ``allreduce_hook``,
33+
``fp16_compress_hook``, ``bf16_compress_hook``) or its name.
34+
use_logging: If True, wrap the resolved hook so it logs bucket info
35+
on rank 0 before/after it runs.
36+
37+
Returns:
38+
A comm hook with the ``(process_group, bucket)`` signature.
39+
"""
40+
if isinstance(hook, str):
41+
try:
42+
hook = _SUPPORTED_COMM_HOOKS[hook]
43+
except KeyError:
44+
raise ValueError(
45+
f"Unsupported comm hook name {hook!r}, expected one of "
46+
f"{sorted(_SUPPORTED_COMM_HOOKS)}."
47+
) from None
48+
49+
if not use_logging:
50+
return hook
51+
52+
hook_name = hook.__name__
53+
54+
def logging_comm_hook(process_group, bucket):
55+
if is_rank_zero():
56+
tensor = bucket.buffer()
57+
logger.info(
58+
"DDP %s: bucket_index=%d numel=%d dtype=%s",
59+
hook_name,
60+
bucket.index(),
61+
tensor.numel(),
62+
tensor.dtype,
63+
)
64+
fut = hook(process_group, bucket)
65+
if is_rank_zero():
66+
fut.add_done_callback(
67+
lambda fut: logger.info(
68+
"DDP %s done: bucket_index=%d", hook_name, bucket.index()
69+
)
70+
)
71+
return fut
72+
73+
return logging_comm_hook

loongforge/embodied/distributed/parallel.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from .activation_checkpointing import apply_activation_checkpointing
1616
from .context import DistributedContext
17+
from .ddp_utils import resolve_comm_hook
1718
from .utils import (
1819
filter_supported_kwargs,
1920
get_module_names_by_dtype,
@@ -93,7 +94,16 @@ def _wrap_ddp(model: nn.Module, training_args, ctx: DistributedContext, dtype: t
9394
"batched_grad_copy": training_args.ddp_batched_grad_copy,
9495
}
9596

96-
return DDP(model, **filter_supported_kwargs(DDP, ddp_kwargs))
97+
ddp_model = DDP(model, **filter_supported_kwargs(DDP, ddp_kwargs))
98+
if training_args.ddp_comm_hook:
99+
# allreduce_hook: full-precision gradient all-reduce (default, no compression);
100+
# fp16_compress_hook: compresses gradients to fp16 before all-reduce to cut traffic;
101+
# bf16_compress_hook: compresses gradients to bf16 before all-reduce to cut traffic.
102+
comm_hook = resolve_comm_hook(
103+
training_args.ddp_comm_hook, use_logging=training_args.ddp_comm_hook_logging
104+
)
105+
ddp_model.register_comm_hook(state=None, hook=comm_hook)
106+
return ddp_model
97107

98108

99109
def _wrap_fsdp(

loongforge/embodied/train/training_args.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,20 @@ class _DistributedArgs:
11641164
"help": "Batch gradient copies into buckets to reduce kernel launches."
11651165
},
11661166
)
1167+
ddp_comm_hook: Optional[str] = field(
1168+
default=None,
1169+
metadata={
1170+
"choices": ["allreduce_hook", "fp16_compress_hook", "bf16_compress_hook"],
1171+
"help": "DDP gradient communication hook.",
1172+
},
1173+
)
1174+
ddp_comm_hook_logging: bool = field(
1175+
default=False,
1176+
metadata={
1177+
"help": "Wrap the DDP comm hook with rank-0 logging of bucket info "
1178+
"before/after each all-reduce."
1179+
},
1180+
)
11671181
dynamo_optimize_ddp: bool = field(
11681182
default=True,
11691183
metadata={

0 commit comments

Comments
 (0)