Movatterモバイル変換


[0]ホーム

URL:


フリーエンジニアのソフト、ビジネス開発記録
PR

【機械学習】GPUの計算誤差について

機械学習のGPUの計算誤差デバイス
2024.10.30

機械学習を行う上で、GPUによる計算誤差が問題となる場合があります。

  • CPUとGPUで学習または推論を行った場合に結果に差が出る
  • GPUの型番やソフトウェアの環境(ドライバやCUDA等)が異なる場合に差が出る
  • 同じ計算を繰り返し行った場合に差が出る

など、環境間や繰り返しの再現性が確保できないといったことが起こります。

この記事ではNVIDIA製GPU(CUDA)とPyTorch環境におけるそれらの原因と対策についてまとめます。

浮動小数点計算の誤差

前提として、コンピュータで浮動小数点の計算を行う場合、CPU、GPU問わず誤差が生じるため、ニューラルネットワークのあらゆる箇所で誤差を生じる可能性があります。

原理を詳しく述べることはしませんが、そもそも一般的に使われる浮動小数点型の32bitや64bitという限られた情報量で実数を表す精度には限界があることが1つの原因です。

詳しい誤差の種類や原理については「浮動小数点 誤差」などで調べて頂くと良い解説ページが見つかると思います。

GPUで計算する際の非決定性

GPUで計算を行う場合、計算の高速化を行うため計算が非決定的となっている場合があります。つまり同じ計算を繰り返した場合に再現性が保たれません。

PyTorchでは再現性について以下のドキュメントが用意されています。

Reproducibility — PyTorch 2.6 documentation
pytorch.org

繰り返し再現性を得たい場合、前提として乱数のシードは固定する必要があります。PyTorch環境では以下のように使っているモジュール別に固定する必要があります。

Python
import torchimport randomimport numpyas np# PyTorchのシードを固定torch.manual_seed(0)# 以下、必要があればrandom.seed(0)# Pythonのrandomモジュールのシード固定np.random.seed(0)# numpyのシード固定

しかしこれらを行っても、GPUの計算の非決定性は残ります。以下のようにして決定的な計算を行うことができます。

Python
torch.backends.cudnn.benchmark =Falsetorch.use_deterministic_algorithms(True)

ただし計算を決定的に出来ない場合にはエラーとなるようで、再現性が保てるかは使用している計算による(つまりモデルによる)ということになります。

GPUアーキテクチャによる差

NVIDIAアーキテクチャの場合(TensorFloat32)

NVIDIAではAmpere以降のアーキテクチャでTensorFloat32(TF32)という浮動小数点型が導入されています。

A100 GPUの TensorFloat-32 が AI の学習とHPC を最大 20 倍高速化
TensorFloat-32 (TF32) は、行列演算 (テンソル演算とも呼ばれる) を処理するための、NVIDIA A100 GPU の新しい演算モードで、Volta GPU での単精度浮動小数点演算 (FP32) に比べて最大 10 ...
blogs.nvidia.co.jp

これは従来の32bit浮動小数点型(FP32)を置き換える目的で導入されているのですが、公式の解説通り値の大小を表す指数部は8bitと同様に確保されているものの、精度を表す仮数部はFP16相当のビット数しか確保されていません。

これはTF32は精度としては半精度しかないことになります。合計のビット数は符号部合わせて19bitなので、32という名前がついているのは少し疑問に思います。

NVIDIAが主張するように、多くの場合モデルの精度を落とさずに計算の高速化に寄与する可能性があるのですが、逆に言うと計算の構造によっては大きく精度が落ちる可能性があります。(実際、結果が大きく異なる計算に出くわしたことがあります)

そしてPyTorchの場合、バージョンにもよりますが32bitの計算をする場合デフォルトでこのTF32が有効になっているため、Ampere前後のアーキテクチャで計算を比較する場合には注意が必要な部分となります。

CUDA semantics — PyTorch main documentation
A guide to torch.cuda, a PyTorch module to run CUDA operations
pytorch.org

以下のようにして無効化することができます。

Python
torch.backends.cuda.matmul.allow_tf32 =Falsetorch.backends.cudnn.allow_tf32 =False

NVIDIA以外のアーキテクチャの場合

上で紹介したTensorFloat32以外にも、機械学習では一般的な浮動小数点型とは異なる構造の浮動小数点型が使われることがあります。

Googleはbfloat16という半精度型の浮動小数点型を提案しており、TPUで使用可能とのことです。

このように機械学習では一般的なものとは異なる構造の浮動小数点型を使う場合があり、CPUと比較する場合やGPUのアーキテクチャ、世代等を超えて比較する場合には注意が必要です。

最後に(再現性を保つことの必要性)

ここまで見てきたように、GPUではいくつかの要因により環境間や繰り返し計算で誤差が生じる可能性があります。

再現性を確保することが重視される場合、なるべく環境を揃え、非決定的な要因を排除することになりますが、その場合パフォーマンスが落ちる可能性が高いです(そもそも誤差の要因が基本的には高速化を目指した仕組みが原因のため)。また、再現性を必ず保てるとも限りません。

そして環境をなるべく揃えようとすると、環境が固定されアップデートが難しくなります。ご存知の通り現在機械学習分野はソフトウェアもハードウェアも日進月歩なのでこれは大きなデメリットとなる可能性があります。

それでも再現性の担保が重要な場合には仕方ないのですが、多くの場合もっと柔軟にモデルの出力が妥当かを確認したほうが良い場合もあります。

モデルの出力テンソルが小数点以下◯桁で一致することが大事なのではなく、分類問題だったら正しく分類できること、生成AIなら妥当な結果が生成されること、を様々な指標を用いて素直に評価した方が良い場合が多いです。

そもそも再現性の確保が必要なのかどうか、バランスよく考える必要があります。

関連記事

デバイス

MacBookのバックアップにはTimeMachine+NASがオススメ

MacBookのバックアップとしてNASとTimeMachineによる方法をおすすめします。NASの選定や設定方法についても解説しています。
デバイス

HHKB StudioからREALFORCE R3に乗り換えた理由

HHKB Studioを購入したものの納得できずREALFORCE R3に乗り換えました。乗り換えた理由や改めてREALFORCE R3のレビューを行います。
デバイス

HHKB Studio日本語配列のキーマップ紹介

他のキーボードやノートPC、Macの利用時にも違和感の少ない配列を目指してキーマップを作成しました。Studioのマウスボタンも有効利用する方法を紹介します。
デバイス

REALFORCE RC1 購入後1年のレビュー

REALFORCE RC1 日本語配列を購入してから1年が経過したので改めて良かった点、気になった点をレビューしました。
デバイス

REALFORCE RC1日本語配列のキーマップ紹介

REALFORCE RC1日本語配列をより使いやすくするキーマップの紹介です。デフォルトでほぼ完成されていますが、少しのカスタマイズでさらに使いやすくなります。
デバイス

REALFORCE RC1レビュー コンパクトの理想形か?

REALFORCE RC1日本語配列のレビューです。キーボード沼にハマりかけた私がようやくこれ!と思うものに出会えました。コンパクトの魅力と扱いやすさを両立した良いキーボードです。

コメント

コメントをどうぞコメントをキャンセル

メールアドレスが公開されることはありません。

キロヒー(kilohii)

フリーランスエンジニア。
会社員時代に組み込み開発やWindowsアプリ開発、データ分析等を経験したのち独立。
現在は業務委託で仕事をする傍ら、個人でスマホアプリ開発に取り組んでいます。

キロヒー(kilohii)をフォローする

検索

人気記事

GeForce GameReadyとStudioドライバの違い
2025.05.092025.07.19
MacBookのバックアップにはTimeMachine+NASがオススメ
2024.02.262025.06.30
REALFORCE RC1日本語配列のキーマップ紹介
2024.12.242025.06.30
32インチ4Kモニタの使い勝手が最高だった
2024.05.302025.06.30
HHKB Studio日本語配列のキーマップ紹介
2024.06.082025.06.24

新着記事

REALFORCE RC1 購入後1年のレビュー
2025.11.172025.11.23
Dartで連番でないenumとintを相互変換する方法
2025.10.31
GitクライアントでForkを選んだ話
2025.10.092025.10.17
Googleの検索結果にサイト名を表示する方法(WordPress)
2025.10.062025.10.08
iOS向けメトロノームアプリ「Tempo to Go」を公開しました
2025.09.212025.10.02

カテゴリー

タイトルとURLをコピーしました

[8]ページ先頭

©2009-2025 Movatter.jp