Skip to content
Published on

マルチモーダルLLMのサービング — 画像入力が生む新たな課題

Authors

はじめに: 画像一枚がサービングを変える

テキストLLMサービングはここ数年でかなり標準化されました。continuous(in-flight)batching でリクエストを絶えず満たし、paged KV cache でメモリを仮想メモリのように管理し、decode 段階がメモリバウンドである点を利用して量子化とKV最適化でスループットを引き上げます。vLLM、TensorRT-LLM、SGLang といったフレームワークがこのパターンをよく実装しています。

ところが入力に画像が入った瞬間、話が変わります。マルチモーダルLLMは、テキストトークンだけを受けていたパイプラインの前にビジョンエンコーダ段階が付き、リクエストごとにビジュアルトークン数がばらつき、プリフィル(prefill)コストがテキスト比で急増します。テキスト専用サービングでよく通用していた前提が揺らぎます。

本記事では、マルチモーダルLLMサービングがテキスト専用と何が違うか、その違いが生む具体的な課題と対応を整理します。ビジョンエンコーダの追加段階、可変ビジュアルトークン、プリフィルコスト、KVキャッシュとバッチングの難しさ、遅延分解、スループット最適化、コスト、そして運用の落とし穴とチェックリストまで扱います。

テキスト専用と何が違うか

ビジョンエンコーダという追加段階

テキスト専用LLMはトークナイズ → プリフィル → デコードの流れです。マルチモーダルはその前に画像前処理とビジョンエンコーディングが加わります。

テキスト専用 vs マルチモーダルのサービング流れ

[テキスト専用]
  テキスト -> トークナイズ -> prefill -> decode(トークン生成)

[マルチモーダル]
  画像 -> 前処理(リサイズ/正規化) -> ビジョンエンコーダ(ViT) ->
          プロジェクタ(アダプタ) -> ビジュアルトークン
  テキスト -> トークナイズ -> テキストトークン
  [ビジュアルトークン + テキストトークン] -> prefill -> decode

ビジョンエンコーダは重いです。ViTの順伝播はGPU計算を追加で消費し、画像が大きく多いほどこの段階が長くなります。この追加段階は最初のトークン遅延(TTFT)にそのまま入ります。

可変のビジュアルトークン数

テキスト専用サービングでも入力長は可変ですが、マルチモーダルは変動がより大きいです。同じ「画像一枚」でも解像度によってビジュアルトークンが256個のことも4000個のこともあります。任意解像度を支援するモデル(動的解像度)ではなおさらです。

ビジュアルトークン数の変動(概念)

リクエスト A: 小さなサムネイル1枚 -> ビジュアルトークン ~256
リクエスト B: 高解像度文書1枚     -> ビジュアルトークン ~3000
リクエスト C: 画像4枚            -> ビジュアルトークン ~4000+

問題: 列長がリクエストごとに大きく異なり
     バッチのメモリ/計算予測が難しく不均衡が生じる

この変動はバッチングとメモリ計画を難しくします。一つのバッチにトークン数が大きく異なるリクエストが混ざると、パディング浪費やメモリ超過が起きやすくなります。

プリフィルコストの急増

ビジュアルトークンが多いことはプリフィル列が長いことを意味します。注意は列長に二乗で高価なので、プリフィル計算が急増します。テキスト専用ではプリフィルが短くデコードが長かったのに対し、マルチモーダルではプリフィル自体が重い作業になります。

プリフィルコスト比較(概念)

[テキスト専用] プロンプト200トークン
  prefill: 200トークン1回処理(相対的に軽い)

[マルチモーダル] テキスト50 + ビジュアル3000 = 3050トークン
  prefill: 3050トークン処理、注意 O(L^2) 項が急増
  -> TTFTの大部分が prefill + ビジョンエンコーディングで発生

画像前処理とキャッシュ

画像前処理(デコード、リサイズ、正規化)とビジョンエンコーディングは高価ですが、しばしば再利用可能です。同じ画像が複数のリクエスト(マルチターン対話、同一文書の反復質問)に現れるなら、ビジョンエンコーディング結果をキャッシュして再利用できます。

画像/ビジュアルトークンのキャッシュ(概念)

リクエスト到着 -> 画像ハッシュ計算
  キャッシュヒット? -> キャッシュ済みビジュアルトークンを再利用(ビジョンエンコーダをスキップ)
  キャッシュミス?  -> 前処理 + ビジョンエンコーディング -> 結果をキャッシュへ保存

効果: マルチターン/反復質問でビジョンエンコーディングコスト削減、TTFT短縮
注意: キャッシュキー(解像度/前処理パラメータを含む)、メモリ上限の管理

前処理自体もCPUボトルネックになりえます。大きな画像のデコード/リサイズをGPUや別ワーカーへオフロードし、非同期パイプラインでGPUの遊休を減らすのがよいです。

ビジョンエンコーダとLLMのパイプライン化

ビジョンエンコーダとLLMは異なる計算特性を持ちます。両者を直列実行すると一方が回る間もう一方が遊びます。パイプライン化で重ねるとスループットが上がります。

直列 vs パイプライン(概念)

[直列]
  [ビジョンエンコード A][LLM prefill A][ビジョンエンコード B][LLM prefill B]...
  -> 段階間で遊休が発生

[パイプライン]
  ビジョンエンコード:  [A][B][C]...
  LLM prefill:            [A][B][C]...  (Aのエンコードが終わり次第すぐ prefill 開始)
  -> 二段階の重なりでGPU活用率が上昇

実務では、ビジョンエンコーダを別段階(あるいは別GPU/サーバ)へ分離してあらかじめビジュアルトークンを作っておき、LLMエンジンはトークンを受けて prefill/decode に集中させる分離構造がよく使われます。これは後述する遅延分解とも結びつきます。

マルチモーダルKVキャッシュとバッチングの難しさ

KVキャッシュ圧迫

KVキャッシュは列の全トークンに対して key/value を保存します。ビジュアルトークンが数千個ならKVキャッシュもその分大きくなります。paged KV cache は断片化を減らしますが、絶対メモリ需要そのものが増えるのは防げません。

マルチモーダルKVキャッシュ圧迫(概念)

KVキャッシュメモリ ~ (総トークン数) x (層) x (ヘッド x 次元) x 2(K,V)

ビジュアルトークン3000個が加わると ->
  当該リクエストのKVキャッシュがテキスト比で数~数十倍
  -> 同時処理可能なリクエスト数(バッチ)が減少

バッチングの不均衡

continuous batching はトークン単位でリクエストを満たしスループットを高めます。しかしマルチモーダルでは列長の変動が大きく、プリフィルの長いリクエスト一つがバッチ全体の進行を遅らせることがあります。またプリフィル(多数のビジュアルトークン)とデコード(1トークンずつ)は計算特性が異なり、一つのバッチに混ぜにくいです。

対応として chunked prefill(長いプリフィルを細かく分割してデコードと交互に実行)と prefill/decode 分離(disaggregation、プリフィル専用・デコード専用インスタンスの分離)が効果的です。マルチモーダルはプリフィルが重いため、この分離の利得がテキスト専用より大きいです。

chunked prefill + 分離(概念)

長いビジュアルプリフィルをチャンクに分割:
  prefill_chunk_1 -> デコード数ステップ -> prefill_chunk_2 -> ...
  -> 長いプリフィルがデコードリクエストを飢えさせない

prefill/decode 分離:
  [Prefill インスタンス] ビジョンエンコーディング + プリフィルを担当
  [Decode インスタンス]  KVを受けてトークン生成を担当
  -> 各段階の特性に合わせた最適化が可能

遅延分解: TTFTにエンコーディングが含まれる

マルチモーダルサービングの遅延はテキスト専用と分解構造が異なります。核心は、TTFT(最初のトークンまでの時間)の中にビジョンエンコーディングが入る点です。

遅延分解(概念)

[テキスト専用]
  TTFT = トークナイズ + prefill
  TPOT = トークンあたりデコード時間

[マルチモーダル]
  TTFT = 画像前処理 + ビジョンエンコーディング + (ビジュアル+テキスト) prefill
  TPOT = トークンあたりデコード時間(テキスト専用と類似)

含意: マルチモーダルはTTFTが大きく増えやすい。
     TTFT最適化 = 前処理/エンコーディング/プリフィルをすべて減らす。

したがってTTFTを減らすには、(1)画像前処理の高速化/オフロード、(2)ビジョンエンコーディングのキャッシュ・バッチ化、(3)トークン圧縮によるプリフィル長の短縮、(4)chunked prefill による体感遅延の分散、を併せて使う必要があります。一方TPOT(トークンあたり時間)は、デコードがメモリバウンドである点でテキスト専用と同様に量子化・KV最適化・speculative decoding が効きます。

スループット最適化

スループットを引き上げるレバーはテキスト専用とかなり共通しつつ、マルチモーダル特性を加えます。

  • ビジュアルトークンを減らす: 動的解像度の上限とトークン圧縮でプリフィルを減らすとスループットが直接上がります。トークンを減らすのが最大のレバーです。
  • ビジョンエンコーディングのバッチ化: 複数画像をまとめてビジョンエンコーダをバッチ実行するとGPU活用率が上がります。
  • prefill/decode 分離 + chunked prefill: 重いプリフィルがデコードを塞がないようにします。
  • 量子化: FP8/INT4でメモリ・帯域を減らし、デコードスループットとバッチサイズを増やします。
  • speculative decoding: ドラフトモデルで候補を作り本モデルが検証、メモリバウンドのデコードで約2~3倍の加速。
  • フレームワーク選択: vLLMは汎用・広いモデル/ハードウェア支援とマルチモーダル支援が強み、TensorRT-LLMはコンパイルベースでH100で約15~30%高いスループット、SGLangはRadixAttentionによるprefixキャッシュ再利用に強いです。
スループットレバーの優先順位(概念)

1) トークン数削減(動的解像度, 圧縮)   <- 最も直接的
2) ビジョンエンコーディングのキャッシュ/バッチ化
3) prefill/decode 分離 + chunked prefill
4) 量子化(FP8/INT4)
5) speculative decoding

コスト

コストはトークン数とGPU時間に直結します。マルチモーダルはビジュアルトークンのため、同じ「一リクエスト」でもテキスト比で高くなります。

コスト要因(概念)

リクエストコスト ~ (ビジョンエンコーディングGPU時間) + (prefill FLOPs) + (decode時間 x 出力長)

ビジュアルトークン N_v 増加 -> prefill FLOPs と KVメモリ増加 ->
  バッチサイズ減少 -> リクエストあたり分担コスト上昇

削減レバー: 解像度ポリシー, トークン圧縮, エンコーディングキャッシュ, 量子化でバッチを増やす

したがってコスト管理の核心は「必要以上に大きな画像を入れない」ことと「再利用可能なビジョンエンコーディングをキャッシュする」ことです。精度損失なくトークンを減らすあらゆる手段がそのままコスト削減になります。

オートスケーリングと負荷特性

マルチモーダルサービングの負荷はテキスト専用より予測が難しいです。同じ毎秒リクエスト数(RPS)でも、リクエストに含まれる画像の大きさ・数によってGPU負荷が大きく異なるからです。単純にRPSでオートスケーリングをかけると、過小/過大プロビジョニングが生じやすいです。

負荷指標の選択(概念)

[不適切] RPSのみでスケール
  -> 同じRPSでもビジュアルトークン量で負荷が大きく異なる

[適切] ビジュアルトークンスループット(tokens/s)またはGPU活用率ベース
  -> 実際の計算負荷をよりよく反映

追加: キュー待機時間、TTFT p95をSLOとし、それに合わせてスケール

またビジョンエンコーダとデコードの負荷が分離されているため、prefill/decode を分離した構造では各プールを独立にスケールするのが効率的です。画像の多いトラフィックパターンでは prefill プールを、長い応答の多いパターンでは decode プールをより大きくします。

モニタリング: 何を見るべきか

マルチモーダルサービングはテキスト専用より観測すべき指標が多いです。段階が増え変動性が大きいためです。

核心モニタリング指標(概念)

遅延系:
  - TTFT(前処理 + エンコーディング + プリフィル含む) p50/p95/p99
  - TPOT(トークンあたりデコード時間)
  - 段階別分解: 前処理 / ビジョンエンコーディング / プリフィル / デコード

スループット系:
  - リクエスト/s, 出力トークン/s, ビジュアルトークン/s

資源系:
  - GPU活用率(ビジョンエンコーダ vs LLM 分離時はそれぞれ)
  - KVキャッシュ占有率, OOM発生回数
  - キャッシュヒット率(ビジョンエンコーディングキャッシュ)

品質/コスト系:
  - 平均ビジュアルトークン数, リクエストあたりコスト

特にTTFTを段階別に分解して見ることが重要です。TTFTが高いとき、原因が前処理かビジョンエンコーディングかプリフィルかによって処方が全く異なるからです。

同時マルチ画像と長いコンテキスト

一つのリクエストに画像が複数枚入る、あるいはマルチターン対話で画像が累積すると、コンテキストが急速に長くなります。これは二つの圧迫を同時に生みます。プリフィル計算の増加とKVキャッシュメモリの増加です。

マルチ画像/長コンテキストの圧迫(概念)

画像4枚(各 ~1000 トークン) + テキストのリクエスト
  -> ビジュアルトークン ~4000, プリフィルが長くなる

マルチターン: ターンごとに画像・応答が累積
  -> KVキャッシュが対話の長さに比例して増加
  -> 長い対話で同時処理可能なセッション数が減少

対応:
  - 画像数の上限, 古い画像トークンの要約/ドロップ
  - ビジョンエンコーディングキャッシュで再エンコードを回避
  - prefixキャッシュ再利用(同一接頭コンテキスト)

マルチターンで同じ画像が繰り返し現れると、prefixキャッシュ再利用が大きな利得を与えます。SGLangのRadixAttentionのように共通接頭を共有する手法は、マルチモーダルのマルチターンで特に効果的です。

堅牢性とフォールバック

マルチモーダルパイプラインは段階が多い分、失敗点も多いです。破損画像、未対応フォーマット、過度に大きな入力などが入りえます。堅牢なサービングはこうした入力を優雅に処理しなければなりません。

入力検証とフォールバック(概念)

入力受信 ->
  フォーマット/サイズ検証(対応フォーマット? 最大サイズ以内?)
    失敗 -> 明確なエラーを返す(パイプライン進入前に遮断)
  破損画像のデコード失敗
    -> 当該画像をスキップまたはエラーを返す
  過大解像度
    -> 上限へダウンスケール後に進行

原則: 不正な入力がGPU段階まで到達して資源を浪費しないよう
     前段で素早く検証/遮断

GPUは高価な資源なので、不正な入力を前処理以前の段階で素早くふるい落とすことが、コストと安定性の両面で有利です。

デプロイトポロジー

マルチモーダルサービングをどう配置するかは、スループットとコストに直接影響します。大きく三つのトポロジーがあります。

デプロイトポロジー(概念)

[単一統合]
  一つのエンジンが前処理+ビジョンエンコーディング+prefill+decode をすべて担当
  利点: 単純, 運用が容易
  欠点: 段階別の独立スケール不可, 資源の不均衡

[ビジョンエンコーダ分離]
  ビジョンエンコーディングサービス | LLMエンジン(prefill+decode)
  利点: ビジョン/LLM の独立スケール, ビジョン結果のキャッシュが容易
  欠点: トークン転送オーバーヘッド, 運用複雑度の増加

[完全分離(prefill/decode 分解)]
  ビジョンエンコーディング | prefill インスタンス | decode インスタンス
  利点: 各段階の最適資源/スケール, 最高効率
  欠点: 最も複雑, KV転送など通信設計が必要

規模が小さければ単一統合から始め、トラフィックが大きくなり画像比重が高まれば、ビジョンエンコーダ分離、さらに完全分離へ進化させる経路が一般的です。分離するほど効率は上がりますが運用複雑度も上がるため、規模に合わせて段階的に導入するのがよいです。

フレームワークのマルチモーダル支援

主要な推論フレームワークがマルチモーダルをどう支援するか、大きな図を整理します。詳細はバージョンによって変わるので、一般的傾向として理解してください。

フレームワーク別の特性(概念)

vLLM:
  - 広いモデル/ハードウェア支援, マルチモーダル入力支援が成熟
  - paged KV cache, continuous batching, chunked prefill
  - 汎用サービングの無難な既定選択

TensorRT-LLM:
  - コンパイルベース最適化, H100で高いスループット
  - マルチモーダルはビジョンエンコーダ統合パイプライン構成が必要
  - 最高性能を追う際, ビルド/運用コストを許容

SGLang:
  - RadixAttention による prefix キャッシュ再利用に強い
  - マルチターン/共通接頭コンテキストで利得が大きい
  - マルチモーダルのマルチターンワークロードに適合

選択基準はワークロードの性格です。多様なモデルを素早く立ち上げる必要があれば vLLM、単一モデルの最大スループットが重要なら TensorRT-LLM、マルチターン対話が核心なら SGLang が出発点になります。実際にはベンチマークを通じて自分のトラフィックで検証するのが正解です。

ワークド例: 遅延分解を追う

抽象的な議論を具体化するため、一つのマルチモーダルリクエストの遅延を段階別に追ってみましょう。数値は説明のための仮想の相対値であり、実際はモデル・ハードウェア・設定によって大きく異なります。

マルチモーダルリクエストの遅延分解(概念, 仮想相対値)

リクエスト: 高解像度画像1枚(ビジュアルトークン ~2000) + テキスト50トークン
出力: 200トークン生成

段階別の寄与:
  画像前処理           : 小さい
  ビジョンエンコーディング : 中程度(画像が大きいほど増加)
  prefill(2050トークン) : 大きい(注意 O(L^2) 項)
  ----- ここまでが TTFT -----
  decode(200トークン)   : トークンあたり時間 x 200

観察:
  - TTFTが全体遅延の大きな部分(エンコーディング + 長い prefill)
  - decode はテキスト専用と類似の様相

この分解が与える教訓は明確です。マルチモーダルでユーザーが体感する初応答遅延(TTFT)を減らすには、テキスト専用で主に気にしていた decode 最適化だけでは不十分です。ビジョンエンコーディングと prefill を減らすことが核心です。

TTFT短縮レバー適用の効果(概念)

基準: エンコーディング + 長い prefill で TTFT が大きい

レバー1) トークン圧縮でビジュアルトークン 2000 -> 600
  -> prefill が大幅減少 -> TTFT が大きく短縮
レバー2) ビジョンエンコーディングのキャッシュヒット
  -> エンコーディング段階がほぼ0 -> TTFT さらに短縮
レバー3) chunked prefill
  -> 長い prefill が他リクエストを塞がない -> 全体 p95 改善

三つのレバーを併用するとTTFTとスループットが同時に改善します。核心は「ビジュアルトークンを減らし、再利用可能なエンコーディングをキャッシュし、重い prefill を分散させる」三方向を常に併せて見ることです。

比較: テキスト専用 vs マルチモーダルサービング

項目テキスト専用マルチモーダル
入力前処理トークナイズ(軽い)画像前処理 + ビジョンエンコーディング(重い)
プリフィルコスト通常軽いビジュアルトークンで急増
トークン数変動中程度非常に大きい(解像度依存)
KVキャッシュテキスト長に比例ビジュアル込みで遥かに大きい
TTFT構成トークナイズ + プリフィル前処理 + エンコーディング + プリフィル
核心最適化バッチング, KV, 量子化上記 + トークン圧縮, エンコーディングキャッシュ, 分離

運用の落とし穴とチェックリスト

落とし穴:

  • 解像度無制限の入力: 高解像度画像がトークンを爆発させTTFTとコストを急騰させます。動的解像度の上限が必須です。
  • ビジョンエンコーダのボトルネックの見落とし: LLMだけ最適化しビジョンエンコーダ/前処理を放置すると、そこがボトルネックになります。
  • バッチ不均衡: 長さの偏差が大きいリクエストを混ぜると、長いプリフィルが短いリクエストを飢えさせます。chunked prefill/分離で緩和してください。
  • KVメモリ超過(OOM): ビジュアルトークンを見落としたメモリ計画はOOMを招きます。最大ビジュアルトークンを基準に予算を立ててください。
  • キャッシュキー誤り: 前処理パラメータ(解像度/正規化)をキャッシュキーから漏らすと、誤ったビジュアルトークンを再利用します。
  • 前処理CPUボトルネック: 画像デコード/リサイズがCPUで直列化されるとGPUが飢えます。オフロード/非同期化してください。

チェックリスト:

マルチモーダルサービング点検項目

[ ] 動的解像度の上限とトークン圧縮ポリシーがあるか
[ ] ビジョンエンコーディング結果のキャッシュ(キーに前処理パラメータを含む)があるか
[ ] ビジョンエンコーダとLLMをパイプライン/分離したか
[ ] chunked prefill または prefill/decode 分離を適用したか
[ ] 最大ビジュアルトークンを基準にKVメモリ予算を立てたか
[ ] TTFT/TPOT/スループットを別々に監視しているか
[ ] 前処理CPUボトルネックをオフロード/非同期化したか
[ ] FP8/INT4量子化でバッチサイズを確保したか

おわりに

マルチモーダルLLMサービングはテキスト専用サービングの延長線上にありますが、画像入力が生み出す違いは本質的です。ビジョンエンコーダという追加段階、リクエストごとにばらつくビジュアルトークン、そして重くなったプリフィルがTTFTとメモリ・コスト構造を変えます。

対応の大筋は明確です。トークンを減らし(動的解像度・圧縮)、エンコーディングをキャッシュ・バッチ・パイプライン化し、プリフィルを分離・チャンク化し、デコードを量子化・KV最適化・speculative decoding で加速することです。vLLMのようなフレームワークのマルチモーダル支援が成熟するにつれ、これらのパターンを比較的容易に適用できるようになりました。結局、核心の問いは一つに収束します。「精度を保ちながら、ビジュアルトークンとプリフィルコストをどれだけ減らせるか」。

参考資料