Files
wehub-resource-sync 2aaeece67c
Codestyle Check / Lint (push) Has been cancelled
Codestyle Check / Check bypass (push) Has been cancelled
Pipelines-Test / Pipelines-Test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:37:14 +08:00

128 lines
4.4 KiB
Python

# Copyright 2020-present the HuggingFace Inc. team.
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import types
import numpy as np
import paddle
from paddle.common_ops_import import LayerHelper
from ...utils.log import logger
def npu_accelerate_plugin(optimizer):
"""npu_accelerate_plugin uses the flatten_param_grads method to speed up the performance of the model on NPU devices.
flatten_param_grads method will be added to `step` function of optimizer.
Args:
optimizer (`paddle.optimizer.Optimizer`):
The Optimizer whose `step` method will be modified.
"""
optimizer.step = types.MethodType(_optimizer_step_with_flatten_param_grads, optimizer)
def _optimizer_step_with_flatten_param_grads(optimizer):
if not isinstance(optimizer._param_groups[0], dict):
params_grads = []
for param in optimizer._param_groups:
if param.stop_gradient:
continue
if param._grad_ivar() is not None:
grad_var = param._grad_ivar()
params_grads.append((param, grad_var))
# currently, only support ClipGradByGlobalNorm and without regularization.
if isinstance(params_grads, list) and optimizer.regularization is None:
if optimizer._grad_clip is None or isinstance(optimizer._grad_clip, paddle.nn.ClipGradByGlobalNorm):
params_grads = _flatten_param_grads(optimizer, params_grads)
optimizer._apply_optimize(
loss=None,
startup_program=None,
params_grads=params_grads,
param_group_idx=0,
)
else:
raise RuntimeError("flatten_param_grads is not supported when _param_groups[0] is dict.")
def _flatten_param_grads(optimizer, params_grads):
optimizer.helper = LayerHelper(optimizer.__class__.__name__)
need_flatten_params = []
need_flatten_grads = []
for p, g in params_grads:
if g is None:
continue
g.persistable = True
if getattr(p, "need_clip", True) is False or getattr(p, "regularizer", None) is not None:
logger.warning(
f"flatten_param_grads=True will be discarded since parameter {p.name}'s need_clip is False or "
"the regularizer is set."
)
return params_grads
need_flatten_params.append(p)
need_flatten_grads.append(g)
shape = [np.prod(p.shape) for p in need_flatten_params]
flatten_param = optimizer.helper.create_global_variable(
name="flatten_param",
persistable=True,
dtype=need_flatten_params[0].dtype,
shape=[np.sum(shape)],
belong_to_optimizer=True,
)
flatten_grad = optimizer.helper.create_global_variable(
name="flatten_grad",
persistable=True,
dtype=need_flatten_grads[0].dtype,
shape=[np.sum(shape)],
belong_to_optimizer=True,
)
flatten_param.stop_gradient = False
# In the final state of the dynamic graph, the `coalesce_tensor` op
# does not support passing the output as an input into the op in
# temporary, so _legacy_C_ops is temporarily used here.
# `use_align` is set to false, which is different from the behavior
# under static graphs. `use_align` can be set to true after calling
# the coalesce_tensor op of the final state (_C_ops).
paddle._legacy_C_ops.coalesce_tensor(
need_flatten_params,
need_flatten_params,
flatten_param,
"copy_data",
True,
"use_align",
False,
"dtype",
need_flatten_params[0].dtype,
)
paddle._legacy_C_ops.coalesce_tensor(
need_flatten_grads,
need_flatten_grads,
flatten_grad,
"copy_data",
True,
"use_align",
False,
"dtype",
need_flatten_grads[0].dtype,
)
return [(flatten_param, flatten_grad)]