モデルを複数GPUに分割 - Shinichi0713/LLM-fundamental-study GitHub Wiki

はい、PyTorchでモデルを複数GPUに分割して並列計算することは可能です。ただし、
「分割」にはいくつかの方法・意味合いがありますので、代表的な手法とその特徴を説明します。


1. Data Parallel(データ並列)

  • モデル全体を各GPUに「複製」し、異なるデータを並列で処理します。
  • 代表例:nn.DataParallelnn.DistributedDataParallel
  • 1つのGPUにモデル全体が入る必要がある(巨大なモデルには不向き)

2. Model Parallel(モデル並列)

  • モデルの一部をGPU0、残りをGPU1…のように「分割」して配置します。
  • 例えば、前半の層をGPU0、後半をGPU1で計算することで、1枚のGPUに収まらない巨大なモデルも扱えます

シンプルな例

import torch
import torch.nn as nn

class ModelParallelNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.seq1 = nn.Sequential(nn.Linear(1000, 1000), nn.ReLU())
        self.seq2 = nn.Sequential(nn.Linear(1000, 1000), nn.ReLU())
        # seq1をcuda:0、seq2をcuda:1に配置
        self.seq1.to('cuda:0')
        self.seq2.to('cuda:1')

    def forward(self, x):
        x = x.to('cuda:0')
        x = self.seq1(x)
        x = x.to('cuda:1')
        x = self.seq2(x)
        return x
  • forward内で明示的にデバイスを移動させる必要があります。
  • モデルの構造によっては通信コストが増えるため、分割位置の設計が重要です。

3. Pipeline Parallel(パイプライン並列)

  • モデルを複数の「ステージ」に分割し、各ステージを異なるGPUに割り当ててパイプライン処理します。
  • PyTorchのtorch.distributed.pipeline.sync.Pipeなどで実装可能です。

例(Pipe API)

from torch.distributed.pipeline.sync import Pipe

model = nn.Sequential(
    nn.Linear(1000, 1000),
    nn.ReLU(),
    nn.Linear(1000, 1000),
    nn.ReLU()
)
# 2分割してcuda:0, cuda:1に割り当て
model = Pipe(model, devices=['cuda:0', 'cuda:1'], chunks=8)

4. まとめ

  • モデルの分割(Model Parallel, Pipeline Parallel)は可能
  • 明示的に.to('cuda:0').to('cuda:1')で層ごとに割り当てる
  • 通信コストや実装の複雑さに注意
  • 一般的にはDataParallel/DDP、モデルが巨大な場合はModel/Pipeline Parallelを使う

参考


ご質問の「モデルを複数GPUに分割」は可能です。
用途・モデルサイズ・実装難易度に応じて最適な手法を選択してください。