トップページ

最新記事

TF32-TCでの計算精度が劣化する話

何の話か

NVIDIA GPUではAmpareアーキテクチャからTF32(s1e8m10)と呼ばれる浮動小数点数が使えるようになりました。
一見するとFP16(s1e5m10)の上位互換なように見えますが、実際に使うと計算精度が落ちることがあります。
これが何故起きるのかという話。
結論から言うと、FP32→TF32の変換の丸めが悪い。

TF32の丸め

CUDAでFP32→FP16変換を行う__float2half関数はRN丸め(最近接偶数丸め)がデフォルトでは使われます。
__float2half_rzとかでゼロ方向丸めなどが使えます。)
この関数はNVIDIAが用意しているヘッダファイルでPTXのcvt.rn.f16.f32命令を呼びます。
この様にCUDAでは型変換はcvt命令で行います。 このときPTXの記法としては命令名に続いて丸め方法(.rn)を指定します。
TF32では、CUDA 11.2現在この丸め方法が零捨一入(.rna)しかありません。[1]
TF32では最近接偶数丸めは使えません。

次にFP32からTF32変換変換で、仮に最近接偶数丸め(RN)を行える場合と零捨一入(RNA)を用いた場合の誤差について考えてみます。
このときRNとRNAのそれぞれの丸めの流れと丸め前後の差はこの図のように表せます。

注目すべきは丸め前後の差の部分です。
RNでは0または±01なのに対し、RNAでは差が00また01(常に正!)となります。
これでは同符号の値に対する丸めは毎回同じ方向に誤差が発生するため、誤差が蓄積されやすく計算精度が劣化します

おわりに

今後のアーキでRNが入るといいですね。
あとTF32のTensorCoreはもっと速くなって欲しい。

参考

記事作成日:2021-04-03