深色模式
LLM 网关限流与配额
摘要:LLM 流量的限流比传统 API 复杂一层:一次"请求"的成本弹性极大(100 token 与 10 万 token 是同一类请求),只按 QPS 限流挡不住账单,只按 token 限流又挡不住连接风暴。本文给出 QPS + TPM + 预算三层限流模型、在网关中的实现要点、429 与客户端退避的契约设计、以及多租户公平性。前置阅读:LLM 网关架构与价值。
三层限流模型
| 层 | 单位 | 防什么 | 时间尺度 |
|---|---|---|---|
| QPS 限流 | 请求数/秒 | 连接风暴、重试雪崩、爬虫 | 秒 |
| TPM 限流 | token 数/分钟 | 单租户吃满厂商配额、失控 Agent 循环 | 分钟 |
| 预算配额 | 金额/月(或 token/月) | 成本失控、租户超支 | 月/日 |
三层是与的关系:任一层超限即拒绝。厂商侧的配额(如 OpenAI 的 RPM/TPM 分级)决定了网关对上游的总 TPM 上限,网关把总配额切片分配给租户,避免一个租户耗尽全局配额导致所有人 429。
关键实现细节
1. TPM 计数用什么 token 口径
厂商配额通常按"输入+输出合计 token"计算。网关计数应与厂商口径对齐(请求前用预估值计输入,响应后按实际 usage 修正),否则限流阈值与厂商实际扣减对不上,会出现"网关没限流、厂商先 429"。
2. 令牌桶参数的设定顺序
- 从厂商控制台拿到账号级 RPM/TPM 配额;
- 预留 20% 余量(厂商配额有瞬时抖动,打满必 429);
- 按租户等级切分:核心租户保底 + 弹性共享池;
- 单租户突发用令牌桶(允许短时 burst),跨分钟窗口用滑动窗口计数。
yaml
# LiteLLM 虚拟 Key 级限流示例
general_settings:
database_url: postgres://... # 多副本共享计数必须用外部存储
litellm_settings:
max_budget: 500.0 # Key 月预算(USD)
tpm_limit: 200000 # Key 级 TPM
rpm_limit: 600 # Key 级 RPM1
2
3
4
5
6
7
2
3
4
5
6
7
多副本部署的计数一致性
限流计数器必须放 Redis/Postgres 等共享存储,网关多副本内存计数会叠加漏放。LiteLLM 多副本依赖 Postgres 记账;Higress 等基于 Envoy 的方案用全局速率限制服务(如 ratelimit service)。
3. 429 契约:让调用方能自愈
网关返回 429 时必须带上结构化信息,客户端才能正确退避:
json
{
"error": { "type": "rate_limit_exceeded", "code": "tpm_limit" },
"retry_after": 12
}1
2
3
4
2
3
4
retry_after(秒)必填,客户端按此退避而非指数盲重试;- 错误码区分
rpm_limit/tpm_limit/budget_exceeded——预算超限的处置是"找平台提额",与"稍后重试"完全不同; - 网关自身对上游 429 做 降级路由,把厂商限流挡在租户感知之外。
多租户公平性
租户切分配额后仍有两个公平性问题:
- 弹性池抢占:共享池被大户吃光 → 对共享池再做单租户二级 TPM 上限;
- 长请求占用:一次 10 万 token 的请求占住并发槽位 → 网关对超长上下文请求单独设并发上限或引导走异步批处理通道。
用 SLO 反推限流值
限流不是越紧越好。反过来算:为保住租户的 TTFT SLO(如 P99 < 2s),实测该租户模型组在多少并发下开始排队,排队并发 × 安全系数就是该租户的合理并发上限。阈值要随模型与硬件升级重测。
监控与告警
限流体系自身的健康度同样要监控:
- 各层限流的触发速率(
llm_ratelimit_rejected_total{layer,tenant}):某租户频繁触顶说明配额规划不足; - 上游 429 穿透率:厂商 429 到达租户的比例,理想值接近 0(应被网关降级消化);
- 限流组件延迟:Redis 计数超时会导致限流失效或误杀,需告警。
告警规则设计见 LLM 应用告警与 SLO 设计,预算水位告警见 Token 成本与用量监控。