Files
paddlepaddle--paddle/test/amp/test_amp_o2_embedding_model.py
2026-07-13 12:40:42 +08:00

141 lines
4.6 KiB
Python

# Copyright (c) 2023 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 random
import unittest
import numpy as np
from amp_base_models import AmpTestBase, _build_optimizer
import paddle
from paddle import nn
from paddle.framework import in_dynamic_or_pir_mode
paddle.enable_static()
_fixed_param = np.random.random(size=[64, 64]).astype("float32")
class SimpleUnittedEmbeddingNet(nn.Layer):
def __init__(self):
super().__init__()
self.vocab_size = 64
self.hidden_size = 64
global _fixed_param
self.param_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.Assign(_fixed_param)
)
self.embedding = nn.Embedding(
self.vocab_size, self.hidden_size, weight_attr=self.param_attr
)
self.linear = nn.Linear(
in_features=self.hidden_size,
out_features=self.vocab_size,
weight_attr=self.param_attr,
)
def forward(self, x):
out = self.embedding(x)
scale = paddle.full(shape=[1], fill_value=2, dtype="int64")
out = paddle.multiply(out, scale.astype("float32"))
out = self.linear(out)
out = nn.functional.dropout(out, p=0.2)
return out
def build_unitted_embedding_model(
use_amp,
amp_dtype="float16",
amp_level="O1",
use_promote=False,
):
if in_dynamic_or_pir_mode():
model = SimpleUnittedEmbeddingNet()
optimizer = _build_optimizer(use_amp=False, model=model)
if use_amp and amp_dtype == "float16":
scaler = paddle.amp.GradScaler(init_loss_scaling=32768.0)
else:
scaler = None
if use_amp and amp_level == "O2":
model, optimizer = paddle.amp.decorate(
models=model,
optimizers=optimizer,
level=amp_level,
dtype=amp_dtype,
)
return model, optimizer, scaler
else:
raise ValueError("Only support pir mode")
class TestUnittedEmbedding(AmpTestBase):
def _generate_feed_x(self):
seed = 0
paddle.seed(seed)
np.random.seed(seed)
random.seed(seed)
x = np.random.randint(1, 64, size=[1, 32]).astype("int64")
return x
def test_pir_compare_o1_and_o2_master_grad(self):
def _run(data, level, use_promote=False):
with paddle.pir_utils.IrGuard():
startup = paddle.static.Program()
main = paddle.static.Program()
with paddle.static.program_guard(main, startup):
model, optimizer, scaler = build_unitted_embedding_model(
use_amp=True,
amp_dtype="float16",
amp_level=level,
use_promote=use_promote,
)
model.train()
with paddle.amp.auto_cast(
enable=True,
dtype='float16',
level=level,
use_promote=use_promote,
):
x = paddle.static.data('x', [None, 32], 'int64')
out = model(x)
loss = paddle.mean(out)
scaled = scaler.scale(loss)
scaler.minimize(optimizer, scaled)
if paddle.is_compiled_with_cuda():
place = paddle.CUDAPlace(0)
elif paddle.device.is_compiled_with_xpu():
place = paddle.device.XPUPlace(0)
else:
raise ValueError("Only support CUDA or XPU Place.")
exe = paddle.static.Executor(place)
exe.run(startup)
exe.run(
main,
feed={
'x': data,
},
fetch_list=[loss],
)
x = self._generate_feed_x()
_run(x, 'O2', use_promote=False)
if __name__ == "__main__":
unittest.main()