大規模モデル並列化の救世主!ColwiseParallelで効率的にTensor Parallelismを使いこなす


Tensor Parallelismは、PyTorchにおける分散訓練を効率化する機能の一つです。大規模なモデルを複数のGPUに分割し、並列処理することで、計算量とメモリ使用量を削減することができます。

torch.distributed.tensor.parallel.style.ColwiseParallel は、Tensor Parallelismにおける並列化スタイルの一つであり、列方向に分割して処理を行います。これは、行方向に分割する RowwiseParallel と対照的なものです。

ColwiseParallel の仕組み

ColwiseParallel は、Tensorを列方向に分割し、各列を異なるGPUに割り当てます。これにより、行列演算における列方向の並列処理が可能になります。

具体的には、以下のようになります。

  1. Tensorを world_size 個の列に分割します。
  2. 各列を異なるGPUに割り当てます。
  3. 各GPU上で、割り当てられた列に対する演算を実行します。
  4. 結果を同期化し、元の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}")

説明

  1. world_sizelocal_rank を設定します。
  2. 各GPU上でデバイスを初期化します。
  3. 入力テンソル input1input2 を初期化します。
  4. ColwiseParallel スタイルを作成します。
  5. ColwiseParallel スタイルで並列化した行列乗算を実行します。
  6. 結果を出力します。
  • 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 ドキュメントを参照してください。