Files
litellm-config/docs/volc-quota-notes.md
T
vibe-code dd349b64cf fix: 限额改 v4 冻结快照,余额红线防扣费
v2 的 stable_limit = usage + balance - BUFFER 依赖余额 API 随消耗实时递减,
实测滞后(08-12 快照 1,558,307 在 usage 涨 45 万期间不动)导致池膨胀、限额
虚高,放行到扣费区(当日超余额 13.8 万已扣费)。
扣费口径(用户确认):是否扣费只取决于当下免费额度,超出即扣费,采集量只
决定明日发放。v4:stable_limit = balance - BUFFER 冻结快照,本地 usage 实时
撞线即拦,等价于本地实时扣减余额;effective = min(2M 配额, stable_limit)。
新增 docs/volc-quota-notes.md 额度机制速查;merge-auto-consume.md 补 §4.5。
2026-08-12 06:58:03 +00:00

11 KiB
Raw Blame History

火山免费额度机制速查(VolcEngine Quota Notes)

日期:2026-08-12 用途:后续限额/防扣费设计、排障、消耗任务的事实基础,避免重复推导 来源:

  • merge-auto-consume.md §1(2026-08-11 用户确认的业务细则)
  • 2026-08-12 对话澄清(扣费口径、余额 API 滞后、限额方案演进)
  • 2026-08-12 生产日志观察(deepseek-v4-flash-ga-260731)

代码现状:v4 已实施(2026-08-12,见 §7.3);工作区在 HEAD c6c1224 之上仅含 v4 改动。 v2/v3 内容保留为历史论证。


1. 业务模型(细则,用户确认)

1.1 日返还循环

每天任意时刻    真实用户 + 消耗任务 的消耗 = 当日采集量(火山实时统计,每模型单独计算)
每天 23:00 CST  消耗任务补齐缺口(可选)
次日 00:00 起   火山按昨日采集量发放资源包(不定时,可能延迟到上午)

1.2 硬规则

规则 值 影响
采集上限 2M token/模型/天 消耗超过 2M 的部分不返还(白烧);所有模型统一
发放额度 = 昨日采集量(≤2M) 消耗 X → 次日返还 X,用多少补多少,延迟一天到账
发放时间 不定时 次日 0:00 至发放时点存在余额空窗
资源包有效期 30 天 过期额度实打实消失,失去"启动资金"
消耗顺序 FIFO(先消耗获得时间早的包) 队列头部 = 最早获得 = 最早过期
余额耗尽 请求不失败,按真实价格扣费 全部防护的终极目标:避免扣费
首次开通 每模型赠送 2M 启动资金的种子(无对应前日采集的免费午餐)

1.3 账目守恒

余额_{N+1} = 余额_N − 消耗_N + 返还_{N+1}
           = 余额_N − 消耗_N + 采集_N
           = 余额_N                    (消耗即采集,≤2M 内全额返还)

推论:

  • 使用不损失额度(用多少补多少,仅延迟一天)
  • 过期才损失额度(额度蒸发 = 启动资金永久减少)
  • 消耗任务的价值 = 防止"启动资金"被 30 天过期侵蚀
  • 真实用量 ≥ 66.7k/天(= 2M/30 天)时,赠送包被自然消耗;低于此值必须靠消耗任务在最后 9 天窗口洗掉

2. 扣费判定(2026-08-12 用户确认口径,最重要)

用户原话:是否扣费只取决于当下有多少免费额度。超出免费额度的请求,都会被扣费。采集量只决定明日发放,与今日是否扣费无关。

扣费判定:消耗 ≤ 当下余额(免费额度)→ 免费,余额扣减
         消耗 > 当下余额            → 超出部分按真实价格扣费(无返还、不退)
今日采集量(≤2M)→ 只决定明日返还的包大小,与今日是否扣费无关

推论(2026-08-12 案例):

  • 当日余额 1,558,307,今日已采 1,696,135 → 超出 137,828 tokens 已扣费,不可挽回
  • 明日返还 = 今日采集量 1,696,135 的包(免费额度回正),但今天扣的钱不退
  • 因此「先采后返」不构成透支许可:消耗超余额的部分当场计费

3. 关键概念区分(反复踩坑处)

概念 含义 量级特征 与扣费的关系
采集量(今日) 今日实时消耗统计(火山网页"今日采集量") 单日流量,0~2M 只决定明日返还
余额(免费额度) 资源包 AvailableAmount 存量之和 累计存量,守恒 ≈2M(种子) 扣费唯一依据
采集配额 2M 今日最大采集量 每模型固定 超了白烧(不返还),未必当场扣费
返还(T+1) 昨日采集量 → 新资源包 单日流量延迟一天 补回余额,不抵今日扣费

核心:余额是累计存量(守恒),采集量是单日流量。限额设计必须用存量(余额), 绝不能用单日流量(昨日采集量)当上限——那会把可用性锁死在水位以下(见 §7.2 v3)。


4. 余额 API 的滞后问题(2026-08-12)

  • 非实时,延迟未知(用户明确)。实测:2026-08-12 13:36:01 同步快照 Bal=1,558,307, 此后 usage 从 1,241,821 涨到 1,696,135(13:36→13:38)期间 Bal 纹丝不动。
  • 观察结论:AvailableAmount 不随今日消耗实时递减(至少滞后 20 万级,上限未知)。
  • 后果:一切「余额随消耗实时递减」的公式(v2 的 usage + balance 池恒定假设)在 滞后下失效——usage 涨而 balance 不动 → 池膨胀 → 限额虚高 → 放行到扣费区。
  • 对策方向:以最近同步快照的余额为当日免费池上限(本地 usage 实时累计撞线), 快照频率由同步间隔(30min 常规 + 低余额 5/10min + 突发阈值触发)保障; 滞后窗口内的消耗用 BUFFER 覆盖(见 §7.3)。

5. 症状对照:Today > Rem(2026-08-12 案例)

日志示例(13:36-13:38,deepseek-v4-flash-ga-260731):

DEBUG: Checking deepseek-v4-flash-ga-260731 (Bal: 1,558,307, Rem: 1,258,307) (余额/剩余)
DEBUG: deepseek-v4-flash-ga-260731 Pool=2,800,128 | Usage=1,241,821 | StaticLimit=2,000,000 | StableLimit=2,500,128 | EffectiveLimit=2,000,000
Set Redis limit:dynamic:volcengine:remaining:deepseek-v4-flash-ga-260731 = 1,258,307
📊 [Usage] deepseek-v4-flash-ga-260731:ba0383d3: +38083 (Today: 1,279,904 | Rem: 1,558,307 | Limit: 2,000,000)

字段口径:

字段 含义 计算
Bal 火山 API 余额(ListResourcePackages AvailableAmount 之和) 同步快照
Rem(Checking 行) 入 Redis 的剩余 Bal − BUFFER
Rem(Usage 行) 展示用余额 Redis remaining + BUFFER = Bal(展示与 API 一致)
Today 本地今日采集量 Redis daily_usage 逐请求累加
Limit 生效限额 min(2M, stable_limit)
StableLimit(v2) 动态限额 usage + balance − BUFFER(随 usage 膨胀,见 §7.1)

Today > Rem 的原因:Today 是单日流量,Rem 是存量余额快照,两套口径本就不该比较。 今日消耗可以暂时大于余额显示值(先采后返),但按 §2 口径,超出部分实际已扣费。 火山网页「今日采集量 1,696,135/2,000,000」对应 Today 与 2M 配额,与余额无关。


6. Redis key 与日志口径(速查)

6.1 Redis key

key 读写方 说明
daily_usage:{北京日期}:{model}:{hash} LiteLLM 成功回调 INCR + 消耗任务 INCR 当日采集量,TTL 48h,北京 00:00 滚动
limit:dynamic:volcengine:remaining:{model} 守护线程写 余额 − BUFFER(同步频率驱动、展示)
limit:dynamic:volcengine:stable_limit:{model} 守护线程写 稳定限额(v2:usage+balance−BUFFER)
consume:last_run:{日期} 消耗任务 23:00 当日去重,TTL 48h

6.2 关键日志

  • 🚫 [PRE-BLOCK] {model} daily limit reached ({usage}+{reserve}/{limit}):请求前闸门 429
  • 📊 [Usage] {model}:{hash}: +{tokens} (Today: X | Rem: Bal | Limit: Y):成功记账
  • 📅 [Quota] ...:每日额度汇总(v4 设计,未实施)

7. 限额方案演进

7.1 v2(现状,HEAD c6c1224):stable_limit = usage + balance − BUFFER

  • 意图:usage + balance = 当日初始可用池,消耗中恒定 → 限额恒定
  • 失效点:该式假设 balance 随消耗实时递减;实测滞后 → usage 涨 balance 不动 → 池膨胀(2026-08-12:2.80M → 3.26M)→ 「余额耗尽 → 限额 0」防线失效 → 放行到扣费区
  • 案例:余额 1,558,307 时 EffectiveLimit 仍取 2M,今日采到 1,696,135(超余额 13.8 万)未被拦

7.2 v3(尝试后否决,已回滚):昨日锚 effective = min(2M, 昨日采集量 × 系数)

  • 思路:把「返还 = 昨日采集量」当作「今日可采上限」
  • 否决理由(用户反例):余额 2M、昨日用量 10K → 今日最多 10K?荒谬。 错误在于把单日流量(昨日采集量)当存量(余额) 用;昨日少用不损余额(守恒), 今日可用 = min(2M, 余额) ≈ 2M,与昨日无关
  • 附:系数 <1.0 还会引发「今日少采 → 明日返还更少」的日复一日递减陷阱(0.9 系数 5 日降至 66%)

7.3 v4(2026-08-12 已实施):冻结快照

stable_limit = max(0, balance − BUFFER)        # 冻结快照,同步时算一次
effective_limit = min(2M 采集配额, stable_limit) # 2M 防白烧;余额红线防扣费
  • 唯一改动点:同步循环 stable_limit 从 usage + balance − BUFFER 改为 balance − BUFFER (volc_limit_sync.py active_monitor_loop 同步段;debug 行 Pool 字段移除,改 Bal 口径)
  • 数学等价于「本地实时扣减余额」:以最近快照余额为当日免费池上限, usage 本地逐请求实时累计,撞线即拦,不再等 API
  • 行为测试(2026-08-12,fake Redis 全过):冻结不膨胀 / 今日 1.696M 撞 1.258M 即拦 / 余额 2M 可用 1.7M(与昨日无关)/ stable 缺失兜底 900K / 次日返还解锁 / 余额 < BUFFER 全拦
  • 效果对照(与 v2 现状):
场景 v2 现状 v4
余额 2M,昨日 10K 可用 ≈2M min(2M, 1.7M)=1.7M,不锁死 ✓
余额 1.558M,今日已采 1.696M 不拦(膨胀到 3.26M) 立即拦(1.696 ≥ 1.258)→ 止损
明日余额跳涨(返还 1.696M) — 红线升 1.4M,自动解锁
  • 与消耗任务防线「余额快照 − 已烧 ≤ 0 停」同一把尺子(merge-auto-consume.md §4.4)
  • 连带改动:get_effective_limit 兜底链不变(stable → FALLBACK_LIMIT 90 万); 文档同步(merge-auto-consume.md §4.2、AGENTS.md 限额描述)

7.4 实施后待观察项(2026-08-12)

  • BUFFER(现 30 万,未调大):防「余额 API 滞后窗口内的消耗」。实测 20 万内不动 + 10 万冗余; 滞后上限未知,若观察同步间隔内(burst 阈值 50 万)烧穿,调大(如 50 万,env 可调)
  • 部署:代码已改(工作区),需重启 litellm 容器加载(挂载文件);重启在生产主机由用户执行

8. 排障速查(今日结论汇总)

  1. 看到 Today > Rem 不是异常,先分清口径(§5);但按 §2 口径,超余额部分已在扣费,应立即收闸
  2. 余额显示不动 ≠ 余额充足,是 API 滞后;以最近快照 + BUFFER 为准
  3. 判断「还能免费采多少」:min(2M, 最近余额快照 − BUFFER) − 今日已采(v4 已落地)
  4. 消耗任务 23:00 直连 Ark 绕过 LiteLLM 闸门(防自杀),其自身 clamp:plan ≤ 2M − usage、 plan ≤ 余额快照 − 已烧 − BUFFER,停止条件三闭环
  5. 扣费既成事实不可挽回(如 08-12 的 137,828);能做的只有止损(收闸)与次日恢复(返还)

9. 待确认/风险清单

  • 余额 API 滞后上限实测(决定 BUFFER 是否调大,现 30 万)
  • v4 方案批准与实施(2026-08-12,§7.3;待生产主机重启生效)
  • 消耗任务口径是否同步收紧(可选:其停止条件与闸门同一把尺子已满足)
  • 空窗期(0:00–返还到账)行为观察:v4 下余额红线自动收紧,确认无异常误杀