最近这段时间,我的工作和生活都遇到了瓶颈。
在生活上,由于时局动荡,我再次有了困在了历史垃圾时刻的感受。所以这阵子,我开始阅读起加缪的传记和《鼠疫》。
一段摘抄的对加缪的评价
面对无处不在的荒诞,冷眼旁观或一笑而过都是不够的。如果荒谬的人生和世界的一片阴影,那么对荒谬的讨论本身,终将引领我们重归阳光之下。因此,加缪反对自杀的反抗哲学在任何时代都显得弥足珍贵,成为他留给后世的不朽遗产。进而言之,在荒诞中找寻永恒,从虚无间生发意义,向无聊处借取灵感,问闲暇时可有创新,乃是贯穿现代人一生的真正课题。
在工作上,为了在开源社区真正完成对 DeepSeek 这种超大规模的 MOE 模型的 RL,我们踩了非常多的坑。具体的麻烦总会有一天在别处道来,但是有一句话,是值得立刻分享的。
大家开发 RL 系统,总是写的代码太多,而做的计算太少了。
这是某位前辈在看了我们 MOE RL 的工作文档后给出的想法,我听了深受震撼。一句话点醒了我们的误区,现在这么高强度的开发,对着 mem-savor 和 megatron resharder 去修复无数的 bug,看上去不可避免,其实先理论计算下 upper bound,再重新设计系统,就可以解决大半。这让我想起前几天发生的其他一些事情:
- 一位朋友在湾区亚麻工作了好几年后,终于离开了美国,回国工作。我问他,是"湾区亚麻"不对,还是"湾区"不对,还是"亚麻"不对,还是"湾区"和"亚麻"都不对。他告诉我,是"湾区"和"亚麻"都不对,于是他一把干掉了两个错误选项。在我看来,先暂停手头繁忙的开发一阵子,好好想想,或许我们的工作也能一把干掉两个错误选项。
- 我不记得是谁给我说过,下等的工程师完成不了需求,中等的工程师完成大量需求,而顶级工程师会让大家的需求变简单。我们现在得停一停,让需求变简单。
whatever,事实上在 RL 系统里,很多事情就是可以算明白的。实测虽然重要,但是算明白代表着自己对系统的理解非常清晰。没有任何道理不在实际做实验之前先做一些基础的计算,先得到基本的预期,再去用预期来指导实验。即便最后在写作投稿时,我们可能根本不会把先期计算写到文章里,但是这样的计算是让我们知道眼下的开发和实验在正确的道路上。这么想来,DeepSeek V3 的 tech report 里提到的部署成本,也是在理论计算的指导下完成了工程实践。最近 SGLang 爆火的 96 H100 复现 DeepSeek 官方推理成本,各类参数,包括 96 卡本身,都是先算明白再去实践的。
总而言之,反正生活和工作都有瓶颈,我打算先停几天,把账算明白,再继续开发。这篇笔记是讲述 TP 的,对之后我们推演 DeepSeek 的 GRPO 成本打下基础。
正如大一学习的线性代数那样,对于矩阵乘法,我们可以将其拆为若干多子矩阵的乘法。
但事实是,这么切分显得非常混乱。在单张 GPU 确实放不下 B 矩阵时,也不需要把 B 四分五裂的切。主要的切分方式就是沿着行切分,或者沿着列切分。
- 沿着行切分 B,则 A 也需要沿着列切分。
其中:
-
$A_1$ 和$A_2$ 分别是 A 矩阵的左右两部分 -
$B_1$ 和$B_2$ 分别是 B 矩阵的上下两部分 - 最终结果通过
$A_1B_1 + A_2B_2$ 得到
- 沿着列切分 B,A 不需要切分。
其中:
-
$B_1$ 和$B_2$ 分别是 B 矩阵的左右两部分 - 最终结果通过
$[AB_1, AB_2]$ 得到
乍一看二者的区别是不大的,我们进一步考虑 A 的大小为