[Bug]: Reservation reseed marks actual cost applied without incrementing it

该问题出现在 LiteLLM Proxy 的预算预留(budget reservation)对账流程中:当预留计数器缺失、非数值或被重置到无法对账的水平时,代码会从数据库重播种(reseed)计数器,但未把本次请求的实际费用补加进去,却仍把调整标记为已应用。优先排查计数器状态重置分支与 reseed

快速结论:该问题出现在 LiteLLM Proxy 的预算预留(budget reservation)对账流程中:当预留计数器缺失、非数值或被重置到无法对账的水平时,代码会从数据库重播种(reseed)计数器,但未把本次请求的实际费用补加进去,却仍把调整标记为已应用。优先排查计数器状态重置分支与 reseed 后的增量逻辑。

适用环境:Issue 已确认的环境为 LiteLLM v1.96.0(commit b1fd20f4cdc8f7a9b4e0c886a277465aedb05ec8),涉及 LiteLLM Proxy 与 Cost & Budgeting(花费计费/预算)功能。Issue 未提供操作系统、Python、CUDA、显卡等信息。

最快修复方案:升级到包含 #40841 修复的版本。该修复使成功 reseed 后,在写入 applied_adjustment 之前,先按本次请求的 settled actual cost 递增实时计数器(验证提交 de0b38920)。

注意事项:修复仅覆盖“reseed 成功”的路径;评论摘要指出,reseed=false 时仍会把调整标记为已应用并跳过计数器递增。也就是说,该问题属于部分修复,若 reseed 失败,本次请求的实际费用仍可能延迟进入实时预算校验,直到后续持久化刷新。是否完全覆盖缺失、重置、非数值计数器的全部场景,Issue 中未给出完整验证证据。

问题场景

在 LiteLLM Proxy 中调用带预算预留(budget reservation)的模型请求时,如果预留花费计数器消失、变为非数值,或数值被重置到低于对账所需值,_set_reserved_entry_actual_cost 会判定预留调整无法直接应用,并在 reseed_on_inconsistent=True 时调用 reseed_spend_counter_from_db,从数据库重播种计数器。

触发时机通常与花费写入异步 flush 有关:请求结束后的数据库实体花费更新先入队,而计数器对账随后进行,因此 reseed 可能读到本次请求之前的数据库“滞后下限”值。随后调用方把该 entry 的 counter key 放入 reserved_counter_keys,直接递增路径会跳过这个 key,导致本次请求的实际费用可能没有进入实时预算校验。

报错原文

[Bug]: Reservation reseed marks actual cost applied without incrementing it

{'reseed_calls': 1, 'increment_calls': 0, 'applied_adjustment': 0.3}

原因分析

可能原因与 Issue 描述一致:在计数器不一致分支重播种后,函数没有按本次请求的 actual cost 补加计数器,也没有重新应用预留差额,但仍然设置 entry["applied_adjustment"] 为目标值,表现得像对账已经成功。

由于数据库中的实体花费是异步 flush 的滞后下限,reseed 读到的值可能不包含当前请求;而调用方又因返回了 reserved_counter_keys 跳过该 key 的直接递增,最终当前请求的实际费用在实时预算中缺失,直到后续持久化刷新和再次 reseed 才可能补上。

环境排查

  • 确认 LiteLLM Proxy 版本是否为 v1.96.0 或包含相同问题逻辑的版本,并核对 commit。
  • 确认是否启用了预算预留(budget reservation)及 reseed_on_inconsistent=True 相关路径。
  • 确认花费追踪回调(proxy_track_cost_callback)是否按预期异步写入数据库。
  • 检查预留花费计数器是否发生过删除、被重置、被写成非数值,或低于对账所需值。
  • Issue 未提供 Python、CUDA、PyTorch、显卡等依赖版本,无需作为必查项。

解决步骤

  1. 使用 Issue 中的最小复现脚本验证当前行为:当 _counter_can_apply_adjustment 返回 False 时,观察 reseed_calls=1、increment_calls=0,但 applied_adjustment 已被写成目标值。
  2. 升级到包含 #40841 修复的版本,或在本地合入对应修复。修复逻辑为:_reseed_reserved_entry 在成功 reseed 后、写入 applied_adjustment 前,按实际费用递增计数器。
  3. 可优先尝试补充回归测试,覆盖 actual cost 大于、等于、小于预留额,以及计数器缺失、重置、非数值三类场景,确认不再出现“标记已应用但未递增”。
  4. 若升级后仍遇到 reseed=false 的路径,需继续关注该分支:评论摘要明确指出此情况仍标记调整已应用并跳过递增,可视为尚未完全修复的边界。

验证方法

重新运行 Issue 中的复现脚本,在成功 reseed 的路径下应能看到计数器按实际费用递增,且 applied_adjustment 的写入发生在递增之后;同时确认 increment_calls 不再为 0。结合预算约束的实际请求验证:请求结束后,本次实际费用应能进入实时预算校验,而不是等待下一次持久化 flush 或 reseed 才体现。

参考来源

BerriAI/litellm #35570

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 33292

发表回复

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