2026.09.14 —— 今日 10 則
TODAY'S THREAD 今天有好幾則都在把省下來的那筆帳翻到背面看是誰在付——KV cache 壓到每 token 890 位元組、build 從 24 分掉到 5 分、never type 兩年換一次 crater run,省的那一欄都寫得很大,付的那一欄要自己去翻。
每個 token 只留 890 位元組
DeepSeek-V4.1-Flash 的 model card 描述的是一顆 40 層的 causal encoder-decoder——20 層 causal encoder 接 20 層 decoder,552B backbone,但 prefill 每個 token 只活化 8B、decode 16B,每個 token 路由 6 個 expert。真正被拿來當賣點的是記憶體:Compressed Sparse Attention 2 把 KV cache 壓到每個 token 890 位元組,官方說法是約 DeepSeek-V4-Flash 的四分之一,另一招 SWA Bounded Replay 只重放最近的 token 來補回缺掉的 SWA KV state,常駐 footprint 再降到大約八分之一。訓練用 45T multimodal token 從頭跑,sparse attention 在 64K 長度上訓練後外推到 1M,推理努力程度做成 1 到 100 連續可調,授權是 MIT。
重算有時候比讀快取快
這篇 9 月 10 日投上 arXiv 的論文做的是 vLLM 外部 KV cache 的效能刻畫,橫跨 GPU、CPU 與 NVMe 三層,用合成負載、長 context benchmark 與 production trace 一起量。作者的說法是快取表現取決於傳輸粒度、中間記憶體用量,以及傳輸在什麼時機進入請求排程,而不只是裝置頻寬。他們寫的 py-kvcache 在 80k token 時從磁碟載入比 LMCache 快 2.0 倍、三層合起來快 1.23 倍,與原生 vLLM KV Offload 實作則差在約 4% 以內,而且在 H100 上很多請求根本跨不過外部快取划算的那道門檻。
三千三百個 crate,七個真的壞了
LWN 報導貢獻者 waffle 在 8 月 24 日把 Rust 的 never type ! 穩定下來,前後兩年多,落點是 Rust 1.99。麻煩的從來不是這個型別本身,是 fallback——2024 edition 之前推不出來就當 (),2024 edition 改成 ! 自己,而 Infallible 同時要變成 ! 的 type alias,兩個 breaking change 幾乎互相抵銷。crater 跑遍 crates.io 的結果是 3,300 個 crate 受影響、只有七個完全壞掉,其餘都是相依到早已修好的舊版本,後續 backport 又救回其中 1,553 個,有些維護者以版本早就 EOL 為由拒收。
GC 不再掃 system image
Julia 1.13 在 9 月 10 日發布,改動集中在延遲:image 物件重新設計之後,GC 不再掃過預先載入的系統程式碼,bare session 的 full collection 從 35ms 掉到 2ms,載入 GLMakie 之後從 187ms 掉到 68ms。hash 從 MurmurHash3 換成純 Julia 寫的 RapidhashNano,長字串從 8.555μs 降到 1.742μs,代價是自訂 hash 方法必須接受 seed 參數、而且不得給預設值。scheduler 這邊 @spawn 改成只叫醒一個 thread 而不是全部閒置 thread,官方量到 16 核 Linux 上 1.1 到 1.6 倍、Windows 上 10 到 300 倍。
翻譯一次,指令數翻倍
Chips and Cheese 把 Windows 11 的 x86-64 轉 ARM64 翻譯層 Prism 產出的程式碼從 translation cache 裡挖出來逐條讀,測試平台是 Snapdragon X2 Elite,對照組是 Neoverse N1 與 N2。作者給的粗略法則是同一份 Geekbench 7 工作負載走過翻譯之後,執行的 aarch64 指令數大約是原生 x86-64 的兩倍,其中 AVX 對應到 NEON 的影片播放負載罰得最重、低 IPC 的導航負載罰得最輕。翻譯本身多半直來直往,漏掉的是迴圈裡沒必要的 register spill 與嚴格 register mapping 逼出來的多餘指令;作者的結論是這條路走不走得通,靠的是硬體本身夠快,不是翻譯器多聰明。
brew 自己帶了一份漏洞清單
Homebrew 7.0.0 在 9 月 13 日發布,新的 brew vulns 直接拿已安裝的 formula 去比對漏洞,背後是內建的 OSV 格式 advisory 資料庫、以 CC0 釋出,不必再外掛第三方 tap。沙箱兩邊一起收緊:Linux 從 Bubblewrap 換成 Landlock、不需要提權,macOS 的 cask 沙箱則限制啟動應用程式、Mach service 與 Unix socket 連線,沙箱建置預設也擋掉讀家目錄。相容性那一欄比較痛,Intel Mac 在 2026 年 9 月降到 tier 3,既有 bottle 留著、例行的 Intel bottle 更新已經停掉,更新過的 formula 可能得從原始碼建,而 Homebrew 在 Intel 上只跑到 2027 年 9 月為止;.pkg 安裝器則改成只支援 Apple Silicon 與 macOS Sequoia 15 以上。
location 後面終於能放變數
NGINX 1.31.5 把 location 從 URL 比對裡解放出來,任何變數都能當成 location 的 traffic modifier,於是 location $vip、location $restricted_methods 這種寫法成立,判斷邏輯搬進 map。搭配 client_body_early_read 提早讀 request body、再用原生的 json_set 取出 JSON 欄位,routing 決策可以建立在 body 內容上,不必再掛一段 script。官方自己把代價講明:body 越大,處理吃的記憶體與 CPU 越多,所以簡單而常見的 predicate location 要擺在前面。
五倍不是語言換來的
這篇的工具叫 buildprof,用 ptrace 追 process 的建立、執行與結束,再用 seccomp filter 追檔案讀寫,把整棵 process tree 攤在時間軸上,還吃得下 -ftime-trace 這類編譯器內部 trace。作者拿它去追 Bun 換掉 Zig 之後 Linux build 從 24 分 24 秒掉到 5 分 40 秒這個說法,發現 ld.lld 在 Full LTO 下就吃掉 16 分 35 秒。把 Bun 自己換成 ThinLTO 只省下 3 分 40 秒,因為連進去的 WebKit 仍是 Full LTO,兩邊一起換才降到 15 分 11 秒——剩下的差距來自 90 幾個 crate 能平行編譯的結構,不是語言。
一個識別碼,寫進七個地方
Session Context 這個展示頁把一次造訪能被讀走的東西攤開來數,自報 56 個欄位檢查、46 個欄位回報,分成程式跑起來之前就知道的(HTTP header 與連線資訊)、需要權限的能力(定位、相機與麥克風、剪貼簿、顯示器、字型、動作感測器、已安裝應用程式)、指紋訊號(繪圖、音訊、效能)與跨站識別碼四張表。它同時示範把同一個識別碼寫進七個地方、第八個藏在瀏覽器快取裡,並引熵值說 plugin 清單 11.1 bits、user agent 9.8 bits、字型 8.4 bits、canvas 8.3 bits、時區 3.3 bits,合計 63 bits,但自己補了一句「Entropy is only additive when signals are independent, and these are heavily correlated」。頁面也寫明幾乎所有值都在瀏覽器裡量完、不離開本機。
union 上了線,沒有 discriminator
C# 15 的 union 會跟著 .NET 11 一起出,而這篇講的是它撞上 System.Text.Json 之後的實際形狀:JsonSerializer.Serialize(new IntOrString(42)) 序列化出來就是 42,沒有 wrapper、沒有 discriminator,只有在兩個 case 的 JSON 型別不同時反序列化才沒有歧義。兩個 object case 就得掛上 [JsonUnion(TypeClassifier = typeof(JsonUnionTypeStructuralClassifier))] 靠屬性名字分辨,OpenAPI 那一側則是每個 case 一個 anyOf 條目。限制寫得很清楚,只有走 System.Text.Json 的綁定來源能用,query string、route value、header 與 form field 都不行,因為 ?id=42 沒有任何線索說該綁 int 還是 string。