Skip to content

Clip grad norm support for dtensors - #4219

Merged
SunMarc merged 8 commits into
huggingface:mainfrom
michaelbenayoun:clip_grad_norm_dtensor
Sep 8, 2026
Merged

Clip grad norm support for dtensors#4219
SunMarc merged 8 commits into
huggingface:mainfrom
michaelbenayoun:clip_grad_norm_dtensor

Conversation

@michaelbenayoun

Copy link
Copy Markdown
Member

What does this PR do?

Seperate the plain tensors from the dtensors, otherwise the foreach op in torch.nn.utils.clip_grad_norm_ fails.

@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@SunMarc SunMarc left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks ! This was kind of tackled in transformers trainer but happy to have it here also ! Can you just check the impl differences and maybe align if necessary ? huggingface/transformers#48208

Comment thread src/accelerate/accelerator.py Outdated
Comment on lines +3022 to +3026
if not any(isinstance(p.grad, DTensor) for p in parameters if p.grad is not None):
return torch.nn.utils.clip_grad_norm_(parameters, max_norm, norm_type=norm_type)

dtensor_params = [p for p in parameters if p.grad is not None and isinstance(p.grad, DTensor)]
plain_params = [p for p in parameters if p.grad is not None and not isinstance(p.grad, DTensor)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe create the dtensor_params once and check for it ?

Comment thread src/accelerate/accelerator.py Outdated
Comment on lines +3014 to +3031
parameters = list(parameters)

is_dtensor_available = torch.distributed.is_available() and is_torch_version(">=", DTENSOR_PYTORCH_VERSION)
if not is_dtensor_available:
return torch.nn.utils.clip_grad_norm_(parameters, max_norm, norm_type=norm_type)

from torch.distributed.tensor import DTensor

if not any(isinstance(p.grad, DTensor) for p in parameters if p.grad is not None):
return torch.nn.utils.clip_grad_norm_(parameters, max_norm, norm_type=norm_type)

dtensor_params = [p for p in parameters if p.grad is not None and isinstance(p.grad, DTensor)]
plain_params = [p for p in parameters if p.grad is not None and not isinstance(p.grad, DTensor)]
group_norms = [
torch.nn.utils.get_total_norm([p.grad for p in group], norm_type)
for group in (dtensor_params, plain_params)
if group
]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a specific case when we have mixed dtensors as we have here no ? huggingface/transformers#48208. maybe have a check for mixed grad + a seperate function to calculate the correct grad. otherwise return torch.nn.utils.clip_grads_with_norm_

@SunMarc SunMarc left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot, much better

Comment thread src/accelerate/accelerator.py Outdated
Comment thread src/accelerate/accelerator.py Outdated
Comment on lines +2971 to +2972
if len(mesh_groups) + bool(plain_params) <= 1:
return torch.nn.utils.clip_grad_norm_(parameters, max_norm, norm_type=norm_type)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice !

Comment thread src/accelerate/accelerator.py Outdated
Co-authored-by: Marc Sun <57196510+SunMarc@users.noreply.github.com>
Comment thread src/accelerate/accelerator.py Outdated
Comment thread src/accelerate/accelerator.py Outdated
@SunMarc
SunMarc merged commit 0f7e35f into huggingface:main Sep 8, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants