PyTorch Foundation 週三發布 PyTorch 2.12——自 2.11 以來 2,926 commits、457 貢獻者。效能頭條來自一個不起眼但非常重要的後端切換:CUDA 上批量的 `linalg.eigh` 加速最高達 100×,原因是放棄了遺留的 MAGMA 後端,改用 cuSolver,並把 dispatch 啟發式更新為無條件使用 `syevj_batched`。以前要跑幾分鐘的工作負載——科學計算和任何需要批量矩陣特徵分解的 ML 訓練步驟裡都很常見——現在幾秒就跑完,終於補上了和 CuPy 之間的長期差距。另外,Adagrad 加入 Adam、AdamW、SGD 的行列支援 `fused=True`,把整步最佳化器塞進一個 CUDA kernel,而不是多個獨立 launch。XPU 上基於 FMA 的 `addcdiv` lowering 讓 `torch.compile` 與 eager 模式在 Intel GPU 上達到位精度一致——單看是小事,但如果你被編譯後的最佳化器行為無法複現追著跑過,這就是承重項。
戰略層面的故事是跨後端轉向。PyTorch 2.12 引入 `torch.accelerator.Graph`,一個與設備無關的圖捕獲與回放 API,把 `torch.xpu.XPUGraph` 這種後端專屬實作抽象統一起來。每個後端透過一個輕量 `GraphImplInterface` 註冊;`c10::Stream` 和 `torch.Stream` 現在暴露 `is_capturing()`,取代了與設備綁定的 `is_current_stream_capturing`。初版支援 CUDA 與 XPU(Intel),並透過 `PrivateUse1` 向外樹後端開放擴充。這正是本週稍早 CUDA 護城河報導裡講的那個動態在框架層級上的對照物:PyTorch 在明確地讓非 CUDA 加速器更容易參與到圖捕獲程式設計模型中,而圖捕獲就是 Inductor 與大部分效能工作所在的那一層。ROCm 使用者在同一版本裡獲得可擴充記憶體段、rocSHMEM 對稱記憶體集合通訊、以及 FlexAttention 流水線——AMD 路徑明顯推進了一步。
還有兩件值得 builder 注意的變化。第一,`torch.export.save` 和 `torch.export.load` 現在能正確地序列化 `float8_e8m0fnu` 這一 dtype——Microscaling(MX)量化格式(MXFP4、MXFP6、MXFP8)裡作為塊共享縮放指數使用的那個。過去,使用這種激進量化技術的模型無法透過 PyTorch 標準的匯出路徑走完;給成本受限或 edge 環境出貨 LLM 的團隊不得不自己發明自訂序列化。這個缺口被堵上了。第二,`torch.cond` 控制流現在可以藉助 CUDA 12.4 的條件 IF 節點在 CUDA Graph 裡被捕獲和重放——以前資料相依分支會強制回退到 CUDA graph trees,因為分支在 CPU 上計算。在 2.12,分支判斷在同一次圖捕獲裡就留在 GPU 上完成(目前支援 eager 與 cudagraphs 後端;Inductor 支援計畫在以後)。對帶資料相依控制流的 agent 類或 RL 工作負載,這一改動消掉了一個實打實的效能懸崖。
對 builder:如果你已經在 2.x 路線上,這是一個低摩擦版本——大多數收益是透明的(eigh dispatch、fused Adagrad、addcdiv FMA),不需要改程式碼。如果你在出貨量化模型,Microscaling 匯出修復是立刻可用的——按文件裡的範例 clone 一份,重測你的匯出 pipeline。torch.accelerator.Graph API 主要對 Intel XPU 目標或自建加速器的人有意義——更長遠的意義是:PyTorch 現在在明確地把圖捕獲跨後端抽象化,這是任何認真挑戰 CUDA 的玩家必須建在上面的地基。分散式訓練團隊應該看一下 FlightRecorder 的 ncclx + gloo 支援,以及 NCCL 新的 `seq_num` 用於跨 rank 的集合通訊關聯——都是具體可感的 debugging 體驗改進。如果你維護一條訓練 pipeline,這份 release notes 值得從頭到尾讀一遍;上面這些頭條只是採樣,不是全部。
