
# 分布式训练

## 1. 简介

* 分布式训练指的是将训练任务按照一定方法拆分到多个计算节点进行计算，再按照一定的方法对拆分后计算得到的梯度等信息进行聚合与更新。飞桨分布式训练技术源自百度的业务实践，在自然语言处理、计算机视觉、搜索和推荐等领域经过超大规模业务检验。分布式训练的高性能，是飞桨的核心优势技术之一，在图像分类等任务上，分布式训练可以达到几乎线性的加速比。图像分类训练任务中往往包含大量训练数据，以ImageNet为例，ImageNet22k数据集中包含1400W张图像，如果使用单卡训练，会非常耗时。因此PaddleClas中使用分布式训练接口完成训练任务，同时支持单机训练与多机训练。更多关于分布式训练的方法与文档可以参考：[分布式训练快速开始教程](https://fleet-x.readthedocs.io/en/latest/paddle_fleet_rst/parameter_server/ps_quick_start.html)。

## 2. 使用方法

### 2.1 单机训练

* 以识别为例，本地准备好数据之后，使用`paddle.distributed.launch`的接口启动训练任务即可。下面为运行代码示例。

```shell
python3 -m paddle.distributed.launch \
    --log_dir=./log/ \
    --gpus "0,1,2,3" \
    tools/train.py \
    -c ./ppcls/configs/ImageNet/ResNet/ResNet50.yaml
```

### 2.2 多机训练

* 相比单机训练，多机训练时，只需要添加`--ips`的参数，该参数表示需要参与分布式训练的机器的ip列表，不同机器的ip用逗号隔开。下面为运行代码示例。

```shell
ip_list="192.168.0.1,192.168.0.2"
python3 -m paddle.distributed.launch \
    --log_dir=./log/ \
    --ips="${ip_list}" \
    --gpus="0,1,2,3" \
    tools/train.py \
    -c ./ppcls/configs/ImageNet/ResNet/ResNet50.yaml
```

**注：**
* 不同机器的ip信息需要用逗号隔开，可以通过`ifconfig`或者`ipconfig`查看。
* 不同机器之间需要做免密设置，且可以直接ping通，否则无法完成通信。
* 不同机器之间的代码、数据与运行命令或脚本需要保持一致，且所有的机器上都需要运行设置好的训练命令或者脚本。最终`ip_list`中的第一台机器的第一块设备是trainer0，以此类推。
* 不同机器的起始端口可能不同，建议在启动多机任务前，在不同的机器中设置相同的多机运行起始端口，命令为`export FLAGS_START_PORT=17000`，端口值建议在`10000~20000`之间。


## 3. 性能效果测试

* 在单机8卡V100的机器上，基于[SSLD知识蒸馏训练策略](../advanced/ssld.md)（数据量500W）进行模型训练，不同模型的训练耗时以及单机8卡加速比情况如下所示。


| 模型    | 精度     | 单机单卡耗时 | 单机8卡耗时 | 加速比  |
|:---------:|:--------:|:--------:|:--------:|:------:|
| PPHGNet-base_ssld   | 85.00% | 133.2d | 18.96d  | **7.04** |
| PPLCNetv2-base_ssld | 80.10% | 31.6d   | 6.4d  | **4.93** |
| PPLCNet_x0_25_ssld  | 53.43% | 21.8d   | 6.2d  | **3.99** |


* 在3机8卡V100的机器上进行模型训练，不同模型的精度、训练耗时、多机加速比情况如下所示。


| 模型    | 数据集   | 单机8卡耗时/精度 | 3机8卡耗时/精度 | 加速比  |
|:---------:|:--------:|:--------:|:--------:|:------:|
| GeneralRecognitionV2_PPLCNetV2_base   | PP-ShiTuv2数据集  | 2.44d/84.2% | 1.02d/83.0%  | **2.39** |


* 在4机8卡V100的机器上进行模型训练，不同模型的精度、训练耗时、多机加速比情况如下所示。


| 模型    | 数据集   | 单机8卡耗时/精度 | 4机8卡耗时/精度 | 加速比  |
|:---------:|:--------:|:--------:|:--------:|:------:|
| PP-HGNet_x_tiny | ImageNet1k |  | 8.75d/-   | 2.33d/80.80%  | **3.75** |
| PPHGNet-base_ssld   | ImageNet1k | 18.96d/- | 4.86d/85.00%  | **3.90** |
| PPLCNetv2-base_ssld | ImageNet1k | 6.4d/-   | 1.67d/80.10%  | **3.83** |
| PPLCNet_x0_25_ssld  | ImageNet1k | 6.2d/-   | 1.78d/53.43%  | **3.48** |
| PPHGNet-large   | ImageNet22k | 15.16d/- | 4.62d/36.00%  | **3.28** |



* 注：在训练的GPU卡数过多时，精度会稍微有所损失（1%左右），此时可以尝试通过添加warmup或者适当增加迭代轮数来弥补精度损失。
