GradScaler¶
- class paddle.amp. GradScaler ( enable=True, init_loss_scaling=32768.0, incr_ratio=2.0, decr_ratio=0.5, incr_every_n_steps=1000, decr_every_n_nan_or_inf=2, use_dynamic_loss_scaling=True ) [源代码] ¶
GradScaler 用于动态图模式下的"自动混合精度"的训练。它控制 loss 的缩放比例,有助于避免浮点数溢出的问题。这个类具有 scale()
、 unscale_()
、 step()
、 update()
、 ``minimize()``和参数的``get()/set()``等方法。
scale()
用于让 loss 乘上一个缩放的比例。 unscale_()
用于让 loss 除去一个缩放的比例。 step()
与 optimizer.step()
类似,执行参数的更新,不更新缩放比例 loss_scaling。 update()
更新缩放比例。 minimize()
与 optimizer.minimize()
类似,执行参数的更新,同时更新缩放比例 loss_scaling,等效与``step()``+``update()``。
通常,GradScaler 和 paddle.amp.auto_cast
一起使用,来实现动态图模式下的"自动混合精度"。
参数¶
enable (bool,可选) - 是否使用 loss scaling。默认值为 True。
init_loss_scaling (float,可选) - 初始 loss scaling 因子。默认值为 32768.0。
incr_ratio (float,可选) - 增大 loss scaling 时使用的乘数。默认值为 2.0。
decr_ratio (float,可选) - 减小 loss scaling 时使用的小于 1 的乘数。默认值为 0.5。
incr_every_n_steps (int,可选) - 连续 n 个 steps 的梯度都是有限值时,增加 loss scaling。默认值为 1000。
decr_every_n_nan_or_inf (int,可选) - 累计出现 n 个 steps 的梯度为 nan 或者 inf 时,减小 loss scaling。默认值为 2。
use_dynamic_loss_scaling (bool,可选) - 是否使用动态的 loss scaling。如果不使用,则使用固定的 loss scaling;如果使用,则会动态更新 loss scaling。默认值为 True。
返回¶
一个 GradScaler 对象。
代码示例¶
import paddle
model = paddle.nn.Conv2D(3, 2, 3, bias_attr=True)
optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())
scaler = paddle.amp.GradScaler(init_loss_scaling=1024)
data = paddle.rand([10, 3, 32, 32])
with paddle.amp.auto_cast():
conv = model(data)
loss = paddle.mean(conv)
scaled = scaler.scale(loss) # scale the loss
scaled.backward() # do backward
scaler.minimize(optimizer, scaled) # update parameters
optimizer.clear_grad()
scale(var)¶
将 Tensor 乘上缩放因子,返回缩放后的输出。 如果这个 GradScaler
的实例不使用 loss scaling,则返回的输出将保持不变。
参数
var (Tensor) - 需要进行缩放的 Tensor。
返回
缩放后的 Tensor 或者原 Tensor。
代码示例
import paddle
model = paddle.nn.Conv2D(3, 2, 3, bias_attr=True)
optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())
scaler = paddle.amp.GradScaler(init_loss_scaling=1024)
data = paddle.rand([10, 3, 32, 32])
with paddle.amp.auto_cast():
conv = model(data)
loss = paddle.mean(conv)
scaled = scaler.scale(loss) # scale the loss
scaled.backward() # do backward
scaler.minimize(optimizer, scaled) # update parameters
optimizer.clear_grad()
minimize(optimizer, *args, **kwargs)¶
这个函数与 optimizer.minimize()
类似,用于执行参数更新。 如果参数缩放后的梯度包含 NAN 或者 INF,则跳过参数更新。否则,首先让缩放过梯度的参数取消缩放,然后更新参数。 最终,更新 loss scaling 的比例。
参数
optimizer (Optimizer) - 用于更新参数的优化器。
args - 参数,将会被传递给
optimizer.minimize()
。kwargs - 关键词参数,将会被传递给
optimizer.minimize()
。
代码示例
import paddle
model = paddle.nn.Conv2D(3, 2, 3, bias_attr=True)
optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())
scaler = paddle.amp.GradScaler(init_loss_scaling=1024)
data = paddle.rand([10, 3, 32, 32])
with paddle.amp.auto_cast():
conv = model(data)
loss = paddle.mean(conv)
scaled = scaler.scale(loss) # scale the loss
scaled.backward() # do backward
scaler.minimize(optimizer, scaled) # update parameters
optimizer.clear_grad()
step(optimizer)¶
这个函数与 optimizer.step()
类似,用于执行参数更新。 如果参数缩放后的梯度包含 NAN 或者 INF,则跳过参数更新。否则,首先让缩放过梯度的参数取消缩放,然后更新参数。 该函数与 update()
函数一起使用,效果等同于 minimize()
。
参数
optimizer (Optimizer) - 用于更新参数的优化器。
代码示例
# required: gpu
import paddle
model = paddle.nn.Conv2D(3, 2, 3, bias_attr=True)
optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())
scaler = paddle.amp.GradScaler(init_loss_scaling=1024)
data = paddle.rand([10, 3, 32, 32])
with paddle.amp.auto_cast():
conv = model(data)
loss = paddle.mean(conv)
scaled = scaler.scale(loss) # scale the loss
scaled.backward() # do backward
scaler.step(optimizer) # update parameters
scaler.update() # update the loss scaling ratio
optimizer.clear_grad()
update()¶
更新缩放比例。
代码示例
# required: gpu
import paddle
model = paddle.nn.Conv2D(3, 2, 3, bias_attr=True)
optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())
scaler = paddle.amp.GradScaler(init_loss_scaling=1024)
data = paddle.rand([10, 3, 32, 32])
with paddle.amp.auto_cast():
conv = model(data)
loss = paddle.mean(conv)
scaled = scaler.scale(loss) # scale the loss
scaled.backward() # do backward
scaler.step(optimizer) # update parameters
scaler.update() # update the loss scaling ratio
optimizer.clear_grad()
unscale_(optimizer)¶
将参数的梯度除去缩放比例。 如果在 step()
调用前调用 unscale_()
,则 step()
不会重复调用 unscale()
,否则 step()
将先执行 unscale_()
再做参数更新。 minimize()
用法同上。
- 参数
-
optimizer (Optimizer) - 用于更新参数的优化器。
代码示例
# required: gpu
import paddle
model = paddle.nn.Conv2D(3, 2, 3, bias_attr=True)
optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())
scaler = paddle.amp.GradScaler(init_loss_scaling=1024)
data = paddle.rand([10, 3, 32, 32])
with paddle.amp.auto_cast():
conv = model(data)
loss = paddle.mean(conv)
scaled = scaler.scale(loss) # scale the loss
scaled.backward() # do backward
scaler.unscale_(optimizer) # unscale the parameter
scaler.step(optimizer)
scaler.update()
optimizer.clear_grad()
is_enable()¶
判断是否开启 loss scaling 策略。
返回
bool,采用 loss scaling 策略返回 True,否则返回 False。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
enable = scaler.is_enable()
print(enable) # True
is_use_dynamic_loss_scaling()¶
判断是否动态调节 loss scaling 的缩放比例。
返回
bool,动态调节 loss scaling 缩放比例返回 True,否则返回 False。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
use_dynamic_loss_scaling = scaler.is_use_dynamic_loss_scaling()
print(use_dynamic_loss_scaling) # True
get_init_loss_scaling()¶
返回初始化的 loss scaling 缩放比例。
返回
float,初始化的 loss scaling 缩放比例。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
init_loss_scaling = scaler.get_init_loss_scaling()
print(init_loss_scaling) # 1024
set_init_loss_scaling(new_init_loss_scaling)¶
利用输入的 new_init_loss_scaling 对初始缩放比例参数 init_loss_scaling 重新赋值。
参数
new_init_loss_scaling (float) - 用于更新缩放比例的参数。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
print(scaler.get_init_loss_scaling()) # 1024
new_init_loss_scaling = 1000
scaler.set_init_loss_scaling(new_init_loss_scaling)
print(scaler.get_init_loss_scaling()) # 1000
get_incr_ratio()¶
返回增大 loss scaling 时使用的乘数。
返回
float,增大 loss scaling 时使用的乘数。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
incr_ratio = scaler.get_incr_ratio()
print(incr_ratio) # 2.0
set_incr_ratio(new_incr_ratio)¶
利用输入的 new_incr_ratio 对增大 loss scaling 时使用的乘数重新赋值。
参数
new_incr_ratio (float) - 用于更新增大 loss scaling 时使用的乘数,该值需>1.0。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
print(scaler.get_incr_ratio()) # 2.0
new_incr_ratio = 3.0
scaler.set_incr_ratio(new_incr_ratio)
print(scaler.get_incr_ratio()) # 3.0
get_decr_ratio()¶
返回缩小 loss scaling 时使用的乘数。
返回
float,缩小 loss scaling 时使用的乘数。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
decr_ratio = scaler.get_decr_ratio()
print(decr_ratio) # 0.5
set_decr_ratio(new_decr_ratio)¶
利用输入的 new_decr_ratio 对缩小 loss scaling 时使用的乘数重新赋值。
参数
new_decr_ratio (float) - 用于更新缩小 loss scaling 时使用的乘数,该值需<1.0。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
print(scaler.get_decr_ratio()) # 0.5
new_decr_ratio = 0.1
scaler.set_decr_ratio(new_decr_ratio)
print(scaler.get_decr_ratio()) # 0.1
get_incr_every_n_steps()¶
连续 n 个 steps 的梯度都是有限值时,增加 loss scaling,返回对应的值 n。
返回
int,参数 incr_every_n_steps。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
incr_every_n_steps = scaler.get_incr_every_n_steps()
print(incr_every_n_steps) # 1000
set_incr_every_n_steps(new_incr_every_n_steps)¶
利用输入的 new_incr_every_n_steps 对参数 incr_every_n_steps 重新赋值。
参数
new_incr_every_n_steps (int) - 用于更新参数 incr_every_n_steps。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
print(scaler.get_incr_every_n_steps()) # 1000
new_incr_every_n_steps = 2000
scaler.set_incr_every_n_steps(new_incr_every_n_steps)
print(scaler.get_incr_every_n_steps()) # 2000
get_decr_every_n_nan_or_inf()¶
累计出现 n 个 steps 的梯度为 nan 或者 inf 时,减小 loss scaling,返回对应的值 n。
返回
int,参数 decr_every_n_nan_or_inf。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
decr_every_n_nan_or_inf = scaler.get_decr_every_n_nan_or_inf()
print(decr_every_n_nan_or_inf) # 2
set_decr_every_n_nan_or_inf(new_decr_every_n_nan_or_inf)¶
利用输入的 new_decr_every_n_nan_or_inf 对参数 decr_every_n_nan_or_inf 重新赋值。
参数
new_decr_every_n_nan_or_inf (int) - 用于更新参数 decr_every_n_nan_or_inf。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
print(scaler.get_decr_every_n_nan_or_inf()) # 2
new_decr_every_n_nan_or_inf = 3
scaler.set_decr_every_n_nan_or_inf(new_decr_every_n_nan_or_inf)
print(scaler.get_decr_every_n_nan_or_inf()) # 3
state_dict()¶
以字典的形式存储 GradScaler 对象的状态参数,如果该对象的 enable 为 False,则返回一个空的字典。
返回
dict,字典存储的参数包括:scale(tensor):loss scaling 因子、incr_ratio(float):增大 loss scaling 时使用的乘数、decr_ratio(float):减小 loss scaling 时使用的小于 1 的乘数、incr_every_n_steps(int):连续 n 个 steps 的梯度都是有限值时,增加 loss scaling、decr_every_n_nan_or_inf(int):累计出现 n 个 steps 的梯度为 nan 或者 inf 时,减小 loss scaling、incr_count(int):连续未跳过参数更新的次数、decr_count(int):连续跳过参数更新的次数、use_dynamic_loss_scaling(bool):是否使用动态 loss scaling 策略。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
scaler_state = scaler.state_dict()
load_state_dict(state_dict)¶
利用输入的 state_dict 设置或更新 GradScaler 对象的属性参数。
参数
state_dict (dict) - 用于设置或更新 GradScaler 对象的属性参数,dict 需要是``GradScaler.state_dict()``的返回值。
代码示例
# required: gpu,xpu
import paddle
scaler = paddle.amp.GradScaler(enable=True,
init_loss_scaling=1024,
incr_ratio=2.0,
decr_ratio=0.5,
incr_every_n_steps=1000,
decr_every_n_nan_or_inf=2,
use_dynamic_loss_scaling=True)
scaler_state = scaler.state_dict()
scaler.load_state_dict(scaler_state)