飞桨框架2.0尝鲜,体验单机多卡与多机多卡并行计算

原创
2020/12/28 12:23
阅读数 943

提到并行计算,很多人脑海里可能就出现了:天河/太湖之光/曙光这些世界排名前几的超级计算机,好像离我们还很远。其实并行计算技术早已经“飞入寻常百姓家”,比如飞桨框架就支持GPU的单机多卡以及多机多卡并行计算,而且操作起来简单,很容易上手。

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

图片

记得刚开始学习AI的时候,是在一台Mac笔记本上跑程序,一个简单的入门例程就要跑好几个小时,后来用了AI Studio提供的Tesla V100环境,几分钟就跑通了,当时就感叹:V100真香。不过幸福总是那么短暂,后来学习物体检测和图像分割,才发现训练一次竟然需要20个小时左右,尤其是打比赛的时候,熬夜“炼丹”导致头发大把大把的掉,往事不堪回首啊!

人生苦短,我用并行计算!

如果一块V100不够,那我就用8块!得益于飞桨优秀的并行计算性能,8卡并行基本上能够将时间缩短为接近单卡的1/8 ,原来要一天一夜的训练时间,现在缩短为3个小时左右,妈妈再也不用担心我的头发啦!

以前并行计算对我来说就是超级计算机那样高大上而又复杂的东西,不过飞桨框架2.0增加了paddle.distributed.spawn函数,用这个函数来启动单机多卡并行计算,就像寄快递那么简单:用快递盒子把要寄的东西装起来,后面的事情就交给快递公司啦!这个快递盒子就是paddle.distributed.spawn函数,用这个函数把训练主体程序包起来,飞桨就会自动并行计算!

具体的写法就是,将原来单卡程序的train函数,用paddle.distributed.spawn包起来,比如我们写个训练文件hello.py:

import paddle
import paddle.distributed as dist
def train():
    # 训练代码
    print (f"Hello world {paddle.fluid.core.get_cuda_device_count()}卡并行计算!"
)

if __name__ == '__main__':
    # 多卡并行计算
    dist.spawn(train)

跟单卡时一样在命令行下执行python hello.py 即可。最后输出会看到“Hello world X卡并行计算!”,其中X是卡的个数。单机多卡并行计算就是这么简单!

下面写一个真实的手写数字识别例子train.py:


import paddle
# 导入并行计算模块
import paddle.distributed as dist 

train_dataset = paddle.vision.datasets.MNIST(mode='train')
test_dataset = paddle.vision.datasets.MNIST(mode='test')
lenet = paddle.vision.models.LeNet()

# Mnist继承paddle.nn.Layer属于Net,model包含了训练功能
model = paddle.Model(lenet)

# 设置训练模型所需的optimizer, loss, metric
model.prepare(
    paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters()),
    paddle.nn.CrossEntropyLoss(),
    paddle.metric.Accuracy(topk=(1, 2))
    )
def train():
    # 启动训练
    model.fit(train_dataset, epochs=1, batch_size=64, log_freq=400)

    # 启动评估
#     model.evaluate(test_dataset, log_freq=20, batch_size=64)

if __name__ == '__main__':
#     启动并行计算
    dist.spawn(train)

还是在命令行下执行:

python train.py

看到下面的输出信息就证明程序正确执行了:

step 400/938 - loss: 0.1245 - acc_top1: 0.8618 - acc_top2: 0.9357 - 5ms/step
step 800/938 - loss: 0.0818 - acc_top1: 0.9069 - acc_top2: 0.9609 - 5ms/step
step 938/938 - loss: 0.0094 - acc_top1: 0.9155 - acc_top2: 0.9653 - 5ms/step
Eval begin...
step 100/157 - loss: 0.0356 - acc_top1: 0.9667 - acc_top2: 0.9909 - 3ms/step
step 157/157 - loss: 0.0206 - acc_top1: 0.9716 - acc_top2: 0.9920 - 3ms/step
Eval samples: 10000

paddle.distributed.spawn具体的启动参数“快递盒子”有如下几种:


   # 启动train多进程训练,默认使用所有可见的GPU卡
    if __name__ == '__main__':
        dist.spawn(train)

    # 启动train函数2个进程训练,默认使用当前可见的前2张卡
    if __name__ == '__main__':
        dist.spawn(train, nprocs=2)

    # 启动train函数2个进程训练,默认使用第4号和第5号卡
    if __name__ == '__main__':
        dist.spawn(train, nprocs=2, selelcted_gpus='4,5')

可以根据实际情况灵活运用。

paddle.distributed.spawn是以function函数为单位启动多进程来实现多卡同步的,可以很好地控制进程,在日志打印、训练退出时也很友好。Spawn方式只支持Python3.4以上版本,在python2环境下多卡同步可以使用paddle.distributed.launch方式,这也是以前低于飞桨框架2.0版本使用的方式。

尽管从单机单卡到单机八卡,运行效率几乎提高了近8倍,但还是远远赶不上训练规模的增长。在大数据浪潮的推动下,训练数据的规模取得了飞速的增长。现在人们通常用数百万甚至上千万的有标签图像来训练图像分类器(如,ImageNet包含1400万幅图像,涵盖两万多个种类),用成千上万小时的语音数据来训练语音模型(如,Deep Speech 2系统使用了11940小时的语音数据以及超过200万句表述来训练语音识别模型)。在真实的业务场景中,训练数据的规模可以达到上述数据集的数十倍甚至数百倍,如此庞大的数据需要消耗大量的计算资源和训练时间使模型达到收敛状态(数天时间)。

为了提高模型的训练效率,多机多卡并行计算(分布式训练)应运而生,对,就像超级计算机那样!值得一提的是,飞桨框架2.0多机多卡并行计算一如既往的简单,使用基础API的飞桨代码只需要修改3处代码就可以实现分布式训练,使用高阶API的飞桨代码不需要修改就可以直接执行分布式训练!也就是不用改代码我们就可以组建自己的超算中心了!现在就差钱了,哈哈。

图片

飞桨框架2.0提供了分布式高级API paddle.distributed.fleet接口,只要用这个“快递盒子”把主体训练程序“包”起来,在命令行执行fleetrun train.py即可启动分布式训练。

下面是多机多卡手写数字识别的程序代码,因为使用了飞桨高层API,也就是用model.fit指令进行训练,如前面所说,我们连“快递盒子”都不用自己准备,这段单机单卡的程序直接就能用于分布式训练。我感觉这是飞桨特别贴心的地方。

在AI Studio中,运行训练文件hapi_fleet.py 即可。

import paddle 

train_dataset = paddle.vision.datasets.MNIST(mode='train')
test_dataset = paddle.vision.datasets.MNIST(mode='test')

lenet = paddle.vision.models.LeNet()

# Mnist继承paddle.nn.Layer属于Net,model包含了训练功能
model = paddle.Model(lenet)

# 设置训练模型所需的optimizer, loss, metric
model.prepare(
    paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters()),
    paddle.nn.CrossEntropyLoss(),
    paddle.metric.Accuracy(topk=(1, 2))
    )

# 启动训练
model.fit(train_dataset, epochs=1, batch_size=64, log_freq=400)

# 启动评估
model.evaluate(test_dataset, log_freq=100, batch_size=64)

以2机4卡为例,我们有两台机器,每台机器有2块GPU卡,那么在2台机器上分别运行以下启动命令:

fleetrun --ips="xx.xx.xx.xx,yy.yy.yy.yy" --gpus=0,1 hapi_fleet.py

fleetrun将在后台分别启动2个多进程任务,执行分布式多机训练。您将在ip为xx.xx.xx.xx的机器上看到命令台输出日志信息,类似这样的:

图片

W1202 15:37:18.338985  1009 device_context.cc:338] Please NOTE: device: 0, CUDA Capability: 70, Driver API Version: 10.1, Runtime API Version: 10.1
W1202 15:37:18.343415  1009 device_context.cc:346] device: 0, cuDNN Version: 7.6.
epoch: 0, batch_id: 0, loss is: [48.277103], acc is: [0.265625]
epoch: 0, batch_id: 400, loss is: [46.22221], acc is: [0.265625]
epoch: 0, batch_id: 800, loss is: [46.283947], acc is: [0.21875]
INFO 2020-12-02 15:37:27,437 launch.py:223] Local processes completed.

当前世界超算第二名Summit,是IBM在田纳西州橡树岭国家实验室(ORNL)建造的系统,以148.8 PetaFLOPS的性能保持着美国最快的系统。拥有4356个节点,每个节点都容纳了两个22核Power9 CPU和6个NVIDIA Tesla V100 GPU。因此朋友们,如果我们每台机器配置8块NVIDIA Tesla V100 GPU,那么只需要3267台机器就能达跑平世界第二名超算的算力(GPU部分),想想还是让人有点小兴奋呢!不过这么多机器,"xx.xx.xx.xx,yy.yy.yy.yy" 这样的IP地址要写3267个呀,命令行里恐怕是写不开啊。Ok,我承认,钱也不够,即使我幸运的完成了一个亿的小目标,大约也只能配出不到200台8卡Tesla V100机器。

不过好消息就是,飞桨还提供了参数服务器并行集群模式,针对上面的大规模集群,只要不差钱,飞桨为你实现梦想!具体可以在飞桨官网里面的“Fleet API”部分获得详细技术信息。

看到这里,大家是不是有点心动呢?我们可以先实现一个小目标:安装飞桨框架2.0 , 跑一下单机多卡和多机多卡手写数字识别并行运算。

1. 本地安装飞桨框架2.0

pip install paddlepaddle-gpu==2.0.0rc1

2. 将前面的程序代码输入,并保存为相应的train.py和hapi_fleet.py文件

3. 执行单机多卡并行运算

python train.py

4. 执行多机多卡并行运算

fleetrun hapi_fleet.py

或者更复杂一点:

fleetrun --ips="127.0.0.1" --gpus=0 hapi _fleet.py

5. 收工,祝贺一下自己吧!

以上小目标,只需要在一台单GPU显卡的Ubuntu linux机器上即可实现!

若本地条件不方便,可以在AI Studio平台,使用免费的Tesla V100 GPU卡来实践,具体为点击下面链接:

https://aistudio.baidu.com/aistudio/projectdetail/1222066

点击页面右边的“运行一下”这个蓝色的按钮 :

图片

选择高级版 ,然后确定 :

图片

稍等一会儿,一个有AI Studio特色的Jupyter Notebook窗口就出现在我们面前。找到上部偏左一点的Notebook字样下面的两个三角在一起的图标,点击一下这个“运行全部”的图标:

图片

飞桨并行计算的大门向我们敞开啦!

让我们荡起双桨,在AI的海洋乘风破浪!

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

·飞桨PaddlePaddle项目地址·

GitHub: 

https://github.com/PaddlePaddle/Paddle

Gitee: 

https://gitee.com/PaddlePaddle/Paddle

本文同步分享在 博客“飞桨PaddlePaddle”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部