ValueError: gammavariate: alpha and beta must be > 0.0

该报错是 LiteLLM 自适应路由器(adaptive router)的持久化状态中出现了 alpha 或 beta 参数小于等于 0 的“毒化(poisoned)单元格”,导致采样时抛出 `ValueError: gammavariate: alpha and beta must be > 0.

快速结论:该报错是 LiteLLM 自适应路由器(adaptive router)的持久化状态中出现了 alpha 或 beta 参数小于等于 0 的“毒化(poisoned)单元格”,导致采样时抛出 `ValueError: gammavariate: alpha and beta must be > 0.0`,并使整个请求类型永久返回 HTTP 500。优先排查 `LiteLLM_AdaptiveRouterState` 表中是否存在非正参数的数据行。

适用环境:LiteLLM v1.93.0(Docker 镜像 `ghcr.io/berriai/litellm:v1.93.0`)中已确认;代码缺陷已排查至 1.96.0.dev2 仍存在。涉及 Python 3.13、LiteLLM Proxy 与自适应路由器(adaptive router)或启用了 adaptive 的 auto-router。

最快修复方案:暂无官方发布的一步修复方案。Issue 中验证过的临时缓解方案是:删除 `LiteLLM_AdaptiveRouterState` 表中参数异常的对应行,然后重启代理服务,即可恢复,但该问题会复发。

注意事项:建议修复方案的提出者明确说明,仅删除状态行不能根治;根因在于 create 分支和状态加载逻辑的代码缺陷,需等待上游 PR 修复,或优先避免将“零成本”模型(literal 0 或 null/未设置)作为自适应路由的候选模型。

问题场景

用户将模型组配置为 LiteLLM 原生的 adaptive router 后,对应请求类型的每次请求都会返回 HTTP 500(永久性故障)。故障在代理重启后不会自动恢复,在删除 `LiteLLM_AdaptiveRouterState` 表中的特定记录并重启后才可恢复,但该问题随后会再次出现。多位用户确认此问题同样会出现在 `complexity_router` 中启用 `adaptive: true` 的场景。

报错原文

gammavariate: alpha and beta must be > 0.0
ValueError: gammavariate: alpha and beta must be > 0.0
litellm.router.py::async_function_with_fallbacks() - Error occurred while trying to do fallbacks - gammavariate: alpha and beta must be > 0.0
litellm.proxy.proxy_server._handle_llm_api_exception(): Exception occured - gammavariate: alpha and beta must be > 0.0

原因分析

根因位于 `litellm/router_strategy/adaptive_router/update_queue.py`。Prisma upsert 的 update 分支正确使用了增量 `{“increment”: …}`,但 create 分支错误地把原始增量(delta)写成了绝对值:

"alpha": payload["delta_alpha"],
"beta": payload["delta_beta"]

`adaptive_router.py::_compute_bandit_delta` 可能合法地产生 `d_alpha = 0.0` 或 `d_beta = 0.0`。因此新行的首次写入就会因为缺少冷启动先验(`COLD_START_MASS = 10.0`)而持久化 `alpha=1.0, beta=0.0`。

代理下次启动时,`adaptive_router.py::load_state_from_db` 会直接用数据库中的 `alpha` 和 `beta` 构造 `BanditCell`,而没有任何校验,从而覆盖了 `initial_cell()` 本应生成的健康冷启动值。随后 `bandit.py:81` 调用 `random.betavariate(cell.alpha, cell.beta)`,CPython 的 betavariate 委托给 gammavariate,在任一参数 ≤ 0 时抛出 `ValueError`。

由于 `pick_best()` 会对该请求类型下所有符合条件的模型单元格进行采样,一个毒化单元格就足以导致该请求类型的所有请求失败(不仅限于本应路由到该模型的请求)。

可能的触发诱因(社区补充确认):

  • 模型被弃用或质量下降,使首轮增量出现 `0` 值(例如满意度增量为 0,导致多行 `alpha = 0`);
  • 将 null/零成本部署(未设置 `input_cost_per_token`/`output_cost_per_token`)或成本为 literal `0`(如真正的免费层模型)作为 adaptive-eligible 候选。

需注意:这些成本相关的线索可能只是表象而非根本原因。评论者后期也修正了自己的观点——在持有正常成本模型的情况下,只要新增行的首轮 delta 为 0,问题依然会出现,因此核心缺陷仍是 create 分支的写入逻辑。

环境排查

  • 确认 LiteLLM 版本(v1.93.0 已确认受影响;1.93.1、1.94.1、1.95.0、1.96.0.dev2 中相关代码完全相同,未修复)。
  • 检查数据库(Prisma 对应的 PostgreSQL 等)中 `LiteLLM_AdaptiveRouterState` 表的记录,查找 `alpha <= 0` 或 `beta <= 0` 的行。
  • 审核 adaptive router 候选池中是否有成本未设置(null 或缺失)或成本为 0 的模型,例如输入/输出 per-token 成本设为 0 的模型。
  • 确认故障表现是否呈“按层(tier)间歇性”——只有包含毒化单元格的层会报错,健康的层正常工作。

解决步骤

  1. 临时恢复(已验证,会复发):

    从 `LiteLLM_AdaptiveRouterState` 表中删除导致问题的行,例如:

    router_name      | request_type | model_name    | alpha | beta | total_samples
    sovereign-router | general      | gpt-oss-cloud |     1 |    0 |             1

    删除该行后重启 LiteLLM 代理服务,使系统基于 `initial_cell()` 重新生成健康状态。

  2. 规避策略(可优先尝试):

    如果根因在于零成本或未设置成本的模型,请勿将该模型作为 adaptive-eligible 候选。应将其保持为仅能通过具体模型名或 `keyword_tier_rules` 规则访问,而不是放进 Thompson 采样的池子中。
  3. 规避策略(如为 literal 0 成本模型):

    将成本 0 替换为一个极小的非零占位值(如 `1e-9`),不要直接设为 0。此操作经验证可立即抑制当前的报错,但并不可靠——如果新增行的首轮增量为 0,即使成本正常仍会发生问题。
  4. 跟踪上游修复:

    最可靠的修复需要等待上游更新 `update_queue.py`(在 create 分支中先填充冷启动先验)或在 `load_state_from_db` / `BanditCell` 中校验读取值,加载时拒绝非正参数并回退至 `initial_cell()`。可关注该 Issue 的 PR 动态。

验证方法

按上述步骤处理后,对该请求类型发起多次连续调用,若不再出现 HTTP 500 且日志中不再出现 “gammavariate: alpha and beta must be > 0.0” 及 “Error occurred while trying to do fallbacks” 堆栈,代表恢复。此外可查询 `LiteLLM_AdaptiveRouterState` 表确认 `alpha` 和 `beta` 均为正数。

参考来源

BerriAI/litellm #35590

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 22022

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注