|
中国三好学生
| 来自黑龙江
有一种说法是“CUDA 是 Nvidia 最深的护城河”。我个人很赞同这种说法,了解越多越赞同。
硬件公司在设计产品的时候需要有一定前瞻性的,需要预测市场的走向,需求的走向,产品的定位等等。这个预测可能是3~5年前出来的。没错,就像你们想的,有的时候预测对了,就是你们看见的大卖的产品;也有很多时候预测错了,就是各种失败的典型,甚至悲惨到“失败”本身都没人知道。就像当年 Intel 的 Skylake 架构准确把握了云计算兴起的脉动,为数据中心业务,也就是以 Xeon 为代表的服务器 CPU (他还有个好听的中文名字,叫“至强”,和我小时候喜欢看的一部动画片 《蓝宝石之谜》里面的男主重名),带来了差不多十年的躺赢时段。还有 Nvidia 从 Pascal 开始准确契合了 AI 的发展进程, 还有目前以 ChatGPT 为代表的 LLM (Large Language Model) 蓬勃发展,简直把 A100 当成了算力的单位。这种“预测”的成功或者失败带来的可能是整个行业翻天覆地的变化。
对于 CPU 和 GPU 在 AI 领域的竞争,可以说 Nvidia 一开始就走在了前面,不过最开始 Intel 落后并不算多。在 Kepler 时代,我还是能依靠出色软件优化能力,拿出全面优于 GPU 的方案;Maxwell 时代实际上就有点力不从心了。那个时间点 Skylake 实际上是有性能优势的,无奈当时我司在 AI 方向的产品策略:默认在部署(Inference)端,认为 CPU 是稳赢的;然后在训练(Training)端,通过 Xeon Phi (这是个类似于 GPU 的通用计算卡,长得和 GPU 差不多,但是复用 CPU 的软件生态) 来和 GPU 抗衡。至今我还对 VP 当时展示的那页 AI 路线图记忆犹新,其实在 Xeon Skylake 和 Xeon Phi 之间还有两款产品,就是上面说的“失败”得都没人知道你的失败的产品。
我这些年见过的最烂的两款产品:一个是 Xeon Phi 的第二代(codename: KNL),另一个是他的第三代 (codename: KNM),当然 KNM 还没量产就被取消了。KNL 多少还是有点市场,这东西比较适合超算,但 KNM 实在扶不起来:它的设计思路是通过一个 4fma 的指令实现 float32 算力的加倍。但实际中,这条指令对矩阵的尺寸有很多限制条件,导致实际的场景中能被加速的情况寥寥无几,也就是标称有差不多 12Tflops,但实际中效率普遍低于 10%。这款产品还给我当时的团队带来了严重的管理危机,因为它“标称”很高,所以老板“认为”它就应该能够干掉当时的 GPU,那个时间点的竞品是 M40。“无奈臣妾做不到”,给我换 Skylake 可以做到,但 KNM 就是怎么优化都不行。最终直接或者间接导致和我一起做 torch 优化工作的另外 4 名工程师全部离职,这几个人还都挺厉害的,他们现在都为各自的公司做出了杰出贡献!不过神奇的是,当时 KNM 在国内是有少量订单的,不得不说 sales 的同事真是厉害!
后来 Nvidia 祭出 P100,这是个 Intel 被甩开的时间点,在这之后差距被越来越大,P100, T100, V100, A100。算力上的差距以肉眼可见的速度被逐渐放大。大模型出来之后简直要砸键盘了,感觉加点又 TM 加错了。
比起硬件算力的差距,软件生态上的差距更让人绝望。当 CUDA 几乎与 AI 画等号的时候,会有大量的社区力量为其助力。这就是一种良性循环:好的性能带来好的生态,好的生态会有助于更好的性能。比如目前 PyTorch 一个季度 release 一次,还有小版本的 release。一次大版本更新可能进 三四千个 Pull Request,这里面 Facebook 固然是主导,当然也有很多专业公司的贡献,但社区开发者的贡献同样不容小觑,而这些改动多数都是 CUDA 为主的。我个人的话,一年大概也能进就百十来个 Pull Request,这里面还不全都是优化,也有一些是在修 BUG。有时候一些比较麻烦的优化,一个就要写个把月,一两百个 commit 的改动。这就是生态的力量,也就是为什么说 CUDA 是 Nvidia 最深的护城河。如果你不加入,感觉就是一个人对抗一个集团。而现实世界中是没有像 Jane 那样的独成一档的5级变种人的。
有一点必须承认的是 Nvidia 在 GPGPU 上的工作不是一蹴而就的,这是个长达十余年的漫长积累。我念硕士的时候也是写 GLSL,CUDA 这些东西。Nvidia 的教育项目做得很好,导致现在的工程师都会写 CUDA。我的导师做过一个比喻:他念书的时候三星做了很多 MCU 的教育推广项目,然后这些学生上班之后都很自然地忘记了它的竞品的名字。类比之下,我司的教育项目简直就是“稀烂”,至今没有一个像样的教程。我早期的学习资料是看 TensorFlow 的对等代码,因为那时候很多抱怨是 PyTorch 在某某模型上不如 TensorFlow,所以我需要去扒对应的代码。当然现在没有这种抱怨了。现在很多时候要学一下 CUDA 的算法,然后搬到 CPU 上面,主要是指数据的并行切分方式,就是 blocking 或者叫 tiling。比如如果性能差距在3~5倍,可以认为是算力差距,但如果差了100倍,那肯定是什么地方没搞好,多数情况是 blocking 的问题。
目前针对 AI 方向的加速器或者 GPU 产品其实很多很多,国内尤其热衷这个感念,多到两只手数不过来,能叫上名字的公司几乎都在搞。至于各家生态如何,个人不太好做过多评论,避免引战。相对于纯纯的硬件算力上的区别(以 A100为单位,有的能做到 2 x A100 甚至更高),生态其实是一个更难弥补的差距。
如果想被社区接受的话,一般大家会有两种策略:
- CUDA 和 "原生" 两套生态同时做。就是维护两套编译器,一套适配 CUDA,另外一套是原生的。这么做的优点和缺点都很明显:可以复用 CUDA 的成熟的生态,随之而来的好处是 upstream (就是把你的工作 merge 到社区) 的工作会很轻松,也就是很容易被社区接受,因为对框架本身的改动会很小。代价是两套编译器就是两个团队。这么玩的比如 AMD。
- 利用自身流量说服社区。这么玩的就是苹果的 mps,其相关的 upstream 工作对框架改动是很大的,但是社区会开绿灯,因为苹果有流量。貌似除了苹果没人有这么玩的实力。本质上这种行为就是耍流氓,是需要资本的。
总结一下,要么有流量,即硬件本身已经被广泛使用,要么改动尽量小,即能以比较“优雅”的姿态被社区接受,而不是重写一个 PyTorch或者重建整个生态。
也有很多玩家上面两条路都不选的,自己维护一个新的框架,或者是做一个PyTorch的插件。这种方式比较适合初创公司打板,就是跑 benchmark,比如 MLPerf。算是兼顾性能、生态和工作量的折中方案。但其实这个工作量也很大(比如目前 PyTorch 大概有 600 个算子,都要实现一遍,这还没算同一个算子下不同的实现: 比如就一个 add,也有不同的 memory format, mixed data type,broadcast 等等)。而且,整个生态的问题规模是个倒三角,越往上面问题规模越大,各种各样的 model zoo:比如 HuggingFace,Detectron,TorchVision,DeepSpeed,等等。维护量一套体系的成本是会被逐渐放大的。如果只需要 python 还好,如果是那种有 C++ 实现的 model zoo,几乎没有办法以一种低成本的方式完美地处理掉。
还有一个潜在的问题是,自建生态在没有经过大规模使用的时候,是难以保障 code quality 的。也就是只能跑 benchmark,跑一下客户的模型就各种 runtime error,而且是那种一眼看上去不知道是什么原因的 bug。在你打了5个patch解决了3个问题之后拿到客户那边试,又出现了新的 bug。在你 online debug 或者屁颠屁颠跑过去 on site bebug 三天三夜,终于能以英雄的姿态凯旋之后,过了三个月客户说 accuracy 达不到 SOTA,或者说有memory leak,或者找茬说为什么 CUDA 的方案用的内存比你小(拿出竞品目的是压价),and so on ...
当然有人会争论说,只要性能足够好,就会有人从 CUDA 的生态上面迁移过来。这个是正确的,但这个足够好一般是要跨数量级的,至少也要是3倍4倍的提升,如果只是20%的提升,没人愿意费这个劲的。因为对客户来讲,尝试不成熟的方案是要担风险的,只有获利足够大,才会有人愿意赌这一把。
不过呢,凡事都有例外。在“天下苦CUDA久已”的趋势下,一种新的方案出现了,就是 Introducing Triton: Open-source GPU programming for neural networks。这个对一众硬件厂商来说是个重大利好。原则上需要两步:1. 完成现有生态与 triton 的对接;2. 给自己的硬件写个后端支持。第1步会有人帮你做好,目前的方案虽然并不是十全十美,但至少不用自己出钱出力。所以重点放在第2步即可,而且更好的地方在于这种项目是典型的个人主义项目,VP会很开心,因为不需要拉个一百人的团队,人多了也没用。 |
|