读书笔记 · 约 13,234 字 · 预计推送 2 部分

模型路由与 Fallback:多模型降级、重试、超时和质量成本权衡 —— 主题精读 未开始

目录

题记与说明


0. 总览:把主题拆成两个正交问题

精读后我认为"模型路由与 fallback"实际是两个互补的层次,文献也明显分两派:

层次决策时机解决什么代表来源
路由(routing / cascade)调用前这个请求值得花多少钱?→ 质量-成本帕累托前沿FrugalGPT、RouteLLM
兜底(fallback / retry / timeout)调用中/失败后请求失败了怎么办?→ 可用性与延迟LiteLLM、AWS 弹性模式、learnwithparam

把两者混为一谈会出错:路由是省钱的统计问题(需要标注数据训练),fallback 是保命的工程问题(需要错误分类与预算控制)。成熟系统两者都要:路由层负责常态下的成本效率,fallback 链负责异常时的可用性底线。


1. 核心问题

商业背景:FrugalGPT 开篇指出,付费 LLM API(GPT-4、ChatGPT、J1-Jumbo 等)定价差异高达两个数量级,而"using LLMs on large collections of queries and text can be expensive"。作者据此提出:"we outline and discuss three types of strategies that users can exploit to reduce the inference cost associated with using LLMs"——prompt adaptation、LLM approximation、LLM cascade。

核心问题可以精确表述为:并非每个查询都需要最强(最贵)的模型,但事先无法确定哪些查询不需要。于是问题变成:

  1. 统计问题:如何为每个 query 动态选择模型,使期望质量 ≥ 约束下期望成本最小(或等价地在成本预算下最大化质量)?
  2. 工程问题:无论路由到哪个模型,API 都会失败(429 限流、5xx、超时、上下文超限、内容策略拒绝),如何在失败后既不雪崩(retry storm)也不静默降质?

RouteLLM 把问题陈述得更直白:目标是在 strong model(GPT-4)与 weak model(Mixtral 8x7B)之间路由,"all queries that can be handled by weaker models should be routed to these models, with all other queries routed to stronger models",即"minimize cost while maintaining response quality"。


2. 主要主张

  1. FrugalGPT 的头条主张(摘要原文):"can match the performance of the best individual LLM (e.g. GPT-4) with up to 98% cost reduction or improve the accuracy over GPT-4 by 4% with the same cost."
  2. RouteLLM 的头条主张(博客原文):"cost reductions of over 85% on MT Bench, 45% on MMLU, and 35% on GSM8K" vs 纯 GPT-4,"while still achieving 95% of GPT-4's performance";且比 Martian、Unify AI 等商业路由器"achieving the same performance as these commercial routers while being over 40% cheaper"。
  3. 重试的第一原则(learnwithparam 原文):"Retry errors that can succeed on the next attempt without any change on your side." —— 不能在下一次尝试中凭空成功的错误(401、400、spend-cap 429、内容策略拒绝)一律立即抛出。
  4. 降级链设计原则(AWS 文章原文):"keep the fallback simpler and more robust than the primary." 兜底路径必须比主路径更简单、更健壮。
  5. 流式的最大陷阱(learnwithparam 原文):"A stream that fails after the first tokens is not covered by SDK retries." SDK 的自动重试只保护首字节之前;流中断后要靠应用层决策(重开/续写/带部分输出降级)。
  6. 重试叠加陷阱(learnwithparam 原文):"Four attempts in your layer times three in the SDK is twelve calls for one request." 多层重试是组合爆炸,SRE 语境下会放大故障。

3. 方法(技术路线深读)

3.1 FrugalGPT:质量门控的 LLM 级联(cascade)

机制:原文定义"LLM cascade sends a query to a list of LLM APIs sequentially. If one LLM API's response is reliable, then its response is returned, and no further LLMs in the list are needed." 两个核心组件:

优化:学习 L 和 τ 被表述为约束优化(预算 b 下最大化期望奖励),"inherently a mixed-integer optimization and thus computationally expensive to solve"。作者的近似方法:剪枝(忽略 LLM 间答案分歧低的组合)+ 少量样本插值。

学到的具体级联(HEADLINES 数据集、预算 $6.5):

GPT-J → 若 score > 0.96 接受
否则 J1-L → 若 score > 0.37 接受
否则 GPT-4

注意阈值不等距:第一级极保守(0.96),意味着便宜的 GPT-J 只在几乎确定对时才被采用;中间级放宽到 0.37。

互补性发现(这是 cascade 有效的根本原因):便宜模型能修正贵模型的错误——"GPT-4 errs on ~6% of cases where GPT-J, J1-L, or GPT-C are right; on COQA, 13% of points where GPT-4 fails are answered correctly by GPT-3"。这不是"弱模型凑合用",而是模型多样性本身产生信息增益。

3.2 RouteLLM:偏好数据训练的前置路由器

3.3 LiteLLM:网关层的 fallback 分类学

LiteLLM 把 fallback 按失败原因分类,这一点在工程上很重要——不同失败需要不同的兜底目标:

3.4 重试工程:错误分类 + full jitter + 预算

错误分类表(learnwithparam,与 AWS 分类一致):

可重试(transient)不可重试(deterministic,立即抛)
连接错误、客户端超时400(含上下文过长)、401、403、404、413、422
408、409429 由 spend cap / 配额耗尽引起(Anthropic 的 "enforced_spend_limit_reached",无 Retry-After 头)
429 带 Retry-After 的普通限流同一 prompt 的内容策略拒绝
500/502/503/504、529 (Anthropic overloaded)

退避公式(AWS 原文):delay = random(0, 1) × min(cap, base_delay × 2^attempt),单次等待上限 20s;瞬时错误 base 为"tens of milliseconds",限流错误 base "around a second"。jitter 缺失的后果(引 AWS/Brooker 分析):无 jitter "did the most work and took the longest"——重试波同步造成 retry storm。

重试预算(两层):

熔断器(AWS 示例参数):failure_threshold=5、recovery_timeout=20.0s、半开态放行 1 次试探;冷却时间建议"seconds to low tens of seconds"起步。注意 AWS 强调 SDK 的 retry quota 是每客户端的窄熔断,不能替代应用层熔断。

Agent 场景特有规则(learnwithparam):只重试失败的那一步;checkpoint 已成功的工具结果;有副作用的工具必须幂等(run ID + step number 作幂等键);"never re-run a tool with side effects because a later model call failed";持续失败开熔断并降级。

3.5 超时:三层预算 + 流式语义

3.6 优雅降级链(graceful degradation)

AWS 给出兜底链的完整排序(从优到劣):

  1. Fallback model:备用模型,或同家族跨 Region 部署;
  2. Cached response:精确或语义缓存,命中即返回;
  3. Non-generative floor(非生成式保底):"a canned answer, results from a plain keyword search over your knowledge base, a template, or a clear message that the AI feature is temporarily degraded."

两条告诫:降级必须可观测(不能静默);兜底路径必须比主路径更简单。


4. 数据与证据

FrugalGPT(Table 3,达到最佳单模型精度的成本节省):

数据集最佳单模型其成本FrugalGPT 成本节省
HEADLINES(金融新闻涨跌分类,10k 样本)GPT-4$33.1$0.698.3%
OVERRULING(法律句子判定,2.4k)GPT-4$9.7$2.673.3%
COQA(阅读理解,8k)GPT-3$72.5$29.659.2%

其余:节省范围 50%–98%;等成本下最多 ~5% 精度增益;HEADLINES 案例研究"its cost is reduced by 80%, while the accuracy is even 1.5% higher"。级联长度固定为 3("cascade length of 3, as this simplifies the optimization space and already demonstrates good results")。涉及 12 个 API(OpenAI、AI21、Cohere、ForeFrontAI、Textsynth)。

RouteLLM:MT Bench 85%+/MMLU 45%/GSM8K 35% 成本下降、保持 95% GPT-4 质量;比商业路由器便宜 40%+;增强数据仅 ~1500 条(<2% 训练集)就把 MMLU 上最佳 router 的 GPT-4 调用需求降到 54%。

反例(同样是证据):RouteLLM 在 MMLU 上,只用 Arena 数据训练时"all routers perform poorly at a near-random level"——归因于 MMLU 问题分布外。偏好数据不是免费的泛化。

工程数字:AWS token bucket 500 容量 / 瞬时重试 5→14 token;熔断 5 次失败 / 20s 冷却 / 半开 1 试探;交互请求 3–4 attempts + 60s 总预算;retry 占比 10% 预算线。

证据充分性评估:


5. 结论

  1. 质量-成本权衡可以显式参数化:FrugalGPT 的阈值序列 τ 和 RouteLLM 的 router-mf-0.11593 都是"把权衡变成旋钮"。与其争论"用哪个模型",不如定义"愿意为 p95 质量付多少钱",再让路由器在曲线上选点。
  2. 级联有效的根本原因是模型多样性:便宜模型在贵模型错的 6–13% 样本上是对的。这说明 fallback 的上限不只是"保可用",配质量门控后还能提质量。
  3. 可靠性工程的主轴是分类与预算:先分类错误(可重试/不可重试/换目标重试),再给每一层预算(重试次数、退避上限、总时长、token bucket、熔断阈值),最后定义降级底线(fallback 模型 → 缓存 → 非生成式保底)。没有预算的重试等于把故障放大器写进系统。
  4. 流式改变了超时与重试的语义:read timeout 作用于 chunk 间,SDK 重试不覆盖 mid-stream 失败——生产 LLM 应用里一半以上的"可靠性 bug"可能出在这里。
  5. 路由省成本,fallback 保可用,两者都依赖可观测性:没有 attempt/success ratio、fallback 命中率、路由强模型占比这些指标,两个层次的旋钮都无法校准。

6. 局限

作者承认的局限:

我推断的局限(标注为推断):


7. 对我的启发

  1. 网关集中化,应用层归零重试:参考 LiteLLM 的分层(组内重试 → 跨组 fallback → 熔断冷却),把 retry/fallback/timeout 收敛到一个网关层;应用 SDK 设 max_retries=0,杜绝"4×3=12 次调用"的叠加(learnwithparam 明确警告的坑)。
  2. 先写错误分类表,再写重试代码:把 429-with/without-Retry-After、spend-cap 429、内容策略拒绝、上下文超限逐一映射到"重试 / 换目标 / 立即抛"。这是整个可靠性模块的第一张表,比任何退避参数都优先。
  3. 成本旋钮显式化并写进配置:像 RouteLLM 那样用 strong-model-pct 校准阈值,而不是在代码里 hardcode "都用最强模型"或"都用便宜模型"。省钱的上限(85%+)来自差异化,不是一刀切。
  4. Agent 工作流的幂等纪律:本机 nightshift 这类多步工作流应 checkpoint 每步结果、只重试失败步骤、给有副作用的步骤加幂等键——这直接适用于我自己的编排系统。
  5. 流式必须自己兜底:任何 SSE/流式集成都要回答"第 37 个 chunk 后断了怎么办":buffer?续写?部分输出+显式降级标记?SDK 不会替你回答。
  6. 监控三件套:retry 占比(>10% 触发预算熔断)、fallback 命中率(降质可见化)、路由强模型占比(成本漂移警报)。AWS 的 "Retry needed but retry quota reached" 日志行是个好范本——预算触发必须留痕。
  7. 给降级链一个非生成式保底:缓存、关键词检索、模板、明确声明"功能暂时降级"。AI 功能的可用性底线不该是"再调一次大模型"。

附:关键原文引述索引

← 资料库今日播报 →