摘要: 2026 年 8 月 27 日至 9 月 9 日之間,Cloudflare Workers AI 上的 GLM-5.3 模型出現跨請求 KV cache 洩漏,共 155 個回應混入其他使用者的 prompt 內容。Cloudflare 與開源推理引擎 SGLang 於 10 月 26 日發布協調揭露報告,說明根因是設定錯誤與引擎缺陷的疊加。這對所有自己部署開源模型的人都是一堂必修課:context window 和 KV pool 大小是兩個獨立數字,沒有人會替你檢查它們一致。
兩個問題疊加,才會洩漏
單獨任何一個問題都不會造成洩漏,但兩個剛好碰在一起。
第一個是 Cloudflare 自己的設定錯誤。他們以 1,048,576 token 的 context window 部署 GLM-5.3,但 prefill GPU 上的 KV cache pool 只裝得下 681,280 token。更麻煩的是,SGLang 的 pool 大小不是設定值,而是啟動時依模型權重載入後剩餘的 GPU 記憶體自動算出來的——什麼都不會強迫這兩個數字一致,部署者必須自己確認。
第二個是 SGLang 的缺陷。當 prompt 超過 pool 大小時,引擎本該拒絕請求並回傳錯誤。排程器確實記錄了拒絕,還把 prompt 換成單一 token 的佔位符。但在分離式 prefill/decode 架構下,admission queue 檢查的是 finished() 而非「是否被拒絕」,於是被拒絕的請求仍被放行:prefill 對一個 token 做了 forward pass、把一頁 KV 傳給 decode 節點、並回報傳輸完成。Decode 節點以為整個 prompt 的 cache 都寫好了,開始生成——但除了第一頁,其餘保留的頁面還留著前一個請求的資料。結果是:客戶端拿到 HTTP 200、回應連貫、prompt_tokens 對得上,內容卻是別人的 session。
值得注意的是,這個缺陷早在 2026 年 7 月 6 日就有人以 issue #30233 回報給 SGLang,Cloudflare 是在調查期間才注意到。事後看,測試的盲點也很清楚:Cloudflare 自己承認 pre-launch 只驗了 HTTP 狀態碼和效能,沒有驗證模型輸出的連貫性。
修復分兩層
Cloudflare 的做法值得借鏡:他們不只修了眼前的設定,還假設定也會再出錯。
第一層是修正 pool 大小。調整後的設定讓 prefill KV pool 容納約 204 萬 token,是 context window 的兩倍左右,合法請求永遠不會走到拒絕路徑。
第二層是把拒絕路徑本身修安全。帶有待處理拒絕的請求現在會在 disaggregation admission queue 就被退回原始錯誤,不會進入任何 bootstrap、配置或 KV 傳輸;decode 節點也會核對實際收到的 token 數是否等於保留的數量。這些修正已透過 PR 提交上游,相關修補分布在 SGLang v0.5.20 至 v0.5.22。SGLang 維護者建議所有依賴它的營運者升級到 v0.5.22 以上。
在部署檢查上,Cloudflare 現在直接從執行中的引擎讀取 KV pool 大小、比對 context length,而不是從回應狀態碼推斷。
對自己部署模型的人的啟示
這次事件裡,Cloudflare 在通報後 40 分鐘內將模型下線、同日修復並恢復服務,並確認其他 Workers AI 模型未受影響、也沒有刻意利用的證據。但更根本的教訓是給每一個跑開源權重的人——包括之前我們談過 GLM-5.3 權重本地部署的現實時提到的部署複雜度:
- 效能測試不等於正確性測試。 200 狀態碼加流式回應,掩蓋了回應內容根本不對的事實。長 context 部署至少要做 canary marker 測試:夾帶已知標記,確認不會出現在別的請求回應裡。
- 引擎自動推導的值要當成運算結果驗證,不是當成常數信任。 換量化方式、改 tensor parallelism、升級模型版本,pool 大小都會跟著變。
- 依賴上游開源引擎,就要跟上上游的安全修補節奏。 同一個缺陷在你自己的部署上,後果由你承擔。
Cloudflare 與 SGLang 的後續強化仍在進行中(報告記錄到 10 月中)。實際的下一步很簡單:如果你的推理堆疊用了 SGLang,先確認版本在 v0.5.22 以上,再從引擎實際讀一次你的 KV pool 大小和 context length 比對。
