PyTorch 1.6.0 リリースノート (翻訳)
翻訳 : (株)クラスキャット セールスインフォメーション
日時 : 07/30/2020
* 本ページは github PyTorch の releases の PyTorch 1.6.0 リリースノートに相当する、
“Stable release of automatic mixed precision (AMP). New Beta features include a TensorPipe backend for RPC, memory profiler, and several improvements to distributed training for both RPC and DDP.”
の Highlights を翻訳したものです:
自動混合精度 (AMP) のステーブルリリース。新しいベータ特徴は RPC のための TensorPipe バックエンド、メモリ・プロファイラーそして RPC と DDP の両者のための分散訓練への幾つかの改良を含みます。
ハイライト
PyTorch 1.6 リリースは幾つかの新しい API、パフォーマンス改良とプロファイリングのためのツール、そして分散訓練に基づいて分散データ並列 (DDP) とリモートプロシージャコール (RPC) の両者への主要更新を含みます。
幾つかのハイライトは以下を含みます :
- 自動混合精度 (AMP) 訓練が今ではネイティブにサポートされてステーブルな特徴です – NVIDIA の貢献に感謝します ;
- 特に機械学習のために構築された tensor-aware な point-to-point 通信プリミティブのために今追加されたネイティブ TensorPipe サポート ;
- 新しいプロファイリング・ツールは tensor-レベルのメモリ消費情報を提供します ; そして
- 分散データ並列 (DDP) 訓練とリモートプロシージャコール (RPC) パッケージのための多数の改良と新しい特徴。
それから、このリリースから先、特徴はステーブル、ベータとプロトタイプに分類されます。プロトタイプ特徴はバイナリ配布の一部としては含まれず代わりに nightlie を使用するか、コンパイラ・フラグでソースからのビルドを通して利用可能です。この変更が何を意味するか ここ の投稿で更に学習できます。
[ステーブル] 自動混合精度 (AMP) 訓練
AMP は Tensor コア GPU 上高いパフォーマンスと 50% までのメモリ節約を可能にする自動混合精度訓練を容易に有効にすることをユーザに可能にします。ネイティブにサポートされた torch.cuda.amp API を使用して、AMP は混合精度のための便利な方法を提供します、そこでは幾つかの演算は torch.float32 (float) データ型を使用して他の演算は torch.float16 (half) を使用します。線形層と畳込みのような幾つかの ops は float16 で遥かに高速です。reduction のような他の ops は float32 の動的範囲をしばしば必要とします。混合精度は各 op をその適切なデータ型に適合させることを試みます。
[Beta] RPC のための TensorPipe バックエンド
PyTorch 1.6 は RPC モジュールのための新しいバックエンドを導入します、これは TensorPipe ライブラリ、機械学習を対象とし PyTorch の分散訓練のための (集合的で断絶的な) 現在のプリミティブ (Gloo, MPI, …) を補完することを意図された、tensor-aware point-to-point 通信プリミティブを活用します。TensorPipe の pairwise で非同期な性質はデータ並列を越える新しいネットワーク・パラダイムに役立ちます : クライアント・サーバ・アプローチ (e.g. 埋め込み、Impala-スタイル RL の actor-learner 分離のためのパラメータサーバ) とモデルとパイプライン並列訓練 (think GPipe)、gossip SGD 等。
# One-line change needed to opt in torch.distributed.rpc.init_rpc( ... backend=torch.distributed.rpc.BackendType.TENSORPIPE, ) # No changes to the rest of the RPC API torch.distributed.rpc.rpc_sync(...)
[Beta] メモリ・プロファイラー
torch.autograd.profiler API は今ではメモリ・プロファイラーを含みます、これは CPU と GPU モデル内の異なる演算子の tensor メモリコストを貴方に調べさせます。
ここに API のサンプル使用方法があります :
import torch import torchvision.models as models import torch.autograd.profiler as profiler model = models.resnet18() inputs = torch.randn(5, 3, 224, 224) with profiler.profile(profile_memory=True, record_shapes=True) as prof: model(inputs) # NOTE: some columns were removed for brevity print(prof.key_averages().table(sort_by="self_cpu_memory_usage", row_limit=10)) # --------------------------- --------------- --------------- --------------- # Name CPU Mem Self CPU Mem Number of Calls # --------------------------- --------------- --------------- --------------- # empty 94.79 Mb 94.79 Mb 123 # resize_ 11.48 Mb 11.48 Mb 2 # addmm 19.53 Kb 19.53 Kb 1 # empty_strided 4 b 4 b 1 # conv2d 47.37 Mb 0 b 20 # --------------------------- --------------- --------------- ---------------
分散と RPC 特徴と改良
[Beta] DDP+RPC
PyTorch 分散は 2 つのパワフルなパラダイムをサポートします : モデルの full sync データ並列訓練のための DDP と、分散モデル並列を可能にする RPC フレームワークです。現在は、これら 2 つの特徴は独立的に動作してユーザはハイブリッド並列パラダイムを試すためにこれらを混在させて適合させることはできません。
PyTorch 1.6 を開始して、DDP と RPC を一緒にシームレスに動作させるために有効にしました、その結果ユーザはデータ並列とモデル並列の両者を達成するためにこれら 2 つのテクニックを結合できます。サンプルでは、ユーザは巨大な埋め込みテーブルをパラメータサーバに置いて埋め込み検索のために RPC フレームワークを使いますが、より小さい密パラメータはトレーナーにストアしてそして密パラメータを同期するために DDP を利用したいです。下は単純なコードスニペットです。
// On each trainer remote_emb = create_emb(on="ps", ...) ddp_model = DDP(dense_model) for data in batch: with torch.distributed.autograd.context(): res = remote_emb(data) loss = ddp_model(res) torch.distributed.autograd.backward([loss])
[Beta] RPC – 非同期ユーザ関数
RPC 非同期ユーザ関数はユーザ定義関数を実行するときサーバ側で yield して resume する機能をサポートします。この特徴の前には、呼び出し先 (= callee) がリクエストを処理するとき、一つの RPC スレッドがユーザ関数が戻るまで待ちました。ユーザ関数が IO (e.g., netsted RPC) やシグナル (e.g., アンブロックする他のリクエスト待ち) を含む場合、対応する RPC スレッドはこれらのイベントを待ってアイドルし続けます。その結果、幾つかのアプリケーションは非常に膨大な数のスレッドを使用して、追加の RPC リクエストを送らなければなりません、これらは潜在的にパフォーマンス劣化に繋がります。ユーザ関数をそのようなイベント上で yield するには、アプリケーションは以下を必要とします : 1) @rpc.functions.async_execution デコレータで関数を修飾する ; そして 2) 関数に torch.futures.Future を返させて Future オブジェクト上のコールバックとして resume ロジックをインストールさせます。例として下を見てください :
@rpc.functions.async_execution def async_add_chained(to, x, y, z): return rpc.rpc_async(to, torch.add, args=(x, y)).then( lambda fut: fut.wait() + z ) ret = rpc.rpc_sync( "worker1", async_add_chained, args=("worker2", torch.ones(2), 1, 1) ) print(ret) # prints tensor([3., 3.])
[Beta] Fork/Join 並列
このリリースは TorchScript における言語レベルコンストラクトのためのサポートと粗粒の (= coarse-grained) 並列性のための実行時サポートを追加します。このサポートは並列でアンサンブルにモデルを実行するか並列にリカレントネットの双方向コンポーネントを実行するような状況のために有用で、タスクレベルの並列性のための並列アーキテクチャ (e.g. 多数コア CPU) の計算パワーを解き放つ能力を許容します。
TorchScript プログラムの並列実行は 2 つのプリミティブ: torch.jit.fork と torch.jit.wait を通して有効にされます。下のサンプルでは、 foo の実行を並列化します :
import torch from typing import List def foo(x): return torch.neg(x) @torch.jit.script def example(x): futures = [torch.jit.fork(foo, x) for _ in range(100)] results = [torch.jit.wait(future) for future in futures] return torch.sum(torch.stack(results)) print(example(torch.ones([])))
- ドキュメント | Link
以上