[Bug]: Bedrock count_tokens returns 400 for cross-region inference-profile models — prefix stripped before request

当 LiteLLM 在 AWS Bedrock 上通过跨区域推理配置文件(inference profile,如 global. / eu. / us. 前缀或 inference-profile ARN)调用 Claude 模型时, POST /v1/messages/count_tokens 会

快速结论:当 LiteLLM 在 AWS Bedrock 上通过跨区域推理配置文件(inference profile,如 global. / eu. / us. 前缀或 inference-profile ARN)调用 Claude 模型时,POST /v1/messages/count_tokens 会在构造 URL 时把该前缀剥掉,导致 Bedrock 收到裸基础模型 ID 并返回 400。优先排查 count-tokens 路径构造出的 modelId 是否与 chat/Converse 路径一致。

适用环境:LiteLLM Python SDK / Proxy;Bedrock 区域为 eu-central-1(后续评论中 us-west-2 也复现);模型为仅支持推理配置文件的 Claude 模型。Issue 中确认过的 LiteLLM 版本:v1.83.14、v1.89.2、v1.94.1;离线复现基于 main 的 1bafdb3c。未提供操作系统、Python、CUDA、显卡信息。

最快修复方案:暂无确认的一步修复方案。截止 Issue 关闭时,两个候选修复 PR(#32692、#34312)当时的评论状态均为未合并;其中 #32692 被评论者评估为改动面更安全的形态,可优先尝试。

注意事项:若采用本地 fallback,请求不会失败,但 count-tokens 仍会先发出一次无效的 Bedrock 请求,并产生 WARNING 日志;返回的 token 数来自本地 tokenizer,可能与 Bedrock 口径存在差异。任何绕过前缀剥离的本地修改都需自行验证对 us-east-1/anthropic.claude-v2 这类内嵌区域写法及 ARN 形式模型的影响。

问题场景

在 LiteLLM 中配置 Bedrock 跨区域推理配置文件模型(例如 bedrock/global.anthropic.claude-opus-4-8),并通过 Anthropic 兼容接口(Claude Code 或指向 LiteLLM proxy 的 Anthropic SDK)发送 POST /v1/messages/count_tokens 统计 token。同一模型的 chat / Converse 补全调用正常,只有 count_tokens 端点返回 400。评论中也有用户通过 Anthropic 原生 /v1/messages 流量命中 global.anthropic.claude-opus-4-8、global.anthropic.claude-opus-5 时出现同类错误。

报错原文

HTTP error in CountTokens handler: Client error '400 Bad Request' for url 'https://bedrock-runtime.eu-central-1.amazonaws.com/model/anthropic.claude-opus-4-8/count-tokens'
Response body: {"message":"Invocation of model ID anthropic.claude-opus-4-8 with on-demand throughput isn't supported. Retry your request with the ID or ARN of an inference profile that contains this model."}

HTTP error in CountTokens handler: Client error '400 Bad Request' for url 'https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-opus-5/count-tokens'
Bedrock CountTokens API error: status=400, message={"message":"The provided model doesn't support counting tokens."}
Provider token counting failed (400): {"message":"The provided model doesn't support counting tokens."}. Falling back to local tokenizer.

原因分析

已确认的根因:count-tokens 端点通过 get_bedrock_count_tokens_endpoint() → get_bedrock_base_model() 构造 Bedrock URL,而该函数在首段属于跨区域推理区域列表(global/us/eu/apac 等,common_utils.py)时,会按第一个 . 切分并丢弃该前缀。两个 count-tokens 调用点(transformation.py 与 bedrock_token_counter.py)都走这个分支,因此 bedrock/global.anthropic.claude-opus-4-8 在 count-tokens URL 中变成裸的 anthropic.claude-opus-4-8。

这些 Claude 模型在对应区域是 inference-profile-only,用裸基础模型 ID 走 on-demand 吞吐不被支持,所以 Bedrock 返回 400 ValidationException。而 Converse 处理器是内联拼装模型 ID(converse_handler.py),不经过该分支,因此 chat 保留了前缀、工作正常。评论中还指出,Bedrock CountTokens 的 modelId 本身允许推理配置文件 ID 与完整 ARN,没有强制剥离的 API 侧原因。

环境排查

  • 确认 LiteLLM 版本:Issue 中 v1.83.14、v1.89.2、v1.94.1 均有该问题;升级前先确认目标版本是否已包含修复。
  • 确认配置的模型名是否带跨区域前缀(global.、eu.、us.、apac.)或为 inference-profile ARN。
  • 对比 chat/Converse 请求与 count-tokens 请求日志中的 modelId:恢复正常时两者应一致保留前缀。
  • 确认所用 Bedrock 区域,以及目标模型在该区域是否仅支持推理配置文件。
  • 检查日志中是否出现 “Falling back to local tokenizer” 的 WARNING,判断是否命中了本地 fallback。

解决步骤

  1. 查看 LiteLLM 代理日志,定位 count-tokens 请求 URL 中的 modelId 是否为裸 anthropic.claude-...;若是,即命中本 Issue。
  2. 若已在本地维护 LiteLLM 源码:在 get_bedrock_base_model() 中对 count-tokens 调用路径不再剥离跨区域前缀(评论提出可给该函数增加开关参数,默认保持原行为,仅 count-tokens 路径关闭剥离),改动后重启代理并复测。
  3. 若不打算改源码:关注并升级到已合入修复的 LiteLLM 版本;截至本 Issue 关闭时,可优先尝试 #32692 形态的修复。
  4. 作为临时缓解,可接受本地 tokenizer fallback 的结果,但需知晓其与 Bedrock 计数口径可能不同,并会伴随每次调用的 WARNING 日志。

验证方法

再次向同一模型发送 POST /v1/messages/count_tokens,确认日志中请求 URL 的 modelId 保留 global./eu. 等前缀(或完整 inference-profile ARN),不再出现 400 与 “Falling back to local tokenizer” 日志,且返回的是 Bedrock 侧计数结果。同时抽查 bedrock/us-east-1/anthropic.claude-v2 这类内嵌区域写法模型,确认其 count-tokens URL 未被改为百分号编码路径。

参考来源

BerriAI/litellm #32683

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 29574

发表回复

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