想象你开了一家连锁奶茶店,城里每个分店店长都有一份“今日各口味销量表”。总部希望每个店长都能拿到全城总销量表,而不仅仅是总部自己知道。最简单的方式是:所有店长把表格发给总部,总部加总后再发回给所有人。这个过程就是分布式训练里最核心的通信操作——All-Reduce。只不过在训练中,每个 GPU 就像一个分店店长,它手里的“销量表”是本地小批量数据计算出来的梯度;同步 SGD 要求所有 GPU 用同一个平均梯度更新模型,所以每一轮训练都要做一次梯度 All-Reduce。这篇内容会用“奶茶店周报”的故事,把 All-Reduce 的数学含义、Ring 与 Tree 两种实现、通信量公式和优化方法讲清楚。

岗位关联

对 AI 从业者而言,理解 All-Reduce 是定位分布式训练性能瓶颈的基础能力。调过一两次大模型训练后你会发现,梯度同步的通信开销往往比计算更值得关注,而 Ring All-Reduce 正是几乎所有主流框架的默认答案。

目录
  1. 可视化演示
  2. 数据并行同步:为什么梯度要“AA”
  3. All-Reduce原理:奶茶店的周报汇总
  4. Ring算法:围成一圈传纸条
  5. Tree算法:层层上报再下发
  6. 通信量计算:传了多少页纸
  7. 通信优化:让汇总再快一点
  8. 工程实践:从原理到调优
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示分布式训练中同步SGD的All-Reduce通信:Ring环形拓扑和Tree树形拓扑两种实现方式,以及梯度分桶优化策略。切换模式对比不同算法的通信效率。

本节配有交互动效(进入视口后自动加载,约 3KB)。

Ring All-Reduce 环形通信 N个节点排列成逻辑环,每个节点仅与左右邻居通信 Scatter-Reduce + All-Gather两阶段完成全局归约 通信量 = 2(N-1)/N × V ≈ 2V 单节点通信量与节点数无关,带宽利用率接近100%

数据并行同步:为什么梯度要“AA”

奶茶店各分店如果各自偷偷改配方,很快就会出现“南城偏甜、北城偏淡”的混乱。同步 SGD 的思路就是:所有分店不要自己乱改,等大家把今天的顾客反馈都整理好,算出一个统一的“修改建议”,再一起调整配方。

在数据并行训练中,每个 worker 都保留一份完整的模型副本,各自读取不同的 mini-batch,前向和反向计算后会得到一份本地梯度 \(g_i\)。同步的含义是:所有 worker 都算完这一轮梯度后,先做一次全局通信,拿到平均梯度,再用它更新模型。这样每个 worker 虽然看的数据不同,但每次走的方向完全一致。

所以同步 SGD 的核心通信动作,就是把这个“平均梯度”高效地送到每一个 worker 手中。这也是 All-Reduce 登上舞台的原因。

θt+1=θt−η⋅1P∑i=1Pgi(t)\theta_{t+1} = \theta_t - \eta \cdot \frac{1}{P}\sum_{i=1}^{P} g_i^{(t)}
这个公式说明:每个 GPU 先算自己的梯度,再把所有梯度求平均,最后所有 GPU 用同一个平均梯度更新模型。
  1. 模型参数\(\theta_t\) 表示第 \(t\) 轮迭代时的模型权重,也就是所有分店当前共用的“配方”。
    θt\theta_t
  2. 本地梯度\(g_i^{(t)}\) 是第 \(i\) 个 worker 在自己那份 mini-batch 上算出的梯度,相当于一家分店的“修改建议”。
    gi(t)∈Rdg_i^{(t)} \in \mathbb{R}^d
  3. 梯度平均将 \(P\) 个梯度逐元素相加再除以 \(P\),得到全局平均梯度,这是所有 worker 下一步共同使用的方向。
    gˉ(t)=1P∑i=1Pgi(t)\bar{g}^{(t)} = \frac{1}{P}\sum_{i=1}^{P} g_i^{(t)}

All-Reduce原理:奶茶店的周报汇总

回到奶茶店场景。店长们手里的销量表不是一份,而是每个口味一行:珍珠奶茶、芋泥奶茶、柠檬茶……每一行都是一类数据。All-Reduce 要做的事,就是把这些表格按行相加,得到一份“全城总销量表”,并且让每个分店店长手里都有一模一样的完整表格。

数学上,假设有 \(P\) 个 worker,每个 worker 有一个向量 \(x_i\)。All-Reduce 的结果是每个 worker 都得到所有向量的逐元素和:

从语义上看,All-Reduce 很像“Reduce 汇总 + Broadcast 广播”两步走。但高效实现并不会真的先汇到一个中心再广播,因为那会带来严重的中心瓶颈。Ring 和 Tree 算法就是为了解决这个问题出现的。

AllReduce(x1,x2,…,xP)=(∑i=1Pxi,  ∑i=1Pxi,  …,  ∑i=1Pxi)\mathrm{AllReduce}(x_1, x_2, \ldots, x_P) = \left(\sum_{i=1}^{P} x_i,\; \sum_{i=1}^{P} x_i,\; \ldots,\; \sum_{i=1}^{P} x_i\right)
公式右边的总共有 \(P\) 份,表示每个参与节点都会收到同一个全局汇总结果。
  1. 输入向量\(x_i\) 是第 \(i\) 个 worker 的完整梯度向量或销量表。
    xi=(xi,1,xi,2,…,xi,d)x_i = (x_{i,1}, x_{i,2}, \ldots, x_{i,d})
  2. 逐元素求和\(\sum_{i=1}^{P} x_i\) 表示把 \(P\) 个向量的第一维相加、第二维相加,依次类推。
    ∑i=1Pxi\sum_{i=1}^{P} x_i
  3. 结果广播等号右侧重复了 \(P\) 次,说明不是只让总部知道,而是每个人都拿到同一份结果。
    ∑i=1Pxi,  …,  ∑i=1Pxi⏟P 份\underbrace{\sum_{i=1}^{P} x_i,\; \ldots,\; \sum_{i=1}^{P} x_i}_{P \text{ 份}}

Ring算法:围成一圈传纸条

店长们不想每次都往总部跑,于是决定围成一圈:每个人只和左右邻居传纸条。这就是 Ring All-Reduce 的直觉。

Ring 算法先把每个 worker 的完整梯度向量切成 \(P\) 块,就像把销量表撕成 \(P\) 沓。然后分两个阶段:

第一阶段是 reduce-scatter。每个人把自己的一沓纸条传给右手边的店长,同时从左手边收到一沓,收到后立刻累加;再继续往右传。经过 \(P-1\) 轮后,每个店长手里都握有“某一行口味在全城的销量总和”,但只是其中一块。

第二阶段是 all-gather。每个店长把自己已经算好的那块全局结果继续沿圈传递,别人收到后复制一份。再经过 \(P-1\) 轮,每个店长手里就集齐了所有块,拼成完整总表。

Ring 的关键在于打破了“中心节点”的假设,让每个 worker 的收发数据量都很均匀,这也是它成为主流的原因。

Si=∑j=0P−1xj(i),i=0,1,…,P−1S_i = \sum_{j=0}^{P-1} x_j^{(i)}, \quad i = 0, 1, \ldots, P-1
这里 \(x_j^{(i)}\) 表示第 \(j\) 个 worker 的第 \(i\) 块梯度,\(S_i\) 是第 \(i\) 块梯度在所有 worker 上的总和。
  1. 分块编号\(x_j^{(i)}\) 把第 \(j\) 份完整向量按位置切成了 \(P\) 块,\((i)\) 表示第 \(i\) 块。
    xj=[xj(0),xj(1),…,xj(P−1)]x_j = \left[x_j^{(0)}, x_j^{(1)}, \ldots, x_j^{(P-1)}\right]
  2. 对角线累加对固定的块号 \(i\),把所有 worker 的这一块加起来。
    ∑j=0P−1xj(i)\sum_{j=0}^{P-1} x_j^{(i)}
  3. 分布式持有每个 worker 只负责最终持有其中一块 \(S_i\),而不是立即持有全部总和。
    Si→worker iS_i \rightarrow \text{worker } i

Tree算法:层层上报再下发

如果奶茶店开到了全国,让所有店长围成一圈传纸条就太慢了,因为消息要绕的圈数太多。这时候需要区域经理:先让同城市的店长两两汇总,再让城市经理向省经理汇报,最后全国总部汇总,然后再逐层下发。

Tree All-Reduce 的逻辑类似。把所有 worker 组织成一棵树,叶子节点把梯度传给父节点,父节点把两个子节点的梯度相加后继续向上传;根节点得到全局总和后,再沿着树向下广播。整个过程用到的通信轮数大约是:

Tree 的优点是延迟随节点数增长更慢,适合大规模跨机场景;缺点是越靠近根的节点负载越重,容易形成新瓶颈。实际框架常把 Ring 和 Tree 结合,单机内用高速 NVLink 跑 Ring,跨机再用 Tree。

rounds=2⌈log⁡2P⌉\text{rounds} = 2 \lceil \log_2 P \rceil
一个二叉树上,从叶子到根要 \(\lceil \log_2 P \rceil\) 轮,再从根回到叶子又要同样多轮。
  1. 树的高度如果每个父节点最多两个孩子,一棵 \(P\) 个节点的树高度约为 \(\log_2 P\)。
    ⌈log⁡2P⌉\lceil \log_2 P \rceil
  2. 上行汇总叶子到根的过程,每层做一次加法,所以需要 \(\lceil \log_2 P \rceil\) 轮。
    reduce: O(log⁡P)\text{reduce: } O(\log P)
  3. 下行广播根拿到结果后再向下发,同样需要 \(\lceil \log_2 P \rceil\) 轮。
    broadcast: O(log⁡P)\text{broadcast: } O(\log P)

通信量计算:传了多少页纸

通信优化的第一步是算清楚:每个 worker 到底要往网线上写多少字节?我们用 \(N\) 表示完整梯度向量的大小,\(P\) 表示 worker 数量。

最朴素的 all-to-all 方案是:每个 worker 把自己的完整梯度发给其他所有 worker,同时也接收其他所有人的完整梯度。这样每个 worker 的通信量是:

Ring 算法因为把梯度切成了 \(P\) 块,每个 worker 每轮只需要传一块,reduce-scatter 和 all-gather 各 \(P-1\) 轮,所以每个 worker 的通信量为:

举个例子:\(N=1\text{ GB}\),\(P=32\)。朴素方案每个 worker 要搬约 \(62\text{ GB}\),Ring 只要约 \(1.94\text{ GB}\)。差距就是“把大表格拆成小块接力传”带来的。

Vnaive=2N(P−1)V_{\text{naive}} = 2N(P-1)
Vring=2N(P−1)PV_{\text{ring}} = \frac{2N(P-1)}{P}
当 \(P\) 很大时,\(V_{\text{ring}}\) 约等于 \(2N\),也就是说每个 worker 的通信量基本不随节点数增长。
  1. 发送一份完整梯度朴素方案中,每个 worker 要发给其余 \(P-1\) 个 worker,所以发送量是 \(N(P-1)\)。
    N(P−1)N(P-1)
  2. 接收所有梯度同时还要接收 \(P-1\) 份完整梯度,又产生 \(N(P-1)\)。
    2N(P−1)2N(P-1)
  3. Ring 分块Ring 把每轮消息从 \(N\) 降到 \(N/P\),总共 \(2(P-1)\) 轮消息,于是得到 \(\frac{2N(P-1)}{P}\)。
    NP×2(P−1)=2N(P−1)P\frac{N}{P} \times 2(P-1) = \frac{2N(P-1)}{P}

通信优化:让汇总再快一点

知道通信量公式后,优化思路就清晰了:要么减少消息数量,要么让通信和计算并行,要么压缩传出去的数据本身。

第一个常用技巧是梯度分桶。模型有成百上千个参数张量,如果每个小张量都单独做一次 All-Reduce,延迟会非常可观。把连续的小梯度合并成一个“桶”再统一通信,就像把零散小票装进一个信封,一次寄走。

第二个技巧是通信与计算重叠。反向传播是从最后一层往前算的,先算出的梯度可以先发出去,不必等全部梯度算完再通信。理想情况下,单次迭代耗时可以写成:

此外,梯度压缩(量化、稀疏化)能直接减小 \(N\),但要注意误差补偿和收敛性验证;层次化 All-Reduce 则能让同机用 Ring、跨机用 Tree,同时兼顾带宽和延迟。

Titer=max⁡(Tcompute,Tcomm)T_{\text{iter}} = \max\left(T_{\text{compute}}, T_{\text{comm}}\right)
如果通信完全被计算掩盖,训练时间就由更慢的那一方决定,而不是两者相加。
  1. 计算时间\(T_{\text{compute}}\) 表示一次前向和反向传播的计算耗时。
    TcomputeT_{\text{compute}}
  2. 通信时间\(T_{\text{comm}}\) 表示一轮 All-Reduce 的通信耗时。
    TcommT_{\text{comm}}
  3. 取最大值重叠后总时间取两者最大值,目标是让 \(T_{\text{comm}}\) 完全藏在 \(T_{\text{compute}}\) 里。
    max⁡(Tcompute,Tcomm)\max(T_{\text{compute}}, T_{\text{comm}})

工程实践:从原理到调优

原理讲完,回到真实训练中。开奶茶店不能只画拓扑图,还要看真实的路况、快递效率和门店分布。分布式训练也一样,实际 All-Reduce 耗时受网络拓扑、NCCL 后端、消息大小和物理网卡带宽共同影响。

工程上常引入“有效带宽”来衡量通信效率。假设梯度总大小为 \(2N\)(Ring 的近似通信量),实际通信耗时为 \(T_{\text{comm}}\),那么:

实践中的几个常见动作:GPU 训练优先选 NCCL 后端,CPU 或调试场景用 GLOO;把 bucket_cap_mb 从默认值调大一些,例如 25 MB,能明显减少小消息带来的延迟损耗;用 torch.profiler 或 nsys 观察通信段占比;遇到异常时打开 NCCL_DEBUG=INFO 查看拓扑和通信链路。

βeff=2NTcomm\beta_{\text{eff}} = \frac{2N}{T_{\text{comm}}}
有效带宽越接近理论网卡带宽,说明 All-Reduce 的通信效率越高。
  1. 数据量\(2N\) 是 Ring All-Reduce 每个 worker 实际需要搬动的字节数。
    2N2N
  2. 实际耗时\(T_{\text{comm}}\) 通过 profile 工具实测得到。
    TcommT_{\text{comm}}
  3. 有效带宽两者相除得到一个“现实版带宽”,用来判断通信层是否已经压榨到位。
    2NTcomm\frac{2N}{T_{\text{comm}}}

AI 应用场景

PyTorch DDP 梯度同步

阶段:数据并行训练 / 梯度通信

解决的问题:传统做法是每张卡把梯度发给主卡,主卡算完再广播,主卡会成为瓶颈。PyTorch DDP 使用梯度分桶和 All-Reduce,让所有 GPU 并行协作。

具体案例:4 张 A100 训练 ResNet-50,DDP 会把反向传播产生的梯度按层序放入 bucket,每填满一个 bucket 就触发一次 All-Reduce,同时计算还在继续,最终显著降低训练等待时间。

大模型多机集群通信

阶段:分布式训练 / 集群集合通信

解决的问题:当模型大到单机放不下或单机算力不够时,需要跨机同步梯度。Ring 算法在 NVLink 内部带宽很高,跨机需要更少轮数的 Tree 算法来降低延迟。

具体案例:训练万亿级参数模型时,8 台机器每台 8 卡,每台机器内部先用 Ring 做 reduce-scatter,机器之间再用 Tree 汇总,最后再反向下发。这样单卡通信量接近理论上限。

通信预算评估

阶段:性能调优 / 集群选型

解决的问题:在采购机器或调整 batch size 前,团队需要估算梯度同步会不会成为瓶颈。用通信量公式可以快速判断“加大 \(P\)”和“压缩梯度”哪个更划算。

具体案例:某团队在 64 卡环境下训练 7B 模型,估算出 Ring All-Reduce 每卡只需传约 2 倍模型大小,于是决定不盲目堆卡,而是优先提高单卡吞吐并开启通信计算重叠。

Python 演示

python40 行
class CommModel:    def __init__(self, nbytes, workers, bandwidth_gbps, latency_us=5.0):        self.nbytes = nbytes        self.workers = workers        self.bandwidth_gbps = bandwidth_gbps        self.latency_us = latency_us     def _bw_time_us(self, data_bytes):        bytes_per_us = self.bandwidth_gbps * 1e3 / 8.0        return data_bytes / bytes_per_us     def ring_time_us(self):        p = self.workers        data = 2.0 * self.nbytes * (p - 1) / p        return 2.0 * (p - 1) * self.latency_us + self._bw_time_us(data)     def naive_time_us(self):        p = self.workers        data = 2.0 * self.nbytes * (p - 1)        return 2.0 * (p - 1) * self.latency_us + self._bw_time_us(data)     def ring_volume(self):        return 2.0 * self.nbytes * (self.workers - 1) / self.workers     def naive_volume(self):        return 2.0 * self.nbytes * (self.workers - 1)  if __name__ == "__main__":    for n in [64 * 1024 * 1024, 512 * 1024 * 1024]:        for p in [4, 16, 64]:            ring = CommModel(n, p, 25)            naive = CommModel(n, p, 25)            print("N(MB)=%d P=%d Ring(ms)=%.2f Naive(ms)=%.2f"                  % (n // 1048576, p,                     ring.ring_time_us() / 1000.0,                     naive.naive_time_us() / 1000.0))            print("  ring volume %.2f MB, naive volume %.2f MB"                  % (ring.ring_volume() / 1048576,                     naive.naive_volume() / 1048576))
目的:用通信量公式估算 Ring 和朴素 All-to-All 在不同节点数下的理论耗时与数据量,帮助你在训练前判断通信是否会成为瓶颈。
  1. data = 2.0 * self.nbytes * (p - 1) / p这是 Ring 每个 worker 实际传输的字节数,节点越多越接近 \(2N\)。
  2. bytes_per_us = self.bandwidth_gbps * 1e3 / 8.0把 Gbps 带宽换算成每微秒能传多少字节。
  3. ring_time_us延迟项随 \(P\) 增长,但带宽项几乎恒定,这是 Ring 的核心优势。
  4. naive_volume朴素 all-to-all 每个 worker 要传输 \(2N(P-1)\) 字节,数据量随节点数线性增长。

常见误区

误区我以为 All-Reduce 就是“先让一台主节点收齐所有人的梯度,算完再分发给所有人”,所以主节点网卡必然会成为瓶颈。

正解语义上确实像 Reduce 加 Broadcast,但 Ring All-Reduce 并不需要中心节点。它把梯度切成小块,让每个节点同时收发并累加,把负载均匀摊到所有节点上。Tree 算法虽然有“根节点”,但叶子到根的路径也是分层的,不是所有数据都直接涌向一个点。

为何常见:因为很多入门教程先用“参数服务器”解释梯度同步,容易把 All-Reduce 和中心化方案画等号。

误区我以为 worker 越多,每个 worker 要传的数据就越多,所以 64 卡一定比 8 卡慢很多。

正解Ring All-Reduce 每个 worker 的通信量是 \(2N(P-1)/P\),当 \(P\) 增大时趋近于 \(2N\),并不线性增长。当然,延迟项 \(2(P-1)\alpha\) 仍会随跳数增加,所以小消息、高延迟场景下大集群依然有挑战。

为何常见:人们容易把“总通信量”和“每卡通信量”混在一起。Ring 的分块设计恰恰是把总量均摊到每个节点上。

误区我以为把梯度从 FP32 变成 FP16 或只传部分梯度,通信量变小,训练速度一定会提升,而且精度不会受影响。

正解梯度压缩会引入信息损失,可能让模型收敛变慢甚至发散。实际工程中,要么使用误差反馈技术补偿压缩误差,要么先在小规模实验上验证压缩后的收敛曲线是否匹配原始训练。

为何常见:看到通信量公式里 \(N\) 变小,就以为代价为零,忽略了梯度信息本身的敏感性。

误区我以为 Tree 只需要 \(\log P\) 轮,Ring 需要 \(P\) 轮,所以 Tree 全面优于 Ring。

正解Tree 的优势是延迟轮数少,但简单树的高层节点和链路负载更重,带宽效率不一定比 Ring 好。实际集合通信库会根据集群规模、消息大小和物理拓扑自动选择 Ring、Tree 或混合算法。

为何常见:只看到轮数复杂度,忽略了带宽瓶颈和网络拓扑对实际耗时的影响。

面试题

Q1. 在同步数据并行训练中,All-Reduce 主要用于做什么?

单选题 · easy

  • A.把每块 GPU 的模型参数广播给所有节点
  • B.把各 GPU 的梯度汇总后再分发给所有节点← 正确答案
  • C.把训练数据切分给每个 GPU
  • D.把损失函数统一为同一个数值

答案:B。同步数据并行下,每个 worker 用自己的数据算出本地梯度,All-Reduce 负责把所有梯度汇总成一个平均梯度,并让每个 worker 都拿到这份平均梯度。选项 A 是参数广播,C 是数据并行前的切分,D 不是通信操作。

Q2. AllReduce 的数学结果有什么特点?

单选题 · easy

  • A.每个节点都得到相同的全局汇总结果← 正确答案
  • B.只有主节点得到全局汇总结果
  • C.每个节点轮流当主节点
  • D.每个节点只得到自己的局部结果

答案:A。AllReduce 的核心语义就是“汇总并广播”:所有参与节点最终持有同一个汇总结果。B 是 Reduce 加 Broadcast 分步实现时某些方案的中间状态,D 是没有通信的本地计算。

Q3. 假设完整梯度大小为 \(N\),worker 数量为 \(P\),Ring All-Reduce 每个 worker 的通信量约为多少?

单选题 · mid

  • A.\(\frac{N(P-1)}{P}\)
  • B.\(\frac{2N(P-1)}{P}\)← 正确答案
  • C.\(2N(P-1)\)
  • D.\(N\log_2 P\)

答案:B。Ring 算法把梯度切成 \(P\) 块,reduce-scatter 和 all-gather 各经历 \(P-1\) 轮,每轮传输 \(N/P\),所以总量是 \(2N(P-1)/P\)。C 是朴素 all-to-all 的通信量,D 是 Tree 类算法的轮数相关表达式。

Q4. Ring All-Reduce 的 reduce-scatter 阶段完成后,每个 worker 手里有什么?

单选题 · mid

  • A.完整的全局梯度总和
  • B.一块全局分块总和← 正确答案
  • C.自己完整的本地梯度
  • D.其他所有 worker 的原始梯度

答案:B。reduce-scatter 的目标是把完整的全局结果分散到不同 worker 上,每个 worker 只持有一块总和。这正好对应公式里的 \(S_i\)。完整总和要在 all-gather 阶段之后才会出现在每个 worker 手里。

Q5. 关于 Tree All-Reduce,下列说法正确的是?

多选题 · mid

  • A.通信轮数通常比 Ring 更少← 正确答案
  • B.根节点不会成为潜在瓶颈
  • C.适合延迟敏感的大规模跨机场景← 正确答案
  • D.通信量一定比 Ring 小

答案:AC。Tree 用树形结构把通信轮数降到 \(\log_2 P\),所以在延迟敏感的大规模跨机场景有优势。但根节点或高层链路仍可能成为瓶颈,因此 B 错误。简单 Tree 的通信量并不一定比 Ring 小,D 是绝对化说法。

Q6. 下列哪些方法能减少 All-Reduce 通信开销?

多选题 · mid

  • A.梯度分桶← 正确答案
  • B.通信与反向计算重叠← 正确答案
  • C.梯度压缩← 正确答案
  • D.提高打印日志频率

答案:ABC。梯度分桶减少消息次数,通信计算重叠隐藏延迟,梯度压缩直接减小 \(N\),都是常见优化手段。打印日志只会干扰训练进程,不属于通信优化。

Q7. 设梯度大小为 \(N=1\text{ GB}\),worker 数量 \(P=16\),Ring All-Reduce 每个 worker 理论通信量约为多少?

单选题 · hard

  • A.1.000 GB
  • B.1.875 GB← 正确答案
  • C.2.000 GB
  • D.30.000 GB

答案:B。代入公式 \(2N(P-1)/P = 2 \times 1 \times 15 / 16 = 1.875\text{ GB}\)。选项 D 对应朴素 all-to-all 的 \(2N(P-1)=30\text{ GB}\),选项 C 是 \(P\) 很大时的极限值。

Q8. 为什么 Ring All-Reduce 的带宽项不会随 worker 数量线性增长?

单选题 · hard

  • A.每个 GPU 只发送完整梯度给相邻节点
  • B.梯度被切成 P 块,每个 worker 每轮只传 1/P 数据← 正确答案
  • C.网络带宽会随 GPU 数自动增加
  • D.梯度在内存中被自动压缩

答案:B。Ring 的核心是分块流水线:每轮每个 worker 只发一块 \(N/P\),总轮数 \(2(P-1)\),所以总数据量约 \(2N\)。A 描述不准确,C 和 D 都不是算法本身的原因。

Q9. 在通信耗时模型 \(2(P-1)\alpha + \frac{2N(P-1)}{P\beta}\) 中,\(\alpha\) 的含义是什么?

单选题 · mid

  • A.单次消息的延迟← 正确答案
  • B.训练数据集大小
  • C.梯度均值
  • D.单卡计算速度

答案:A。\(\alpha\) 通常表示一次消息从发出到被接收所需的固定延迟,\(\beta\) 表示带宽。模型里 \(2(P-1)\alpha\) 是所有消息跳数带来的延迟开销,与传输字节数无关。

Q10. 关于同步 SGD 数据并行训练,下列说法正确的是?

多选题 · extreme

  • A.每个 worker 拥有完整模型副本← 正确答案
  • B.每轮需要 All-Reduce 梯度平均值← 正确答案
  • C.每个 worker 可以使用不同的 mini-batch 数据← 正确答案
  • D.每个 worker 使用不同的全局梯度更新模型

答案:ABC。数据并行要求每个 worker 都复制一份模型,各自读取不同 mini-batch,并在一轮结束时 All-Reduce 梯度平均值,所以 A、B、C 正确。同步 SGD 的关键恰恰是所有 worker 使用同一个平均梯度更新,D 错误。