はじめに
NVIDIA Triton Inference Serverについて最近調査する中で、機械学習モデルの推論パフォーマンスを測定するツールであるperf_analyzerがあることを知った。
Triton Inference Serverの設定パラメータチューニングを行う際に使用した方が良いことは把握しているが、詳細についてはまだ把握出来ていないため、今回調べて実際に使ってみた。
本記事の主な内容は以下となる。
- perf_analyzerの基本的な使い方の確認
- 実際のモデル(multilingual-e5-large)を使ってのパフォーマンス検証
- 同時並列数やインスタンス並列数を変化させて測定する
perf_analyzer(Triton Performance Analyzer)とは
NVIDIA Triton Inference Serverで実行される機械学習モデルの推論パフォーマンスを測定・最適化するための公式CLIツール。
Triton Inference Serverのconfig.pbtxtで設定可能なバッチサイズやインスタンス数、動的バッチングといったパラメータを変更した際に、パフォーマンスがどう変化するかを正確に測定することに特化している。
最もシンプルな実行方法は以下のコマンドで、モデル名を指定するだけで測定が開始される。
% perf_analyzer -m my_model
リポジトリ:
主な役割
- 最適化支援
- モデル設定(バッチサイズ、インスタンス数など)の最適化。config.pbtxtの設定を変更して測定・評価を繰り返すことで最適値を発見できる
- 負荷テスト
- 本番環境と同等の負荷をかけたパフォーマンス検証。Request Rate Modeを使えば実際のトラフィックパターンを再現可能
- ボトルネック特定
- パフォーマンスのボトルネックの特定。キュー時間、計算時間、ネットワーク時間を分解して測定することで、どこに問題があるかを把握できる
- 比較分析
- 異なる設定や最適化によるパフォーマンス比較。同じモデルの設定違いだけでなく、異なるモデル間のパフォーマンス比較も可能
測定可能な項目
- エンドツーエンドのレイテンシ
- リクエスト送信から結果受信までの全体的な応答時間を詳細に分析
- ネットワークオーバーヘッド
- HTTP/gRPCプロトコル毎の通信オーバーヘッドの測定
- モデルのインスタンス並列性の効果
- インスタンス数を変えた際のスループットとレイテンシの変化を測定
- 動的バッチング(dynamic batching)の効果
- GPU利用率とスループットの改善効果を測定
- 異なるハードウェア(GPU/CPU)でのパフォーマンス
- 同じモデルを異なるハードウェアで実行した際のパフォーマンス差を比較
参考ドキュメント:
パフォーマンス測定(モデル: simple)
まず、perf_analyzerがどのような出力を返すのかを確認するため、Triton Inference Serverに同梱されているsimpleモデルで測定を行う。
環境は、MacBook Pro(Apple M1 Pro、コア数8、メモリ16GB)のDocker環境を利用。
ここでは出力フォーマットの確認が目的のため、perf_analyzerコマンドのオプションは特に指定せず、デフォルト設定で実行する。
perf_analyzerのセットアップについては以下を参照。
Triton Inference Server起動
% docker run --rm -p8000:8000 -p8001:8001 -p8002:8002 -v $(pwd)/model_repository:/models nvcr.io/nvidia/tritonserver:24.11-py3 tritonserver --model-repository=/models
測定実行
% docker run --rm nvcr.io/nvidia/tritonserver:24.11-py3-sdk perf_analyzer -m simple -u host.docker.internal:8000
=================================
== Triton Inference Server SDK ==
=================================
NVIDIA Release 24.11 (build 124543102)
Copyright (c) 2018-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
Various files include modifications (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved.
This container image and its contents are governed by the NVIDIA Deep Learning Container License.
By pulling and using the container, you accept the terms and conditions of this license:
https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license
WARNING: The NVIDIA Driver was not detected. GPU functionality will not be available.
Use the NVIDIA Container Toolkit to start this container with GPU support; see
https://docs.nvidia.com/datacenter/cloud-native/ .
*** Measurement Settings ***
Batch size: 1
Service Kind: TRITON
Using "time_windows" mode for stabilization
Stabilizing using average latency and throughput
Measurement window: 5000 msec
Using synchronous calls for inference
Request concurrency: 1
Client:
Request count: 39806
Throughput: 2200.43 infer/sec
Avg latency: 451 usec (standard deviation 56 usec)
p50 latency: 447 usec
p90 latency: 484 usec
p95 latency: 499 usec
p99 latency: 549 usec
Avg HTTP time: 448 usec (send/recv 24 usec + response wait 424 usec)
Server:
Inference count: 39813
Execution count: 39813
Successful request count: 39813
Avg request latency: 48 usec (overhead 11 usec + queue 24 usec + compute input 4 usec + compute infer 6 usec + compute output 3 usec)
Inferences/Second vs. Client Average Batch Latency
Concurrency: 1, throughput: 2200.43 infer/sec, latency 451 usec
測定結果から、以下の情報が取得できることが確認できた。
Client側の測定値:
- スループット: 2200.43 infer/sec(1秒間に処理できる推論数)
- レイテンシ: 平均451 usec、p50/p90/p95/p99の各パーセンタイル値
- HTTP通信時間: send/recv 24 usec + response wait 424 usec
Server側の測定値:
- リクエスト処理時間の内訳: overhead 11 usec + queue 24 usec + compute input 4 usec + compute infer 6 usec + compute output 3 usec
この内訳を見ることで、ボトルネックがキュー待ち時間にあるのか、計算時間にあるのかを特定できる。
今回の測定では計39806リクエストが処理され、測定ウィンドウは5000 msecで安定化された。
測定やメトリクスの詳細情報は以下参照。
パフォーマンス測定(モデル: e5-large)
simpleモデルでperf_analyzerの基本的な出力フォーマットを確認できたので、次は実際のモデルを使った測定を行う。
今回は、テキストをベクトル化するためにintfloat/multilingual-e5-largeモデルを使用する。このモデルは多言語対応のテキスト埋め込みモデルで、1024次元のベクトルを出力する。
パフォーマンス検証では、リクエスト数を500に固定し、以下の2つの設定パラメータを変化させることでパフォーマンスがどう変動するかを確認する。
- 同時並列数(concurrency-range): perf_analyzerのオプションで指定
- インスタンス並列性(instance_group): Triton Inference Serverのconfig.pbtxtで設定
Triton Inference Serverのモデルディレクトリ構成、設定
model_repository/e5_large/
├── config.pbtxt # Triton設定ファイル(モデルの入出力定義)
├── 1/ # モデルバージョン1
│ ├── model.py # Python Backendの推論ロジック
│ ├── model.onnx # ONNXモデル本体(2.7MB)
│ └── model.onnx.data # ONNXモデルの重み(1.3GB)
└── tokenizer/ # トークナイザーファイル群
├── tokenizer.json # トークナイザーの設定(711KB)
├── tokenizer_config.json # トークナイザーの追加設定
├── vocab.txt # 語彙ファイル(231KB)
└── special_tokens_map.json # 特殊トークンのマッピング
設定ファイル(config.pbtxt)の主要な設定項目:
name: "e5_large"
backend: "python"
max_batch_size: 32
instance_group [
{
count: 2
kind: KIND_CPU
}
]
dynamic_batching {
preferred_batch_size: [ 4, 8, 16 ]
max_queue_delay_microseconds: 1000
}
input [
{
name: "INPUT_TEXT"
data_type: TYPE_STRING
dims: [ -1 ]
}
]
output [
{
name: "OUTPUT_EMBEDDING"
data_type: TYPE_FP32
dims: [ 1024 ]
}
]
この設定では、Pythonバックエンドを使用し、最大バッチサイズは32、インスタンス数は2で動的バッチングが有効になっている。
測定用データ準備
パフォーマンス測定で利用するテキストデータ群(perf_input.json)として、27件のデータを準備する。
短いクエリ("machine learning tutorial"など)から長文(AI技術の説明文)まで、様々な長さのテキストを含めることで、実際の利用シーンに近い測定を行う。
{
"data": [
{
"INPUT_TEXT": ["machine learning tutorial"]
},
{
"INPUT_TEXT": ["how to train neural networks"]
},
{
"INPUT_TEXT": ["deep learning frameworks comparison"]
},
{
"INPUT_TEXT": ["natural language processing basics"]
},
・・・
{
"INPUT_TEXT": ["The field of artificial intelligence has made remarkable progress in recent years, with deep learning models achieving human-level performance on many tasks. These advancements have been driven by several factors: increased computational power through GPUs and TPUs, availability of large datasets, and improvements in algorithms and architectures. Transformer models, in particular, have revolutionized natural language processing, enabling applications like machine translation, text summarization, and question answering at unprecedented scales. As we look to the future, researchers are exploring ways to make these models more efficient, interpretable, and aligned with human values."]
},
{
"INPUT_TEXT": ["近年、人工知能の分野は目覚ましい進歩を遂げており、深層学習モデルは多くのタスクで人間レベルの性能を達成しています。これらの進歩は、GPUやTPUによる計算能力の向上、大規模データセットの利用可能性、アルゴリズムとアーキテクチャの改善など、いくつかの要因によって推進されてきました。特にTransformerモデルは自然言語処理に革命をもたらし、機械翻訳、文章要約、質問応答などのアプリケーションを前例のない規模で可能にしました。今後、研究者たちはこれらのモデルをより効率的で、解釈可能で、人間の価値観と整合性のあるものにする方法を探求しています。"]
}
]
}
同時並列数を変化させての測定
同時並列数とは
- 常に何個のリクエストが処理中の状態を維持するかを指定するパラメータで、サーバーの同時処理能力を測定するのに適している。
まず、同時並列数(concurrency-range)の値を変化させてパフォーマンスがどう変化するかを検証する。
今回は 1, 2, 4, 8, 16 の5パターンで測定を行った。
測定コマンド例(同時並列数=1の場合):
docker run --rm \
-v $(pwd)/data:/data \
nvcr.io/nvidia/tritonserver:24.11-py3-sdk \
perf_analyzer -m e5_large -u host.docker.internal:8000 \
--concurrency-range 1 \
--request-count 500 \
--input-data /data/perf_input.json \
--shape INPUT_TEXT:1
このオプション指定により、Concurrency Mode(同時実行モード)で測定が実行される。
Concurrency Modeでは常にN個のリクエストが処理中の状態を維持し、サーバーの最大同時処理能力を測定するのに適している。
詳細やその他のモードに関する情報は以下参照。
結果
現在の設定(instance count: 2, KIND_CPU)での結果:
| 同時実行数 | スループット (req/s) | 平均レイテンシ (ms) | P50 (ms) | P90 (ms) | P99 (ms) |
|---|---|---|---|---|---|
| 1 | 3.52 | 283 | 152.6 | 456.3 | 1924.3 |
| 2 | 3.33 | 596 | 437.1 | 1063.5 | 2796.5 |
| 4 | 2.40 | 1513 | 1129.0 | 2906.0 | 7681.3 |
| 8 | 2.54 | 2936 | 2717.1 | 5117.7 | 7983.7 |
| 16 | 2.79 | 4906 | 3891.4 | 8909.1 | 14465.0 |
測定結果から、以下のことが分かった。
スループットの傾向:
- 同時実行数1の時に3.52 req/sで最も高いスループット
- 同時実行数を増やすとスループットが低下(4の時に2.40 req/sまで低下)
- 同時実行数8以降は若干回復するが、1には及ばない
レイテンシの傾向:
- 同時実行数1が最も低いレイテンシ
- 同時実行数1では平均283 msだが、16では4906 msと 約17倍に増加
- P99レイテンシは同時実行数16で14465 msに達している
考察
この環境(M1 Pro、CPUのみ)では、 同時実行数1が最も効率的 で、並列度を上げてもスループットは向上せず、レイテンシが悪化する結果となった。これはCPUリソースの競合、Pythonバックエンドのオーバーヘッドが影響している可能性がある。
インスタンス並列数を変化させての測定
インスタンス並列数とは
- モデルインスタンスをいくつ起動するかを指定するパラメータで、複数のインスタンスを起動することで並列処理能力が向上し、同時に処理できるリクエスト数が増加する(並列数を増やすことで、コアの稼働率が向上しその恩恵を受ける可能性があるため)
次に、Triton Inference Serverのconfig.pbtxtで設定するインスタンス並列数(instance_group の count)を変化させてパフォーマンス検証を行う。
今回の測定では、同時実行数を2に固定し、インスタンス数を1、2、4、8と変化させることで、インスタンス数がパフォーマンスに与える影響を確認する。
config.pbtxtのinstance_group設定例:
instance_group [
{
count: 2 # モデルインスタンス数(この値を変更して測定)
kind: KIND_CPU
}
]
それぞれの設定でTriton Inference Serverを再起動してから測定を実施した。
測定環境は前述と同じ、MacBook Pro(Apple M1 Pro、コア数8、メモリ16GB)のDocker環境を利用。
結果
Instance Count比較(同時実行数2固定)の結果:
| Instance Count | スループット (req/s) | 平均レイテンシ (ms) | P50 (ms) | P90 (ms) | P99 (ms) |
|---|---|---|---|---|---|
| 1 | 4.13 | 479.7 | 339.1 | 913.6 | 1858.9 |
| 2 | 4.03 | 496.1 | 343.9 | 891.3 | 2662.6 |
| 4 | 4.31 | 462.3 | 310.8 | 915.2 | 2613.6 |
| 8 | 2.96 | 675.7 | 455.4 | 1320.2 | 2741.5 |
測定結果から、以下のことが分かった。
スループットの傾向:
- Instance Count 4の時に4.31 req/sで最も高いスループット
- Instance Count 1、2では4.13、4.03 req/sとほぼ同等のパフォーマンス
- Instance Count 8では2.96 req/sに大幅に低下(Count 4比で約31%のパフォーマンス低下)
レイテンシの傾向:
- Instance Count 4が最も低いP50レイテンシ(310.8 ms)
- Instance Count 2が最も低いP90レイテンシ(891.3 ms)
- Instance Count 8ではすべてのパーセンタイル値が悪化
考察
この結果から、 Instance Count 4が最適値 であることが分かった。これ以上インスタンス数を増やすと、インスタンス間のリソース競合やスケジューリングのオーバーヘッドでパフォーマンスが低下している可能性がある。
さいごに
NVIDIA Triton Inference Serverの推論パフォーマンスの測定・最適化を行うツールperf_analyzerについて調査や検証を行った。
今回はMacBook Pro(M1 Pro、CPUのみ)環境での測定結果であったが、同時実行数1の時にスループットが最も高く(3.52 req/s)、インスタンス並列数4の時にスループットが最も高い(4.31 req/s)ことを確認することが出来た。
並列度を上げてもパフォーマンスが線形にスケールしないことは、環境特有の制約の可能性がある。
今後は、GPU環境での検証やdynamic_batching設定(preferred_batch_size、max_queue_delay_microseconds)、最大バッチサイズ(max_batch_size)の変更によるパフォーマンス検証も実施したい。



