正如之前所说,在b200上用单卡和两卡重新测试了相同的1.5B模型的结果,进而得到了一些有意思的小结论。数据删去繁杂的细节之后(感谢ai),整理在下表中。
性能数据汇总
wall-clock端到端时间(含CPU开销)
硬件 tp 延迟 tok/s 加速比
───────────────────────────────────────────────────────────────────────
5090 PCIe (Py3.12+Xeon 8470Q) 1 2.74ms 365 —
5090 PCIe (Py3.12+Xeon 8470Q) 2 2.13ms 470 1.29x
B200 NVLink (Py3.10+Xeon 6960P) 1 1.64ms 610 —
B200 NVLink (Py3.10+Xeon 6960P) 2 2.08ms 480 0.79x
可以看到,前者可以达到一定程度的加速,而后者不仅没有加速,反而被拖慢了。这可能是什么原因?第一反应肯定是因为B200本身算力太高,分摊GEMM计算量的好处相当有限,而通信带来的提升不足以被PCIe到NVLink的配置升级所补偿。算力的升级幅度远大于通信的升级幅度,因此前者可以加速,而后者就不行了。
这个解释本身就是可以接受的。不过,还有一个疑惑:NVLink的性能比PCIe按理来说高很多,B200的性能,无论是算力还是带宽,按理来说也比5090高很多,但为什么在tp=2的情况下,两者的延迟如此接近,几乎完全相等(只有不到3%)?接下来的分析揭示了对小模型(以及不够大的大模型)来说另一个很隐蔽,但是可能同样也很重要的开销:CPU调度开销。
纯GPU replay时间(无CPU开销)
为了解答这个问题,设计了纯基于CUDA Graph的连续replay测试。这部分测试是为了揭示在没有CPU控制流开销的情况下GPU本身的性能如何,以反过来倒推CPU开销的大小如何对性能产生影响(这个的测试没有那么直截了当)。
见下表。可以看到一个非常有趣的细节:在5090+PCIe的配置组合上,端到端的开销和纯GPU开销相对来说较小:CPU侧的开销要么很小,要么可以被部分的overlap住。而对于B200+NVLink来说,其平均的CPU侧开销几乎是5090+PCIe的两倍以上。这主要有这样几个原因:
1、CPU主频不同。CPU侧的代码并没有那么高的并行度,堆叠核数的意义小很多。而Xeon 8470Q的睿频是约3.8GHz,与此同时Xeon 6960P的单核睿频是约3.2GHz。这两者的性能差异造成了很大的CPU侧时延不同,因此最终在并行度增加的时候抹平了GPU侧的性能优势。
2、Python版本的不同。更新的版本具有更完善的解释器优化,因此能够更好的降低CPU侧阻塞时间。
因此,CPU在现代大模型推理里真的不重要吗?其实不完全是。在模型较小、或者并行度够高以至于单步推理时间较为短的时候(以我们的测试为例,小于2.0ms的时候),CPU的overhead并不一定总是能够忽略的。因此,CPU侧代码的优化和恰当实现同样有其必要性。
硬件 tp 纯GPU延迟 GPU加速比
────────────────────────────────────────────────────
5090 PCIe 1 2.62ms —
5090 PCIe 2 2.12ms 1.24x
B200 NVLink 1 1.46ms —
B200 NVLink 2 1.89ms 0.77x
AllReduce 延迟(单次3KB传输)
可以看到,NVLink的单次通信固定延迟大约是PCIe的三分之一,而带宽是20倍,这也是一个有助于建立直感的数字。它也再次验证了计算机学科几乎通用的一个真理:降低延迟永远比提高带宽困难多了。小数据量的AllReduce是纯latency-bound,其对性能造成的损害于取得的收益相比不成比例(至少不是线性的),因此只适合在足够大的模型、足够好的配置下才值得用,尽管它是实现起来最直接也最方便的。
固定延迟 数据传输 总延迟 56次/步
─────────────────────────────────────────────────────────────────
5090 PCIe ~28μs 0.06μs ~28μs 1.59ms
B200 NVLink ~10μs 0.003μs ~10μs 0.57ms
值得一提的细节
benchmark环境的隐藏变量不一定可以忽略,有时候影响显著。在最初测试的时候,B200 NVLink (Py3.10+Xeon 6960P)的配置在tp=2的时候甚至慢于5090 PCIe (Py3.12+Xeon 8470Q)的tp=2的情况,而这几乎说不通。经过检查,发现是环境变量中,OMP_NUM_THREADS设置不同(B200侧未指定,默认为1),autodl平台进行了专门的预先设置(指定为了50)但B200的环境中没有,这造成了明显的性能改变,通过拖累CPU侧的性能进而拖累了整个端到端的性能。
此外,这也验证了另一个问题:TP不是万能药,甚至有时候有害。对于小模型、网络延迟不够低的机器配置,尤其如此。