LOADING

読み込みが遅い場合はキャッシュを有効にしてください。ブラウザはデフォルトで有効になっています

AMP と Autocast

目次


Automatic Mixed Precision とは

デフォルトでは、ほとんどのディープラーニングフレームワークは 32 ビット浮動小数点アルゴリズムを使用してトレーニングされる。

2017 年、NVIDIA は、ネットワークをトレーニングする際に単精度(FP32)と半精度(FP16)を組み合わせ、FP32 とほぼ同じ精度を達成するために同じハイパーパラメータを使用する混合精度トレーニングの方法を研究した。

FP16 は半精度とも呼ばれ、コンピュータで使用される 2 進数の浮動小数点データ型で、2 バイトのストレージを使用する。 そして FLOAT は FP32 である。

Automatic Mixed Precision

  • 定義:
    モデルの計算をFP32(単精度)FP16(半精度)で効率的に切り替えて実行することで、パフォーマンス向上メモリ削減を実現する技術。
  • 目的:
    • 訓練速度の向上
    • GPU メモリ使用量の削減
    • 数値精度の維持

torch.cuda.amp.autocast 機能概要

役割

  • 推論・訓練中の演算に対して、自動的に適切な精度(FP16/FP32)を選択して実行
  • 特に数値安定性が重要な部分は FP32 を使用し、性能が重要な部分は FP16 を使用。

基本的な使い方

from torch.cuda.amp import autocast

with autocast():
    output = model(input)
    loss = loss_fn(output, target)

autocast の原理

  • 内部処理フロー:

    1. 算子呼び出し時に、入力テンソルの型に基づいて自動で精度変換
    2. FP16 で安全な演算のみ実行、不安定な演算は FP32 で実行。
    3. 出力は必要に応じて元の精度に戻す。
  • 適用範囲:

    • 多くの PyTorch 演算が対象。
    • GPU でのみ利用可能(CUDA サポートが必要)。

GradScaler との併用

なぜ必要か

  • FP16 では勾配消失や inf/nanが発生しやすいため、数値安定性を確保するために使用。
  • 勾配を一定倍率(scale)で拡大して保存し、更新前に縮小。

使用方法

from torch.cuda.amp import autocast, GradScaler

scaler = GradScaler()

for data, target in dataloader:
    optimizer.zero_grad()
    with autocast():    # 自動精度変換を有効化する。
        output = model(data)
        loss = loss_fn(output, target)
    scaler.scale(loss).backward() # 自動精度変換と勾配スケーリングを行う。
    scaler.step(optimizer) # 勾配を更新する。
    scaler.update() # 勾配スケーリングを更新する。

利点(メリット)

項目 内容
高速化 FP16 演算により、特に NVIDIA Ampere アーキテクチャ以降の GPU で顕著に高速化。
メモリ削減 半精度使用により、モデルサイズやバッチサイズの上限が緩和。
自動管理 手動でのデータ型指定不要で、開発負荷が軽減される。
精度保持 クリティカルな演算は FP32 で行われるため、精度低下が最小限。

注意点(デメリット)

問題点 対応策
ハードウェア依存 FP16 対応 GPU(例: NVIDIA Volta 以降)が必要。
NaN/Inf 問題 GradScaler を使用して勾配スケーリングを行う。
特定演算の非対応 一部の演算は FP16 未対応の場合あり(ドキュメント参照)。
デバッグ難易度 精度が自動選択されるため、中間出力の確認が複雑化する場合あり。

一般的な問題と対処法

Loss が NaN になるケース

  • 原因:
    • FP16 による数値誤差
    • log(0) や除算ゼロなど数学的エラー
  • 解決策:
    • GradScaler を必ず併用
    • 安全な値で clamp(例: x.clamp(min=1e-8)

モデルが深すぎて勾配消失

  • 対処法:
    • 層ごとの勾配クリッピング
    • 活性化関数や正則化手法を見直し

サンプルコード

基本的な AMP 訓練ループ

from torch.cuda.amp import autocast, GradScaler

model = MyModel().cuda()
optimizer = torch.optim.Adam(model.parameters())
scaler = GradScaler()

for epoch in range(epochs):
    for inputs, targets in dataloader:
        inputs, targets = inputs.cuda(), targets.cuda()
        optimizer.zero_grad()

        with autocast():
            outputs = model(inputs)
            loss = loss_fn(outputs, targets)

        scaler.scale(loss).backward()
        scaler.step(optimizer)
        scaler.update()

まとめ

項目 内容
AMP FP32 と FP16 を自動で切り替える技術
autocast 自動で演算精度を最適化するコンテキストマネージャー
GradScaler FP16 勾配のスケーリングを行い、数値不安定性を回避
推奨環境 NVIDIA GPU(Volta 以降)、CUDA 対応アプリケーション
主な利点 パフォーマンス向上、メモリ節約、自動管理による簡潔さ
注意点 NaN/Inf 問題、一部演算の FP16 非対応、デバッグの複雑化

参考文献

avatar
lijunjie2232
個人技術ブログ
My Github
目次0