想象你是连锁餐厅的总厨:灶台是 GPU,传菜员是网络。老办法是一道菜炒完,必须等传菜员把菜送到各家分店、再跑回来报信,才开始炒下一道——锅铲停着,传菜员在路上,灶台空转;新办法是让主厨炒下一道菜的同时,传菜员正好把上一道端出去。分布式训练里的“通信计算重叠”就是这个道理:把梯度同步藏进反向传播的计算阴影里,让 GPU 和网卡同时满负荷。这篇文章用厨房流水线的故事,讲清楚重叠的原理、反向传播的梯度顺序、梯度异步聚合、梯度分桶(Bucket)机制,以及怎么把重叠度调到最大。看完你就能看懂训练框架里那些 overlap、bucket 参数到底在干什么,以及为什么它们能实打实缩短训练时间。

岗位关联

对 AI 从业者来说,这是分布式训练里最划算的优化之一:不大改模型结构,单靠重叠和分桶就能省下大量 GPU 空转时间,直接转化为训练成本下降。

目录
  1. 可视化演示
  2. 重叠基本原理
  3. 反向传播顺序
  4. 梯度异步聚合
  5. 梯度分桶机制
  6. 重叠最大化策略
  7. 工程实践要点
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示分布式训练通信与计算重叠优化的核心机制,通过源头/管道/节点/终端四种模式展示关键概念与交互流程。

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

分布式训练通信与计算重叠优化:通信计算 通信计算重叠的基本原理与时间线 反向传播中的梯度异步聚合机制 核心机制可视化 分布式训练通信与计算重叠优化整体架构与关键组件

重叠基本原理

想象你是一家连锁餐厅的总厨。灶台是你的计算资源,传菜员是你的通信网络。老式做法是:主厨炒完一道菜,必须站在原地等传菜员把菜送到各家分店、再跑回来报信,才能开始炒第二道。锅铲停下,传菜员在路上——灶台空转,时间白白溜走。

分布式训练里,场景几乎一模一样。数据并行时,每张 GPU 卡都在自己的“灶台”上算同一个模型的副本,算完一小批数据后会得到一组梯度,这组梯度必须通过网络同步给其他卡,大家才能更新模型继续下一步。同步期间 GPU 只能干等,这就是通信时间。

于是有人想到:何必傻等?让通信和计算在时间上重叠起来。如果把反向传播按层切碎,先算完的层立刻发起通信,同时继续算下一层,通信就“藏”进了计算里。假设模型有 N 层,每层反向计算耗时 T_c、梯度通信耗时 T_w,串行模式下每步要 N(T_c+T_w),而完美重叠后只需要 N·T_c 再加上最后一个通信的尾巴。这,就是整篇文章的出发点。

回到厨房:真正的效率不是跑得更快,而是让灶台和传菜员同时都在干活。主厨炒下一道菜的时候,传菜员正把上一道送到各家分店,两者互不阻挡,总出餐时间自然缩短。

S=T串行T重叠=N(Tc+Tw)NTc+Tw\displaystyle S = \frac{T_{\text{串行}}}{T_{\text{重叠}}} = \frac{N\left(T_c + T_w\right)}{N T_c + T_w}
加速比 S 衡量重叠之后训练快了多少倍:N 层模型,单层计算 T_c、单层通信 T_w,串行是每层“算完再传”,重叠后只剩最后一个通信尾巴暴露。
  1. N — 参与流水线的层数模型有多少层,反向传播就要依次算出多少份梯度,对应流水线上的 N 道工序。
    NN
  2. T_c — 单层计算时间GPU 算完某一层梯度所需的耗时,单位通常是毫秒级。
    TcT_c
  3. T_w — 单层通信时间把某一层的梯度同步到所有卡上所需的时间。
    TwT_w
  4. 串行总耗时 N(T_c+T_w)每层都严格“算完再传、传完再算”,层数越多耗时线性增长。
    T串行=N(Tc+Tw)T_{\text{串行}} = N\left(T_c + T_w\right)
  5. 重叠总耗时 N·T_c+T_w各层计算首尾相接,通信全部藏在计算背后,只有最后一个通信尾巴暴露。
    T重叠=NTc+TwT_{\text{重叠}} = N T_c + T_w
  6. 加速比 S串行耗时除以重叠耗时,得到一个大于等于 1 的数,表示提速了多少倍。
    S=T串行T重叠S = \frac{T_{\text{串行}}}{T_{\text{重叠}}}

反向传播顺序

怎么检查一桌菜的味道?厨师长从最外层开始尝,觉得甜了就往回追:糖是哪一步加的?糖是哪个环节买的?一直追到最初的下锅步骤。检查必须层层回溯,不能从第一步开始查。

神经网络的反向传播也同样“倒车”。前向传播从输入层一路算到输出层,产出损失;反向传播则从输出层开始,把损失对输出的梯度沿着依赖链一层一层传回输入层。先算出来的,永远是靠近输出层的梯度。

数学上,第 l 层的梯度依赖第 l+1 层传来的梯度,层与层之间有严格的前后依赖:上层(靠近输出)的梯度先就绪,下层(靠近输入)的梯度后就绪。串行做法是等全部层的梯度都算完再一次过通信;而聪明的做法,是让先就绪的梯度先出发,而不是干等后面的层。

这个“倒车”顺序,给了重叠天然的机会:梯度不是同时就绪的,而是像菜一道一道出锅一样,先出锅的先上菜。只要把“出锅”和“上菜”两条线错开,整个流程就流畅了。

g(l)=g(l+1)⋅(W(l+1))⊤⊙σ′(z(l))\displaystyle \mathbf{g}^{(l)} = \mathbf{g}^{(l+1)} \cdot \left(\mathbf{W}^{(l+1)}\right)^{\top} \odot \sigma'\left(\mathbf{z}^{(l)}\right)
第 l 层的梯度等于“上层传来的梯度”乘“上层权重的转置”,再乘“当前层激活函数的导数”。这就是梯度为什么必须从输出层往输入层逐层倒推的原因。
  1. g^{(l+1)} — 上层回传的梯度来自更靠近输出层的梯度,是当前层梯度的“原料”。
    g(l+1)\mathbf{g}^{(l+1)}
  2. W^{(l+1)} 的转置 — 梯度逆流的方向前向传播是 x 乘权重往下游走,反向时梯度要乘权重的转置才能回流,相当于顺着来时的路倒车回去。
    (W(l+1))⊤\left(\mathbf{W}^{(l+1)}\right)^{\top}
  3. σ'(z^{(l)}) — 激活函数导数当前层线性输出经过激活函数后的局部变化率,相当于“口味修正系数”,告诉误差该放大还是缩小。
    σ′(z(l))\sigma'\left(\mathbf{z}^{(l)}\right)
  4. 逐层倒推相乘三部分连乘得到第 l 层梯度,然后继续传给更早的层,直到输入层为止。
    g(l)=g(l+1)⋅(W(l+1))⊤⊙σ′(z(l))\mathbf{g}^{(l)} = \mathbf{g}^{(l+1)} \cdot \left(\mathbf{W}^{(l+1)}\right)^{\top} \odot \sigma'\left(\mathbf{z}^{(l)}\right)

梯度异步聚合

老式宴席有个规矩:所有菜必须一次上齐,哪怕第一道已经凉了,也要等最后一道出锅。结果传菜员在厨房门口干等,灶台因为没地方放菜也只好放慢速度。

传统分布式训练同步就是这种“宴席规矩”:所有层的梯度都算完后,才发起一次全局 AllReduce。早算完的梯度在显存里躺着睡觉,传输链路空着,计算也在等——三重浪费,而这正是通信与计算不重叠的最大代价。

异步聚合(Wait-Free Backprop)打破规矩:每个梯度桶一旦就绪,立刻发起 AllReduce,不用等其他桶。因为反向传播本来就按层依次产出梯度,前面的桶通信时,后面的层还在计算,两者天然并行。主流训练框架的梯度分桶与重叠调度,都是这个思想。

就像五星级酒店的自助餐:哪道菜好了就先摆上餐台,客人随到随取,后厨和传菜员永远在忙。训练单步时间从“一整段长等待”变成“计算的流水线加一小段收尾通信”。

G=∑p=1PG(p)\displaystyle \mathbf{G} = \sum_{p=1}^{P} \mathbf{G}^{(p)}
数据并行下,每个桶的 AllReduce 就是把各张卡算出的局部梯度加起来,得到全局梯度再广播回去。每桶就绪即发,不等其他桶。
  1. G^{(p)} — 第 p 张卡的局部梯度每张卡用自己那份数据算出的梯度,相当于各家分店统计的“口味反馈”。
    G(p)\mathbf{G}^{(p)}
  2. P — 并行卡数参与数据并行训练的 GPU 总数,分店越多,反馈来源越多。
    PP
  3. 求和符号 Σ — 聚合动作AllReduce 的核心操作,把所有分店的反馈累加在一起。
    ∑p=1P\sum_{p=1}^{P}
  4. 全局梯度 G所有卡统一使用的梯度,等于各卡局部梯度之和;聚合完就广播回每家分店。
    G=∑p=1PG(p)\mathbf{G} = \sum_{p=1}^{P} \mathbf{G}^{(p)}

梯度分桶机制

传菜员跑一趟后厨到分店,路上固定要花 1 分钟。如果你让他为了一小碟盐专门跑一趟,再为了一小碟糖又跑一趟,他一整天全在路上了。聪明的做法是把各种小调料装进一个大托盘,一次端出去。

梯度同步也是这个道理。每次 AllReduce 都有固定延迟(latency),跟消息大小关系不大。把 48 层的梯度切成 48 个小消息分别通信,相当于让传菜员跑 48 趟;如果能合并成几个大桶(Bucket),每桶装好几层的梯度,通信次数立刻降下来。

这就是分桶机制:在显存里开辟一块连续缓冲,把反向传播过程中相继就绪的梯度攒进去,攒满一个桶就触发一次 AllReduce。通信耗时近似为 B·α + V/BW,其中 B 是桶数、α 是单次通信固定延迟、V 是梯度总字节数、BW 是带宽。桶数越少,B·α 这项越小。

但托盘也不是越大越好——太大就得等太久的菜才能凑满,重叠机会反而变少。桶大小是后面要讲的调优关键。先记住:把零碎消息合并成大块,是网络效率的基石。

T通信≈B⋅α+VBw\displaystyle T_{\text{通信}} \approx B \cdot \alpha + \frac{V}{B_{\text{w}}}
通信耗时由“次数 × 单次固定延迟”和“总字节数 ÷ 带宽”两部分组成。分桶压缩的是前半部分,带宽相关的那部分省不掉。
  1. B — 桶数一个训练步里发起的通信次数,桶越大 B 越小,跑腿趟数越少。
    BB
  2. α — 单次通信固定延迟哪怕只传一个字节也要付的“跑腿费”,与消息大小无关。
    α\alpha
  3. V — 梯度总字节数所有层梯度加起来的体积,训练过程中基本不变。
    VV
  4. BW — 网络带宽链路每秒能传多少字节,决定大消息的传输时间。
    BwB_{\text{w}}
  5. 分桶的意义V/BW 那部分省不掉,但 B·α 可以通过减少桶数大幅压缩。
    T通信=B⋅α+VBwT_{\text{通信}} = B \cdot \alpha + \frac{V}{B_{\text{w}}}

重叠最大化策略

要让灶台和传菜员都满负荷,关键在于节奏咬合:主厨炒菜的时间,恰好够传菜员跑一个来回。如果一道菜只要 1 分钟而传菜要 3 分钟,传菜员迟早拖住后厨;反过来传菜只用 10 秒,传菜员大部分时间在等。

重叠度 η 定义为 1 减去“暴露在外的通信等待”占总耗时比例。η=1 代表完美重叠,即通信完全被计算掩盖;η=0 代表完全串行。想逼近理想值,就得让每个通信桶的传输时间,小于或等于下一批梯度计算所需的时间,并且桶要尽快就绪。

工程上有三个旋钮:一是桶大小,小桶就绪早、重叠充分但通信次数多,大桶反之;二是梯度切分粒度,可以把一个桶再切成多个小段,边算边传;三是调度顺序,让先算完的桶先发。结合计算时间和通信时间的比值,找到最小的暴露时间。

厨房的终极理想:主厨的锅铲不停,传菜员的腿不停,谁也不用等谁。训练的最佳状态就是每个通信桶都“恰好”落在下一段计算的阴影里,阴影之外只剩最后的尾巴。

η=1−T等待T总\displaystyle \eta = 1 - \frac{T_{\text{等待}}}{T_{\text{总}}}
重叠度 η 是衡量优化效果的核心指标:暴露在外的等待时间越短,η 越接近 1,说明通信藏得越好。
  1. T_wait — 暴露在外的等待时间通信没有计算可以藏身、只能裸等的时间,相当于传菜员到了但菜还没炒好的那段空档。
    T等待T_{\text{等待}}
  2. T_total — 单步总耗时从这一步开始到这一步结束的整体时间,包括计算和所有暴露的通信。
    T总T_{\text{总}}
  3. 重叠度 η1 减去等待占比,η=1 是完美重叠,η=0 是完全串行,工程目标就是让 η 尽量靠近 1。
    η=1−T等待T总\eta = 1 - \frac{T_{\text{等待}}}{T_{\text{总}}}

工程实践要点

餐厅开成全国连锁后,事情就不只是炒菜和传菜了:各家分店远近不同,传菜员在路上花的时间天差地别。你得先搞清楚哪条路慢,才知道该多派人手还是该换路线。

优化重叠的第一步不是盲目调参,而是测出通信占比 ρ = T_comm / (T_calc + T_comm)。如果占比只有 5%,重叠优化收益有限;如果占到 30% 以上,这就是最大的金矿。用性能分析工具(profiler)把计算和通信时间画出来,看时间线哪里在等。

第二步是感知拓扑:单机多卡走 NVLink,带宽大延迟低;跨机走 InfiniBand 或 RDMA,延迟高得多。高延迟场景优先减少通信次数(加大桶、用梯度压缩),低延迟场景才适合更细粒度的重叠。第三步是 A/B 实验:扫几个桶大小,跑同样的步数看吞吐,用数据说话。

成熟的厨房团队会记录每道菜的出餐时间、传菜路线用时,定期复盘。训练集群也一样:吞吐量、通信占比、桶就绪延迟这些指标,是让重叠优化从“碰运气”变成“开卷考”的关键。

ρ=T通信T计算+T通信\displaystyle \rho = \frac{T_{\text{通信}}}{T_{\text{计算}} + T_{\text{通信}}}
通信占比 ρ 是调优的“体检指标”:占比越高,重叠优化的收益空间越大;占比很低时,不值得花大力气。
  1. T_comm — 每步通信时间所有梯度同步占用的网络时间,相当于传菜总时长。
    T通信T_{\text{通信}}
  2. T_calc — 每步计算时间前向加反向的 GPU 计算时间,相当于炒菜总时长。
    T计算T_{\text{计算}}
  3. 通信占比 ρ通信在“计算+通信”总和里的份额,是判断优化优先级的第一指标。
    ρ=T通信T计算+T通信\rho = \frac{T_{\text{通信}}}{T_{\text{计算}} + T_{\text{通信}}}

AI 应用场景

千卡集群大模型预训练提速

阶段:数据并行预训练性能调优

解决的问题:千卡集群每步训练都要做全局梯度同步,通信等待常占单步时间的 30% 以上,大量 GPU 时钟空转。传统做法是等全部梯度算完再一次性 AllReduce,网络和计算互相干等。

具体案例:某团队预训练 130B 参数模型时,用 1024 张 A100 做数据并行。通过调大梯度桶、启用反向传播与通信重叠,单步耗时从 11.2 秒降到 8.7 秒,整体训练时间缩短约 22%,相当于省下上百张 GPU 卡时的租金。

多机大模型微调加速

阶段:大模型微调(SFT 等场景)

解决的问题:微调时 batch 往往较小,单步计算时间短,通信占比反而被抬高;如果不做重叠,GPU 利用率可能跌到 50% 以下。模型虽然不大,但多机间的同步延迟照样拖慢节奏。

具体案例:某团队在 4 机 32 卡 A100 上微调 7B 模型,开启梯度分桶与异步聚合,并把桶大小从默认值下调以匹配微调的小计算量,训练吞吐提升约 35%,迭代等待时间明显减少。

Python 演示

python63 行
import math NUM_LAYERS = 48BYTES_PER_LAYER = 4 * 1024 * 1024BW = 25e9 / 8COMPUTE = 4e-3ALPHA_LOW = 2e-4ALPHA_HIGH = 5e-3  def simulate_step(bucket_size, alpha, overlap):    compute_end = 0.0    comm_end = 0.0    total = 0.0    bucket_layers = 0    for layer in range(NUM_LAYERS - 1, -1, -1):        if overlap:            compute_end += COMPUTE        else:            total += COMPUTE        bucket_layers += 1        if bucket_layers == bucket_size or layer == 0:            dur = alpha + bucket_layers * BYTES_PER_LAYER / BW            if overlap:                comm_end = max(comm_end, compute_end) + dur            else:                total += dur            bucket_layers = 0    return max(compute_end, comm_end) if overlap else total  def find_best(alpha, overlap):    best_size = 1    best_time = float("inf")    for size in range(1, NUM_LAYERS + 1):        t = simulate_step(size, alpha, overlap)        if t < best_time:            best_time = t            best_size = size    return best_size, best_time  def report(alpha_name, alpha):    s_best, s_time = find_best(alpha, False)    o_best, o_time = find_best(alpha, True)    print(f"[{alpha_name}] 串行最优桶数={s_best} 耗时={s_time:.4f}s")    print(f"[{alpha_name}] 重叠最优桶数={o_best} 耗时={o_time:.4f}s")    print(f"[{alpha_name}] 加速比={s_time / o_time:.2f}x")    for size in (1, 4, 8, 16, 48):        st = simulate_step(size, alpha, False)        ot = simulate_step(size, alpha, True)        print(f"  bucket={size:2d}: 串行={st:.4f}s 重叠={ot:.4f}s")  def main():    print("=== 低延迟集群(单机多卡) ===")    report("低延迟", ALPHA_LOW)    print("=== 高延迟集群(跨机通信) ===")    report("高延迟", ALPHA_HIGH)  if __name__ == "__main__":    main()
目的:用离散事件模拟对比“串行等待”与“通信计算重叠”两种梯度同步方式,并扫描不同桶大小,直观展示重叠带来的加速比以及桶大小的权衡。
  1. compute_end += COMPUTE每算完一层,就把模拟时钟推进一个单层计算时间。
  2. comm_end = max(comm_end, compute_end) + dur通信和计算并行,但通信必须等该桶梯度全部算完才能开始。
  3. if bucket_layers == bucket_size or layer == 0:桶攒满或到达最后一层时,触发一次 AllReduce。
  4. dur = alpha + bucket_layers * BYTES_PER_LAYER / BW一次通信的耗时等于固定延迟加传输时间。
  5. return max(compute_end, comm_end) if overlap else total重叠模式下,单步结束时间是“计算线”和“通信线”中较晚的那一条。
  6. for size in range(1, NUM_LAYERS + 1):扫描所有可能的桶大小,找出耗时最短的最优配置。

常见误区

误区通信计算重叠了,通信是不是就不花时间了?我理解重叠就是把通信时间从训练里彻底抹掉。

正解重叠并没有减少通信的数据量或传输时间,它只是把通信和计算并排安排,让通信不再单独占用训练时间线。就像传菜员送菜的时间并没有变短,但主厨没闲着等菜。总通信量不变,被“藏起来”的只是暴露在外的等待。

为何常见:看时间线对比图时,重叠后总时间条明显变短,很容易误以为是通信本身变快了。

误区桶越大合并的消息越多、通信次数越少,那直接把所有层合成一个大桶不就好了吗?

正解桶太大意味着要等很多层梯度都算完才能开始通信,重叠窗口被推迟,前面一大段网络时间都在空转。最优桶大小是“通信次数”和“重叠机会”之间的平衡点,需要实验确定,不是单调关系。

为何常见:通信耗时公式 T≈Bα+V/BW 让人只盯着 B 变小,忽略了“等桶攒满”造成的尾端等待。

误区梯度异步聚合里带“异步”两个字,那不就是和 AsyncSGD 一样,会破坏收敛吗?

正解完全两回事。梯度异步聚合只是把“等所有层梯度齐了再通信”改成“哪个桶就绪就先通信”,但它仍然等本步全部梯度同步完成才更新参数,是严格的同步训练语义,收敛性质与标准同步训练一致。

为何常见:“异步”这个词容易让人联想到异步更新权重的老方法,望文生义。

误区profiler 显示通信只占 15%,那是不是不用做重叠优化了?

正解15% 的通信如果完全暴露,就白白浪费 15% 的时间和 15% 的 GPU 租金;重叠优化后可能只暴露 2%。优化成本低、收益是乘法效应——训练总时长缩短 10% 可能意味着省下一整天的机时。只要通信存在,就值得检查重叠度。

为何常见:人容易线性思维,觉得占比小就不重要,忽略了暴露时间完全是净浪费。

误区PyTorch 的梯度桶默认参数是官方调好的,不用改,改了反而容易出问题。

正解默认值只是在通用场景下“不太差”,远非最优。它对网络拓扑、模型大小、每层梯度字节分布都高度敏感。7B 模型和 175B 模型、单机 8 卡和跨 4 机 32 卡,最优桶大小都不一样,必须实测调优。

为何常见:对框架“官方默认”存在盲信,缺乏亲手测量和 A/B 实验的意识。

面试题

Q1. 通信与计算重叠优化的核心思想是什么?

单选题 · easy

  • A.减少通信的数据总量
  • B.让通信与计算同时进行← 正确答案
  • C.提高单张显卡算力
  • D.压缩模型参数规模

答案:B。重叠的核心是把通信时间藏进计算时间,让两者并行执行,B 正确。A、D 属于压缩与剪枝手段,C 属于硬件升级,都不是重叠本身的含义。

Q2. 反向传播中梯度的计算顺序是?

单选题 · easy

  • A.从输入层到输出层
  • B.从输出层到输入层← 正确答案
  • C.与网络深度无关
  • D.所有层完全并行

答案:B。反向传播依赖链式法则,梯度从输出层逐层传回输入层,B 正确。A 是前向传播的顺序,C、D 与梯度的依赖关系矛盾。

Q3. 不做重叠时,每一步训练的耗时约为?

单选题 · easy

  • A.仅计算时间
  • B.仅通信时间
  • C.计算加通信时间← 正确答案
  • D.取二者较大值

答案:C。不重叠时每步要先算梯度再干等通信,总耗时约等于计算时间加通信时间,C 正确。D 是完美重叠后的理想值,A、B 只算了其中一半。

Q4. Bucket 机制的主要作用是什么?

单选题 · mid

  • A.减少梯度的计算量
  • B.合并小消息减少通信次数← 正确答案
  • C.增加模型表达能力
  • D.替代全部梯度同步

答案:B。Bucket 把多个小梯度消息合并成一个大消息,显著减少通信次数,B 正确。它不改变计算量、模型能力,也不替代 AllReduce 本身,所以 A、C、D 错。

Q5. 梯度异步聚合中,某个桶梯度就绪后应当?

单选题 · mid

  • A.等待所有梯度就绪
  • B.立即发起该桶同步← 正确答案
  • C.丢弃该桶的梯度
  • D.暂停反向传播

答案:B。异步聚合的核心是“就绪即发”,一个桶算完就立刻发起 AllReduce,B 正确。A 是传统同步聚合,C、D 会破坏训练流程。

Q6. 数据并行中 AllReduce 的作用是?

单选题 · mid

  • A.交换全部模型参数
  • B.汇总全部卡梯度并广播← 正确答案
  • C.切分训练数据集
  • D.计算损失函数值

答案:B。数据并行中每张卡算出的梯度不同,AllReduce 把所有卡的梯度求和并广播回每张卡,B 正确。A 描述的是参数交换,C、D 是训练流水线的其他环节。

Q7. 下列哪些因素会影响重叠优化效果?

多选题 · mid

  • A.网络带宽的大小← 正确答案
  • B.Bucket 桶大小设置← 正确答案
  • C.模型层数的多少← 正确答案
  • D.学习率数值大小

答案:ABC。带宽决定通信时长,桶大小决定通信次数与重叠窗口,层数决定可切分的粒度,三者都直接影响重叠效果。学习率影响收敛但不影响通信与计算的并行关系。

Q8. 关于 Bucket 大小的权衡,正确的说法有?

多选题 · hard

  • A.桶越小通信次数越多← 正确答案
  • B.桶越大通信启动越晚← 正确答案
  • C.需要实验寻找最优值← 正确答案
  • D.桶越大效果一定越好

答案:ABC。桶小则通信次数多、固定延迟开销大,桶大则等得久、重叠启动晚,所以存在一个最优值,A、B、C 正确。D 的“越大一定越好”是典型误区。

Q9. 高延迟网络环境下,优先考虑哪种策略?

单选题 · hard

  • A.增加桶的总个数
  • B.扩大桶合并消息← 正确答案
  • C.增大每卡批次大小
  • D.关闭梯度压缩功能

答案:B。高延迟意味着单次通信的固定开销大,优先把消息合并、减少通信次数,B 正确。A 会增加通信次数,C 不直接影响通信延迟,D 与重叠优化方向相反。

Q10. 若通信计算完美重叠,一个训练步的表现是?

多选题 · extreme

  • A.耗时接近纯计算时间← 正确答案
  • B.只剩最后的通信尾巴← 正确答案
  • C.通信总量被完全消除
  • D.等待时间基本被隐藏← 正确答案

答案:ABD。完美重叠时通信全部藏进计算,等待基本消失,只剩最后一个桶的通信尾巴,所以耗时接近纯计算时间,A、B、D 正确。C 错在重叠并不减少通信数据总量,只是把通信藏起来。