PyNvVideoCodecとvLLMでマルチGPU動画字幕生成をスケールする
日本語
コピー


NVIDIA GPU に内蔵されたハードウェア動画デコードのサポートを発表します。これにより、これまで CPU の制約を受けていた動画キャプションとアノテーションのタスクが、データセンター級のマルチ GPU ノードでスループットを向上できるようになります。
動画キャプションは多くの業界で一般的なタスクで、動画内で何が起きているかを説明するために使われます。自動運転(AV)の学習システムでは、危険なシーンを記述・分類し、人間が読めて検索できるメタデータを生成するために利用されています。用途はほかにも多数あります。
これまで vLLM でこうしたデータセットを処理するには動画を渡す必要があり、その動画は CPU ベースの OpenCV+FFMPEG バックエンドでしかデコードできませんでした。マルチ GPU ノードでこの種の視覚言語モデル(VLM、GPU 1 基につき vLLM サーバー 1 台)を動かすと、VLM の推論が始まる前に CPU が動画フレームのデコードで大きな負荷を受けることになります。動画キャプションでは特にこれが顕著です。出力が比較的短く(100〜200 トークン)、動画のデコードが占める時間の割合がはるかに大きくなるため、CPU ベースの動画デコードはすぐにボトルネックになり、GPU が 2 基や 4 基でも CPU コアを使い切ってしまいます。
NVIDIA のハードウェア動画デコーダ(別名「NVDEC」)の Python インターフェースである PyNvVideoCodec を統合することで、vLLM は動画デコードの負荷を CPU からオフロードし、このボトルネックを解消できます。8 基の GPU までスケールしても良好なスケーラビリティを維持します。
以下はこのタスクの入力プロンプトと出力の例です(実際のプロンプトはもっと長く、構造も複雑です)。
入力プロンプトの例
Analyze this front-facing dashcam video. Briefly describe the driving environment, relevant road users and traffic controls, and the ego vehicle’s actions. Report only clearly visible details and avoid speculation.
出力例
The ego vehicle travels along a multi-lane urban road in daylight with clear visibility. Several vehicles are ahead in the same and adjacent lanes, and a signalized intersection is visible. The ego vehicle maintains its lane, slows as it approaches traffic, and continues while keeping distance from the vehicle ahead.
vLLM で NVIDIA ハードウェア動画デコードを使う
前提依存関係のインストール
標準の CUDA 版 vLLM には PyNvVideoCodec が提供する機能が組み込まれています。自分で vLLM をインストールした場合は、プロジェクトの PyPi 依存関係に PyNvVideoCodec==2.0.4 が含まれていることを確認してください。
PyNvVideoCodec 動画デコーダを有効にして vLLM を起動する
# First launch CUDA MPS Daemon
nvidia-cuda-mps-control -d
# Launch vLLM with pynvvideocodec video backend
vllm serve Qwen/Qwen3-VL-8B-Instruct \
--dtype bfloat16 \
--max-model-len 32768 \
--max-num-seqs 1024 \
--max-num-batched-tokens 32768 \
--api-server-count 4 \
--renderer-num-workers 4 \
--async-scheduling \
--mm-ipc-gpu-memory-gb 2 \
--media-io-kwargs \ '{"video":{"backend":"pynvvideocodec","min_frames":16,"max_frames":16,"hw_decoders":2}}' \
--mm-processor-kwargs \
'{"size":{"shortest_edge":65536,"longest_edge":9437184}}'
CUDA MPS は、マルチプロセスの高並列シナリオ(バッチ VLM 推論など)のパフォーマンスに不可欠です。vllm serve を実行する前に、MPS デーモンが起動していることを確認することをおすすめします。
--mm-ipc-gpu-memory-gb は動画デコード用に VRAM を確保するために使います。さまざまな値でスループットを試し、スループットに影響しない最小値を採用するとよいでしょう。PyNvVideoCodec デコーダバックエンド関連パラメータの詳細なドキュメントは vLLM のドキュメント を参照してください。
マルチ GPU にスケールする場合、通常は vLLM サーバーレプリカごとに 1 つのコンテナを動かし、各コンテナに GPU を 1 基だけ見せる構成をおすすめします。別の方法として、CUDA_VISIBLE_DEVICES を使って vLLM レプリカごとに GPU を 1 基見せることもできます。リクエストはリバースプロキシ経由で各 vLLM レプリカに振り分けます。
動画キャプションタスクでのマルチ GPU スケーリング

図 1:H100 GPU を使ったマルチ GPU スケーリングの改善。8xH100 では、GPU ベースの動画デコードのスループットは CPU ベースの動画デコーダの 2 倍以上になります。vLLM レプリカ 8 台、各レプリカに GPU 1 基。
この手法の効果を示すために、NVIDIA の AV チームが使っている動画キャプションタスクを見てみましょう。これらのシステムは数十万時間分の動画クリップのキャプションを生成し、累計で数億件の動画キャプションリクエストを処理しています。こうしたタスクでは通常、比較的軽量なモデル(たとえば Qwen/Qwen3-VL-8B-Instruct)を使い、入力プロンプトで必要なキャプションの種類を指定し、出力は 100〜200 トークン程度になります。

図 2:以前は最大 8 基の GPU を使う大規模な負荷でも、GPU が 4 基に達する前に CPU 使用率が制約になっていました。ハードウェアベースの動画デコード対応により、CPU のボトルネックは解消されました。データはベンチマークの定常状態で取得。
注意点
動画デコードでは、確かに VRAM を一部確保する必要がある点を補足しておきます。ユースケースによっては、VRAM のすべてを KV cache に割り当てている場合、何らかの影響が出る可能性があります。ただし、実際のテストでは、PyNvVideoCodec の使用によって性能が低下したケースは確認されていません。
謝辞
vLLM のハードウェア動画デコード対応にご貢献くださったすべての方々に感謝します。
- NVIDIA:
NVCV チーム:Brandon Pelfrey、Benjamin Chislett、Dhaval Suthar、Jeremy Bottleson、Ernesto Zamora Ramos、David Lesage
- PyNvVideoCodec チーム:Rohit Naskulwar、Jayant Mukundam、Hareshkumar Borse
vLLM チームとコミュニティ: Roger Wang、Nick Hill、Cyrus Leung、Zifeng Mo