この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載しています。転載の際は出典元にご連絡ください。 PyTorch の「錬金術」の速度を向上させるにはどうすればよいでしょうか? 最近、Lorenz Kuhn という人物が、最小限の投資で最高の効果でトレーニング速度を向上させるための錬金術のプロセスでまとめた 17 の方法を共有しました。基本的に、追加のライブラリを導入することなく、PyTorch で直接変更できます。
ただし、これらの方法はすべて、モデルが GPU 上でトレーニングされることを前提としていることに注意してください。 このシェアはRedditで600ヒットを獲得しました。 次に、速度向上から始めて、これらの方法を1つずつ紹介します。 1. 適切な学習率スケジュールを選択します。 選択された学習率スケジュールは、収束速度とモデルの一般化パフォーマンスに大きな影響を与えます。 Leslie Smith が提案した循環学習率 (CLR) と 1 サイクル戦略により、複雑なモデルのトレーニングを迅速に完了できます。 例えば、cifar10 で resnet-56 をトレーニングする場合、1cycle を使用すると、反復回数を 10 倍減らして元の論文と同じ精度を得ることができます。 最良の場合、このスケジュールは従来のスケジュールと比較して大幅な高速化を実現します。ただし、欠点の 1 つは、追加のハイパーパラメータが導入されることです。 なぜこれが機能するのでしょうか?考えられる説明の 1 つは、学習率を定期的に増加させることで、損失関数の鞍点をより速く通過できるようになるということです。 2. DataLoader で複数のワーカーを使用し、メモリを固定します。 torch.utils.data.DataLoader を使用する場合は、デフォルト値の 0 ではなく num_workers > 0 を設定し、デフォルト値の False ではなく pin_memory=True を設定してください。 Nvidia のシニア エンジニアである Szymon Micacz 氏は、4 つのワーカーと固定メモリを使用して、1 回のトレーニング エポックで 2 倍の高速化を達成しました。 ワーカーの数を選択するときは、利用可能な GPU の数の 4 倍に設定することを推奨することに注意してください。 ワーカーの数が多くても少なくても速度は遅くなり、ワーカーの数が増えると CPU とメモリの消費量が増加します。 3. バッチサイズを最大化します。 このアプローチは非常に議論を呼んでいます。ただし、一般的には、GPU メモリが許す最大のバッチ サイズを使用すると、トレーニングが高速化されます。 バッチ サイズを変更する場合は、学習率などの他のハイパーパラメータも調整する必要があります。一般的に、バッチ サイズを 2 倍にすると学習率も 2 倍になります。 これまで、異なるバッチ サイズを使用したいくつかの実験が行われており、バッチ サイズを 64 から 512 に増やすことで 4 倍の高速化が達成されました。 4. 自動混合精度 (AMP) を使用します。 PyTorch 1.6 には、PyTorch の自動混合精度トレーニングのネイティブ実装が含まれています。 一部の操作は、他の場所で使用される単精度 (FP32) と比較して、精度を損なうことなく半精度 (FP16) でより高速に実行できます。 次に、AMP がどの形式で操作を実行するかを自動的に決定するようにします。これにより、トレーニングが高速化され、メモリ使用量が削減されます。 一部の研究者は、NVIDIA V100 GPU で一般的な言語およびビジョン モデルをベンチマークした場合、AMP を使用すると、通常の FP32 トレーニングと比較してトレーニングが 2 倍、最大 5.5 倍高速化されることを発見しました。 現在、この方法で自動的にブロードキャストできるのは CUDA オペレーションのみです。
5. 異なるオプティマイザーを使用する たとえば、重み減衰 (L2 正則化ではなく) を備えた Adam である AdamW は、エラー実装とトレーニング時間の点で Adam を上回ります。 さらに、LARS や LAMB など、注目に値する非ローカル オプティマイザーもいくつかあります。 NVIDA の APEX は、Adam などの一般的なオプティマイザーの融合バージョンを実装しています。 Adam の PyTorch 実装と比較すると、GPU メモリへの複数回の転送が回避され、約 5% の速度向上が実現します。 6. cudNN ベンチマークを開きます。 モデル アーキテクチャが固定され、入力サイズが一定である場合は、torch.backends.cudnn.benchmark = True を設定して cudNN 自動チューナーを有効にすることができます。 cudNN で畳み込みを計算する複数の異なる方法をベンチマークして、最高のパフォーマンス メトリックを取得します。 7. CPU と GPU 間の頻繁なデータ転送を防ぎます。 テンソルを GPU から CPU に転送するには、常に tensor.cpu() を使用する必要があることに注意してください。.item() と .numpy() についても同様です。代わりに .detach() を使用してください。 テンソルを作成する場合は、キーワード引数 device=torch.device('cuda:0') を使用して、テンソルを GPU に直接割り当てることができます。 データを転送するコンテキストでは、転送後に同期ポイントがない限り、.to(non_blocking=True) を使用できます。 8. 勾配/活性化チェックポイントを使用します。 チェックポイントは計算をメモリと交換することによって機能します。チェックポイント部分は、計算グラフ全体のすべての中間アクティベーションが保存され、逆方向に計算されることを意味するのではなく、中間アクティベーションが保存され、逆方向パスで再計算されることを意味します。 モデルのどの部分にも適用できます。 具体的には、フォワードパスでは、関数は torch.no_grad() で実行されます。つまり、中間アクティベーションは保存されません。代わりに、フォワード パスは入力タプルと関数の引数を保存します。 後方パスでは、保存された入力と関数が取得され、関数に対して前方パスが再度実行され、中間アクティベーションを追跡し、これらのアクティベーション値を使用して勾配を計算します。 これにより、特定のバッチ サイズでの実行時間がわずかに長くなる可能性がありますが、メモリ フットプリントは大幅に削減されます。これにより、使用するバッチ サイズをさらに増やすことができ、GPU の使用率が向上します。 9. 勾配累積を使用します。 バッチ サイズを増やす別の方法は、optimizer.step() を呼び出す前に、複数の .backward() パスで勾配を蓄積することです。 この方法は主に GPU メモリの制限を回避するために開発されましたが、追加の .backward() ループとのトレードオフがあるかどうかは不明です。 10. マルチ GPU トレーニングには DistributedDataParallel を使用します。 分散トレーニングを高速化する方法には別の記事が必要になるかもしれませんが、簡単な方法は torch.nn.DataParallel の代わりに torch.nn.DistributedDataParallel を使用することです。 これにより、各 GPU を専用の CPU コアで駆動できるようになり、DataParallel の GIL 問題を回避できます。 11. グラデーションを 0 ではなく None に設定します。 .zero_grad() の代わりに .zero_grad(set_to_none=True) を使用してください。 こうすることで、メモリ アロケータが勾配を積極的に 0 に設定する代わりに勾配を処理できるようになり、速度が若干向上します。 ただし、副作用がないわけではないことに注意してください。 12. .tensor() の代わりに .as_tensor を使用する torch.tensor() は常にデータをコピーします。変換する numpy 配列がある場合は、データのコピーを回避するために torch.as_tensor() または torch.from_numpy() を使用します。 13. 必要ない場合はデバッグ API をオフにしてください。 Pytorch には、autograd.profiler、autograd.grad_check、autograd.anomaly_detection などの多くのデバッグ ツールが用意されています。必要なときに必ず使用し、不要なときはオフにしてください。そうしないと、トレーニングの速度が低下します。
14. グラデーションクリッピングを使用します。 勾配をクリッピングすると収束が速くなります。これはもともと RNN での勾配爆発を回避するために使用され、orch.nn.utils.clipgrad_norm を使用して実装できます。 勾配クリッピングによってどのモデルがどの程度高速化されるかは明らかではありませんが、RNN、Transformer ベースおよび ResNet ベースのアーキテクチャ、およびさまざまなオプティマイザーでは非常にうまく機能するようです。 15. BatchNorm の前にバイアスをオフにします。 これは非常に単純なアプローチで、BatchNormalization レイヤーの前のレイヤーのバイアスをオフにします。 2D 畳み込み層の場合、bias キーワードを False に設定することでこれを実行できます: torch.nn.Conv2d(...,bias=False,...) 16. 検証中は勾配計算をオフにします。 検証中に torch.no_grad() を設定します。 17. 入力とバッチの正規化を使用します。 ボーナスのヒント: JIT を使用してポイントごとの操作を統合します。 隣接するポイント単位の操作がある場合は、PyTorch JIT を使用してそれらを FusionGroup にマージし、単一のコアで起動することで、メモリの読み取りと書き込みを節約できます。 多くのネットユーザーは感謝の気持ちを表すと同時に、トレーニングに関する独自のヒントも共有した。 たとえば、この錬金術師は、より多くの RAM をダウンロードするという「18 番目の」方法を共有しました。 他に2つの提案がありました: 1. データ変換(データ拡張用)は、速度向上のもう 1 つの手段となります。単純な Python ステートメントのみを使用する一部の変換は、numba パッケージを使用することで高速化できます。 2. データセットを 1 つのファイルに前処理すると、速度も向上します。 これらに加えて、トレーニング速度を上げるためにどのような方法を使用できますか?ぜひシェアしてくださいね〜 |
>>: MITの博士課程の学生と北京大学の卒業生が、データセットにおけるこの一般的な「難しい問題」を解決するために自己教師ありアルゴリズムを使用した。
Google のアルゴリズムは毎年何百回も更新されます (Google は通常、これらの更新について...
人工知能(AI)技術の発展により、いつか「超人」的なAIが出現する日は来るのでしょうか?もしそうなれ...
「ディープラーニングフレームワークは、インテリジェント時代のオペレーティングシステムです。百度のP...
こんにちは、みんな。最近はAIGCのコンテンツを研究しており、公式アカウントのコンテンツを長い間更新...
Microsoft の人工知能チャットボット Bing Chat が、Google Chrome お...
特にインフラとして重要な役割を担うデータセンターにおいては、運用・保守は決して軽視できるものではなく...
この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...
[[257320]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...
大規模言語モデル (LLM) のサイズが大きくなるにつれて、これらのモデルを本番環境で推論に導入して...
LangChain、OpenAI、PineconeDB を使用して、任意のデータ ソースから質問応答...
[51CTO.com からのオリジナル記事] IT 部門のステータスが一向に向上しないのはなぜか、上...
翻訳者 | ブガッティ企画 | 梁策、孫淑娟機械学習と今日の世界におけるその応用については、すでにご...
UI デザイナーとフロントエンド エンジニアの間にニューラル ネットワークが必要になる場合があります...
ChatGPTの立ち上げから1年以上が経った今、2023年のAIに関する最大の話題は、技術そのもので...
[[413812]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...