强化学习——Actor Critic Method
强化学习——Advantage Actor-Critic(A2C)
强化学习——Deep Deterministic Policy Gradient (DDPG)
通过AutoEncoder实现时序数据异常检测
使用动转静完成以图搜图
API 文档
常见问题与解答
2.0 升级常见问题
安装常见问题
数据及其加载常见问题
组网、训练、评估常见问题
模型保存常见问题
参数调整常见问题
分布式训练常见问题
其他常见问题
2.2.2 Release Note
单机多卡训练
飞桨框架2.0增加
paddle.distributed.spawn
函数来启动单机多卡训练,同时原有的
paddle.distributed.launch
的方式依然保留。
一、launch启动
1.1 高层API场景
当调用
paddle.Model
高层API来实现训练时,想要启动单机多卡训练非常简单,代码不需要做任何修改,只需要在启动时增加一下参数
-m
paddle.distributed.launch
。
# 单机单卡启动,默认使用第0号卡
$ python train.py
# 单机多卡启动,默认使用当前可见的所有卡
$ python -m paddle.distributed.launch train.py
# 单机多卡启动,设置当前使用的第0号和第1号卡
$ python -m paddle.distributed.launch --gpus='0,1' train.py
# 单机多卡启动,设置当前使用第0号和第1号卡
$ export CUDA_VISIBLE_DEVICES=0,1
$ python -m paddle.distributed.launch train.py
# 加载数据集
train_dataset = paddle.vision.datasets.MNIST(mode='train')
test_dataset = paddle.vision.datasets.MNIST(mode='test')
# 第2处改动,初始化并行环境
dist.init_parallel_env()
# 定义网络结构
mnist = paddle.nn.Sequential(
paddle.nn.Flatten(1, -1),
paddle.nn.Linear(784, 512),
paddle.nn.ReLU(),
paddle.nn.Dropout(0.2),
paddle.nn.Linear(512, 10)
# 用 DataLoader 实现数据加载
train_loader = paddle.io.DataLoader(train_dataset, batch_size=32, shuffle=True)
# 第3处改动,增加paddle.DataParallel封装
mnist = paddle.DataParallel(mnist)
mnist.train()
# 设置迭代次数
epochs = 5
# 设置优化器
optim = paddle.optimizer.Adam(parameters=mnist.parameters())
for epoch in range(epochs):
for batch_id, data in enumerate(train_loader()):
x_data = data[0] # 训练数据
y_data = data[1] # 训练数据标签
predicts = mnist(x_data) # 预测结果
# 计算损失 等价于 prepare 中loss的设置
loss = paddle.nn.functional.cross_entropy(predicts, y_data)
# 计算准确率 等价于 prepare 中metrics的设置
acc = paddle.metric.accuracy(predicts, y_data)
# 下面的反向传播、打印训练信息、更新参数、梯度清零都被封装到 Model.fit() 中
# 反向传播
loss.backward()
if (batch_id+1) % 1800 == 0:
print("epoch: {}, batch_id: {}, loss is: {}, acc is: {}".format(epoch, batch_id, loss.numpy(), acc.numpy()))
# 更新参数
optim.step()
# 梯度清零
optim.clear_grad()
修改完后保存文件,然后使用跟高层API相同的启动方式即可。 注意: 单卡训练不支持调用init_parallel_env
,请使用以下几种方式进行分布式训练。
# 单机多卡启动,默认使用当前可见的所有卡
$ python -m paddle.distributed.launch train.py
# 单机多卡启动,设置当前使用的第0号和第1号卡
$ python -m paddle.distributed.launch --gpus '0,1' train.py
# 单机多卡启动,设置当前使用第0号和第1号卡
$ export CUDA_VISIBLE_DEVICES=0,1
$ python -m paddle.distributed.launch train.py
二、spawn启动
launch方式启动训练,以文件为单位启动多进程,需要用户在启动时调用paddle.distributed.launch
,对于进程的管理要求较高。飞桨框架2.0版本增加了spawn
启动方式,可以更好地控制进程,在日志打印、训练退出时更友好。使用示例如下:
from __future__ import print_function
import paddle
import paddle.nn as nn
import paddle.optimizer as opt
import paddle.distributed as dist
class LinearNet(nn.Layer):
def __init__(self):
super(LinearNet, self).__init__()
self._linear1 = nn.Linear(10, 10)
self._linear2 = nn.Linear(10, 1)
def forward(self, x):
return self._linear2(self._linear1(x))
def train(print_result=False):
# 1. 初始化并行训练环境
dist.init_parallel_env()
# 2. 创建并行训练 Layer 和 Optimizer
layer = LinearNet()
dp_layer = paddle.DataParallel(layer)
loss_fn = nn.MSELoss()
adam = opt.Adam(
learning_rate=0.001, parameters=dp_layer.parameters())
# 3. 运行网络
inputs = paddle.randn([10, 10], 'float32')
outputs = dp_layer(inputs)
labels = paddle.randn([10, 1], 'float32')
loss = loss_fn(outputs, labels)
if print_result is True:
print("loss:", loss.numpy())
loss.backward()
adam.step()
adam.clear_grad()
# 使用方式1:仅传入训练函数
# 适用场景:训练函数不需要任何参数,并且需要使用所有当前可见的GPU设备并行训练
if __name__ == '__main__':
dist.spawn(train)
# 使用方式2:传入训练函数和参数
# 适用场景:训练函数需要一些参数,并且需要使用所有当前可见的GPU设备并行训练
if __name__ == '__main__':
dist.spawn(train, args=(True,))
# 使用方式3:传入训练函数、参数并指定并行进程数
# 适用场景:训练函数需要一些参数,并且仅需要使用部分可见的GPU设备并行训练,例如:
# 当前机器有8张GPU卡 {0,1,2,3,4,5,6,7},此时会使用前两张卡 {0,1};
# 或者当前机器通过配置环境变量 CUDA_VISIBLE_DEVICES=4,5,6,7,仅使4张
# GPU卡可见,此时会使用可见的前两张卡 {4,5}
if __name__ == '__main__':
dist.spawn(train, args=(True,), nprocs=2)
# 使用方式4:传入训练函数、参数、指定进程数并指定当前使用的卡号
# 使用场景:训练函数需要一些参数,并且仅需要使用部分可见的GPU设备并行训练,但是
# 可能由于权限问题,无权配置当前机器的环境变量,例如:当前机器有8张GPU卡
# {0,1,2,3,4,5,6,7},但你无权配置CUDA_VISIBLE_DEVICES,此时可以通过
# 指定参数 gpus 选择希望使用的卡,例如 gpus='4,5',
# 可以指定使用第4号卡和第5号卡
if __name__ == '__main__':
dist.spawn(train, nprocs=2, gpus='4,5')