快捷方式

數值精度

在現代計算機中,浮點數使用 IEEE 754 標準表示。有關浮點算術和 IEEE 754 標準的更多詳細資訊,請參閱 浮點算術。特別是,請注意浮點數提供有限的精度(單精度浮點數約 7 位小數,雙精度浮點數約 16 位小數),並且浮點加法和乘法不具有結合性,因此操作順序會影響結果。正因為如此,PyTorch 不保證對於數學上相同的浮點計算會產生逐位相同的結果。同樣,不保證在不同 PyTorch 版本、單個提交或不同平臺之間產生逐位相同的結果。特別是,即使輸入完全相同,並且即使控制了隨機性來源,CPU 和 GPU 結果也可能不同。

批次計算或切片計算

PyTorch 中的許多操作支援批次計算,即對輸入批次中的元素執行相同的操作。torch.mm()torch.bmm() 就是這樣的例子。儘管從數學上講,批次計算可以透過迴圈遍歷批次元素並將必要的數學運算應用於單個批次元素來實現,但出於效率原因,我們並未這樣做,通常會對整個批次執行計算。在這種情況下,我們呼叫的數學庫以及 PyTorch 內部操作實現與非批次計算相比,可能會產生略微不同的結果。特別是,設 AB 是維度適合批次矩陣乘法的 3D 張量。那麼 (A@B)[0](批次結果的第一個元素)不保證與 A[0]@B[0](輸入批次的第一個元素的矩陣乘積)逐位相同,儘管數學上它們是相同的計算。

同樣,應用於張量切片的操作不保證與應用於完整張量結果的切片產生相同的結果。例如,設 A 是一個 2 維張量。A.sum(-1)[0] 不保證與 A[:,0].sum() 逐位相同。

極值

當輸入包含較大的值,導致中間結果可能超出所用資料型別的範圍時,即使最終結果在原始資料型別中是可表示的,最終結果也可能溢位。例如:

import torch
a=torch.tensor([1e20, 1e20]) # fp32 type by default
a.norm() # produces tensor(inf)
a.double().norm() # produces tensor(1.4142e+20, dtype=torch.float64), representable in fp32

線性代數 (torch.linalg)

非有限值

torch.linalg 使用的外部庫(後端)不保證輸入包含非有限值(如 infNaN)時的行為。因此,PyTorch 也不提供此保證。操作可能返回包含非有限值的張量,或引發異常,甚至導致段錯誤(segfault)。

在呼叫這些函式之前,考慮使用 torch.isfinite() 來檢測這種情況。

linalg 中的極值

torch.linalg 中的函式相比其他 PyTorch 函式更容易遇到 極值 問題。

求解器求逆器 假定輸入矩陣 A 是可逆的。如果它接近不可逆(例如,如果它具有非常小的奇異值),則這些演算法可能會靜默返回不正確的結果。這些矩陣被稱為病態矩陣。如果提供病態輸入,這些函式的結果在使用相同輸入但在不同裝置上或使用不同的 driver 關鍵字後端時可能會有所不同。

svdeigeigh 等譜運算在其輸入具有接近的奇異值時,也可能返回不正確的結果(並且它們的梯度可能為無窮大)。這是因為用於計算這些分解的演算法對於這些輸入難以收斂。

float64 中執行計算(NumPy 預設這樣做)通常會有所幫助,但這並不能在所有情況下解決這些問題。透過 torch.linalg.svdvals() 分析輸入的奇異值或透過 torch.linalg.cond() 分析其條件數可能有助於檢測這些問題。

Nvidia Ampere(及後續)裝置上的 TensorFloat-32(TF32)

在 Ampere(及後續)Nvidia GPU 上,PyTorch 可以使用 TensorFloat32 (TF32) 來加速計算密集型操作,特別是矩陣乘法和卷積。當使用 TF32 Tensor Core 執行操作時,只讀取輸入尾數的頭 10 位。這可能會降低精度併產生令人驚訝的結果(例如,矩陣乘以單位矩陣可能產生與輸入不同的結果)。預設情況下,矩陣乘法的 TF32 Tensor Core 是停用的,而卷積的 TF32 Tensor Core 是啟用的,儘管大多數神經網路工作負載在使用 TF32 時與使用 fp32 具有相同的收斂行為。如果您的網路不需要完整的 float32 精度,我們建議使用 torch.backends.cuda.matmul.allow_tf32 = True 啟用矩陣乘法的 TF32 Tensor Core。如果您的網路對於矩陣乘法和卷積都需要完整的 float32 精度,則可以使用 torch.backends.cudnn.allow_tf32 = False 停用卷積的 TF32 Tensor Core。

更多資訊請參閱 TensorFloat32

FP16 和 BF16 GEMM 的降精度歸約

半精度 GEMM 操作通常在單精度下進行中間累加(歸約),以提高數值精度並增強抗溢位能力。為了效能,某些 GPU 架構,特別是更新的架構,允許將中間累加結果截斷到較低精度(例如半精度)幾次。這種改變通常對模型收斂是良性的,儘管它可能導致意外結果(例如,最終結果應在半精度範圍內但出現 inf 值)。如果降精度歸約有問題,可以使用 torch.backends.cuda.matmul.allow_fp16_reduced_precision_reduction = False 將其關閉。

BF16 GEMM 操作也存在類似的標誌,並且預設是開啟的。如果 BF16 降精度歸約有問題,可以使用 torch.backends.cuda.matmul.allow_bf16_reduced_precision_reduction = False 將其關閉。

更多資訊請參閱 allow_fp16_reduced_precision_reductionallow_bf16_reduced_precision_reduction

縮放點積注意力 (SDPA) 中 FP16 和 BF16 的降精度歸約

一個樸素的 SDPA 數學後端在使用 FP16/BF16 輸入時,由於使用低精度中間緩衝區,可能會累積顯著的數值誤差。為了緩解這個問題,預設行為現在涉及將 FP16/BF16 輸入上轉換為 FP32。計算在 FP32/TF32 中執行,然後將最終的 FP32 結果下轉換回 FP16/BF16。這將提高使用 FP16/BF16 輸入的數學後端最終輸出的數值精度,但會增加記憶體使用量,並可能導致數學後端的效能下降,因為計算從 FP16/BF16 BMM 轉移到 FP32/TF32 BMM/Matmul。

對於偏好速度而選擇降精度歸約的場景,可以使用以下設定啟用它們:torch.backends.cuda.allow_fp16_bf16_reduction_math_sdp(True)

AMD Instinct MI200 裝置上的 FP16 和 BF16 GEMM 和卷積降精度

在 AMD Instinct MI200 GPU 上,FP16 和 BF16 的 V_DOT2 和 MFMA 矩陣指令會將輸入和輸出的次正規值重新整理為零。FP32 和 FP64 的 MFMA 矩陣指令不會將輸入和輸出的次正規值重新整理為零。受影響的指令僅由 rocBLAS (GEMM) 和 MIOpen (卷積) 核心使用;所有其他 PyTorch 操作都不會遇到這種行為。所有其他支援的 AMD GPU 都不會遇到這種行為。

rocBLAS 和 MIOpen 為受影響的 FP16 操作提供了備用實現。BF16 操作沒有提供備用實現;BF16 數值的動態範圍比 FP16 數值更大,遇到次正規值的可能性較低。對於 FP16 的備用實現,FP16 輸入值被轉換為中間 BF16 值,然後在累加 FP32 操作後轉換回 FP16 輸出。透過這種方式,輸入和輸出型別保持不變。

使用 FP16 精度進行訓練時,某些模型可能會因為 FP16 次正規值重新整理為零而無法收斂。次正規值更常出現在訓練的反向傳播過程中,即梯度計算期間。PyTorch 預設在反向傳播過程中使用 rocBLAS 和 MIOpen 的備用實現。可以使用環境變數 ROCBLAS_INTERNAL_FP16_ALT_IMPL 和 MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL 覆蓋預設行為。這些環境變數的行為如下:

正向傳播

反向傳播

環境變數未設定

原始

備用

環境變數設定為 1

備用

備用

環境變數設定為 0

原始

原始

以下是可能使用 rocBLAS 的操作列表

  • torch.addbmm

  • torch.addmm

  • torch.baddbmm

  • torch.bmm

  • torch.mm

  • torch.nn.GRUCell

  • torch.nn.LSTMCell

  • torch.nn.Linear

  • torch.sparse.addmm

  • 以下 torch._C._ConvBackend 實現

    • slowNd

    • slowNd_transposed

    • slowNd_dilated

    • slowNd_dilated_transposed

以下是可能使用 MIOpen 的操作列表

  • torch.nn.Conv[Transpose]Nd

  • 以下 torch._C._ConvBackend 實現

    • ConvBackend::Miopen

    • ConvBackend::MiopenDepthwise

    • ConvBackend::MiopenTranspose

文件

訪問 PyTorch 的完整開發者文件

檢視文件

教程

獲取面向初學者和高階開發者的深入教程

檢視教程

資源

查詢開發者資源並獲得問題解答

檢視資源