从全能医院到智慧分诊:用医院作比喻理解 DeepSeek 的模型进化

DeepSeek 的 v3 模型最近引发了很多讨论。但是,很多人也许有跟我一样的困惑:铺天盖地的公众号文章中,哪些是标题党,哪些是干货?如果我想理解 DeepSeek 为什么这么牛,应该去看哪些资料?如何确认自己的认知是正确的?怎样用直观的方式去理解这些繁杂的 Paper 背后的直觉?

怀着同样的问题,我去读了 DeepSeek v2 和 v3 这两篇 Paper。在这篇文章里,用医院的分诊系统做一个比方,来让不是 LLM 技术专家的人也能理解中间的直觉。

不过在我们具体讲述之前,首先需要做一些澄清:

  1. 这篇文章讲述的重点是 DeepSeek v3,也就是低成本实现媲美 GPT-4o 的模型。我们在这里不涉及 R1 这个推理模型。
  2. 这篇文章是一个科普性质的文章,会用大量的比喻来让大家理解 Paper 中技术细节背后的直觉。比喻不可避免地会带来信息的丢失和曲解。在这个过程中,我会尽最大努力来实现直观和严谨之间的平衡。但是,用这种方式来理解文章毕竟会带来信息走样。所以,如果你只是想大概了解一下 DeepSeek 的技术直觉,这篇文章是够用的。但如果你是想复现他们的结果,或者在这个基础上做进一步的创新,去研读他们的论文是最基本的要求。这篇文章的深度不足以支撑严谨的科学研究和工程实践。

LLM就像一个医院

下面进入正题。从某种程度上来说,大语言模型或者LLM就像是一个庞大的医院,不断地有病人从大门进去,看完医生以后离开。在这个过程中,病人就是输入的文本,出院的病人就好比是模型的输出。在病人从进医院到出医院的这段时间里,他需要去做检查、看医生、取药、挂号、缴费,这是模型内部对于输入进行的一系列复杂的操作。

在这个过程中,我们一般会着重看三个指标: 第一是这个模型的智能程度。也就是病人来看病,他所享受的医疗服务的质量如何,病是不是都看好了; 第二是模型的吞吐量和延时。也就是一个病人他从进医院到出医院平均花多少时间,整个医院一天能看多少病人; 第三是模型的大小。也就是这个医院为了接纳同样多的病人,需要一个复杂的医疗综合体,还是一个一层楼的简易门诊。这对我们进行实际的部署非常重要。

传统的LLM就像是一家全科医生组成的医院,里面的每个医生都可以负责所有科室的工作。当一个病人进来的时候,所有医生都要忙起来为这个病人服务。这个病人看完了,所有医生再去看下一个病人。这就是传统的稠密模型(Dense Model)。它有一定的优点:训练简单,显存占用小,模型规模小。因为每个医生都是全能选手,所以培养医生的教育系统可以高度复用。培养一个医生虽然难度上未必简单,但是程序(Procedure)上更加统一,不用花太多精力来优化程序。同时因为每个医生都是全能选手,可以身兼数职,所以整个医院所需的医生和占地面积都不大。

混合专家系统

在这种传统架构之外,还有一种LLM的架构,叫做混合专家系统(Mixture of Expert,MoE)。它更像是我们生活中的医院:每个医生都有自己擅长的领域。他们先接受一定程度的基础医学教育,然后再去深入学习自己的专业领域。而在看病的时候,会有一个病人导诊台去自动决定每个病人挂什么号,比如程序调试送去“代码外科”,数学证明交给“逻辑内科”,创意写作找“文学艺术科”。每位专家就只需要深入研究自家领域,不必面面俱到。这样一来,训练难度和推理负担都能分散出去。

这样的设计会带来一些好处,也会带来一些坏处。好处是一个病人进来之后,不用让所有医生都忙碌起来。而是可以根据他的病情,只让相关科室的人员为他服务。类似一个车祸创伤病人进来,不用安排肿瘤科医生来值班。这样的设计可以节约资源,增加模型的吞吐量。

但是从另一个角度来说,它也让模型的架构更加复杂。每一个进来的病人(输入的文本),都需要先经过一个自动分诊台,来确定自己要挂哪个科室(在实际LLM中,可以同时挂多个科室)的号。在挂完号之后,下面就只激活负责这几个科室的医生(Expert,专家),来为他服务。这也是Mixture of Expert混合专家系统的名字的由来。

因为混合专家系统在看病的过程中,只有一部分医生参与诊疗工作,所以要想实现相同的医疗质量(模型的智能程度),它在经验上是需要比传统稠密模型更大的占地面积(模型规模)的。但是因为看病的过程中仍然只有少部分医生被激活参与实际诊疗工作,所以它并不影响模型的速度和吞吐量,而只是单纯地让占用的空间变大而已。

这里要注意混合专家系统和医院和我们实际的医院一个主要的不同在于,它的科室划分,或者说专家的擅长领域的划分,不是预先给定的。比如我们实际的医院里,骨科和五官科的划分是事先定死的。但是在LLM里,专家的领域是在训练的过程中动态学习得来的。比如说,有可能在训练过程中算法发现,把骨科和神经外科并在一起做一个新科室,反而更有利于模型的智能程度和吞吐量。在这种情况下,他就会发明出来一个新的科室叫神经骨外科,来作为专家擅长的领域。

混合专家系统和传统的稠密模型更多的是两种不同的实现思路,并没有绝对的优劣之分。DeepSeek v2和v3采用的都是混合专家系统的策略。在介绍这两个模型之前,我们先来看一下如果要训练一个混合专家系统的LLM的话,有哪些技术难点。

混合专家系统的难题

相比于传统的LLM,混合专家系统的训练要复杂很多。其中一大难点就在于每个专家所擅长的领域和自动分诊台(在LLM里叫Router)的综合训练,很容易掉入一个陷阱。这个陷阱是,一些科室人满为患,而一些科室则门可罗雀。比如一个专家他既擅长诗词歌赋又擅长写程序,那这就会导致LLM在导流分诊的过程中,大多数的病人(输入Token)都被分配给了这个专家。而负责弦理论的专家则一直拿不到病人。这样一来,混合专家模型就退化成了传统的稠密模型。这种巨大的流量不均衡不仅会带来拥堵,同时也会造成资源的巨大浪费。毕竟整个医院准备了这么多医生和医疗设备,占用了这么大的地盘,但只有十分之一的医生和医疗设备始终在忙,其他九成只是机械待命。这样的效果反而不如去做一个全科医院来得好。因此,如何避免这种负载不均衡的情况出现,是混合专家系统的一大研究热点。

混合专家系统的另一个常见问题是,当医院的规模只是一层楼、一栋楼的时候,患者在楼层之间奔波还不是特别大的问题。但是当医院的规模大到有几个园区甚至上百个园区,分布在城市的不同角落,每个园区里又有很多栋大楼的时候,患者的分流就成了一个严重的问题。在LLM的角度来说,这就好像我们有一个很大的模型,没办法放在一个GPU甚至一台机器上,我们就必须要把它放在多个独立的机器上。在这里,不同的机器就好比医院有不同的园区,跨机器的通信就好比患者坐地铁在园区之间奔波。而同一台机器中不同GPU之间的通信,就是同一个园区中不同大楼之间的患者走动。

所以当模型规模大了以后,就算医生很厉害,可以在短时间内做出诊疗开出药方,但如果患者要在这个园区看医生,那个园区做检查,另一个园区拿药的话,整个看病的效率也会被这种奔波通信的过程给严重拖累。这也是混合专家系统所面临的另一个问题。而DeepSeek v2 和 v3 主要就是针对这一系列问题提供了自己创新的解决方案。

DeepSeek v2

DeepSeek v2主要是通过三个核心策略来一定程度上解决了混合专家系统的这两大难题,让整个医院的诊疗效率得到大大提升。

第一是他们引入了病历压缩技术(Multi-head Latent Attention, MLA)。他们发现,医生看病的过程中最耗费时间的部分不是做诊断,而是一方面需要去读之前的病历,另一方面他也要把最新的诊疗记录写到病历里面去。而且为了诊疗的准确性,病历往往要非常详细。正是这个大量病历的读写操作限制了医生进行高效诊断。DeepSeek v2的一大改动就类似于给医生发明了速记符号,让他们用一些自己能看懂的符号来代替长篇大论的病历叙述。这样用 MLA 来大幅缩减KV Cache,等于压缩了病历,一方面让显存的压力大大减低,另一方面也让看病的过程大大加速。

第二个策略是科室细分与共享(DeepSeek MoE)。在这篇论文里,它引入了DeepSeek MoE这个框架(这个框架本身是之前其他文章已经提出的),把一些大的科室进行了进一步的拆分,让它们细化成一些更小的专家。这样每个病人进来之后,可能会找多个小专家进行会诊。同时,还保留一些共享专家来做通用的支持。这样等于在科室内部又做了一层混合专家系统。又实现了专业化,又不至于因为科室的割裂而缺乏通用性,一定程度上解决了混合专家系统专家领域难划分、容易出现负载不均衡的情况。

它的第三个策略是限制病人的跨园区跑动(Device/Node Limited Routing)。传统的混合专家系统需要大量的all-to-all通信,也就是每个病人都需要去每个园区走一遍。但是DeepSeek v2引入了device limited routing,在v3中进一步引入了node limited routing。比如一个医院有一百多个园区,这种设计让绝大部分病人都可以在两到三个园区内就可以完成检查、诊断、抓药等所有诊疗操作,极大地减少了病人奔波的时间(通信量),提高了运作效率。

DeepSeek v3

而 DeepSeek v3 又是针对 v2 的另一次重大升级。它主要从算法和工程两个角度对医院进行了改进。

从算法的角度来说,它引入了三个策略:

第一是自适应负载平衡(Auxiliary-Loss-Free Load Balancing):传统的混合专家系统中,病人导诊台和每个专家的训练是共同(jointly)进行的。也就是说,导诊台的负载平衡做得好不好,会影响每个专家在医学上的培养,反之亦然。这件事其实很没道理,因为如果我们用改变医生的专业技能的方法去优化导诊台的负载均衡的话,虽然确实可以得到一个相当好的导诊的路由算法,但它也会带来很多副作用,造成医生的专业素养下降。各种实验也证明了这一点。而 DeepSeek v3 提出的一项核心创新就是引入了一种特殊的导诊台训练算法,把它和医生的培养解绑。当导诊台自己的负载不均衡的时候,它只更新自己的导流算法,而不去干涉医生的培养方案。通过这样的方法,减少了对每个专家学习的扰动,实现了整体智能程度的提升。

第二是预判式诊疗(Multi-Token Prediction, MTP):DeepSeek 引入了一个创新,叫做多令牌预测(MTP)。传统的 LLM 是一个 token 一个 token 生成的。而DeepSeek 让模型一下生成好几个 token。在训练的时候,通过一下读取、生成和验证多个 token,改善了信息利用率。而在推理的时候,它也可以让推理变得更快(speculative decoding)。这就好比是医生看到患者有什么典型症状,就一方面让他去做检查,一方面通知药房备药。如果病人检查的结果符合之前的预判,这时候药品已经备好了,就不用二次挂号二次复诊直接打发病人去拿药。但如果检查的结果对不上,那还是得进行状态回滚,药房备的药就白费了。但是它可以通过智能学习,让备药成功的概率变得更高,来改善整体的诊断时效。

第三,引入 FP8 混合精度进行训练:目前主流的训练方法用的都是16位和32位浮点数进行混合精度训练的。这就好比医生在诊疗的时候,有时候用普通的 X 光,有时候用更复杂的 CT 机,甚至必要的时候动用核磁共振来进行检查。为了保证不误诊,即使动用大量资源也在所不惜。在 DeepSeek v3 中,广泛地采用了 8 位的浮点数进行训练。这好比 DeepSeek 觉得之前过度医疗的问题太严重了,它让医生能只拍 X 光就只拍 X 光,其他的检查能不做就不做,从而提高诊疗效率。这确实会带来一些误诊的问题,但是它通过精巧的工程优化来把这个误差控制在可以容忍的范围之内,大幅提高了速度。

在算法以外,DeepSeek也做了很多工程优化。其中两个比较重要的是:

第一,叫双管道并行(DualPipe)。它把各种训练时候的操作进行巧妙的时序交错,就好比让不同病人的挂号、检查、取药、缴费各个环节尽可能地并发执行。A病人去做检查的时候,医生正好在看B病人,与此同时C病人在缴费取药,通过这样的方式减少空转,从而大幅提升了吞吐量。

第二,是智能药房管理。它把最常用的药品资源放在GPU的显存里;而不常用的资源则丢到CPU或者是FP8的缓存里。就好像常用药物放在药房里,但是罕见药物放在后勤仓库,有需求再调度。这样也在有限的资源里增加了整体运转效率。

小结

从全能医院到专科医院,再到智慧分诊 + 并行流水线 + 不过度医疗,就是 DeepSeek 团队在 LLM 架构上不断演进的脉络。通过给LLM这个医院做各种优化,他们在保证甚至提升模型表现的同时,减少了大规模场景下的通信和显存瓶颈。

不过我想再次强调的是:这些比喻只是帮助非专业读者快速上手的一种方式,真正的论文中有大量的数学公式、分布式系统技术和工程细节。如果你想在此基础上实现或改进相关研究,一定要回到原文仔细研读。如果你觉得其中的比喻有严重失真或者遗漏的地方,也欢迎指出讨论。我们一起把论文的细节解释地更加精准易懂。

Comments