マルチノードDeepSeekデプロイによる低遅延と高スループットの実現

マルチGPUデプロイメントは、速度と規模の両面でMoEモデルのパフォーマンスを同時に向上させます

著者Perplexity Research

ほとんどのシステムにおいて、レイテンシ(遅延)とスループットは相反する目標であることが多く、設計およびデプロイメントの過程でトレードオフが求められます。例えば、高密度な大規模言語モデルでは、バッチサイズを大きくするとスループットは向上しますが、レイテンシも増加します。また、単一マシン内でのテンソル並列数を増やすとレイテンシは低減されますが、レプリカ数が減少するためスループットは低下します。

DeepSeek-V3/R1のようなMixture of Experts(MoE)モデルは、優れたモデル能力と運用効率を実証しています。例えば、DeepSeek-V3/R1モデルは合計671Bのパラメータを有していますが、推論時に各トークンが使用するのは37Bのパラメータのみです。このモデルアーキテクチャは、推論システムにとって課題と機会の両方を提示しています。

本記事では、従来のシステムとは異なり、DeepSeek-V3/R1のようなMoEモデルは、ほとんどのシナリオにおいて、マルチノードデプロイメントでより多くのGPUを利用することで、スループットの向上とレイテンシの低減を同時に達成できることを実証します。

デプロイメントアーキテクチャ

NVLink上でのシングルノード展開。attentionとエキスパート計算はGPU間で分散されます。
InfiniBand上でのマルチノード展開。GPUグループはノード内およびノード間で接続されています。

モデルが持つ多数の小規模なエキスパートにより、デプロイメントは複数のデバイスに分散させる必要があります。我々は、8基のH200 GPUを搭載したシングルノードでのデプロイメントと、8基のH100 GPUを使用したマルチノードでのデプロイメントの両方を検討しました。

両デプロイメントアーキテクチャは、社内のリクエストスケジューラーによって調整されるデータ並列処理を活用しています。データ並列処理の実装には、複数の推論エンジンインスタンスを起動し、それぞれが独立してリクエストを処理・保持するように動作させることが含まれます。GRPCを通じてエンジンと対話するリクエストスケジューラーは、リクエストを可能な限り均等に分散させる役割を担うとともに、KVキャッシュの再利用を促進し、部分的に一致するプレフィックスを持つリクエストをキャッシュを保持するサーバーへ送信します。エンジンインスタンスは複数のノードにまたがることはありません。テンソル並列処理をオプションで使用し、複数のデバイスにわたりアテンションをシャーディング(分割)することは可能です。インスタンスは、シングルノードの場合はNVLink、マルチノードの場合はInfiniBandを通じて相互接続され、エキスパートのディスパッチと収集を行います。

シングルノードのデプロイメント構成は、バッチサイズが小さい場合に優れたレイテンシを実現しますが、負荷が高まるとパフォーマンスが急速に低下します。

サービングエンジンをデプロイするために、複数のエンジンインスタンスをホストするノードごとに1つのポッドを起動します。分散通信の設定およびNVSHMEM初期化のネゴシエーションはPyTorchが担います。通信には、以前のブログ投稿で説明したカスタムCUDAカーネルを使用しています。これら2つのデプロイメントの実装はほぼ同一であり、モデルはエキスパート並列処理を実装するファブリックに基づいて、適切なカーネルを選択します。

並列化テクニック

パフォーマンス比較の詳細に入る前に、DeepSeek-V3/R1のような大規模なMoEモデルのデプロイを可能にする重要な並列化戦略を理解することが不可欠です。

テンソル並列処理

LLM推論において、テンソル並列処理(TP)は通常、GPUごとのメモリ使用量と計算量を削減し、レイテンシを低減するために使用されます。通常、アテンション層とMLP層のLinear Projectionを行方向または列方向にシャーディングし、アテンション操作をアテンションヘッド次元に沿ってシャーディングできます。

TPを使用すると、Llama-3アーキテクチャではLinear Projectionおよびアテンション操作の計算の重複がGPU間で発生しないため、理想的なシャーディング手法となります。しかし、DeepSeek-V3/R1モデルでは、TPでこれを達成することはできません。

DeepSeek-V3/R1モデルはMulti-Latent Attention(MLA)を使用しています。MLA層は、まずLinear Projection kv_a_projを使用して潜在ベクトルを計算し、次に別のLinear Projection kv_b_projを使用して各アテンションヘッドのスペースに変換します。すべてのアテンションヘッドが同じ潜在ベクトルを共有するため、TPは潜在ベクトルをシャーディングできず、すべてのTPランクでkv_a_projとkv_b_projのパラメータおよび計算を複製する必要があります。同様に、MLAはKVキャッシュに潜在ベクトルを格納するため、各TPランクは同一のKVキャッシュコピーを保持します。

MLAにおける重複は存在するものの、テンソル並列処理は依然として計算需要を部分的に削減し、高い出力速度を必要とするシナリオにおいて価値を発揮します。

エキスパート並列処理

DeepSeek-V3/R1モデルはMLP層をMoE層に置き換えています。MoE層には256個のルーティングされたエキスパートと1個の共有エキスパートがあります。各トークンは計算のために8つの異なるルーティングされたエキスパートにディスパッチされ、その結果が重み付き合計されます。各トークンは共有エキスパートでも計算され、その結果がルーティングされたエキスパートからの結果に加えられます。

エキスパート並列処理(EP)はMoE層における一般的なシャーディング手法であり、各GPUが256 / EP個のルーティングされたエキスパートを管理しつつ、共有エキスパートのコピーを保持します。TPと比較して、EPの利点は計算をより多くのGPUに分散させ、GPUあたりの計算量とメモリ使用量を削減できる点にあります。

エキスパート計算を実行する前に、すべてのGPUはAllToAll通信を行い、トークンを対応するエキスパートが存在するGPUにディスパッチする必要があります。エキスパート計算後、様々なGPUから計算結果を収集し、重み付き合計を実行するために別のAllToAll通信が必要です。我々は、これら2つのAllToAll通信カーネルであるDispatchとCombineを、NVSHMEMを使用して最適化したバージョンを実装しました。以前のブログ投稿で詳細を解説しており、当社のカーネルはGitHubでオープンソース化されています。

データ並列処理

EPを使用すると、MoE計算を128個以上のGPUに分散できます。しかし、MLA計算はEPでパーティション化することはできません。ここでデータ並列処理(DP)を導入します。各DPグループはMLA層の完全なコピーを持ちます。各DPグループは異なる入力を受け取り、独立してMLA層の計算を実行します。

MLA層のDPとTPは組み合わせることができ、1つのDPグループを複数のTPランクに分割できます。MoE層のEPはMLA層のDP/TPと組み合わせることが可能です。EP = DP * TPとなります。例えば、16台のマシンにおいて、EP128 DP32 TP4は、ルーティングされたエキスパートを128個のGPUに分散させ、4個のGPUごとに1つのDPグループを形成し、合計32個の独立したDPグループで構成することを意味します。

シングルノード vs マルチノード

DeepSeekの671Bパラメータは単一の8-GPU H100マシンのメモリ容量(80 GB * 8)を超えますが、単一の8-GPU H200マシンはモデル全体を十分に収容できます(141 GB * 8)。EP8 DP8 TP1構成を使用すると、モデルはGPUあたり約100 GBのメモリを使用し、KVキャッシュおよびその他の中間結果用に約40 GBが残ります。1トークンは70,272バイトのKVキャッシュを占有します。各リクエストが5,000トークンを持つと仮定すると、各GPUは約100リクエストを収容できます。

我々は、異なる構成下でのシングルノードとマルチノードのデプロイメントのパフォーマンスの違いを理解したいと考えました。シングルノードのデプロイメントにはH200マシンを1台、マルチノードのデプロイメントには最大16台のH100マシンを使用しました。各デプロイメント環境において、TP 1、2、4、8の組み合わせと、GPUあたりのバッチサイズ1、2、4、8、16、32、64、128を使用しました。各リクエストのKVキャッシュ長は5,000トークンであると仮定しました。また、Multi-Token Prediction(MTP)は1つの追加トークンを予測し(つまり、各リクエストのクエリ長は2)、許容率を60%と保守的に見積もりました。下図は、異なる構成のスループットと出力速度を示しています。

さまざまなエキスパート並列構成におけるレイテンシーとスループットのパレートフロンティア。

横軸はリクエストあたりの出力速度(トークン/秒)を表します。縦軸は対数スケールを使用し、マシンあたりのスループット(トークン/秒)を示しています。各EP構成のパレートフロンティアを色分けした線でマークしました。

非常に高い出力速度が求められるシナリオでは、バッチサイズ1でシングルノードのEP8 DP1 TP8を使用すると、100トークン/秒を超える出力速度を達成できますが、スループットは出力速度と同等で極めて低くなります。このシナリオでは、バッチ全体でトークンは2つしかなく、最大で2*8=16個のエキスパートにディスパッチでき、合計で最大57Bのパラメータがアクティブ化されます。

出力速度80~40トークン/秒の範囲では、スループットが向上するにつれて出力速度が大幅に低下します。対照的に、EP128は同じ出力速度においてシングルノードデプロイメントの約5倍のスループットを実現します。

この現象は、シングルノードデプロイメントの挙動を調べることで説明できます。バッチサイズを増やすと、アクティブ化されるエキスパートの数と直接相関します。バッチサイズが1の場合、GPUあたりの平均アクティブ化エキスパート数は2 * 8 / 8 = 2となります。バッチが十分に大きい場合、すべてのエキスパートがアクティブ化され、各GPUは256 / 8 = 32個のエキスパートをアクティブ化します。エキスパートの数が増えると、GPUはメモリからより多くのパラメータを読み込む必要があり、メモリ帯域幅の負荷が大幅に増加します。大規模言語モデルのデコードフェーズは既に計算性能ではなくメモリ帯域幅によってボトルネックとなっているため、シングルノードデプロイメントでバッチサイズを増やすと出力速度が著しく低下します。

4つのマルチノードデプロイメント構成(EP16、EP32、EP64、およびEP128)を比較すると、より高いEP値は、スループットと出力速度の両方を同時に改善する方向へパレートフロンティアをシフトさせることが分かります。

より高いEP数を使用することは、各GPUに割り当てられるエキスパートが少なくなることを意味します。例えば、EP128は各GPUが256 / 128 = 2個のエキスパートを担当することを意味するため、メモリ帯域幅の負荷が大幅に軽減されます。言い換えれば、より大きなEP数を使用することで、実質的により多くのメモリ帯域幅を得ることができます。GPUあたりのバッチサイズが64未満の場合、入力数が増えてもメモリ帯域幅の負荷はそれほど増加しないため、バッチサイズを増やしてもエキスパートの計算速度には大きな影響を与えません。したがって、EP128を使用している場合、バッチサイズを増やしても出力速度にはそれほど影響しないことが確認できます。

興味深いことに、より大きなバッチサイズ(GPUあたり64リクエスト)において、新しい現象が観察されました。シングルノードデプロイメントのスループットがマルチノードデプロイメントよりわずかに高いのです。その理由の一部として、ノード内のNVLinkはノード間のInfiniBandよりも高い帯域幅を持つことが挙げられます。別の要因として、当社の実装における制約があります。この現象については後ほど詳しく分析します。

メモリ容量の制限により、EP8 DP8 TP1構成ではGPUあたり128というバッチサイズに到達できないため、より高いスループットを追求するシナリオでは、依然としてマルチノードデプロイメントが優れた選択肢となります。

計算と通信のオーバーラップ

エキスパート並列処理に関して先述した通り、MoE層の通信中、GPUはアイドル状態になります。無駄を省きレイテンシを低減するためには、このアイドル時間を埋めるために、データに依存しない計算タスクを見つける必要があります。

計算と通信のオーバーラップなし、ディスパッチオーバーラップ、5段パイプラインのスケジュール。

上図の上部は、1層の計算フローを示しています。MoE計算はDispatchに依存し、次の層の計算はCombineの結果に依存します。

各GPU上に共有エキスパートを配置します。これにより、共有エキスパートの計算はAllToAll通信を必要としなくなります。したがって、Dispatch Sendの直後に共有エキスパート計算を実行し、Dispatch Recvが完了するのを待機できます。我々はこのオーバーラップスキームを「Dispatch Overlap」と呼んでいます。

Dispatch Overlapは直感的な実装と幅広い適用性を提供します。この技術により、すべてのEPサイズとバッチサイズにおいて、共有エキスパートの計算時間を隠蔽(Hiding)できます。

計算と通信のオーバーラップをさらに高めるため、DeepSeek技術レポートで言及されているマイクロバッチングを使用して、データ依存性を解消しました。図の下部に示すように、1つのTransformer層の計算を5つのステージに分割しました。

ステージ1: InputNorm, QKVProj, AppendKV, BMM

ステージ2: BMM, Attn, OProj, PostNorm, Gate

ステージ3: Dispatch Send, Shared Expert

ステージ4: Dispatch Recv, MoE, Combine Send

ステージ5: Combine Recv

最初の3つの高密度Transformer層ではバッチ全体を使用します。それに続く58個のMoE Transformer層では、バッチを2つのマイクロバッチに均等に分割します。2つのマイクロバッチは、3ステージずらして交互に実行されます。これら2つのマイクロバッチ間にはデータ依存関係がないため、Dispatch Sendの後およびCombine Sendの後に、別のマイクロバッチの計算に切り替えることができます。

レイテンシの内訳

次に、実験を通じてオーバーラップの効果を比較し、さらにシングルノードデプロイメントEP8とマルチノードデプロイメントEP128のパフォーマンスの違いを比較します。比較を容易にするため、以下の実験ではH100 GPUを使用しました。TP1、GPUあたり128のバッチサイズ、リクエストあたりクエリ長2、KVキャッシュ長5000を使用しました。

比較対象のエキスパート並列構成およびオーバーラップ構成における、カーネル別の層レイテンシー。

上図は、1つのMoE Transformer層で費やされた合計時間と、異なるタイプのカーネルのレイテンシ比率を示しています。Dispatch、Combine、GroupGEMMを除き、EP8、EP128 NoOverlap、およびEP128 DispatchOverlapシリーズのその他のカーネル実行時間は、バッチサイズが同じであるため同等であるはずです。

オーバーラッピング

まず、3つのオーバーラップ方法の効果を比較しましょう。NoOverlapは合計2667µs、DispatchOverlapは2651µsを要し、16µs(わずか0.6%)の節約でした。MicroBatchは非常に大きな改善を示し、1896µsとなり29%の高速化を達成しました。DispatchとCombineの時間は両方とも大幅に短縮されました。Dispatchは593µsから367µsへ、Combineは1012µsから237µsへと減少しました。

計算カーネルについては、サイズ128のバッチをサイズ64の2つのバッチに分割すると、実行時間が合計で増加することに注意してください。そのため、通信に費やされる時間が1001µs短縮されたにもかかわらず、合計時間は771µsしか短縮されませんでした。その理由は、次セクションのRooflineモデルを使用して説明します。

このため、マイクロバッチングが常にパフォーマンスを向上させるとは限りません。

マイクロバッチングによる出力速度とノードごとのスループットの変化を、GPUごとのバッチサイズに対してプロットしたもの。

上図は、バッチサイズ4〜128におけるDispatchOverlapと比較したMicrobatchのパフォーマンス改善を示しています。バッチサイズが32未満の場合、Microbatchはパフォーマンスを5%〜40%低下させます。バッチサイズが32以上の場合、Microbatchはパフォーマンスを10%〜35%向上させます。

EP8 vs EP128

前の図に戻り、EP8とEP128 Microbatchを比較しましょう。EP8は合計1802µsを要し、EP128の1896µsよりもわずかに短い時間でした。前述のMicrobatchによるカーネル実行時間の増加を除けば、主な違いはMoE計算で使用されるGroupGEMM、および2つの通信カーネルであるDispatchとCombineにあります。

EP8のGroupGEMMは555µsを要しましたが、EP128のGroupGEMMは270µsで、半分に短縮されました。これがマルチノードデプロイメントの核心的な利点です。

残念ながら、通信に費やされる時間が213µs増加し、GroupGEMMの利点を大きく相殺しました。当社の通信カーネルの個別のパフォーマンス試験では、Infiniband帯域幅の半分しか達成できないことが分かりました。今後も通信カーネルの最適化を継続します。

もう1つ、大幅に遅延しているカーネルがGEMMです。MicrobatchはGEMMを95µs増加させました。GEMMについては、以下のRooflineセクションでより深く分析します。現在のGEMM実装は、まだ最適なパフォーマンスを達成していないと考えています。

Roofline

Rooflineモデルは、カーネルのパフォーマンスを分析するための優れたツールです。横軸は算術強度(Arithmetic Intensity)であり、FLOPとメモリI/Oバイトの比率です。横軸の値はカーネルのセマンティクスから直接計算できます。縦軸は達成されたパフォーマンスを表し、FLOPをベンチマークレイテンシで割って計算されます。

カーネルパフォーマンスの理論的な上限は、GPUの仕様によって直接決定されます。H100のFP8ピークパフォーマンスは1979 TFLOP/秒で、Rooflineモデルでは水平線として表されます。H100のメモリ帯域幅は3.35 TB/秒で、原点を通る直線の傾きとして表されます。これら2つの線は、それぞれ計算バウンド(compute-bound)なカーネルとメモリバウンド(memory-bound)なカーネルのパフォーマンス限界を示します。

以下では、GroupGEMMおよびGEMMカーネルのパフォーマンスについて論じます。

GroupGEMM

MoEにおけるGroupGEMMカーネルは、以下の計算を実行します。合計g個のグループがあり、i番目のグループはm_i個のトークンを持ち、[m_i, k] x [k, n] -> [m_i, n]の行列乗算を実行します。パフォーマンス試験では、各グループのトークン数は等しいと仮定し、m_i = mと表記します。その場合、GroupGEMMのFLOP数は2 * g * m * k * n、メモリI/Oバイト数はg * (m * k + n * k + m * n)となります。

DeepSeek-V3/R1モデルには256個のエキスパートがあり、各トークンは8個のエキスパートにディスパッチされて計算されます。バッチサイズ128、クエリ長2、EP128 DP128構成を使用すると仮定すると、各エキスパートが受け取るトークンの平均数(つまりm)は128 * 2 * 8 * 128 / 256 = 1024となります。同様に、他の構成やバッチサイズについてもmを計算できます。

パフォーマンス試験にはDeepGEMMのGroupGEMM実装を使用しました。テストポイントは、TP1およびバッチサイズ1〜128でのEP8、EP16、EP32、EP64、EP128構成の組み合わせを網羅しました。

計算およびメモリ帯域幅の屋根線に対するGroupGEMMの性能。

上図は、異なるEP構成下でのGroupGEMMのRooflineモデルを示しています。EPが異なるとグループの数も異なります。図はパフォーマンスラインがほぼ重なっていることを示しており、GroupGEMMのパフォーマンスは合計トークン数(g * mとして表される)によって主に決定されることを示しています。

星印は、各EP構成においてバッチサイズをGPUあたり128としたデータポイントを示しています。これらの星印付きデータポイントを比較すると、EPが増加する(およびDPが同期して増加する)につれて、エキスパートあたりのトークン数mも増加していることが分かります。EP8ではm=128ですが、EP128ではm=2048となります。

mが増加すると、算術強度も増加します。ほとんどの構成においてGroupGEMMはメモリ帯域幅によって制限されるため、mを増やすことでパフォーマンスが向上します。

GEMM

GEMMカーネルは、Q/K/V/O Projectionなど、モデル内のLinear Projectionに対応します。[m, k] x [k, n] -> [m, n]の行列乗算において、FLOP数は2 * m * k * n、メモリI/Oバイト数はm * k + n * k + m * nとなります。バッチサイズ1〜128でのレイテンシをテストすることも可能です。

計算およびメモリ帯域幅の屋根線に対するGEMMの性能。

上図は、異なるEP構成下でのGEMMのRooflineモデルを示しています。GEMMのパフォーマンスはメモリ帯域幅によって制限されていることが分かります。バッチサイズが増加するにつれて算術強度も増加し、パフォーマンスが向上します。

Microbatch

マイクロバッチングを使用する場合、バッチを2つに等分します。上記の2つの図から分かるように、mがm/2になると、行列乗算の効率が低下します。したがって、サイズm/2の2つの行列乗算を実行する時間は、サイズmの1つの行列乗算を実行する時間よりも長くなります。

Multi-Token Prediction

本記事全体を通して、推論的デコード(speculative decoding)のためにMulti-Token Prediction(MTP)を使用していると仮定してきました。MTPは、リクエストあたりのクエリ長を1から2に変更します。行列乗算にとって、これはmをm * 2に変更することと同等であり、行列乗算の効率を高めます。一方で、MLAのRooflineモデルを描くと、クエリ長を増やすことがMLAカーネルの効率を著しく高めることが分かります。

したがって、MTPの使用はモデルの効率化において重要な役割を果たします。

実装と最適化

本セクションでは、DeepSeek-V3/R1モデルの実装および最適化の詳細を紹介します。

量子化

DeepSeek-V3/R1は、ブロック単位の量子化スキームを使用してFP8でネイティブにトレーニングされました。重みは静的に量子化され、アクティベーションはオンザフライで量子化されます。チャネルごとや行列ごとに静的にスケーリング係数を計算するのではなく、アクティベーションに対しては128要素ベクトル、行列に対しては128x128要素タイルにわたってスケーリング係数を計算することで、量子化による精度低下を抑えています。

Perplexityでは、推論をサポートするためにCUDAカーネルとTritonカーネルを組み合わせて使用しています。CUDAはアテンションやGEMMなど、パフォーマンスに敏感で変更頻度が低いカーネルに使用され、Tritonはアクティベーション、正規化、および広範なユーティリティカーネルの実装に使用されています。Tritonにより、カーネルをブロック量子化スキームに迅速に適応させることができました。

Linear層およびMoE層では、Deep GEMMカーネルと独自のTriton GEMMカーネルを組み合わせています。特定の行列次元や低いバッチサイズにおいて、Split-Kの方がレイテンシが低いことに気づいたためです。量子化されていない層が(M, K) x (K, N)の乗算を実行する場合、ブロック量子化には(M x ceil_div(K, 128)) x (ceil_div(K, 128), ceil_div(N, 128))のスケーリング係数が必要です。ブロック量子化では、アクティベーションのスケーリング係数は事前に調整されるのではなく、オンザフライで計算されます。アクティベーションのスケーリング係数はK次元に沿ってのみ集計され、M次元には沿わないため、このスキームをサポートするためにカーネルに必要な修正はわずかです。

バッチ化されたSiLUと乗算の計算。エキスパート入力テンソル、出力テンソル、スケーリング係数を示しています。

DeepSeek-V3/R1で使用されているSiLUアクティベーション関数は、CUDAグラフ、ブロック量子化、および動的にルーティングされるトークン数をサポートするために大幅な変更が必要でした。ブロック量子化は水平リダクションを導入するため問題となる可能性がありますが、カーネルは既にアクティベーションを隠れ次元に沿って1024要素のブロックにチャンク分割していました。1つのブロック内で、量子化対象のテンソルは最大絶対値を計算するためにさらに128のブロックに分割され、Tritonが効率的なクロスワープ最大値リダクションを生成し、オーバーヘッドを最小限に抑えています。

CUDAグラフ下でのMoEルーティングをサポートするために、カーネルはトークン数の上限を保持するために割り当てられたバッファのサイズに基づいて作業をスケジュールするのではなく、エキスパートあたりのトークン数を示すルーティング情報を認識する必要があります。入力テンソルの次元に基づいて問題を分割することはできないため、ルーティング情報を読み取って何個のトークンが格納されているかを判断し、それらの間でアクティベーション処理の作業を動的に分割する、固定数の永続的カーネルを起動しています。

当社のカーネルの一部はすでにFlashInferプロジェクトにアップストリームしており、今後さらに多くのコードをオープンソース化する予定です。

MLA層

MLA計算にはFlashInferを使用しています。FlashInferは柔軟なページテーブル設定と極めて高いパフォーマンスをサポートしています。

q_a_projとkv_a_projを単一のqkv_a_projに融合させました。これにより、レイテンシは15.4 µs + 14.8 µs = 30.2 µsから16.7 µsへ短縮されました。

kv_b_projをk_b_projとv_b_projの2つの行列に分解しました。これら2つの行列に関連する計算のために、FP8ブロック量子化されたBMMカーネルを作成しました。

Cuda Graph

Cuda Graphはカーネル起動のオーバーヘッドを大幅に削減でき、パフォーマンスにとって極めて重要です。バッチサイズごとにCuda Graphを作成しています。

独自のAllToAllカーネルを開発する前は、AllToAll通信にtorch.all_to_all_single()を使用していました。この操作では、すべてのGPUが同じバッチサイズを使用する必要があります。しかし、異なるDPグループは異なるバッチサイズで実行される場合があります。

all_to_all_single()が異なるバッチサイズを使用するDPグループと互換性を持つことを保証するため、まず各モデル実行前にallreduce()操作を使用して、すべてのDPグループ間で最大バッチサイズを取得しました。次に、すべてのDPグループにこのバッチサイズを使用して実行させました。

このアプローチはCuda Graphを使用できることを保証しますが、3つの欠点があります。第1に、追加のallreduce()操作が必要です。第2に、バッチサイズが小さいDPグループはパディングを強制されます。第3に、実装コードが複雑になります。

独自のAllToAllカーネルを実装した後、すべてのGPUが同じバッチサイズを使用する必要はなくなりました。したがって、追加のallreduce()操作を実行したり、バッチサイズをパディングしたりする必要はなくなりました。

MoEルーター

MoEルーターはTritonで実装されており、標準ライブラリから派生した修正版ソートに依存しています。このソートはソートされた要素のインデックスも追跡します。MixtralルーティングはTop-Kグループがすべてのエキスパートのグループと同じであるDeepSeekルーティングの特殊なケースであるため、この実装はすべてのMoEモデル間で共有されます。疎カーネル(sparse kernels)はTop-Kインデックスとスコアを直接消費しますが、All-to-Allに依存する高密度なディスパッチ/Combineスキームでは、トークン単位ではなくエキスパート単位で集約されたルーティング情報が必要です。

今後の課題

今後の作業として、DeepSeekモデルのパフォーマンスをさらに最適化する予定です。

最も重要な次の最適化は、Prefill(プレフィル)の分離です。DeepSeek-V3/R1モデルのPrefillフェーズとDecodeフェーズは、計算上の特性が大きく異なります。それぞれが異なる最適化戦略とデプロイメントスキームを利用できます。

MLA層については、Decodeフェーズにおいて行列吸収(Matrix Absorption)を使用してMLA計算のFLOP数を削減します。Prefillフェーズでは、まず潜在ベクトルをK/Vスペースに投影し、次にMulti-Head Attention(MHA)形式で計算する方がパフォーマンスが高くなります。

PrefillとDecodeが同じGPU上で実行される場合、PrefillがDecodeの出力速度に与える影響を軽減するために、通常はチャンク化したプレフィルを使用してクエリを複数のチャンクに分割します。KVキャッシュが潜在ベクトルを格納するため、MLAをMHA形式に変換することは困難です。

MoE層については、Decodeフェーズにおいてエキスパートあたりの入力トークン数を増やし、GroupGEMMのパフォーマンスを向上させるため、可能な限り大きなEPとDPを使用します。Prefillフェーズでは、トークン数が既に十分に多いため、GroupGEMMは既に計算バウンドです。したがって、Prefillにはより小さなEPとDPを使用できます。

PrefillとDecodeが同じGPU上で実行される場合、いずれかのDPグループがPrefillを実行している限り、すべてのGPUにおけるMoE層のレイテンシが増加し、Decodeの出力速度に大きな影響を与えます。

Prefillの分離以外にも、以下の側面を最適化する予定です。

AllToAllパフォーマンス:当社のAllToAllカーネルは現在、Infiniband帯域幅の1/3しか達成できません。このカーネルの最適化を継続します。

EAGLEスタイルの推論的デコード:上記のデータでは、1トークンを予測する推論的デコードを使用すると仮定しました。EAGLEはツリー構造を使用して複数のトークンを予測し、受け入れの長さを改善できるため、出力速度を大幅に高めることができます。

GEMMカーネル:先述のRooflineモデルでは、GEMMカーネルの効率が理論上の限界には程遠いことが分かります。このカーネルの最適化を継続します。

GB200 NVL72:NVIDIAの最新のGB200 NVL72ソリューションでは、72個のBlackwell GPUが高速なNVLinkを通じて相互接続されます。MoEアーキテクチャモデルにとって、これは非常に大きな機会であり課題でもあります。

結論

DeepSeek MoEモデルのマルチノードデプロイメントは、高密度LLMでは通常不可能なこと、すなわちスループットとレイテンシの両方を同時に改善することを達成します。エキスパートをより多くのGPUに分散させることで、デバイスあたりのメモリ帯域幅の負荷が軽減され、処理の高速化とシステム全体のスループット向上が可能になります。実験では、EP128構成がシングルノードデプロイメントと比較して、同等の出力速度で最大5倍高いスループットを達成することを示しています。

マイクロバッチングなどの計算・通信のオーバーラップ技術は、マルチノードの通信オーバーヘッドを大幅に削減し、当社の実装では最大40%の高速化を示しています。独自のAllToAll通信カーネルと最適化されたカーネル実装により、671Bパラメータモデルの効率的なデプロイが可能になりました。

MoEアーキテクチャはその能力によって人気を集めており、これらのデプロイ戦略は、そのようなモデルを効率的にスケーリングするための貴重な洞察を提供します。

参考文献

DeepSeek-V3技術レポート

DeepSeek-V3/R1推論システム概要

Megatron-LM: モデル並列処理を使用した数十億パラメータの言語モデルのトレーニング

EAGLE: 推論的サンプリングには特徴量不確実性の再考が必要

引用

BibTeX
@online{perplexity2025LowerLatencyAndHigherThroughputWithMultiNodeDeepseekDeployment,
  author = {{Perplexity} and Lequn Chen and Nandor Licker and Erin McKnight},
  title = {{Lower latency and higher throughput with multi-node DeepSeek deployment}},
  date = {2025-04-18},
  url = {https://perplexity.coolkeypoint.com/hub/blog/lower-latency-and-higher-throughput-with-multi-node-deepseek-deployment}
}