3行のコードでモデルのトレーニングを高速化: このアルゴリズムにより、GPUの古い木に新しい花が咲きます

3行のコードでモデルのトレーニングを高速化: このアルゴリズムにより、GPUの古い木に新しい花が咲きます

[[313508]]

Baidu と Nvidia Research Institute は、N カードの基盤となるコンピューティング最適化を組み合わせて、ニューラル ネットワークのトレーニングを加速する効果的な方法を提案しました。この方法は事前トレーニングだけでなく、誰もが BERT を微調整している今日でも非常に役立ちます。

すべては ICLR 2018 の論文から始まりました。

「MIXED PRECISION TRAINING」は、BaiduとNvidia Research Instituteが共同で発表したものです。Nカードの基盤となるコンピューティング最適化を組み合わせ、非常に効果的なニューラルネットワークトレーニング加速方法を提案しています。事前トレーニングだけでなく、誰もがBERTを微調整している今日でも非常に役立ちます。

さらに、調査では、Baidu の Paddle フレームワークが混合精度トレーニングをサポートしているだけでなく、Tensorflow と Pytorch にも対応する実装があることが分かりました。まず理論について説明し、次に 3 つの主要なディープラーニング フレームワークで混合精度トレーニングがどのように実装されているかを分析します。

理論的原則

ニューラル ネットワークをトレーニングしたことがある人なら誰でも、ニューラル ネットワークのパラメーターと中間結果のほとんどが単精度浮動小数点数 (つまり float32) を使用して保存および計算されることを知っています。ネットワークが非常に大きくなると、半精度浮動小数点数を使用するなど、浮動小数点数の精度を下げることは、明らかに計算速度を上げ、ストレージ オーバーヘッドを削減する非常に直接的な方法です。

しかし、副作用も明らかです。浮動小数点数の精度を直接下げると、必然的にモデルのトレーニング精度が低下します。しかし、より優れた人が必ず存在します。この記事では、モデルの精度の低下を効果的に防ぐために 3 つのメカニズムを使用します。小曦が一つずつ教えてくれるのを待っててくださいo(* ̄▽ ̄*)ブ

ウェイトバックアップ(マスターウェイト)

コンピュータにおける半精度浮動小数点数 (float16) の表現は、1 ビットの符号ビット、5 ビットの指数ビット、10 ビットの仮数ビットに分かれており、表現できる最小の正の数は 2^-24 (つまり、精度はここで終了) であることがわかっています。ニューラル ネットワークの勾配が非常に小さい場合、ネットワークのトレーニング プロセスの各ステップの反復回数 (非常に小さい勾配 ✖ また非常に小さい学習率) は小さくなります。float16 精度で表現できないほど小さい場合、対応する勾配を更新できません。

この論文では、中国語データセットでDeepSpeech 2モデルをトレーニングする際に生成された勾配を数え、学習率を掛ける前に、勾配の約5%が悲惨なことに0になり(2^-24より高い精度の勾配は直接0になる)、大きな損失が発生することを発見しました/(ㄒoㄒ)/~~

さらに困難なのは、反復ボリュームが生き残り、それ自身に専念する準備ができたときです。 。 。ネットワーク内の重みは更新したい量よりもはるかに大きいことが多いため、反復量が Float16 の現在の範囲で表現できる最小間隔よりも小さい場合、更新は失敗します (盲目的に泣く ┭┮﹏┭┮なぜ私にとってはこんなに難しいのでしょうか?)

それで何をすればいいのでしょうか?著者は、順方向伝播と勾配計算の両方に float16 を使用し、ネットワーク パラメーターの勾配の保存には float32 を使用するという、非常にシンプルですが効果的な方法を提案しています。これにより、上記の2つの問題がある程度解決されます~~~

トレーニング曲線を見てみましょう。青い線は通常の float32 精度トレーニング曲線、オレンジ色の線は float32 を使用してネットワーク パラメータを保存する学習曲線、緑の線は float32 を使用してパラメータを保存しない曲線です。これら 2 つを比較すると見劣りします。

損失スケーリング

上記のマスターウェイトを使用すると、多くのネットワークを高精度でトレーニングすることがすでに可能ですが、強迫性障害を少し抱えているXiao Xiは、まだ何かがおかしいと感じていますo((⊙﹏⊙))o。

float32 を使用して勾配を保存しても精度は失われませんが、計算中に現れる指数が -24 未満の勾配は失われます。これは、漏れやすいふるいを使って川から村まで水を運ぶのと同じです。より多くの水を貯めるために、村人たちは貯水ボウルを大きな桶に取り替えました。しかし、ふるいはまだ漏れていて、途中で水が漏れ出していました。 。

そこで損失スケーリング法が生まれました。まず、著者はトレーニング中に活性化関数の勾配の分布を数えました。ネットワーク内の勾配は非常に小さいことが多いため、FP16 を使用する場合、右側の大きな範囲は使用されません。この場合、損失を増幅することで勾配全体を右にシフトすることができ、精度によりいつでも 0 になる勾配を減らすことができます。

そこで疑問になるのが、損失を合理的に増幅するにはどうすればいいのか、ということです。最も簡単な方法は定数スケーリングで、損失を S 倍に増幅します。 float16 が表すことができる最大の正の数は 2^15*(1+1-2^-10)=65504 です。ネットワーク内の勾配を数え、最大勾配が float16 が表すことができる最大の整数を超えないように定数 S を計算できます。

もちろん、よりインテリジェントな動的調整(自動スケーリング)もありますo(* ̄▽ ̄*)ブ

まず、大きな S を初期化します。勾配がオーバーフローする場合は、S を元の値の半分に減らします。多くの反復で勾配がオーバーフローしない場合は、S を 2 倍に拡大することもできます。などにより、動的な損失スケーリングが実現されます。

オペレーションの精度

さらに一歩進んで、ニューラル ネットワークにおける演算は、主に 4 つのカテゴリに分類できます。混合精度トレーニングでは、より高い精度が求められる一部の演算の計算プロセスで float32 を使用し、保存時に float16 に変換します。

  • 行列乗算: linear、matmul、bmm、conv
  • ポイントワイズ: relu、シグモイド、tanh、exp、log
  • 削減: バッチノルム、レイヤーノルム、合計、ソフトマックス
  • 損失関数: 交差エントロピー、L2損失、重み減衰

行列の乗算とほとんどの点計算は float16 を使用して直接計算して保存できますが、削減、損失関数、および一部の点関数 (関数値が変数よりもはるかに大きい exp、log、pow など) ではより高度な処理が必要になるため、計算には float32 が使用され、結果は float16 に変換されて保存されます。

まとめ: 3つの主要なディープラーニングフレームワークを開く方法

混合精度トレーニングでは、前方計算と後方計算の両方で半精度浮動小数点数を使用し、以前の研究のように追加のハイパーパラメータを導入しません。さらに重要なのは、実装が非常にシンプルでありながら、非常に大きなメリットをもたらすことができることです。ビデオメモリを半分にし、速度を 2 倍にしてモデルの精度を維持するのは、まさに驚異的です。

ハードコアな技術的詳細を読んだ後、コードの実装を見てみましょう。このような強力な混合精度トレーニングのコード実装は、あまり単純であってはなりません😮

ピトーチ

自動混合精度(AMP)を輸入、998も288も不要、たった3行で簡単に使えます!

  1. from apex import ampmodel, optimizer = amp.initialize(model, optimizer, opt_level= "O1" ) # ここでは "O1" であり、"01" ではありません。 with amp.scale_loss(loss, optimizer) as scaled_loss:scaled_loss.backward()

例を見てみましょう。上記の 3 行を元のコードの正しい位置に挿入すると、クールな半精度トレーニングが実現します。

  1. import torchfrom apex import ampmodel = ... optimizer = ...#モデルとオプティマイザーをラップします。model, optimizer = amp.initialize(model, optimizer, opt_level= "O1" ) for data, label in data_iter: out = model(data) loss = criterion(out, label) optimizer.zero_grad() #損失のスケーリング、loss.backward() の代わりに amp.scaled_loss(loss, optimizer) as scaled_loss:scaled_loss.backward() optimizer.step()

テンソルフロー

混合精度トレーニングを一文で実装する: Python スクリプトで環境変数を変更し、環境変数を設定する

  1. os.environ[TF_ENABLE_AUTO_MIXED_PRECISION] = 1  

さらに、オプティマイザーは pytorch と同様の方法でパッケージ化することもできます。

グラフベースの例

  1. opt = tf.train.AdamOptimizer()# 行を追加opt = tf.train.experimental.enable_mixed_precision_graph_rewrite( opt, loss_scale= dynamic ) train_op = opt.miminize(loss)

Kerasベースの例

  1. opt = tf.keras.optimizers.Adam()# 行を追加opt = tf.train.experimental.enable_mixed_precision_graph_rewrite( opt, loss_scale= dynamic ) model.compile(loss=loss, optimizer=opt)model.fit(...)

パドルパドル

混合精度トレーニングを一文で実装するための設定を追加(驚いた🙃 結局のところ、混合精度トレーニングはBaiduによって提案され、内部で長い間熟練して使用されてきた)

  1. --use_fp16=有効 

たとえば、BERT に基づいて XNLI タスクを微調整する場合は、実行中に use_fp16 を true に設定するだけで済みます。

  1. export FLAGS_sync_nccl_allreduce=0export FLAGS_eager_delete_tensor_gb=1export CUDA_VISIBLE_DEVICES= 0 1 2 3 4 5 6 、7BERT_BASE_PATH= "chinese_L-12_H-768_A-12" TASK_NAME= XNLI DATA_PATH=/path/to/xnli/data/CKPT_PATH=/path/to/save/checkpoints/python -u run_classifier.py --task_name ${TASK_NAME} --use_fp16= true #!!!!!! 1 行追加 --use_cuda true --do_train true --do_val true --do_test true --batch_size 32 --in_tokens false --init_pretraining_params ${BERT_BASE_PATH}/params --data_dir ${DATA_PATH} --vocab_path ${BERT_BASE_PATH}/vocab.txt --checkpoints ${CKPT_PATH} --save_steps 1000 --weight_decay 0.01 --warmup_proportion 0.1 --validation_steps 100 --epoch 3 --max_seq_len 128 --bert_config_path ${BERT_BASE_PATH}/bert_config.json --learning_rate 5e- 5 --skip_steps 10 --num_iteration_per_drop_scope 10 --verbose true  

<<:  25倍のパフォーマンス向上: RustはCとC++に取って代わり、機械学習のPythonバックエンドとして好まれるようになると期待されています。

>>:  なぜ機械学習展開プラットフォームを Python ではなく Go で作成したのでしょうか?

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

...

...

自動運転車を壁に衝突させ、他人の顔を使って代金を支払う:最新のAIの抜け穴が私たちの目を覚まさせる

かつて専門家が懸念していたAIアルゴリズムの抜け穴は起こり得るし、予想もしなかった抜け穴さえも起こり...

機械学習プロジェクトにおける特徴エンジニアリングの 5 つのベスト プラクティス

私たちは長年にわたり、機械学習プロジェクトで何が機能し、何が機能しないかを特定するために、さまざまな...

...

...

転移学習の魔法:ディープラーニングは誰でも利用できるようになる

1 年前、私は数人の友人と機械学習 API を構築するためのオープンソース プラットフォームである ...

人工知能が高等教育を支援する:変化と持続

[[434825]]人工知能が教育に浸透する中で、我々は「静をもって動を制御する」という決意を持ち、...

...

...

Java 上級: 負荷分散のための 5 つのアルゴリズムの詳細な理解

この記事はWeChatの公開アカウント「Android Development and Progra...

アルトマンが帰ってきた!取締役会解散の強い要求、OpenAIの究極の宮廷闘争が始まる

スティーブ・ジョブズが解雇されてから王として復帰するまでに12年かかりましたが、サム・アルトマンの場...

...

制御可能な人工知能には未来がある

8月29日、2019年世界人工知能会議が上海で開幕した。世界各国の著名なテクノロジー企業や学界、産業...