刚接触 LoRA 和 MoE 路由的人,往往先被一个问题卡住:手头已经有好几个训练好的 LoRA 专家,系统不知道当前请求该交给谁。于是大家会想到让路由器看不确定性,也就是“哪个模型更犹豫就避开哪个”。但这个思路往往只能帮你排除错误答案,并不能告诉你换了专家以后,结果能提升多少。所以这里想展开的核心观点是:在做混合 LoRA 专家的路由时,不确定性,也就是 entropy、置信度、多采样不一致性这些信号,只是一个参考维度;真正做决定时应该尽量去估计信息价值,也就是“把请求切换到另一个 LoRA 专家之后,比当前决策多出来的收益”。
这套思路特别适合已经在做 LoRA 微调、并且手上攒了不止一个领域 LoRA 的团队。如果你只是在单模型上做一次性微调,路由问题离你很远;但一旦你想让代码 LoRA、SQL LoRA、客服 LoRA 同时服务于同一个入口,路由就变成模型之外最核心的系统问题。
1. LoRA 专家一多,路由很容易成为系统瓶颈
1.1 你迟早会碰到“几个 LoRA 同时在线”的场景
在 LoRA 微调落地得很顺的团队里,模型的扩散方式非常快:有人训练了面向代码补全的 LoRA,有人训练了面向数据库 SQL 优化的 LoRA,还有人训练了面向客服话术的 LoRA。单独部署每个 LoRA,或者按用户手动选择,都能跑;但一旦你希望多个 LoRA 支撑同一个入口,就不得不面对路由问题。所谓路由,就是在用户请求进来后,判断到底应该由哪个专家处理,或者哪些专家并行处理后再选出一个最终结果。
很多人在这个阶段会误以为路由问题等价于分类问题:给每个请求打一个标签,然后调用对应的 LoRA。但实际场景往往没有干净标签,也没有唯一正确答案。同一个输入放在“生活常识” LoRA 下也能答,放在“医疗健康” LoRA 下也能答,只是质量、风格、风险程度不同。这时候需要的不再是一个硬分类器,而是一个能够权衡质量的决策器。
1.2 只看不确定性,最典型的问题是什么
如果你使用不确定性路由,通常会计算当前模型或候选专家在输出上的置信度,例如:
- softmax 概率最大的那个值;
- logits 之间的差值,或置信区间宽度;
- 多次随机采样后答案的语义一致性;
- 多个 LoRA 输出之间的分歧程度。
这些指标都能反映“当前模型拿不准”,但它们都缺少一个关键维度:候选专家本身是否真的更好。一个很现实的情况是:当前 LoRA 很犹豫,说明它不适合这条输入,但另一个 LoRA 可能同样差,甚至更差。不确定性只能告诉你“这里有问题”,但不能告诉你“换谁来解决这个问题”。在决策论里,这条额外的判断就是信息价值。
我见过不少把 top k 个不确定样本交给所有专家并行生成、最后再用一个打分模型挑选的工程方案。它能解决问题,但成本容易被忽略。尤其是候选 LoRA 数量达到十几个时,每个请求都要跑十几遍生成,延迟、显存、token 消耗都会快速上涨。更稳的做法是先用一个轻量路由器计算每个候选专家的预期收益,只调动收益增量最大的一个或两个专家。
1.3 路由需要回答的其实是两个问题
第一,当前默认方案在这个输入上有多好;第二,换成候选专家之后,又会变好多少。第一个问题可以用历史平均分、当前基础模型的置信度、甚至是规则默认值来估计;第二个问题是路由的核心,它不能只看不确定性的绝对值,而要结合该专家在这个输入类别上的历史表现,以及当前输入和该专家训练分布的接近程度。所以标题里说的“不确定性不够”,本质上是在提醒你:路由指标应该和最终业务指标挂钩。如果你的业务指标是答案采纳率、任务完成率、回答正确率,那路由器的打分就应该逼近这个指标,而不是只逼近“模型自己觉得有多自信”。
2. 信息价值路由:从“我慌不慌”到“换了值不值”
2.1 先把路由当成一个决策问题
把决策拆成三步会很清楚:
- 你有一个当前策略,它可能是“默认模型直接回答”,也可能是“按关键词调度到某个 LoRA”。
- 你有一组候选策略,也就是切换到的 LoRA 专家 k。
- 你有一个收益函数,用来衡量某个专家在当前输入 x 上的输出质量,这个函数可以是评分模型、人工标注、任务成功率等。
路由问题就变成了:在当前已知信息下,哪个候选策略的期望收益最高,并且它的期望收益显著高于当前策略。信息价值这个概念在这里的含义是:如果你获取更多信息后再做选择,选择质量能提升多少。放到混合 LoRA 专家的场景里,多获取的信息可能是某个专家头部的 logits、某个隐藏层向量、或者干脆是把请求先让默认模型生成一小段草稿再打分。
2.2 不确定性和信息价值在计算上的差异
不确定性通常是一个标量,描述分布本身的弥散程度。比如熵越高,表示模型输出概率越平均,这时模型没有明显偏好。信息价值则不一样,它描述的是“采取某个行动之后收益的期望提升”。
举一个简化版的数值例子。现在有两个候选专家 A 和 B:
- A 在编程类问题上的历史评分是 0.9,但它在当前输入上的不确定性很高。
- B 在编程类问题上的历史评分是 0.6,但它在当前输入上的不确定性很低。
如果只看不确定性,你可能会觉得 B 更稳定,所以选 B。但如果你估算的是“选择某个专家后期望能拿到的收益”,A 可能仍然是 0.9 附近,B 只有 0.6,最终应该选 A。当然,现实比这个例子复杂,因为历史评分不一定能迁移到当前输入,还需要结合相似度、最近一次任务表现等特征,但核心区别已经清楚了:不确定性告诉你的东西,不直接等于收益。
| 路由方式 | 核心判断依据 | 优点 | 容易出现的问题 |
|---|---|---|---|
| 规则路由 | 关键词、来源、用户标签 | 可控、可解释 | 泛化差,新输入没法覆盖 |
| 向量检索路由 | 输入 embedding 和专家描述相似度 | 简单,适合冷启动 | 相似不等于任务效果更好 |
| 不确定性路由 | 熵、置信度、多采样不一致性 | 能识别“边界输入” | 只提示有问题,不提示谁更好 |
| 信息价值路由 | 预期收益提升、切换代价、确定性收益 | 与业务指标对齐 | 需要构造收益数据,训练成本高 |
这四种方式不是互斥的。工程里往往先用规则兜底,再用向量检索做粗筛,最后用一个小模型输出每个候选 LoRA 的预期质量分。信息价值路由更像是对最后一层决策的升级。
2.3 不搞完整贝叶斯框架,也能近似计算信息价值
完整的信息价值计算非常重,因为你需要模拟“获取所有可能信息后的所有可能决策”,这对在线推理不现实。实践中可以用更简单的代理:训练一个打分网络,输入是当前请求的特征和某个候选专家的描述,输出是该专家在这个请求上的预期质量分;然后把当前默认方案的质量分也估计出来。当某个候选专家的预期质量分明显高于默认方案,且高于当前不确定性的惩罚项时,才触发切换。你也可以把“切换成本”设计成一个参数,例如额外增加的延迟、token 消耗、失败率,最终路由分数就是收益减去成本。
我在实际项目里会更倾向于做一个回归任务,而不是分类任务。分类任务通常问“这个请求属于哪个 LoRA”,但一个请求可能同时属于多个 LoRA,也可能哪个都不属于。回归任务则问“如果让第 k 个 LoRA 处理,质量大概能到多少”,这样更容易支持 top_k 选择和多专家投票。
3. 落地实现:路由器的输入、训练数据和推理流程
3.1 先解决“什么是好输出”,再谈训练路由器
很多人在训练路由器之前没有准备专家质量分,这是一个容易踩的坑。路由器要预测的是“这个专家在这个输入上能不能拿高分”,所以手里必须有一批已经标好分数的数据。
构造这套数据的大致流程:
- 准备 2000 到 10000 条有代表性的输入,尽量覆盖上线后可能遇到的任务类型、语言、长度和格式。
- 每一个输入都喂给所有候选 LoRA,生成答案,或者至少喂给候选 LoRA 的一个子集。
- 用一个统一评分器给答案打分。评分器可以是一个更强的模型、一个奖励模型,也可以是程序化规则加人工抽检。
- 把输入特征、候选 LoRA 标识、评分结果整理成训练集。
这一步特别要注意两件事。第一,所有候选 LoRA 都要用同一套评分标准,不然路由会偏向评分更宽松的专家。第二,不要只用“那条输入最终选了谁”来作为标签,因为最终的硬选择会丢掉大量信息;更好的形式是保留每个专家在这个输入上的完整得分向量。
3.2 输入特征别只拿 logits
我建议把特征分成三组:
- 输入侧特征:提示文本 embedding、输入长度、语言、是否多轮、是否包含代码块或公式等。
- 模型侧特征:基础模型最后一层隐藏状态的 pooling 结果、默认模型在该输入上的置信度或熵。
- 专家侧特征:候选 LoRA 的描述 embedding、历史平均表现、最近 N 条任务的成功率、当前输入与该专家训练分布的相似度。
很多实现只用了输入 embedding 和专家 embedding 做相似度匹配,效果往往不够好,因为相似度高不代表该专家的生成能力强。把模型侧特征和专家侧的历史统计加进去之后,路由会更接近“哪个专家更有可能成功”,而不是“哪个专家看起来相关”。
如果你担心特征太多导致延迟增加,可以让特征计算走一个小模型,或者缓存专家侧特征。每个请求真正需要动态计算的,通常只有输入侧的 embedding 和一个轻量分类器。
3.3 推理链路可以参考这个顺序
在线推理时,我一般按下面这个顺序接:
- 用户请求进来,先走规则路由。如果命中强规则,比如请求明确带有“翻译为英文”,就直接走对应 LoRA。
- 规则没有命中时,计算输入 embedding,做一次候选专家粗筛,过滤掉明显无关的 LoRA,把候选集缩小到 3 到 5 个。
- 对留下来的候选专家,让路由打分网络逐个输出预期质量分。
- 把当前默认方案的质量分也估算出来,或者用一个兜底策略。
- 如果最高预期质量分超过兜底分数,并且差额大于阈值,就切换到对应专家。
- 把所有路由日志写入存储,供后续离线评估和重新训练。
这里每一步都不是必须的。如果候选 LoRA 只有 3 个,第 2 步可以省略。如果打分网络的计算量已经很小,第 3 步和第 4 步可以合并。关键是形成一条从“规则到模型再到回退”的链路,而不是让路由器成为新的单点。
3.4 一个小型路由模块的示意结构
下面这个代码块只是用来说明流程,不是某个具体框架的完整实现。真实落地时,你需要根据自己的推理后端调整。
# 示意:候选专家质量分路由 def route_request(request, cand_adapters, router, default_score, threshold=0.05): feats = extract_features(request) scores = router.predict(feats, cand_adapters) base_score = default_score(feats) best_name = None best_score = base_score for name, score in scores.items(): if score > best_score and score - base_score > threshold: best_name = name best_score = score if best_name is None: return generate_with_default(request) return generate_with_adapter(request, best_name)这个逻辑的核心是“只有当候选专家预期收益明显高于默认方案时才切换”。threshold 控制路由的保守程度。调小 threshold,路由器会变得激进,也可能把请求切给一个表面分高但实际不稳定的专家。调大 threshold,路由更稳,但会错过一些收益较高的切换。
4. 影响稳定性和成本的几个关键参数
4.1 top_k 和阈值决定成本和质量的平衡
top_k 表示最终并行激活多少个候选专家。top_k=1 最省资源,但一旦路由分错误,就没有回旋余地。top_k=2 到 3 可以让多个专家并行生成,再让后端统一打分选优,代价是 token 消耗和显存占用明显上升。如果你刚上线,我建议先跑 top_k=1,只做“切换专家”,不要同时跑多个专家。等日志积累足够多,证明路由本身准确率不错后,再尝试 top_k=2。
阈值没有通用推荐值,因为它取决于你用的评分器范围。如果评分器范围是 0 到 1,0.05 到 0.1 是一个可以接受的起点;如果评分器是 1 到 5 分,阈值可能要放到 0.3 到 0.5。更稳的做法是:先用一批离线数据画出“阈值-准确率-成本”曲线,再选一个业务上可接受的平衡点。
4.2 每个请求路由一次,还是每个 token 路由一次
LoRA 专家路由有两种常见频率:
- 请求级路由:一个对话或一个请求只路由一次,所有生成过程都使用同一个 LoRA。这种方式更稳定,适合客服、问答、代码生成等场景。
- token 级路由:生成过程中每一步都可能切换到不同 LoRA。这种方式需要更复杂的实现,而且切换上下文很可能引入不稳定输出。
如果你在做细粒度 MoE,或者希望在一个 LoRA 里同时容纳多种能力,token 级路由是值得研究的方向。但对大多数生产系统,我建议先做请求级路由。主要原因不是 token 级做不到,而是排查复杂:一旦输出质量波动,你很难判断是路由评错了,还是中途切换导致上下文破坏。请求级路由至少能让问题边界清晰。
4.3 显存和延迟的真实边界
LoRA 微调时大家常问“需要多少显存”,到了推理路由阶段,反而容易忽略多个 LoRA 同时挂载的代价。单个 LoRA 权重文件通常不大,可能只有几十 MB,也可能到几百 MB,但要让多个 LoRA 处于可用状态,不只是权重加载,还会影响前向计算路径、缓存空间和显存碎片。
低配置机器也能把混合 LoRA 专家系统跑起来,但需要把候选数、上下文长度、batch size 一起调小。我见过有人在 8GB 显存的环境里挂 5 个 7B 模型的 LoRA,单请求还能跑,并发一上来就频繁 OOM。原因是路由本身需要一次额外的模型前向提取特征,候选 LoRA 在切换时又要重新加载,峰值显存比预想的更高。
更合理的做法是:
- 单请求测试时,观察切换专家时的峰值显存和第一次生成延迟。
- 批量压力测试时,观察 p99 延迟和 OOM 出现次数。
- 如果延迟超标,优先减少候选专家数量,而不是单独优化某个专家。
5. 我实测中经常遇到的问题和排查顺序
5.1 看起来像路由问题,实际是特征对齐问题
路由结果的波动,很多时候不是因为打分网络不够强,而是因为特征没有对齐。最典型的是输入长度不一致问题:训练时用 512 token 的截断长度,上线时请求长度涨到 2000 token,模型侧的 embedding 语义已经发生变化。另一个问题是多轮对话没有把历史消息拼进去,导致路由只看到了最后一句话,自然很难判断领域。
遇到路由结果不理想时,不要急着换模型,先检查:
- 输入是否走了和训练时相同的前处理流程;
- 是否所有候选专家都使用了同一套 tokenizer;
- 特征抓的是哪一层的 hidden state,层数变了,分布也会有差异;
- 路由服务器和推理服务器是否版本一致。
5.2 评分器不一致,训练数据再干净也没用
如果你用 A 模型的输出作为 B 模型的评分器,而 A 模型明显偏好长答案,那么所有长答案都会被推到高分,路由器就会学出一个“谁生成更长就选谁”的偏差。这未必是你想要的业务目标。解决方法是:先在小样本上做一次人工校验,确认评分器给出的分数和人工判断方向一致;然后固定评分器版本,不要频繁更换。
对于业务指标比较明确的场景,完全可以不用模型评分器。比如代码补全任务,可以直接用测试用例是否通过;翻译任务,可以用双语评测指标;客服场景,可以用用户是否点击、是否继续追问、工单是否关闭等行为数据。越接近真实业务标签,路由器的预测就越有用。
5.3 我建议的排查顺序
如果上线后路由表现不好,按这个顺序排查:
- 先看路由日志,确认每条请求到底被分给了哪个专家,以及分数是多少。
- 再看输入,确认特征提取、tokenizer、上下文长度都没有偏离训练配置。
- 再看训练数据,确认每个专家在训练集里的样本数量不要太悬殊。某个专家样本占 80% 时,路由器很容易变成“万事不决选 A”。
- 再看阈值,确认不是切换太频繁导致输出抖动。
- 最后看评分器,确认训练时的评分标准和线上评估标准一致。
这个顺序能帮你把问题归因到数据、特征、参数还是评分器,避免一上来就重新训练一个大模型。
5.4 一张简单的排查对照表
| 现象 | 优先排查位置 | 常见原因 |
|---|---|---|
| 路由器永远选同一个 LoRA | 训练数据分布、评分器偏差 | 某个专家样本过多或评分被抬高 |
| 在线结果不如离线评测 | 特征一致性、阈值 | 特征没对齐,或者阈值选得不合适 |
| 切换后答案更差 | 评分器、专家本身 | 评分器和真实业务不一致,或该专家只是历史平均分高但当前输入不匹配 |
| 显存峰值异常 | 候选数、batch、路由前向 | 额外前向和多个 LoRA 同时挂载导致峰值上涨 |
| 延迟大幅上升 | 候选数、top_k、并行生成 | 触发了过多专家并行生成 |
6. 先跑通再优化的建议路线
6.1 从一个最小的硬路由开始
不要一上来就构建完整的信息价值路由系统。最稳妥的路线是:
- 选 3 到 5 个差异明显的 LoRA,比如代码、SQL、客服,或者你业务中真正高频的三个领域。
- 先用规则或向量检索做一个硬路由,记录每条请求被分配给了谁,同时让所有候选专家都生成答案,做离线对比。
- 累积几千条带评分的数据后,再训练一个简单的打分网络,替换掉硬路由。
- 上线时保留所有日志,持续对比路由策略和兜底策略的表现。
这样做的原因很简单:信息价值路由需要的数据、特征、评分器都不是一次能建好的,先跑通一个可解释的硬路由,你会更容易看清问题出在哪个环节。而且硬路由可以在失败时回退,不会让系统陷入“完全依赖一个黑盒路由器”的状态。
6.2 给新手的预期管理
信息价值路由不是银弹。它适合的场景是:你确实有多个质量不错的 LoRA,并且投入了时间和资源去准备质量分数据。如果只是学习,或者只有两个 LoRA,用固定规则甚至手动选择反而更省事。默认配置下,先用一个轻量分类器粗筛,再用阈值控制切换,比强行套一个复杂的决策框架要靠谱得多。
值得再强调的是,路由器的上限不会超过候选专家的上限。如果所有 LoRA 在该输入上都表现不好,再精确的路由也只能选出一个“最不差”的答案。所以我更建议把注意力同时放在两个方向:底座的通用能力、候选 LoRA 的场景覆盖度。两者都做实了,路由才会成为锦上添花的一环。
6.3 真正落地时该盯住的三个长期事项
一是日志。每一条请求的路由分数、候选专家分数、最终选择、线上反馈都要尽量留存。没有日志,你就没法评估路由器的改进效果。
二是定期重新训练。用户输入分布会变化,LoRA 本身也可能被更新,路由器如果一直用旧数据,会慢慢失真。
三是保留兜底策略。无论路由表现得多么好,都要有一个不经过候选专家直接回答的默认路径。这个兜底不仅能处理评分器失效的异常,也能在路由器的分数差异不显著时避免无谓切换。
踩过几次之后我的感受是,混合 LoRA 专家的重心往往不是专家模型训练,而是路由系统的数据闭环。你能不能让路由器知道自己选得好不好,比选一个更复杂的模型更关键。先把日志和评分标准做好,再把信息价值路由的路一步一步走出来。