## 35-分布式训练

### 本节目录

- [1.分布式计算](#1分布式计算)
- [2. GPU机器架构](#2-gpu机器架构)
    - [2.1 样例：计算一个小批量](#21-样例计算一个小批量)
    - [2.2 总结](#22-总结)
- [3.  关于性能](#3--关于性能)
    - [3.1 对于**同步SGD**：](#31-对于同步sgd)
    - [3.2 **性能**：](#32-性能)
    - [3.3 性能的权衡](#33-性能的权衡)
- [4. 实践时的建议](#4-实践时的建议)
- [5. 总结](#5-总结)

### 1.分布式计算

- 本质上来说和之前讲的单机多卡并行没有区别。二者之间的区别是分布式计算是通过网络把数据从一台机器搬到另一台机器

<img src="../imgs/35/35-01.png" alt="image" width="300" />

### 2. GPU机器架构

- 总的来说，gpu到gpu的通讯是很快的，gpu到cpu慢一点。机器到机器更慢。因而总体性能的关键就是尽量在本地做通讯而少在机器之间做通讯

##### 2.1 样例：计算一个小批量

- 每个worker从参数服务器那里获取模型参数：首先把样本复制到机器的内存，然后把样本分到每个gpu上
- 复制参数到每个gpu上：同样，先把每一次的参数放到内存里，然后再复制到每个gpu上
- 每个gpu计算梯度
- 再主内存上把所有gpu上的梯度加起来
- 梯度从主内存传回服务器
- 每个服务器对梯度求和，并更新参数

##### 2.2 总结

- 由于gpu到gpu和gpu到内存的通讯速度还不错，因此我们尽量再本地做聚合（如梯度相加），并减少再网络上的多次通讯

### 3.  关于性能

##### 3.1 对于**同步SGD**：

- 这里每个worker都是同步计算一个批量，称为同步SGD
- 假设有n个ggpu，每个gpu每次处理b个样本，那么同步SGD等价于再单gpu运行批量大小为nb的SGD
- 再理想情况下，n个gpu可以得到相对单gpu的n倍加速

##### 3.2 **性能**：

- t1 = 在单gpu上计算b个样本梯度时间
- 假设有m个参数，一个worker每次发送和接受m个参数、梯度
  - t2 = 发送和接受所用时间
- 每个批量的计算时间为max（t1，t2）
  - 选取足够大的b使t1>t2
  - 增加b或n导致更大的批量 大小，当值需要更多计算来得到给定的模型精度

##### 3.3 性能的权衡

<img src="../imgs/35/35-02.png" alt="image" width="300" />

### 4. 实践时的建议

- 使用一个大数据集
- 需要好的gpu-gpu和机器-机器带宽
- 高效的数据读取和预处理
- 模型需要有好的计算和通讯比
  - Inception>ResNet>AlexNet
- 使用足够大的批量大小来得到更好的系统性能
- 使用高效的优化算法对应大批量大小

### 5. 总结

- 分布式同步数据并行是多gpu数据并行在多机器上的拓展
- 网络通讯通常是瓶颈
- 需要注意使用特别大的批量大小时的收敛效率
- 更复杂的分布式有异步、模型并行（这里没有介绍）