

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# ステップ 1: SageMaker の分散モデル並列ライブラリを使用して独自のトレーニングスクリプトを変更する
<a name="model-parallel-customize-training-script"></a>

このセクションでは、Amazon SageMaker AI モデル並列処理ライブラリのコア機能を使用するためにトレーニングスクリプトをカスタマイズする方法を学習します。ライブラリ固有の API 関数とパラメータを使用するには、このドキュメントを『*SageMaker Python SDK ドキュメント*』にある「[SageMaker モデル並列ライブラリ API](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html)」と共に使用することをお勧めします。

これらのセクションで提供されるトレーニングスクリプトの例は簡略化されており、ライブラリを使うために必要な変更を強調するように考えられています。SageMaker モデル並列処理ライブラリと共に TensorFlow または PyTorch トレーニングスクリプトを使用する方法を示す、エンドツーエンドで実行可能なノートブックサンプルについては、「[Amazon SageMaker AI モデル並列処理ライブラリ v2 の例](distributed-model-parallel-v2-examples.md)」を参照してください。

**Topics**
+ [SageMaker モデル並列処理ライブラリを使用してトレーニングスクリプトのモデルを分割する](#model-parallel-model-splitting-using-smp-lib)
+ [TensorFlow トレーニングスクリプトを変更する](model-parallel-customize-training-script-tf.md)
+ [PyTorch トレーニングスクリプトを変更する](model-parallel-customize-training-script-pt.md)

## SageMaker モデル並列処理ライブラリを使用してトレーニングスクリプトのモデルを分割する
<a name="model-parallel-model-splitting-using-smp-lib"></a>

トレーニングスクリプトを変更してモデル分割を設定するには、自動分割と手動分割の 2 つの方法があります。

### 自動モデル分割
<a name="model-parallel-automated-model-splitting"></a>

SageMaker のモデル並列処理ライブラリを使用すると、自動モデル分割 (自動モデルパーティショニングとも呼ばれる) を活用できます。****このライブラリは、メモリのバランスを取り、デバイス間の通信を最小限に抑え、パフォーマンスを最適化するパーティショニングアルゴリズムを使用します。自動パーティショニングアルゴリズムを設定して、速度やメモリを最適化できます。

また、手動でモデルを分割することもできます。モデルアーキテクチャに精通していて、モデルを効率的に分割する方法について十分に理解している場合を除き、自動モデル分割をお勧めします。

#### 仕組み
<a name="model-parallel-automated-model-splitting-how-it-works"></a>

自動パーティショニングは、最初のトレーニングステップで、`smp.step` で修飾された関数が最初に呼び出されたときに行われます。この呼び出し中、ライブラリは最初に CPU RAM 上にモデルのバージョンを構築し (GPU メモリの制限を回避するため)、次にモデルグラフを分析してパーティショニングを決定します。この決定に基づいて、各モデルパーティションが GPU にロードされた後、最初のステップが実行されます。これらの分析とパーティショニングのステップのため、最初のトレーニングステップには時間がかかる場合があります。

どちらのフレームワークでも、ライブラリは、 AWS インフラストラクチャ用に最適化された独自のバックエンドを介してデバイス間の通信を管理します。

自動パーティション設計はフレームワークの特性に適応し、ライブラリは各フレームワークでより自然な粒度レベルでパーティショニングを行います。例えば、TensorFlow では、それぞれ固有のオペレーションを異なるデバイスに割り当てできますが、PyTorch では、割り当てはモジュールレベルで行われ、各モジュールは複数のオペレーションで構成されます。次のセクションでは、各フレームワークにおける設計の詳細を確認します。

##### PyTorch による自動モデル分割
<a name="model-parallel-auto-model-split-pt"></a>

最初のトレーニングステップでは、モデル並列処理ライブラリは、モデルグラフを構築し、テンソルとパラメータの形状を決定するためのトレースステップを内部的に実行します。このトレースステップの後、ライブラリは、モデル内のネストされた `nn.Module` オブジェクトと、保存されている `nn.Parameters` の量や各 `nn.Module` の実行時間などのトレースから収集された追加データからなるツリーを構築します。

次に、ライブラリは、ルートからこのツリーをトラバースし、各 `nn.Module` をデバイスに割り当てるパーティショニングアルゴリズムを実行し、計算負荷 (モジュール実行時間で測定) とメモリ使用量 (保存されている `nn.Parameter` サイズとアクティベーションの合計で測定) のバランスを取ります。複数の `nn.Modules` が同じ `nn.Parameter` を共有する場合、同じパラメータの複数のバージョンを維持しないように、これらのモジュールは同じデバイス上に配置されます。パーティショニングが決定されると、割り当てられたモジュールと重みがデバイスにロードされます。

`smp.step` デコレータを PyTorch トレーニングスクリプトに登録する方法については、「[PyTorch による自動分割](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16)」を参照してください。

##### TensorFlow による自動モデル分割
<a name="model-parallel-auto-model-split-tf"></a>

モデル並列処理ライブラリは、トレーニング可能な変数のサイズとグラフ構造を分析し、内部でグラフパーティショニングアルゴリズムを使用します。このアルゴリズムは、デバイス間で必要な通信量を最小化することを目的に、次の 2 つの制約条件の下での、各オペレーションに対するデバイスの割り当てを導き出します。
+ 各デバイスに保存されている変数の数のバランスを取る
+ 各デバイスで実行されるオペレーションの数のバランスを取る

`optimize` に `speed` を指定した場合 (Python SDK のモデル並列処理パラメータで)、ライブラリは各デバイスにおけるオペレーションと `tf.Variable` オブジェクトの数のバランスを取ろうとします。それ以外の場合は、`tf.Variables` の合計サイズのバランスを取ろうとします。

パーティショニングの決定が行われると、ライブラリは各デバイスの実行に必要なサブグラフのシリアル化された表現を作成し、各デバイスにインポートします。パーティショニング中、ライブラリは同じ `tf.Variable` を使用するオペレーションと、同じ Keras レイヤーの一部であるオペレーションを同じデバイス上に配置します。また、TensorFlow によって課されるコロケーション制約にも対応します。これは、例えば、`tf.Variable` を共有する 2 つの Keras レイヤーがある場合、これらのレイヤーに含まれるすべてのオペレーションは、1 つのデバイスに配置されることを意味します。

`smp.step` デコレータを PyTorch トレーニングスクリプトに登録する方法については、「[TensorFlow による自動分割](model-parallel-customize-training-script-tf.md#model-parallel-customize-training-script-tf-23)」を参照してください。

##### フレームワーク間での自動モデル分割の比較
<a name="model-parallel-auto-model-split-comparison"></a>

TensorFlow では、計算の基本ユニットは `tf.Operation` であり、TensorFlow はモデルを `tf.Operation` の有向非巡回グラフ (DAG) として表すため、モデル並列処理ライブラリはこの DAG を分割して、各ノードが 1 つのデバイスに向かうようにします。非常に重要な点は、`tf.Operation` オブジェクトにはカスタマイズ可能な属性が十分豊富にあり、すべてのモデルがそのようなオブジェクトのグラフで構成されることが保証されているという意味で、それらのオブジェクトが普遍的であるということです。

一方、PyTorch には、十分に豊富で普遍的なオペレーションに相当する概念はありません。これらの特性を持つ PyTorch で最も近い計算ユニットは `nn.Module` であり、これははるかに高い粒度レベルです。ライブラリが PyTorch でこのレベルでパーティショニングを行うのはこのためです。

### 手動モデル分割
<a name="model-parallel-manual-model-splitting"></a>

デバイス間でモデルのパーティショニング方法を手動で指定する場合は、`smp.partition` コンテキストマネージャーを使用します。手動パーティショニング用にコンテキストマネージャーを設定する方法については、以下のページを参照してください。
+ [TensorFlow による手動分割](model-parallel-customize-training-script-tf.md#model-parallel-customize-training-script-tf-manual)
+ [PyTorch による手動分割](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16-hvd)

変更を加えた後にこのオプションを使用するには、ステップ 2 で `auto_partition` を `False` に設定し、SageMaker Python SDK のフレームワーク推定器クラスで `default_partition` を定義する必要があります。`smp.partition` コンテキストマネージャーを介してパーティションに明示的に配置されていないオペレーションは、`default_partition` で実行されます。この場合、自動分割ロジックはバイパスされ、各オペレーションはユーザーの指定に基づいて配置されます。結果のグラフ構造に基づいて、モデル並列処理ライブラリがパイプライン化された実行スケジュールを自動的に作成します。