テンソル並列・パイプライン並列・レイヤー分割の違いとは?マルチGPUでLLMを動かす3方式を比較

テンソル並列・パイプライン並列・レイヤー分割の違いとは?マルチGPUでLLMを動かす3方式を比較

マルチGPU推論の並列化方式とは、1枚のGPUに載らない、または1枚では遅いLLMを複数のGPUで動かすために、モデルをどこで分け、GPU同士がいつ通信するかを決めるやり方です。代表的なものに、テンソル並列(TP)、パイプライン並列(PP)、そしてOllamaなどが使うレイヤー分割の3つがあります。

3つとも「GPUを複数使う」点は同じですが、速くなるもの、必要な接続、向いている使い方はかなり違います。GPUを2枚に増やしたのに応答が速くならない、という現象も、この違いを知ると説明がつきます。

この記事では、社内でローカルLLMやオンプレミスのGPUサーバーを検討している技術担当者に向けて、3方式の仕組みを比較表で整理し、PCIeとNVLinkでの向き不向き、vLLMとOllamaでの選び方までを解説します。

テンソル並列・パイプライン並列・レイヤー分割は何が違う?

テンソル並列・パイプライン並列・レイヤー分割は何が違う?

3つの方式の違いは、モデルを「層の中」で切るか「層と層の間」で切るか、そして切ったあとにGPUをどう働かせるかにあります。まず表で全体をつかみ、次に違いが生まれる理由を見ていきます。

3方式の比較表

結論から言うと、1リクエストの応答を速くしたいならテンソル並列、多くのリクエストを同時にさばきたいならパイプライン並列、1枚に載らないモデルをまず動かしたいならレイヤー分割が出発点になります。

比較の軸テンソル並列(TP)パイプライン並列(PP)レイヤー分割
分ける単位層の中の重み行列連続した層のまとまり(ステージ)層(GPUごとに担当する層を決める)
GPU間の通信層ごとに全GPUで結果を集計(all-reduce)ステージの境目で隣のGPUへ受け渡し担当の境目で次のGPUへ受け渡し
通信の量と回数多い少ない少ない
1リクエストの応答速くなる速くならない速くならない
多数のリクエストの同時処理伸びる伸びる(流し続けることが前提)主な目的ではない
向いている接続NVLink・NVSwitchPCIeでも扱いやすいPCIeでも問題になりにくい
主な実装の例vLLMの --tensor-parallel-sizevLLMの --pipeline-parallel-sizeOllama、llama.cppの既定

表の中で3方式の性格をいちばんよく表しているのは「1リクエストの応答」の行です。層と層の間で切る方式では、GPUを何枚足しても、1つのリクエストは層の順番どおりにGPUを渡っていくしかありません。1つの層の計算を全員で同時に進められるのは、層の中で切るテンソル並列だけです。

その代わり、テンソル並列は通信の回数がはるかに多くなります。どの方式が速いかは、GPU同士をつなぐ接続の速さと、1人で使うのか大勢で使うのかによって変わります。

違いを生むのは「どこで切るか」と「いつ通信するか」

LLMは、同じ形の層(Transformerブロック)を何十段も積み重ねた構造をしています。文章を1トークン生成するたびに、入力はこの層を1段目から最後まで順番に通ります。並列化の方式は、この積み重ねをどの向きで切るかの違いだと考えると整理しやすくなります。

積み重なった層を、層と層の間で切るのがパイプライン並列とレイヤー分割です。GPU0が1〜20段目、GPU1が21〜40段目というように担当を分けるので、GPU同士がやり取りするのは担当が切り替わる境目だけです。その代わり、1つのトークンを計算している瞬間に働いているのは、そのトークンがいる段を担当するGPUだけになります。

もう1つの切り方が、各層の中身を切るテンソル並列です。どのGPUも全部の段を担当し、各段の計算を少しずつ受け持ちます。全員が同時に働けますが、段ごとに途中結果を持ち寄らないと次の段に進めません。

たとえるなら、レイヤー分割とパイプライン並列は工程ごとに担当者が分かれた流れ作業、テンソル並列は1つの工程を全員で分担し、工程が終わるたびに集まって答え合わせをする作業です。どちらが速いかは、集まるのにかかる時間、つまりGPU間の接続の速さで決まります。

テンソル並列(TP)はどう動き、どこで速くなる?

テンソル並列(TP)はどう動き、どこで速くなる?

テンソル並列は、1つの層の計算そのものを複数のGPUで分担する方式です。1リクエストの応答を短くできる一方で、GPU同士の接続の速さに大きく左右されます。

層の中の行列を分け、層ごとに結果を足し合わせる

LLMの各層で行われる計算の中心は、大きな行列の掛け算です。テンソル並列では、この重み行列を列や行の方向に切り分けて各GPUに持たせ、それぞれが自分の担当分を同時に計算します。TP=4なら、各GPUが持つのは各層の重みのおよそ4分の1です。

担当分を計算しただけでは、層の出力は完成しません。全GPUの途中結果を足し合わせ、同じ結果を全員に配り直す通信が必要で、これをall-reduceと呼びます。テンソル並列の代表的な設計を示したMegatron-LMの論文では、Transformerの1層につき、順方向の計算でall-reduceが2回(注意機構の後と、全結合層の後)入る構成が説明されています。Megatron-LMの論文

層が数十段あれば、1トークンを生成するたびに、その2倍の回数だけ全GPUが足並みをそろえることになります。それでも1リクエストが速くなるのは、各GPUが読み出す重みが自分の担当分だけで済むからです。1トークンずつ生成する段階では、計算そのものより重みをメモリから読み出す時間が効きやすく、その読み出しを複数のGPUで分け合えます。

vLLMでは --tensor-parallel-size 4 のように指定します。よく見かける「TP=4」はこの設定のことです。

PCIe接続だと伸びにくいのはなぜか

all-reduceは、全員の結果がそろうまで次に進めない通信です。層ごとに毎回発生するので、1回あたりの待ち時間は小さくても、積み重なると応答時間に直接響きます。そのため、テンソル並列の効き目はGPU同士をつなぐ経路の速さに強く依存します。

参考までに、NVIDIAはデータセンター向けGPU H100(SXM版)の接続帯域を、NVLinkで900GB/s、PCIe Gen5で128GB/sと公表しています。NVIDIA H100の仕様 実際の通信性能は構成によって変わりますが、経路の太さに大きな差があることは分かります。

vLLMの公式ドキュメントも、L40SのようにNVLinkを持たないGPUのノードでは、テンソル並列ではなくパイプライン並列を使うと、高いスループットと少ない通信オーバーヘッドが得られると案内しています。vLLMの公式ドキュメント

ワークステーションやゲーミング向けのGPUを複数挿した構成では、GPU同士がPCIe経由でしかつながっていないことが少なくありません。こうした環境でもテンソル並列は動きますが、GPUの枚数に見合うほど速くなるとは限りません。モデルの大きさや同時リクエスト数で結果が変わるため、自社の環境で1リクエストの応答時間を測ってから採用を決めるのが確実です。

パイプライン並列(PP)はどう動き、何に向く?

パイプライン並列(PP)はどう動き、何に向く?

パイプライン並列は、モデルを層のまとまり(ステージ)に分け、工場のベルトコンベアのように順番に流す方式です。通信が少なくPCIeでも扱いやすい代わりに、1リクエストの応答は速くなりません。

層のまとまりを順に流し、流し続けて稼ぐ

たとえば80層のモデルを4枚のGPUでパイプライン並列にすると、1〜20層、21〜40層、41〜60層、61〜80層の4ステージに分かれます。各GPUは自分のステージの計算を終えたら、途中結果を次のGPUへ渡すだけです。全員で結果を集計するall-reduceは要らず、通信はステージの境目で隣のGPUへ送る分に限られます。PCIeでも扱いやすいのはこのためです。

この方式が力を発揮するのは、リクエストが次々に届く場面です。GPU1がリクエストAの続きを計算している間に、GPU0は次のリクエストBの前半に取りかかれます。リクエストを流し続ければ、どのステージも手を止めずに働き、全体のスループット(一定時間に処理できる量)が上がります。

逆に、流れが途切れると待ちが生まれます。パイプラインの立ち上がりと終わりに一部のGPUが手持ち無沙汰になる時間は「バブル」と呼ばれます。学習向けのパイプライン並列を提案したGPipeの論文では、ミニバッチをさらに小さなマイクロバッチに分けて流すことで、この待ちを減らしています。GPipeの論文 推論サーバーでも考え方は同じで、多くのリクエストを並べて流せるほど効率が上がります。

1リクエストだけでは速くならない

パイプライン並列で注意したいのは、1つのリクエストだけを処理するときの速さです。リクエストAはステージ1から4まで順番に通るしかなく、ある瞬間にAを計算しているのは1枚のGPUだけです。同じ性能のGPU1枚で全層を計算できた場合と比べて、計算にかかる時間はほぼ変わらず、ステージ間の受け渡しの分だけわずかに長くなることもあります。

1リクエストの応答を短くできるテンソル並列とは対照的です。社内の数人がチャットで使う程度で同時リクエストが少ないと、パイプライン並列の利点であるスループットはほとんど生きません。後ろのステージは、前のステージの計算が終わるのを待つ時間が長くなります。

つまり、パイプライン並列は「1人を速くする」方式ではなく「大勢を止めずにさばく」方式です。社内向けのAPIとして多くの部署から呼ばれる、夜間にまとめて文書を処理するといった、リクエストが重なる使い方で選ぶ価値が出てきます。1人で使うチャットの応答を速くしたいなら、テンソル並列を検討するか、1枚に載る大きさのモデルを選ぶほうが近道です。

レイヤー分割(Ollamaの既定)は何のための方式か?

レイヤー分割(Ollamaの既定)は何のための方式か?

レイヤー分割は、層をGPUごとに割り振り、順番に処理を渡していく方式です。速くするためではなく、VRAMを合わせて1枚に載らないモデルを動かすための方式と考えると分かりやすくなります。

目的は速さではなく、VRAMを合わせること

レイヤー分割では「この層はGPU0、次の層からはGPU1」と担当を割り振るだけで、1本の会話でトークンを生成するときの計算はほぼ逐次です。GPU0が担当分を終えたらGPU1へ渡し、その間GPU0は次の出番を待ちます。複数のGPUを使っても、1つの応答が速くなることはほとんど期待できません。

その代わり、各GPUのVRAMを合わせて使えます。たとえば24GBのGPUが2枚あれば、1枚には収まらない重みとKVキャッシュを2枚に分けて載せられます。通信は担当の境目だけなので、PCIe接続でも問題になりにくい方式です。

形だけを見るとパイプライン並列とよく似ています。違いは目的で、パイプライン並列は複数のリクエストを流し続けてステージを埋めるところまでを前提にした方式、レイヤー分割はまずモデルを載せることを目的にした置き方です。

llama.cppでは --split-mode の既定が layer で、層とKVキャッシュをGPUに分けて載せます。llama.cppのllama-serverの説明 長いプロンプトのようなまとまったバッチを小分けにして、GPU間で処理を重ねる仕組みも取り込まれています。llama.cppにパイプライン並列を追加した変更 速くなる余地があるのはこうしたバッチ処理の部分で、1トークンずつ生成する部分は順番どおりに進みます。

1枚に載らない理由がモデルの大きさなら、GPUを足す前に量子化で必要なメモリを減らせないかを確かめる価値もあります。

Ollamaは「1枚に載るなら1枚」を優先する

OllamaはマルチGPU環境で、いつもモデルを分散させるわけではありません。公式FAQによると、Ollamaはモデルを読み込むときに必要なVRAMと空き容量を比べ、どれか1枚のGPUに完全に収まるなら、そのGPUだけに載せます。推論中にPCIバスを通るデータが減り、たいていはこれが最も速いからです。1枚に収まらない場合に限り、使えるすべてのGPUに分散させます。OllamaのFAQ

つまり、Ollamaがレイヤー分割を使うのは、主に「1枚では載らない」ときです。2枚目のGPUを挿したのにGPUの使用状況が変わらないなら、モデルが1枚に収まっているだけかもしれません。

いつも全GPUに分散させたい場合は、環境変数 OLLAMA_SCHED_SPREAD を有効にします。Ollamaのソースコードでは「常にすべてのGPUにまたがってモデルを配置する」設定として定義されています。Ollamaの環境変数の定義 ただし、分散させても1つの応答が速くなるわけではなく、公式FAQの説明どおり、1枚に収まるモデルは1枚に載せたほうが速いのが普通です。

1リクエストの応答を複数のGPUで速くしたいなら、テンソル並列に対応したvLLMのような推論サーバーを検討することになります。

自分の環境ではどれを選べばよい?

自分の環境ではどれを選べばよい?

選ぶときは「1枚に載るか」「1リクエストの速さと同時処理量のどちらが大事か」「GPU同士の接続は何か」の順に考えると迷いにくくなります。

判断の順番

最初に確かめるのは、モデルが1枚のGPUに載るかどうかです。載るなら分割しないのが基本です。GPUが複数あるなら、同じモデルをGPUごとに別々に起動してリクエストを振り分けるほうが、全体の処理量を素直に増やせます。

載らない場合は、次に目的を決めます。

  1. 1人あたりの応答を速くしたい:テンソル並列を検討する。ただしNVLinkなど速い接続があることが前提
  2. 多くのリクエストを同時にさばきたい:パイプライン並列を検討する。PCIe接続でも効果を出しやすい
  3. 動けば十分で、利用者は少ない:レイヤー分割で足りる。Ollamaなら設定なしでこの形になる

最後に接続を確かめます。NVLinkやNVSwitchでつながったサーバーならテンソル並列が第一候補になり、PCIeだけの構成ならパイプライン並列かレイヤー分割が現実的です。1ノードに収まらないほど大きなモデルについては、vLLMの公式ドキュメントが、ノード内はテンソル並列、ノード間はパイプライン並列と組み合わせる方法を示しています。vLLMの公式ドキュメント

「GPUを増やしたのに速くならない」という結果も、この順番で目的と方式の組み合わせを見直すと、理由が見えてきます。

用途別の構成例

具体的な使い方に当てはめると、次のような組み合わせが出発点になります。

検証や少人数での利用で、PCIe接続のGPUを2枚挿したワークステーションを使う場合は、Ollamaのレイヤー分割でまず動かすのが手軽です。応答の遅さが気になるなら、GPUを足すより、量子化したモデルや1枚に収まる大きさのモデルを試すほうが効果が出やすいでしょう。

社内の複数の部署にAPIとして提供し、NVLinkでつながったGPUサーバーがある場合は、vLLMのテンソル並列が有力です。1リクエストの応答を短くしながら、同時処理にも対応できます。

NVLinkのないGPUを複数積んだサーバーで同時リクエストが多い場合は、vLLMのパイプライン並列を試す価値があります。前述のとおり、vLLMの公式ドキュメントも、NVLinkのないノードではこちらを勧めています。

どの構成でも、最後は自社の負荷で測るのが確実です。1リクエストの応答時間と、同時に何件までさばけるかの両方を、本番に近いプロンプトの長さで確かめてください。ローカルLLMをクラウドAPIと比べてどう位置づけるかは、ローカル LLM / SLM 導入比較で詳しく解説しています。

マルチGPU推論でよくある失敗は?

マルチGPU推論でよくある失敗は?

失敗の多くは、方式の性格と目的が食い違っているときに起こります。代表的な2つと、その避け方を紹介します。

GPUを足せば応答が速くなると考える

まず押さえたいのは、GPUを2枚、4枚と増やせば1つの応答もそれに比例して速くなるはずだ、という思い込みです。ここまで見てきたとおり、レイヤー分割とパイプライン並列では1リクエストの計算は順番どおりに進むため、GPUの枚数を増やしても応答時間はほぼ変わりません。テンソル並列でも、PCIe接続では通信待ちが増え、枚数に見合った効果が出ないことがあります。

この誤解を避けるには、GPUを足す前に「何を速くしたいのか」を数字で決めておくことです。1リクエストの応答時間なのか、1秒あたりに処理できるリクエスト数なのかで、選ぶ方式も測り方も変わります。

測るときは、追加の前後で同じプロンプト、同じ出力の長さ、同じ同時接続数をそろえます。応答時間は、最初の文字が出るまでの時間と、その後の生成の速さを分けて見ると、どこが変わったのかが分かりやすくなります。期待と違う結果が出たら、方式と目的の組み合わせを見直すのが先で、GPUをさらに足すのは最後の手段です。

GPUの枚数とテンソル並列の数が合わない

テンソル並列には、GPUの枚数を自由に選べないという制約もあります。注意機構は複数の「ヘッド」に分かれていて、テンソル並列ではこのヘッドをGPUに均等に割り振るためです。vLLMでは、ヘッドの総数がテンソル並列の数で割り切れないと Total number of attention heads (X) must be divisible by tensor parallel size (Y). というエラーが出て起動できません。vLLMの該当ディスカッション

GPUが3枚あるからTP=3にしよう、と考えてこの壁に当たることがあります。ヘッド数が32や64のように3で割り切れないモデルでは、TP=3は使えません。

対処の方法は2つあります。1つは、TP=2のように割り切れる数にして、余ったGPUは別の用途に回すことです。もう1つは、パイプライン並列を使うことです。パイプライン並列は層の単位で分けるので、ヘッド数の制約を受けません。GPUを買い足す前に、使う予定のモデルのヘッド数を設定ファイルで確かめておくと、無駄な投資を避けられます。

マルチGPU推論についてよくある質問

マルチGPU推論についてよくある質問

最後に、構成を検討するときに出てきやすい疑問に答えます。

Q1: PCIe接続のGPU 2枚でもテンソル並列は使える?

使えます。vLLMなどの推論サーバーは、NVLinkがない構成でもテンソル並列で起動できます。問題は効果の大きさで、層ごとのall-reduceがPCIeを通るため、通信待ちが増えます。

1リクエストの応答が多少速くなる場合もありますが、同時リクエストが多い使い方なら、vLLMの公式ドキュメントが勧めるとおり、パイプライン並列のほうが高いスループットを得やすくなります。どちらが合うかは、実際のモデルと負荷で両方を試して比べるのが確実です。

Q2: Ollamaで2枚目のGPUを足しても速くならないのはなぜ?

理由は2つ考えられます。1つは、モデルが1枚のGPUに収まっていて、Ollamaがそのまま1枚だけで動かしている場合です。もう1つは、2枚に分散されていても、レイヤー分割なので1つの応答の計算は順番どおりに進む場合です。どちらも故障ではなく、Ollamaの設計どおりの動きです。

Q3: テンソル並列とパイプライン並列は組み合わせられる?

組み合わせられます。vLLMでは2つの指定を同時に使え、公式ドキュメントには --tensor-parallel-size 4 --pipeline-parallel-size 2 のように、4枚ずつのテンソル並列を2段のパイプラインでつなぐ例が載っています。この場合、使うGPUは合計8枚です。

典型的なのは、NVLinkでつながった1台のサーバーの中をテンソル並列に、サーバー同士をつなぐより遅い経路をパイプライン並列にする構成です。通信の多い処理を速い経路に、少ない処理を遅い経路に割り当てる、という考え方です。1台のサーバーに収まるモデルなら、まずはどちらか一方で始め、足りなくなってから組み合わせを検討すれば十分です。

まとめ:速さ・同時処理量・載せること、目的で方式を選ぶ

まとめ:速さ・同時処理量・載せること、目的で方式を選ぶ

テンソル並列は層の中を切って全GPUで同時に計算し、1リクエストの応答を短くします。その代わり層ごとにall-reduceが発生するため、NVLinkのような速い接続が前提になります。パイプライン並列は層のまとまりを順番に流す方式で、通信が少なくPCIeでも扱いやすく、多くのリクエストを流し続けるほど力を発揮します。レイヤー分割は層を割り振るだけの置き方で、速さよりも、VRAMを合わせて大きなモデルを載せることが目的です。

OllamaはマルチGPU環境でも、1枚に収まるモデルなら1枚に載せ、収まらないときにレイヤー分割で全GPUに分散させます。GPUを足しても速くならないときは、まずこの仕組みを疑ってみてください。

構成を決めるときは、モデルが1枚に載るか、1人の応答を速くしたいのか大勢をさばきたいのか、GPU同士の接続は何か、の順に確かめてください。社内でローカルLLMの導入やGPUサーバーの構成を検討する際は、当社にもお問い合わせいただけます。

著者・監修者

Yusuke Ishihara

Yusuke Ishihara

13歳でMSXに触れプログラミングを開始。武蔵大学卒業後、航空会社の基幹システム開発や日本初のWindowsサーバホスティング・VPS基盤構築など、大規模システム開発に従事。 2008年にサイトエンジン株式会社を共同創業。2010年にユニモン株式会社、2025年にエニソン株式会社を設立し、業務システム・自然言語処理・プラットフォーム開発をリード。 現在は生成AI・大規模言語モデル(LLM)を活用したプロダクト開発およびAI・DX推進を手がける。