[Bug]: `/v1/images/generations` requests refused by the router never reach failure callbacks (chat ones do)

当 LiteLLM Proxy 的 router 在调用任何 provider 之前就拒绝一个 /v1/images/generations 请求(例如部署超出 max_budget 、在 usage-based-routing-v2 下超出 rpm、或所有部署处于 cooldown)时,该请求不会

快速结论:当 LiteLLM Proxy 的 router 在调用任何 provider 之前就拒绝一个 /v1/images/generations 请求(例如部署超出 max_budget、在 usage-based-routing-v2 下超出 rpm、或所有部署处于 cooldown)时,该请求不会进入失败回调(CustomLogger.async_log_failure_event、Langfuse、OTel 都收不到),只有 async_post_call_failure_hook 能看到;同样是拒绝,/v1/chat/completions 和 /v1/images/edits 却能正常进入失败回调。优先排查图像生成端点是否缺少 logging 对象,以及回调是否只录入了 proxy 层异常。

适用环境:LiteLLM 1.105.1;Issue 报告者在 main 的 81a3802 上确认代码未变。操作系统、Python 版本、CUDA、显卡等环境在 Issue 中未给出。复现配置使用 usage-based-routing-v2 路由策略,并为部署设置 rpm: 1;无需真实 provider,api_base 指向关闭的回环端口 http://127.0.0.1:9/v1。

最快修复方案:升级到包含 PR #49349 修复的 LiteLLM 版本(该 PR 已合并)。Issue 未给出具体版本号,请以发布说明为准。

注意事项:Issue 只说明了修复已合并,未验证升级后的回调输出细节;若修复后仍收不到 async_log_failure_event,需要另行确认回调是否注册正确、以及被拒请求是否仍走图像生成端点自身的构建路径。

问题场景

用户运行 LiteLLM Proxy(版本 1.105.1),在配置中通过 model_list 定义图像模型 img(openai/gpt-image-1,rpm: 1)并启用 callbacks: custom_logger.proxy_handler_instance,同时设置 routing_strategy: usage-based-routing-v2。通过 CustomLogger 子类实现 async_log_failure_event 与 async_post_call_failure_hook 两个回调,然后连续向 /v1/images/generations 发请求触发 router 拒绝,观察日志输出。

报错原文

[Bug]: `/v1/images/generations` requests refused by the router never reach failure callbacks (chat ones do)

No deployments available - crossed budget…

No deployments available for selected model…

原因分析

根据 Issue 中的分析,最可能的原因是图像生成路径没有为 router 的拒绝日志准备 logging 对象:

Router.async_get_available_deployment(litellm/router.py)在其 except 分支中,会通过 request_kwargs["litellm_logging_obj"] 把拒绝记录到 Langfuse/OTel 等;当该键不存在时,它会跳过日志。而 /v1/chat/completions 与 /v1/images/edits 会经过 ProxyBaseLLMRequestProcessing.base_process_llm_request,在 pre-call 检查之前用 litellm.utils.function_setup(...) 创建这个 logging 对象,从而保证被拒请求也能被记录。

litellm/proxy/image_endpoints/endpoints.py 中的 image_generation 自行构造 data 并直接调用 route_request,没有创建 logging 对象,因此 router 的拒绝日志没有可用的分发通道。

此外,proxy 的 post_call_failure_hook 只记录 proxy 层错误(HTTPException、ProxyException、GuardrailRaisedException)。而 router 的拒绝表现为 ValueError(No deployments available - crossed budget…)或 litellm.RateLimitError(No deployments available for selected model…),因此这条路径也不会记录。

环境排查

  • 确认 LiteLLM 版本是否为 1.105.1 或 main 上 81a3802 附近、尚未包含 PR #49349 的版本。
  • 确认 litellm_settings.callbacks 指向的 CustomLogger 实例已正确加载,且 async_log_failure_event 已实现。
  • 确认路由策略为 usage-based-routing-v2,且相关部署设置了会触发拒绝的 rpm 或预算限制。
  • 确认 /v1/chat/completions 与 /v1/images/edits 在同样条件下是否能进入失败回调,用于对比定位。
  • Issue 未涉及 Python 版本、CUDA、PyTorch、显卡等依赖,这些项无需作为本问题的排查重点。

解决步骤

  1. 先按 Issue 的复现步骤确认现象:用 rpm: 1 的部署连续发送三次图像请求,再发送三次 chat 请求,观察 stdout 中是否只有 POST_CALL_FAILURE_HOOK 而没有图像请求的 FAILURE EVENT。
  2. 确认当前 LiteLLM 版本是否已包含 PR #49349 的修复;若未包含,升级到包含该修复的版本。
  3. 升级后重新执行同一复现流程,检查被拒绝的图像请求是否出现在 async_log_failure_event 的输出中。
  4. 若升级后仍缺失,可优先尝试在自定义回调侧做兜底:在 async_post_call_failure_hook 中记录 ValueError 和 litellm.RateLimitError,因为 Issue 已确认该钩子能够看到被拒的图像请求。

验证方法

按 Issue 的复现方式,在 proxy stdout 中观察三次图像请求。修复前通常只能看到 POST_CALL_FAILURE_HOOK 行;修复后应能看到图像请求对应的 FAILURE EVENT,且其 call_type 与异常信息符合预期。同时对比 chat 请求,两者的失败回调行为应保持一致。

参考来源

BerriAI/litellm #47061

修复 PR:BerriAI/litellm #49349(Issue 评论确认已合并)

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 32525

发表回复

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