chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2021 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
|
||||
from .dygraph_sharding_optimizer import DygraphShardingOptimizer # noqa: F401
|
||||
from .heter_parallel_optimizer import HeterParallelOptimizer # noqa: F401
|
||||
from .hybrid_parallel_gradscaler import HybridParallelGradScaler # noqa: F401
|
||||
from .hybrid_parallel_optimizer import HybridParallelOptimizer # noqa: F401
|
||||
|
||||
__all__ = []
|
||||
+1480
File diff suppressed because it is too large
Load Diff
Executable
+65
@@ -0,0 +1,65 @@
|
||||
# Copyright (c) 2021 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 paddle.autograd as imperative_base
|
||||
from paddle import framework
|
||||
|
||||
__all__ = []
|
||||
|
||||
|
||||
def _obtain_optimizer_parameters_list(optimizer):
|
||||
if getattr(optimizer, '_param_groups', None) and isinstance(
|
||||
optimizer._param_groups[0], dict
|
||||
):
|
||||
parameters_list = []
|
||||
for group in optimizer._param_groups:
|
||||
for param in group['params']:
|
||||
parameters_list.append(param)
|
||||
else:
|
||||
parameters_list = list(optimizer._parameter_list)
|
||||
|
||||
return parameters_list
|
||||
|
||||
|
||||
class HeterParallelOptimizer:
|
||||
# adapter wrapper for optimizer
|
||||
def __init__(self, optimizer, strategy):
|
||||
self._inner_opt = optimizer
|
||||
self._strategy = strategy
|
||||
|
||||
# NOTE(liubo48): In pure DataParallel mode,
|
||||
# the gradient synchronization is achieved through reducer.
|
||||
|
||||
@imperative_base.no_grad()
|
||||
@framework.dygraph_only
|
||||
def step(self):
|
||||
parameters_list = _obtain_optimizer_parameters_list(self._inner_opt)
|
||||
self._inner_opt.step()
|
||||
|
||||
@imperative_base.no_grad()
|
||||
def minimize(
|
||||
self, loss, startup_program=None, parameters=None, no_grad_set=None
|
||||
):
|
||||
# minimize does not support parameters in the form of param_group,
|
||||
# so no need use _obtain_optimizer_parameters_list
|
||||
parameter_list = (
|
||||
parameters if parameters else self._inner_opt._parameter_list
|
||||
)
|
||||
|
||||
return self._inner_opt.minimize(
|
||||
loss, startup_program, parameter_list, no_grad_set
|
||||
)
|
||||
|
||||
def __getattr__(self, item):
|
||||
return getattr(self._inner_opt, item)
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
# Copyright (c) 2021 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 paddle
|
||||
import paddle.autograd as imperative_base
|
||||
from paddle import _legacy_C_ops
|
||||
|
||||
from ...base.topology import ParallelMode
|
||||
|
||||
__all__ = []
|
||||
|
||||
|
||||
class HybridParallelGradScaler:
|
||||
def __init__(self, scaler, hcg):
|
||||
self._scaler = scaler
|
||||
self._hcg = hcg
|
||||
self._use_dp_mode = (
|
||||
self._hcg.get_parallel_mode() == ParallelMode.DATA_PARALLEL
|
||||
)
|
||||
|
||||
def scale(self, var):
|
||||
return self._scaler.scale(var)
|
||||
|
||||
def minimize(self, optimizer, *args, **kwargs):
|
||||
if not self._enable:
|
||||
return optimizer.minimize(*args, **kwargs)
|
||||
|
||||
# unscale the grad
|
||||
self._unscale(optimizer)
|
||||
|
||||
optimize_ops, params_grads = (None, None)
|
||||
|
||||
if hasattr(optimizer, "_set_auxiliary_var"):
|
||||
optimizer._set_auxiliary_var('found_inf', self._found_inf)
|
||||
optimize_ops, params_grads = optimizer.minimize(*args, **kwargs)
|
||||
# TODO: Fix to _cache_found_inf after PaddleNLP update
|
||||
self._cache_found_inf = optimizer._get_auxiliary_var('found_inf')
|
||||
else:
|
||||
if self._found_inf:
|
||||
self._cache_found_inf = True
|
||||
else:
|
||||
optimize_ops, params_grads = optimizer.minimize(*args, **kwargs)
|
||||
self._cache_found_inf = False
|
||||
|
||||
if self._use_dynamic_loss_scaling:
|
||||
self._update()
|
||||
|
||||
return optimize_ops, params_grads
|
||||
|
||||
@imperative_base.no_grad()
|
||||
def _unscale(self, optimizer):
|
||||
if not self._enable:
|
||||
return
|
||||
param_grads = [
|
||||
param._grad_ivar()
|
||||
for param in optimizer._parameter_list
|
||||
if param._grad_ivar() is not None
|
||||
]
|
||||
_legacy_C_ops.check_finite_and_unscale(
|
||||
param_grads, self._scale, param_grads, self._found_inf
|
||||
)
|
||||
# allreduce_max found_inf in check_group
|
||||
if not self._use_dp_mode:
|
||||
self._found_inf = paddle.cast(self._found_inf, dtype="int32")
|
||||
# TODO(shenliang03) Since the minimize call in the optimizer is
|
||||
# after the grad scaler, check_finite needs to synchronize global
|
||||
# information. In the future, we should use check_group
|
||||
paddle.distributed.all_reduce(
|
||||
self._found_inf, op=paddle.distributed.ReduceOp.MAX, group=None
|
||||
)
|
||||
self._found_inf = paddle.cast(self._found_inf, dtype="bool")
|
||||
|
||||
def __getattr__(self, item):
|
||||
return getattr(self._scaler, item)
|
||||
Executable
+1241
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user