MOE 和 MOA,这两个词这两年在大模型圈子里隔三差五就被提起。很多刚接触的朋友以为它们是同一个东西的两种写法,或者干脆当成一对互为替代的技术方案。但实际上一个是模型的内部结构设计,一个是多模型协同的推理组织方式。两者各有各的适用场景,也各有各的坑。这篇文章我从实际使用角度把 MOE(混合专家模型)和 MOA(混合代理)拆开讲,结合我跑模型、调推理框架、搭多模型链路的经历,把背后的设计逻辑、实操步骤和踩过的坑一次说清。
如果你正准备选型一个大规模模型,或者打算在现有业务里把多个不同模型组合起来用,这篇内容会比较对口。我会尽量把枯燥的架构概念用大白话解释,也会给出能直接上手的排查思路和配置建议。
1. 先把概念对齐:MOE 解决什么问题,MOA 又是什么
1.1 MOE:让一个大模型同时拥有多个领域的专业能力
MOE 全称 Mixture of Experts,混合专家模型。核心思路很直接:以前一个模型就是一个人,什么都得会,但训练一个大而全的大脑代价很高。MOE 的做法是,把模型内部拆成多个"专家"子网络,每个专家擅长不同的输入模式或知识领域,再由一个路由机制按输入内容决定激活哪些专家。
你可以把 MOE 想象成一家综合医院。普通模型是一个全科医生,每个科室的知识都装在脑子里,但科目太多必然摊薄深度。MOE 则是把内科、外科、骨科分成多个科室,来了病人先由预检台(路由)判断该去哪个科室,只有对应的科室医生动手处理。这样每个专家可以做得更专、更深,而每次推理并不需要全院所有科室同时参与。
这一结构带来的最直接收益是:模型总参数量非常大,但单次推理实际激活的参数只是一个子集,推理成本低于同等规模的全参模型。这在业界被称为稀疏激活。早期大家担心的"参数量暴涨导致训练成本不可控"的问题,通过稀疏性得到了一定缓解。
需要注意:MOE 不是一个新的训练范式,它解决的是模型容量和计算成本之间的矛盾。同样的一个 transformer 结构,把其中的前馈网络层替换成多个并行专家模块,配合门控路由,就成了一个 MOE 层。一个模型里通常只会在部分层做这种替换,不是全层都改。
1.2 MOA:把多个模型当成协作团队来用
MOA 全称 Mixture of Agents,混合代理。它完全不是模型内部结构,而是推理阶段的多模型协作策略。做法是把多个不同的模型当作多个"代理",各自独立生成回答或处理同一任务的不同方面,再通过一个聚合模型或规则把结果合成最终输出。
打个比方,MOA 像你把一个问题同时发给几位资深同行,让他们分别给出意见,你再综合这些意见形成最终方案。每位同行擅长的方向不同、表述习惯不同、出错点也不同,把多份意见合并之后,往往比单独一个人的回答更全面、更少遗漏。
MOA 的典型流程分三层:
- 输入分发:把同一个 prompt 同时发送给 N 个模型。
- 结果收集:等待各模型返回各自的回答。
- 聚合合成:用另外的模型或固定规则挑选、排序、融合多份答案。
聚合这一步是 MOA 的核心。最简单的做法是让一个较聪明的模型扮演"主编",阅读所有候选答案后重写一版。效果通常超过任意单一模型,缺点是额外多了一次推理调用,成本和延迟都会上升。
1.3 MOE 与 MOA 容易混淆的三个地方
我在不少讨论帖里看到有人把 MOE 和 MOA 混为一谈,总会出现以下三类混淆:
- 混淆层次:MOE 是模型骨架层面的结构优化,发生在模型内部,对使用者基本不可见。MOA 是使用层面的策略,发生在模型外部,使用者要主动设计和调度。一个是"身体结构",一个是"组队方式"。
- 混淆目标:MOE 的目标是在相近算力下扩大模型容量、提升单模型上限。MOA 的目标是多模型互相补位、减少单一模型的版本偏差和漏答。
- 混淆代价:MOE 的代价主要发生在训练期,推理期需要处理显存占用和带宽问题。MOA 的代价是每次请求都要跑多个模型,直接增加推理调用量。
这两者在工程实践中完全可以同时使用,比如底层用一个 MOE 结构的模型,上层再叠加一层多模型聚合路由,把多个 MOE 模型当作代理来协作。这一点后面我会细说。
2. 核心机制拆解:从路由到聚合
2.1 MOE 的专家选择与门控路由
MOE 的关键机制是门控路由,也叫 Gate Network。它本质上是一个轻量级的分类器,接收当前 token 的隐层表示,输出每个专家的得分,再依据得分选出 top-k 个专家参与计算。
这里有个容易忽略的细节:路由的对象是 token,不是整句话。同一个句子中的不同 token 可能被路由到不同专家。比如一句话里涉及代码的 token 被送到代码专家,涉及自然语言的 token 被送到通用语义专家。这种 token 级别的路由精度很高,但也带来了一个工程问题:不同 token 路由到不同专家,意味着同一批数据在多个专家之间来回跳跃,对显存带宽的要求成倍上升。
一个模型常设定 top-k 为 2,即每个 token 由两个专家共同处理。为什么不是 1 或 4?实验经验是 top-1 容易造成路由错误后完全没有纠错余地,而 top-4 会显著增加计算量且专家间协同收益递减。top-2 是效果和成本的常见平衡点。
注意:很多 MOE 模型的"总参数数量"看着吓人,千万不要按总参数去估算部署显存需求。实际上你只需要关心激活参数量和全部专家参数量的关系。推理时只有被路由选中的专家权重需要加载进显存计算,但所有专家权重仍然需要常驻显存,因为每批输入路由结果都不同。
2.2 负载均衡:MOE 里最容易翻车的地方
路由机制听上去干净利落,实际运行时最怕一个问题:负载不均衡。如果路由总把大量 token 送给少数几个专家,其他专家长期闲着,这些闲着的专家训练不到位,而热门的专家承担了过多计算压力。
为了对付这个毛病,训练时通常会给路由损失加一个辅助的负载均衡损失函数。它的作用是鼓励路由把 token 尽量均匀地分配到各个专家。损失系数需要调得合适,太大了会牺牲任务效果,模型会因为强迫平均而无法让能力强的专家多干活;太小了负载不均衡就会失控。
具体排查时,可以从训练日志中看到专家激活次数的直方图。正常情况应该是大部分专家都有合理的激活量,如果看到某个专家激活量为 0 的轮次持续出现,先别急着调模型结构,先看负载均衡损失的权重是不是被调没了。
MOE 训练还有一个隐性代价:每个专家在反向传播时都要更新参数,哪怕当前前向没有激活它,梯度也会因为辅助损失而传导过去。所以 MOE 虽然推理时省算力,训练时的通信开销却比同参数量普通模型更大。
2.3 MOA 的输出合成:投票、排序还是融合?
MOA 核心从技术角度看有两个技术路线:一是基于规则的聚合,二是基于模型的聚合。
基于规则的聚合常见方式有几种:
- 投票法:多个模型各自生成选项或答案,出现最多的作为最终结果。适合答案有固定选项的场景,不适合开放式问答。
- 排序法:让每个模型对候选答案打分,按平均分或最高分选出一条。前提是打分标准和候选答案来自同一体系,容易出现自卖自夸的偏差。
- 拼接法:把多个模型回答中各自最自信的段落拼接成完整答案。实现难度高,段与段之间容易出现重复冲突,很少用。
基于模型的聚合是目前效果最好的方式。做法是固定一个"合成模型"作为主编,把各模型的原始回答和原始 prompt 一起交给它,让它重新写一版。合成模型需要具备两个能力:能综合不同答案的公共信息,能识别哪个答案在某一块更可靠。
实操中我发现一个规律:聚合模型的综合能力反而比个体模型的单项能力更重要。优先选择指令理解能力强、长上下文处理能力足的模型做聚合,而不是选择单点知识最强的模型。因为聚合任务的核心在于"取舍"和"重写",不在于回答内容本身。
在成本上,基于模型的聚合会额外增加一次或多次模型调用,如果候选模型有 4 个,总 token 消耗约等于 5 次模型调用。想控制成本,可以把候选模型减少到 2 到 3 个,太多的话边际收益快速递减,我实测下来 3 个候选加 1 个聚合模型是性价比比较好的组合。
3. 实操落地:怎么把 MOE 模型跑稳,怎么搭 MOA 链路
3.1 部署 MOE 模型时的显存与带宽观察
把 MOE 模型拉起来跑和部署普通模型有很大差异。最大的差异点在于显存布局和通信开销。
普通模型部署时,模型各层权重按顺序加载,推理时是全量激活,显存占用和参数量直接挂钩。MOE 模型部署时,所有专家权重都要常驻显存,虽然每次只用两个专家,但不同层、不同 token 可能用到任何一组专家,你不能只把部分专家留在显存里。
举例说明:一个总参数接近千亿级的 MOE 模型,实际激活参数量可能只有百亿级,但推理时的显存需求仍然按全量参数估算,这是很多新手上来就踩的坑。他们以为激活参数量小就能用小显存卡跑,实际加载模型时还是会显存溢出。
带宽的影响同样不能忽略。MOE 推理时,每个 token 都可能跳转不同专家,数据在专家模块之间流动频繁,显存带宽决定了单位时间内能完成多少跨专家访问。在同样的硬件条件下,MOE 模型的吞吐量往往低于同激活量级的普通密集模型。
实际部署建议从几个方向入手:
- 使用支持专家并行策略的推理框架,把不同专家分散到不同 GPU 上,减少单个设备显存压力。
- 批量大小不要一开始就拉满,从较小的 batch 起步观察显存和耗时曲线,确认没有异常再逐步加大。
- 关注每个 GPU 之间的通信耗时,如果多卡通信占比超过整体推理耗时三分之一,优先检查数据并行切分方式是否合理。
3.2 推理参数对稀疏激活的影响
同一个 MOE 模型在不同采样参数下的表现差异,比密集模型更加敏感。原因在于路由网络接收到的是带有随机性的上下文表示,当温度和 top-p 调高时,模型生成路径的随机性增加,token 分布更散,专家使用模式也会随之偏移。
经验上看,把温度调高到 1.0 以上时,MOE 模型容易出现两个问题:
- 不同 token 激活的专家数量变化幅度更大,推理耗时波动明显。
- 生成结果的一致性变差,同一 prompt 连续跑多次,主题方向可能偏差较大。
如果想要更稳定的输出,可以在解码阶段使用较低的采样温度,比如 0.6 到 0.8,同时不要配合过高的 top-p 值。这能有效压缩 token 分布范围,让上层路由更容易落回几个稳定的专家,输出质量也更可控。
不要为了"多样性"盲目调高温度,MOE 模型本身已经通过专家分工拥有了多样性能力,过高的采样温度反而把所有专家的努力都抹平了,生成质量可能出现明显下滑。
3.3 搭一个可用的 MOA 管线:角色划分与结果合并
接着说一下如何把 MOA 落到实际业务里。我现在维护的一套多模型协作管线,最初只用了两个模型轮流回答,后来扩展成"一个调度器 + 三个候选模型 + 一个聚合模型"的结构。
具体的搭建步骤,你可以照着这套思路来:
- 明确分工:三个候选模型尽量选自不同技术路线或不同训练侧重点的模型,这样失败模式不同,答案多样性才够。如果三个模型来自同一公司同一代技术,大概率是同源偏差,多模型协作的价值会大打折扣。
- 统一输入格式:把原始 prompt 转成结构化的请求体,包含任务描述、上下文材料、输出要求。所有候选模型用同一套格式,保证聚合模型对比答案时不会因为格式差异而判断错乱。
- 设置超时和降级:给每个候选模型调用设置独立的超时时间,比如 15 秒。任何一个模型超时,管线自动跳过它直接进入聚合阶段,不能让单个慢模型拖垮整条链路。
- 聚合提示词设计:聚合提示词我用的是中文三段式:先说明任务背景,再列出所有候选答案,最后要求"综合以上答案的优缺点,给出一个更完整、准确且不冗余的最终回答"。注意提示词里明确要求不能叠加多个答案的所有内容,重点在于整合。
- 加一层质量校验:最终答案回到调度器后,用一套规则快速校验长度、关键词覆盖率和是否包含明显的矛盾表述。如果校验不过,直接回退到质量最好的单个候选答案,避免聚合模型产生比单个模型还差的结果。
这套管线在延迟上会比单个模型调用多个 40% 到 100%,这是无法避免的代价。如果业务对延迟极敏感,可以把候选模型从 3 个减到 2 个,再合并聚合模型为轻量模型,能有效把额外延迟控制在 60% 以内。
4. 常见的坑和排查记录
4.1 路由倾斜导致部分专家没被训练
MOE 模型训练时最常见的问题是专家退化,也就是部分专家从未被激活,导致训练权重长期不更新。排查方法是从训练日志里监控每个专家的 token 分配比例。正常阈值是每个专家的激活占比不低于总量的 1%(专家数量很多时)和不高于总量的 15%。如果某个专家激活占比持续为 0,基本可以确定路由已经忽略了它。
我遇到过一次比较隐蔽的情况:某个专家在训练初期有正常激活,到中期开始逐渐下降,最终趋向于 0。这不是因为专家本身能力差,而是路由网络在训练中形成了路径依赖,少数专家表现稍有优势以后,路由会越来越倾向于选择它们,造成正反馈失衡。
处理办法分两步。第一步是恢复负载均衡损失的权重,调到训练初期水平的 2 倍试跑若干步,观察激活占比分布是否重新分散。第二步是检查训练数据的领域覆盖,如果数据里某个领域的比例畸高,路由会自然而然集中到擅长该领域的专家,数据侧补齐之后往往比调整损失函数更有效。
4.2 MOE 在长上下文场景下的不确定性
长上下文场景下,MOE 模型的表现没有想象中稳定,我测试时发现过几个确定性的问题:
- 当上下文长度超过模型训练时见过的最大长度后,路由分布会明显异常,部分专家开始被过度激活。
- 长上下文中同时包含多个主题时,路由网络容易处在前一个主题的惯性中,后一个主题的 token 被错误导向先前主题偏好的专家。
- 对长文本进行切块再单独推理,结果往往好过把完整长文本一次性喂入模型,也是因为路由可以在每块内部保持相对稳定的分工。
如果你要在长上下文场景里使用 MOE 模型,建议用滑动窗口切片的方式做分段处理。窗口重叠设定在 10% 到 20% 比较合适,重叠太少会导致相邻段的信息衔接不上,重叠太多则计算浪费。
4.3 MOA 的调用成本与延迟监控
MOA 在业务里最大的阻力不是效果,而是成本和延迟。我当时搭建管线时只关注了最终答案质量,上线一段时间后发现一个问题:聚合模型读入所有候选答案,输入 token 数量是原始 prompt 的好几倍,账单直接翻了几番。
成本失控的根源在于聚合阶段没有做长度控制。候选模型的回答可能又长又散,聚合模型必须吞下所有这些内容。把候选模型的 max tokens 从 2000 降到 800,同时要求它们用精简格式输出,这项改动让聚合阶段的 token 消耗降了大约 60%,最终答案质量几乎没有下降,因为聚合模型只需要有效信息,不需要看冗余铺陈。
延迟监控上,建议把 MOA 管线的各个阶段分别埋点,统计三个候选模型各自的耗时、聚合模型耗时、排队耗时。实际优化时,优先处理耗时最长的候选模型,而不是协调调度器的超时阈值。多数情况下,慢模型是某项特定能力很强的模型,把它替换成另一款能力接近但响应更快的模型,整体延迟降幅更明显。
| 排查方向 | 可能原因 | 处理建议 |
|---|---|---|
| 某个候选模型频繁超时 | 模型服务端负载高或上下文过大 | 缩短该模型的输入裁剪长度,或替换模型 |
| 聚合结果反而更差 | 聚合提示词没有要求取舍 | 强化提示词:必须剔除矛盾点并合并有效信息 |
| token 成本飙升 | 候选答案长度失控 | 压缩候选模型输出长度,精简格式 |
| 最终答案不一致波动大 | 采样温度过高 | 调低温度到 0.6 至 0.8 区间 |
5. 我实际用下来的几条经验
5.1 什么时候值得选 MOE 架构
MOE 不是万能解。从我的项目经验来看,以下情况选 MOE 收益明显:
- 需要覆盖的领域跨度大,比如要处理代码、医疗、金融、法律等多种文本,单模型难以在每个领域都做到顶尖。
- 推理预算相对稳定,但对模型能力上限有较高的要求,希望在同样算力下把容量做大。
- 训练数据体量足够大,MOE 的专家分化才真正有意义。数据量小时,专家之间学到的功能高度重叠,稀疏激活几乎没有优势。
如果任务范围很窄,比如只做特定格式的实体抽取,一个几百亿参数的密集模型可能就比一个参数量更大但激活受限的 MOE 模型更好用。密集模型在窄任务上通常收敛更快、推理更稳定、部署更简单。
5.2 比调参更值得先做的事:看路由分配统计
很多人在拿到 MOE 模型后第一反应是翻各种解码参数,四处调 temperature、top-p、repeat penalty,试图压榨效果。我的经验是,先看路由分配统计,再谈调参。
路由统计能反映模型的注意力分布状态。如果某一类特定输入总是走同一个专家,说明模型已经形成了针对该模式的专门通路,这时候强行调采样参数也许能获得表面上的随机性,但容易破坏原来的结构化能力。反过来,如果输入在不同专家之间跳来跳去,说明该类型输入本来就不是任何一个专家的强项,此时调整解码参数比调整专家选择更有效。
查看路由分配统计一般可以通过推理框架的日志开启专家激活跟踪功能,或者把模型中间层的门控输出导出做离线分析。这点投入非常值得,它帮你建立对整个模型行为的全局认识,而不是盲目凭感觉调参。
5.3 最后一条提醒:不要为了跟风强行做 MOA
MOA 听起来多模型协同很高级,实际上大部分业务场景根本不值得引入。如果单个模型已经能满足绝大多数需求,叠加 MOA 只会让系统复杂度上升,成本和延迟也随之增加。做技术选型,永远是从需求倒推实现方式,不是为了应用某个炫酷名词而强行设计功能。
我的参考标准很简单:当单个模型在目标评测集上准确率达到业务预期,或者业务对响应有高实时性要求时,坚决不上 MOA。只有当准确率明显不达标,且多模型协作能带来可量化的提升,再考虑构建聚合管线。真实业务里,决定系统上限的往往不是单个模型的技巧,而是对任务数据的理解和工程链路的基本功。
如果需要更进一步了解 MOE 的训练细节或 MOA 的聚合策略,可以先从各自的基准测试工具入手,搭一套小规模的评测集持续跟踪实验效果,用数据说话,而不是靠印象做决策。这也是我在多次模型切换中体会最深的一点。