要件を満たすベースラインから始める
通常の入力、エッジケース、決定境界を含む短いデータセットを選んでください。モデル、重み、前処理、train または eval モードを固定してください。2つのモデルや2つのバッチの比較では、その差異を精度に帰属させることはできません。
損失だけでなく、アプリケーションに有用な出力を記録してください。分類器の場合、スコアと決定を含めることができます。回帰の場合、誤差と極値を含めることができます。ベースラインに NaN や inf が存在しないことをすでに確認してください。誤った FP32 実行は、ビット数が多いからといって信頼できる基盤にはなりません。
試行前に許容範囲、最低品質、非有限値の不在を定めてください。PyTorch は、浮動小数点計算がデバイスや実行パス間で同一の結果を保証するものではないと注意を促しています。
autocast、数値フォーマット、GradScaler を区別する
autocast は計算ポリシーに従って一部の演算の型を選択します。プログラム全体を単一の形式に変換するわけではありません。この使い方では、モデル全体を手動で half() に変換することは避けてください。現在のドキュメントは torch.autocast または torch.amp.autocast を推奨しており、旧インターフェースの torch.cuda.amp は非推奨です。
GradScaler は学習中に損失と勾配のスケールに対して作用します。backward を行わない推論の高速化手段として使うものではありません。FP16 は BF16 より数値範囲が狭く、BF16 向けに設計されたモデルは FP16 でオーバーフローする可能性があります。したがって、スケールの低下が繰り返されたからといって問題が解決したとは言えません。
形式はモデルの制約と実際に使用する演算から選び、その後ターゲットでの対応状況を確認してください。カードの製品名や PyTorch の準備に関する好みは、自作オペレータが目的のカーネルを持つことの証明にはなりません。
表をスクロールしてすべての列を表示してください。| 選択 | 役割 | 必要な確認 |
|---|---|---|
| FP32 リファレンス | プロジェクトの比較基準 | 有限な出力と期待される品質 |
| Autocast FP16 | 一部の演算は低精度 | 数値範囲と勾配 |
| Autocast BF16 | 範囲と精度の別のトレードオフ | 利用可能なオペレータと品質 |
| GradScaler | 勾配のスケール管理 | 実際に適用される更新 |
学習の各ステップを正しい順序で配置する
提示するコード断片は、モデルとオプティマイザが既に構築済みで、入力とターゲットが同じ GPU 上にあり、損失がスカラーであることを前提としています。これは実行されておらず、いかなる提供内容の検証でもありません。autocast コンテキストは forward と損失を囲み、backward はその終了後に実行されます。scaler はバッチごとではなく、学習セッションにつき一度作成します。
勾配を検査したりクリップしたりするには、まず unscale_ でスケール係数を取り除きます。公式の AMP サンプルでは、これをオプティマイザごとに一度、その更新に用いる勾配の蓄積後に行うよう明示されています。以下のクリップ閾値 1.0 は、プロジェクトで選ぶべき例示的な値であり、普遍的な推奨値ではありません。
ここでのガードは、損失、勾配、または全ノルムが有限でない場合に診断を中断します。これらの CPU 読み取りは負荷が高いため、このコード断片の所要時間を計測しないでください。蓄積、複数のオプティマイザ、スケジューラにはそれぞれ独自の更新定義が必要です。
import torch
# 前提条件: model、optimizer、loss_fn、inputs、targets が存在すること。
# モデルと入力は同じ CUDA/HIP デバイス上にあること。
dtype = torch.float16 # 検証すべき選択。BF16 は別の試行。
scaler = torch.amp.GradScaler("cuda", enabled=(dtype == torch.float16))
# ループ内に配置し、scaler はバッチ間で保持する。
optimizer.zero_grad(set_to_none=True)
with torch.autocast(device_type="cuda", dtype=dtype):
prediction = model(inputs)
loss = loss_fn(prediction, targets)
if not bool(torch.isfinite(loss).item()):
raise FloatingPointError("Perte non finie : interrompre le diagnostic")
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
if any(p.grad is not None and
not bool(torch.isfinite(p.grad).all().item())
for p in model.parameters()):
raise FloatingPointError("Gradient non fini : interrompre le diagnostic")
torch.nn.utils.clip_grad_norm_(
model.parameters(), max_norm=1.0, error_if_nonfinite=True,
)
scaler.step(optimizer)
scaler.update()実例:近い選択肢でも互換性があるとは限らない
最大スコアのクラスを選択するサービスを仮定します。ある教育用の入力では、参照実装が非常に近い2つのスコアを生成します: 1.0000 と 1.0003。別の数値経路では、それらの順序が変わるか、同点が生じる可能性があります。これらの数値は決定境界を例示するものであり、FP16 や BF16 の実測出力ではありません。
適切な検証には2つのレベルがあります。明示的な許容範囲でスコアを比較し、次に決定と同点時に適用されるルールを比較します。絶対値でわずかな差でも、選択されるアクションが変わることがあります。逆に、数値的に目に見える差でも、しきい値が観測されたスコアから遠く離れているタスクでは結果に影響しないことがあります。
識別子、リファレンス出力、AMP 試行、意思決定への影響を記録します。結果を読む前に合格基準を定めます。厄介なケースを消すために許容範囲を広げてはいけません。スケールの異なる出力には別々の基準が必要になる場合があります。
表をスクロールしてすべての列を表示してください。| 基準 | 参照番号 | AMP 試行 | 判断 |
|---|---|---|---|
| 有限の出力 | 確認事項 | 確認事項 | 説明のつかない非有限は拒否する |
| 数値の差 | 保持された値 | 差は計算すること | 試行前に定義した許容範囲 |
| アプリケーション上の判断 | クラスまたはアクション | クラスまたはアクション | 変更点を確認する |
| 固定データセットでの品質 | 測定対象 | 測定対象 | プロジェクトのしきい値を守る |
NaN とスキップされた更新の解釈
非有限値が現れたら、それを生成する最初のステップを探します。入力、中間出力、損失、または勾配です。同じケースをリファレンスで再実行し、疑わしい演算の周辺で autocast を局所的に無効化し、その入力の型も確認します。トレーニング全体を FP32 に戻すことは比較には役立ちますが、問題を自動的に特定するわけではありません。
スケーラーは勾配に inf や NaN が含まれる場合、更新を見送ることがあります。したがって、ループが継続していても、必ずしもイテレーションと同じ回数の更新が行われたわけではありません。診断中はこの挙動を記録します。実際の更新回数に従うと想定した学習ポリシーを、盲目的に進めてはいけません。
損失が有限であっても、勾配が有限であることは保証されません。逆に、一度の偶発的なインシデントだけでトレーニングが使えないと断定することはできません。頻度、進行状況、品質を調べます。AMP のレシピは、autocast とスケーリングのどちらかが疑わしい場合に、それぞれを個別に切り分ける方法を提供します。
再現可能なロールバックの準備
試行の前に、リファレンス設定、重み、オプティマイザの状態、一貫したチェックポイントを保存します。トレーニングでスケーラーを使用している場合、その状態も再開の一部です。dtype と FP32 のままにした領域があれば文書化します。異なるポリシーで再開することは特定すべき実験的な変更であり、暗黙的に等価な継続ではありません。
出力が非有限になった場合、品質が定めた基準を外れた場合、または更新が実用的に進まなくなった場合は、以前の設定に戻します。このロールバックのきっかけとなったケースを保存します。変更後は、期間を延ばす前に同じデータセットで比較をやり直します。
Kernodeck のチェックポイント演習では、AMP なしの CPU 再開を検証します。その比較方法を再利用し、ループが実際に消費する状態を追加します。
数値検証の後にのみ利得を測定する
検証後は、詳細な診断なしでメモリと時間を測定します。形状、バッチ、モデル、品質は保ちます。スカラー値の読み取り、同期、プロファイラは所要時間を変える可能性があるため、最終測定からは侵入的なチェックを外します。
ROCm では、PyTorch のデバイス名は依然として cuda であり、対応するインターフェースが再利用されます。これは、NVIDIA と同じカーネルや同一の結果を保証するものではありません。ターゲット上でプロジェクトのバックエンドと演算子を確認します。このガイドは、固定のメモリ削減、速度の倍増、Kernodeck の準備の互換性を一切謳っていません。