返回首頁

GitHub Repo

PyTorch 社群回報 BF16 編譯梯度偏差,卷積接 log_softmax 可能影響訓練

10 月 17 日的 PyTorch 社群回報指出,BF16 混合精度下,特定卷積與 log_softmax 計算圖經 Inductor 編譯後可能產生錯誤梯度。回報附有重現程式與暫時繞過方式,但維護者尚未確認完整影響範圍,也未公布修復版本。

Pytorch Deepdream (https://github.com/gordicaleksa/pytorch-deepdream) by gordicaleksa (https://github.com/gordicaleksa/pytorch-deepdream/commits?author=gordicaleksa) · MIT · Image source
zh-Hant

PyTorch 社群於 10 月 17 日提出一項訓練正確性問題:啟用 CUDA BF16 autocast 後,卷積接 log_softmax 的計算圖,若再加入後續運算,經 torch.compile 編譯可能出現梯度偏差。回報環境為 PyTorch 2.10.0、CUDA 12.8;截至查核時,議題仍開啟,尚無關聯修補。問題回報

重現程式比較兩個理應具有相同梯度的函式,其中一個額外加入經 detach() 處理的項。未編譯時兩者梯度一致;編譯後,當 logits 的共同偏移量增至 1000,梯度餘弦相似度降至 0.6943,範數比達 2.295。這提供了可供開發者檢查的具體案例,而非僅憑訓練曲線推測異常。重現數據

依回報者對生成核心的分析,前向運算以 FP32 logits 計算最大值與 log-sum-exp,卻將 logits 存入 BF16 緩衝區;反向重算時,混用已捨入的 logits 與未捨入資料的統計量,導致前後向不一致。這仍是回報者的根因判讀,尚待維護者驗證。核心分析

官方數值精度文件說明,浮點運算順序與後端差異本就可能改變結果,數學等價的計算也不保證逐位元一致。因此,工程端應檢查偏差幅度與收斂影響,並保留未編譯路徑作為對照。數值精度文件

回報者表示,切換至 aot_eager,或設定 torch._inductor.config.emulate_precision_casts = True,可解除其案例的問題。對使用類似運算鏈的團隊,實務上可先比較編譯前後的梯度方向與範數;上述內部設定的效能代價仍需自行量測。後續應追蹤維護者重現、受影響版本,以及修補是否納入回歸測試。暫時處理方式與追蹤

來源

  1. [Inductor] Wrong gradient for bf16 conv -> log_softmax -> op under autocast #201296
  2. Numerical accuracy — PyTorch 2.14 documentation