You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Image session permanent 503: re-sending 48.6 MiB outbound body every round (fold blocked by cadence, archived images sti | 图片会话永久 503:每轮重发 48.6 MiB 出站体(fold 被 cadence 挡住,已归档图片仍在 wire 上) #3909
Command Code: A Worker script configured by the website owner exceeded its resource limits (CPU time or memory) and was terminated. (503: you can retry your request)
bili.log 里每一轮都是同一组:
request: 4829 msgs, inbound=115.1MiB, outbound=48.6MiB, local=3752ms
forward POST → http://127.0.0.1:3425/v1/chat/completions
stream silent 15000ms — holding client with SSE keep-alive comments past its undici body timeout (#1647)
client disconnected mid-stream after 474900ms (2125 bytes written to client)
network failure with no usage report — armed emergency shrink with local estimate 738022.4007379536 tokens
拍板点(三选一 + 两个子项): ① 选 A / B / C?② 配置项命名(泛化 wsOutboundBytes vs 新增 httpOutboundBytes)?③ 默认阈值取多少(建议 10 MiB 起)?④ 要不要顺带加「reactive-to-503 有界重发」(我倾向不加,理由见 C 的风险)?
Activity
[-]图片会话永久 503:每轮重发 48.6 MiB 出站体(fold 被 cadence 挡住,已归档图片仍在 wire 上)[/-][+]Image session permanent 503: re-sending 48.6 MiB outbound body every round (fold blocked by cadence, archived images sti | 图片会话永久 503:每轮重发 48.6 MiB 出站体(fold 被 cadence 挡住,已归档图片仍在 wire 上)[/+]ranxianglei commentedon Oct 20, 2026
(ai: vllm-qwen/qwen3.8-27b)
查重:不重复。 按失败签名(HTTP chat/completions 车道 · 图片密集 · 出站体恒定 ~48 MiB · 上游 Worker 资源上限 503 · fold 被 cadence 挡住)检索 open+closed issue 与 PR,无同签名条目。最近邻但机制不同:
close 1009零事件),[PR] fix: WS-lane egress byte budget with image shedding for close-1009 oversize requests (#3701) #3706 给 WS 加了network.wsOutboundBytes预发送图片 shedding + 1009 有界重发——且明确只作用 WS transport,HTTP 车道不进该路径。本 issue 正是它漏掉的 HTTP 车道。标签: bug · p1 · pi · scope/wiring(HTTP 车道会话完全不可用且无自愈路径 = 核心承诺失灵;落点在 host 侧出站管线,故 wiring)。
人话版:到底发生了什么
这个会话攒了 ~100 张 1MB 级 PNG 截图,token 占用才 70%(图片 token 轻),但出站体每轮恒定 ~48.6 MiB(图片字节重)。于是:折叠永远不触发(够不着触发线)→ 图片永远留在 wire 上 → 每轮都把 48.6 MiB 原样发给上游 → 上游 Cloudflare Worker 被图片解码的 CPU/内存撑爆回 503 → 客户端等 ~8 分钟超时 abort → 下一轮又重来。死锁,且没有任何一条恢复路径能把它拉回来。 你的对照实验(同样 48MB 纯文本 → 干净 400,不 503)已经钉死了:触发量级是图片像素/解码成本,不是裸字节数。
三步审核结论
① 复现/查证(master 代码核实) —— 你把三点判断全写对了方向,但第 2 点其实是第 1 点的下游症状,第 3 点在这里基本是旁观者:
pendingT1=51457 > 50000说明待折叠质量够了,但内核 nudge 决策要同时满足质量阈值和增长节奏(growth 6578 < floor 22500),节奏门把注入挡了(blocked: T1 (cadence))。图片 token 轻,token 占用停在 70%,growth 长期上不去 → 节奏门永远关着。src/image-restore.ts、src/server/handle.ts、src/session.ts:548):像素只有在所在消息范围被折叠时才会从出站副本摘除(Archive-then-fold: default folding for archivable media (Closes #2607, Fixes #2609) #2640);你在retrieve/img/看到的 163 个文件是入站索引时的落盘通道(ingest-time spill,decompress-shared.ts:283),不是「折叠摘除」的证据。因为从没折叠过,像素自然一直在 wire 上。修好 (1)/字节护栏,这条自动消失,不需要单独改。[acp-drift] fold coverage mismatch(prepare-openai.ts:189)代码里定位就是纯观测日志("fix: rescue context-overflow turns in-request instead of arming a rescue that never comes (#1195) #1328 overflow rescue 的可观测补充"),本身不触发 rebuild 也不该触发——覆盖 id「missing from resent history」意味着客户端自己把这些消息删了/截断了(它们本就不在 wire 上,没东西可重建)。按 KDD feat: self-update (auto + manual) #11 顺序为中心的对账,个别 cell 失配只作废那个 cell,不会级联成整段 unfold。真正让东西折不掉的是 (1) 的节奏门,不是漂移。要不要针对「客户端截断后残留失效 fold」单独排查可以另开,但它不是这次死锁的根因。② 层次定位(根因) —— 一句话:压缩管线在 token 空间做折叠决策,而这条链路的拒绝方(Cloudflare Worker)按图片解码成本判定;中间缺一层「字节空间护栏」。 #3706 已经为 WS 车道补了这层(
wsOutboundBytes+ shedding),唯独 HTTP 车道没有——它只有一个 5 GiB 硬拒绝上限(checkOutboundBody/limitsOutboundBytes),48.6 MiB 远远够不着,畅通无阻。第三层:网络失败武装的 emergency shrink 是 token estimate,被 usage 锚点压住(#3701 已确认这是防 ghost-overcount 的有意设计),所以 token 空间的恢复手段对「字节过大」天然无效。③ 方案评估 —— 你的期望 1(字节护栏)打到根因,方向认可;期望 2 是 (1) 的下游不用单修;期望 3(cadence/floor 让位)我能做到但不建议,理由见下;期望 4 见上面 (3);期望 5 是新配置项、可选。
需要你拍板的:HTTP 车道的护栏怎么加
核心是一个产品/config-surface 决策(新增或泛化一个默认字节预算 = 默认行为变更,按配置面纪律需你先点头)。三个方案:
egress-shed(owner 已审过的机器)我的推荐:A 打底。 理由:#3706 的 shedding 本来就是「从最旧的非保护尾部图片开始归档为占位注记(保留 mNNNNN 引用、原件可恢复)→ 仍超再走 jimp 降采样阶梯」,这恰好直接砍掉像素-CPU 成本,不需要另造像素计量器;跨车道统一、有 opt-out、CI 已验证过同型改动。关于期望 3(cadence 让位)我建议不做:字节 shedding 已经把出站体压下去了,没必要再去动折叠节奏那条精心设计的纪律(KDD #8 平直 50K + #3006 净收益地板,都是防零收益折叠循环的)。若你仍希望「pendingT1 已就绪 + 出站异常巨大时 cadence 让位」,请当第二个独立变更单列评审,别和护栏混在一个 PR。
结构化八问(决策请求)
egress-shed从「WS-only」泛化到 HTTP 车道——发送边界测最终序列化字节,超预算先归档受保护尾部之外的最旧图片为占位注记(保留 mNNNNN 引用可恢复),仍超走既有 jimp 阶梯;relay 预发送与 loop 内部重请求共用同一 helper。不动 kernel、不动折叠 cadence。network.wsOutboundBytes泛化为通用名(WS+HTTP 共用),要么新增network.httpOutboundBytes;默认值对齐 [PR] fix: WS-lane egress byte budget with image shedding for close-1009 oversize requests (#3701) #3706 量级(10 MiB 起,可下调),0=关闭回旧行为;CONFIGURATION.md 中英随生成器同步。这是 config-surface 变更,按规约需你拍板后才实现。拍板点(三选一 + 两个子项): ① 选 A / B / C?② 配置项命名(泛化
wsOutboundBytesvs 新增httpOutboundBytes)?③ 默认阈值取多少(建议 10 MiB 起)?④ 要不要顺带加「reactive-to-503 有界重发」(我倾向不加,理由见 C 的风险)?另外两点(你标注为独立问题)——我会拆出去单独跟,不塞进本 PR
lane=pi服务同一 sessionId,日志交织、同一会话被两进程重复 cold-load):不同失败域(安装拓扑/多实例态竞争),拆独立 issue。这两条我随后各开一个带
来源: #3909标记的 issue 走各自 triage,保持 #3909 聚焦 503 死锁这一族。下一步: 上述护栏方向你拍板后我立即开工(我会先把工作区 rebase 到当前 master——它已含 #3706 的
egress-shed.ts,本分支现在停在 v0.1.201、落后 280 提交)。在你拍板前我不擅自动 config surface / 默认行为。ranxianglei commentedon Oct 20, 2026
(ai: vllm-qwen/qwen3.8-27b)
跟进:上一条回复里承诺的两条独立问题已各自立项(均带
来源: #3909标记 + 查重声明,保持 #3909 聚焦 503 死锁这一族):reasoning_content(169 with / 47 without) | thinking 模式回传 400:部分 assistant tool-call 消息缺 reasoning_content(169 条带 / 47 条无) #3922 — thinking/reasoning 严格回传 400:169 条 assistant 消息带 reasoning_content、另 47 条 tool-call 消息不带,strict-reasoning 回传路径会 400。待查是源数据本就不一致还是 bili 重建/折叠丢了 reasoning 块(后者属 KDD release v0.1.3 #10 保真问题)。probe-do-not-file)。该环境 API 支持建 issue 但不支持删除(DELETE 返回 405),我已把它关闭并改标为「误建探针,请忽略」。无实际内容,不影响任何工作;在此如实报告,不藏着。当前状态 / 下一步:#3909 主问题(HTTP 车道图片会话永久 503 死锁)的护栏方案仍等你拍板——① A(泛化 #3706 字节预算到 HTTP,推荐)/ B(图片载荷感知)/ C(只对 503 反应)?② 配置项命名?③ 默认阈值?④ 要不要 reactive-to-503 重发?拍板后我先把工作区 rebase 到当前 master(已含 #3706 的
egress-shed.ts)再动手实现。在此之前不动 config-surface / 默认行为。ranxianglei commentedon Oct 20, 2026
(ai: vllm-qwen/qwen3.8-27b)
补充一条对上一条决策请求的精确化(我按承诺读了当前 master v0.1.202 的真实代码核对 #3706 机制,发现一个会影响你选项 ② 的细节):
Option A 确认可落地。 当前 master 的
src/egress-shed.ts正是我描述的那套:两档 shedding——(A) 把受保护尾部(最近 8 条 top-level entry)之外的最旧图片归档为占位注记(原件留在会话存储 + 入站索引,read_original_image/decompress({imageRef})仍可达,客户端自身历史不动),(B) 剩余图走 jimp maxDim 阶梯[1024,768,512,384];只改出站副本、绝不改 kernel 状态(与 Egress image downscale: shrink big images before sending to the model, originals stay local and self-readable | 重做图片降采样(简化版):发模型前压大图、原图留本地不动、模型被告知尺寸后可自读原图 #3400 同纪律),且对同一输入确定性产出稳定字节(保 prefix-cache)。而且src/server/relay.ts里调用点已经存在(现在只是被 gate 挡成 passthrough)——所以「泛化到 HTTP」是个外科手术式的小改动,不是新机制。但有个坑,直接影响选项 ②(配置命名):[PR] fix: WS-lane egress byte budget with image shedding for close-1009 oversize requests (#3701) #3706 的 WS 门被刻意收窄——代码注释写明它排除
dsh-inline(一个 managed-but-HTTP transport,实测能正常送 16 MiB,[Bug] Jimp is active, but image accumulation still triggers Responses WS 1009; duplicate request size not reduced (v0.1. | [Bug] Jimp 已生效,图片累积仍触发 Responses WS 1009;重复请求未缩小(v0.1.200) #3701 Finding 1 明确说它绝不能 shed)。所以「把所有 HTTP 车道一刀切纳入 shedding」会错误地开始裁 dsh-inline。正确做法是给一个 transport 类别谓词,只覆盖出问题的非托管直连 HTTP chat/completions relay 车道(你的 pi→magpie→Cloudflare Worker 这条),保持 dsh-inline 继续豁免。据此我把选项 ② 的倾向改明确:新增独立的
network.httpOutboundBytes,而不是把wsOutboundBytes泛化共用——WS 与 HTTP 的尺寸容忍度、豁免集合都不同(WS 更紧且要排 dsh-inline;HTTP 能扛更大)。默认值 ③ 建议落在 10–16 MiB(只要低于本例 48.6 MiB 就会触发;HTTP 比 WS 容忍大,取上沿可少误伤合法中大会话)——具体由你定。结论不变:仍等你拍板 ① A/B/C(我推荐 A)② 命名(现推荐新增独立
httpOutboundBytes)③ 默认阈值 ④ 要不要 reactive-to-503(我倾向不加)。拍板前我不动 config-surface / 默认行为;工作树干净、无仓库改动。fix(ranxianglei#3923): name both sides when two bili instances serve …