大規模モデル並列化の救世主!ColwiseParallelで効率的にTensor Parallelismを使いこなす
Tensor Parallelismは、PyTorchにおける分散訓練を効率化する機能の一つです。大規模なモデルを複数のGPUに分割し、並列処理することで、計算量とメモリ使用量を削減することができます。
torch.distributed.tensor.parallel.style.ColwiseParallel
は、Tensor Parallelismにおける並列化スタイルの一つであり、列方向に分割して処理を行います。これは、行方向に分割する RowwiseParallel
と対照的なものです。
ColwiseParallel
の仕組み
ColwiseParallel
は、Tensorを列方向に分割し、各列を異なるGPUに割り当てます。これにより、行列演算における列方向の並列処理が可能になります。
具体的には、以下のようになります。
- Tensorを
world_size
個の列に分割します。 - 各列を異なるGPUに割り当てます。
- 各GPU上で、割り当てられた列に対する演算を実行します。
- 結果を同期化し、元のTensorの形に再構成します。
ColwiseParallel
の利点
ColwiseParallel
には、以下の利点があります。
- 行方向に分割する
RowwiseParallel
に比べて、一部の演算 (例:行列乗算) に対して効率的な場合があります。 - 行方向に分割する
RowwiseParallel
に比べて、通信量が少ない場合があります。 - 行方向に分割する
RowwiseParallel
に比べて、メモリ使用量が少ない場合があります。
ColwiseParallel
の例
以下は、ColwiseParallel
を使用して行列乗算を実行する例です。
import torch
import torch.distributed as dist
import torch.distributed.tensor.parallel as tp
world_size = 4
local_rank = dist.get_rank()
device = torch.device("cuda", local_rank)
# 入力テンソルを初期化
input1 = torch.randn(1024, 128, device=device)
input2 = torch.randn(128, 512, device=device)
# ColwiseParallel スタイルを作成
colwise_style = tp.ColwiseParallel(dim=1)
# ColwiseParallel スタイルで並列化した行列乗算を実行
output = tp.einsum("abc,bcd->abd", input1, input2, parallel_style=colwise_style)
ColwiseParallel
の注意事項
ColwiseParallel
を使用する際には、以下の点に注意する必要があります。
- 一部の演算は、
ColwiseParallel
で効率的に並列化できない場合があります。 - 入力テンソルの列数が
world_size
で割り切れるようにする必要があります。
torch.distributed.tensor.parallel.style.ColwiseParallel
は、PyTorch Tensor Parallelismにおける並列化スタイルの一つであり、列方向に分割して処理を行います。メモリ使用量や通信量が少ない場合があり、一部の演算に対して効率的な場合があります。
- Tensor Parallelism は、実験的な機能であり、今後変更される可能性があります。
- Tensor Parallelism は、PyTorch 1.6 以降で利用可能です。
- 本解説は、PyTorch 1.12.1 を対象としています。
import torch
import torch.distributed as dist
import torch.distributed.tensor.parallel as tp
world_size = 4
local_rank = dist.get_rank()
device = torch.device("cuda", local_rank)
# 入力テンソルを初期化
input1 = torch.randn(1024, 128, device=device)
input2 = torch.randn(128, 512, device=device)
# ColwiseParallel スタイルを作成
colwise_style = tp.ColwiseParallel(dim=1)
# ColwiseParallel スタイルで並列化した行列乗算を実行
output = tp.einsum("abc,bcd->abd", input1, input2, parallel_style=colwise_style)
print(f"Local rank: {local_rank}, output: {output}")
説明
world_size
とlocal_rank
を設定します。- 各GPU上でデバイスを初期化します。
- 入力テンソル
input1
とinput2
を初期化します。 ColwiseParallel
スタイルを作成します。ColwiseParallel
スタイルで並列化した行列乗算を実行します。- 結果を出力します。
tp.einsum
関数は、Tensor Parallelism で並列化されたテンソルに対して効率的に実行できる行列演算を提供します。ColwiseParallel
スタイルは、dim
引数を使用して、分割する次元を指定できます。デフォルトはdim=1
です。
- Tensor Parallelism は、複雑なモデルを並列化するために使用できます。
- このコードは、行列乗算以外にも様々な演算に適用できます。
しかし、いくつかの状況では ColwiseParallel
が最適な方法とは限りません。以下のような場合、ColwiseParallel
の代替方法を検討する必要があります。
行方向に分割が必要な場合
ColwiseParallel
は列方向に分割しかできません。行方向に分割が必要な場合は、RowwiseParallel
を使用します。
rowwise_style = tp.RowwiseParallel(dim=0)
メモリ使用量が少ない方法が必要な場合
ColwiseParallel
は、行方向に分割する RowwiseParallel
よりもメモリ使用量が多い場合があります。メモリ使用量が少ない方法が必要な場合は、ShardingParallel
を使用します。
sharding_style = tp.ShardingParallel(dim=1)
すべての演算が ColwiseParallel で効率的に並列化できない場合
一部の演算は、ColwiseParallel
で効率的に並列化できません。そのような演算に対しては、PipelineParallel
を使用します。
pipeline_style = tp.PipelineParallel(dim=1)
- Tensor Parallelism は、複雑なモデルを並列化するために使用できます。モデルの構造や演算の種類に応じて、最適な並列化スタイルを選択する必要があります。
- 上記以外にも、Tensor Parallelism には様々な並列化スタイルがあります。詳細は、PyTorch Tensor Parallelism ドキュメントを参照してください。