Triton Inference Serverは、TensorRT・PyTorch・ONNX・Pythonなど形式の違うモデルを、1台のサーバーから同じ推論APIで配信するNVIDIA製のOSSです。2026年10月31日時点の最新リリースは2.73.0(NGCコンテナ26.09)で、製品名はNVIDIA Dynamo-Tritonへ改められています。この記事では、GPUのないPCでも動くモデルリポジトリとconfig.pbtxtの書き方、動的バッチの設定をperf_analyzerで測って詰める手順、本番でのモデルの入れ替え方、vLLMバックエンドとの関係、そして採用を見送る条件までを、コピーして動かせる設定例とあわせて整理します。
まとめ:Triton Inference Serverを選ぶ条件と、最初に動かす最小構成
最初に動かすのは、モデル名のディレクトリにconfig.pbtxtと版番号のディレクトリを置いたモデルリポジトリと、それを読み込むtritonserverコンテナの2つだけです。PythonバックエンドならGPUがなくても起動し、curlで推論の往復まで確かめられます。
採用の決め手は、形式の違う複数のモデルを1つの基盤で配信したいかどうかです。画像分類はTensorRT、表形式はONNX、前後処理はPythonのように混在するなら、Tritonは配信の作法を1本にまとめられます。
LLMだけを配信するなら話は別です。vLLMを単体で立てるほうが部品は少なく済みます。
Tritonの役割と26.09の版数、Dynamo-Tritonへの改称
複数形式のモデルを1台で配信する仕組みと、KServe互換の推論API
GitHubのTritonリポジトリのREADMEは、対応形式としてTensorRT、PyTorch、ONNX、OpenVINO、Python、RAPIDS FILなどを挙げています。形式ごとの実行部分は「バックエンド」として分かれており、サーバー本体はリクエストの受付、キューへの振り分け、バッチのまとめ、メトリクスの出力を受け持ちます。
推論APIは、プロトコルの説明のとおりKServeのコミュニティ標準に沿ったHTTP/RESTとgRPCです。リクエストの形はKServeのV2推論プロトコルで定義され、POST v2/models/<モデル名>/inferに入力テンソルの名前・形・型・値を送ります。クライアントを同じ規格の別サーバーへ向け替えられるのが、この規格に乗る利点です。推論APIの層構造やKServe・BentoMLとの選び分けは推論APIの構成とKServe・Triton・BentoMLの選定基準にまとめており、本記事はTriton固有の設定に絞ります。
2.73.0(コンテナ26.09)の版数と、BSD-3-Clause・商用サポートの関係
GitHubのリリース一覧では、2026年9月30日に2.73.0が出ており、対応するNGCコンテナのタグは26.09です。サーバーの版(2.x)とコンテナのタグ(年.月)は別の番号なので、手順書にはコンテナのタグで書くと取り違えが起きません。26.09ではNVIDIA Rubin世代のGPUへの初期対応が入った一方、既知の問題として「TensorRT-LLMバックエンドのコンテナイメージはこのリリースに含まれない」と明記されています。
ライセンスはBSD-3-Clauseで、自社サービスに組み込んで提供しても制約はかかりません。NVIDIAの製品ページは名称をDynamo-Tritonとし、LLM向けには別製品のNVIDIA Dynamoを案内しています。障害時の保守契約が要る場合は、有償のNVIDIA AI Enterpriseに含まれる版を選ぶ形です。
検証環境の作り方:モデルリポジトリとconfig.pbtxtをCPUだけで動かす手順
ここから手を動かします。DockerとPythonが入ったPCがあれば、GPUなしで最後まで試せます。
モデルリポジトリの階層と、バックエンドごとに決まるファイル名の規則
モデルリポジトリの仕様では、モデル名のディレクトリの下に、版を表す数字のディレクトリを最低1つ置きます。ファイル名も既定で決まっており、TensorRTはmodel.plan、ONNXはmodel.onnx、PyTorchはmodel.pt、OpenVINOはmodel.xml、Pythonはmodel.pyです。名前が違うと読み込みに失敗するため、学習側から成果物を受け取る時点でこの名前に揃えておきます。
今回は、入力の4要素を2倍して返すだけのPythonモデルをdoublerという名前で置きます。
models/
└── doubler/
├── config.pbtxt
└── 1/
└── model.py
Pythonバックエンドで最小モデルを書き、config.pbtxtで入出力を宣言する
Pythonバックエンドは、クラス名をTritonPythonModelとし、execute()で受け取ったリクエストの数だけ応答を返す決まりです。
# models/doubler/1/model.py
import numpy as np
import triton_python_backend_utils as pb_utils
class TritonPythonModel:
def execute(self, requests):
responses = []
for request in requests:
x = pb_utils.get_input_tensor_by_name(request, "INPUT0").as_numpy()
out = pb_utils.Tensor("OUTPUT0", (x * 2).astype(np.float32))
responses.append(pb_utils.InferenceResponse(output_tensors=[out]))
return responses
入出力の名前・型・形は、モデル設定の仕様に沿ってconfig.pbtxtで宣言します。max_batch_sizeを1以上にすると、dimsにはバッチの次元を含めず、1件分の形だけを書きます。
# models/doubler/config.pbtxt
name: "doubler"
backend: "python"
max_batch_size: 8
input [
{ name: "INPUT0", data_type: TYPE_FP32, dims: [ 4 ] }
]
output [
{ name: "OUTPUT0", data_type: TYPE_FP32, dims: [ 4 ] }
]
instance_group [ { count: 1, kind: KIND_CPU } ]
dynamic_batching { }
ONNXやTensorRTのモデルは、config.pbtxtを省いても入出力を読み取って設定を補います。ただ補われた内容は版の更新で変わりうるので、本番では--disable-auto-complete-configを付け、書いた設定だけで動かすのが安全です。
26.09-py3の起動とcurl・tritonclientによる推論手順
クイックスタートの手順から--gpusを外すとCPUで起動します。8000番がHTTP、8001番がgRPC、8002番がメトリクスです。
docker run --rm -p8000:8000 -p8001:8001 -p8002:8002 \
-v ${PWD}/models:/models \
nvcr.io/nvidia/tritonserver:26.09-py3 \
tritonserver --model-repository=/models
# 別の端末で: 準備完了なら HTTP 200
curl -v localhost:8000/v2/health/ready
# 推論: shape の先頭 1 はバッチの次元
curl -X POST localhost:8000/v2/models/doubler/infer \
-H "Content-Type: application/json" \
-d '{"inputs":[{"name":"INPUT0","shape":[1,4],"datatype":"FP32","data":[1,2,3,4]}]}'
応答のoutputsに[2,4,6,8]が入っていれば成功です。アプリから呼ぶときは、PyPIのtritonclientをpip install "tritonclient[http]"で入れ、NumPy配列のまま送ります。
import numpy as np
import tritonclient.http as httpclient
client = httpclient.InferenceServerClient(url="localhost:8000")
x = np.array([[1, 2, 3, 4]], dtype=np.float32)
inp = httpclient.InferInput("INPUT0", list(x.shape), "FP32")
inp.set_data_from_numpy(x)
res = client.infer("doubler", inputs=[inp])
print(res.as_numpy("OUTPUT0")) # [[2. 4. 6. 8.]]
動的バッチと実行インスタンスの設定をperf_analyzerで測って詰める手順
dynamic_batchingを既定値で始め、待ち時間の上限を少しずつ広げる理由
バッチ処理の仕様が示す調整の順番は明快です。まず最大バッチサイズを決め、dynamic_batching { }を既定値のまま有効にして遅延とスループットを測ります。遅延に余裕があれば、max_queue_delay_microsecondsを0から少しずつ増やし、遅延の予算を超える手前で止めます。
dynamic_batching {
max_queue_delay_microseconds: 100
}
この値は、リクエストを束ねるために待つ時間の上限です。広げるほどGPUに1回で渡す件数が増えて処理量は伸び、代わりに1件ごとの応答は遅れます。よく見かけるpreferred_batch_sizeは、同じ仕様が「大半のモデルでは使わない」としています。例外は、バッチサイズごとにoptimization profile(実行条件ごとの事前設定)を複数持つTensorRTのモデルだけです。
perf_analyzerで同時接続数を振り、遅延とスループットの折れ目を探す
測定にはperf_analyzerを使います。-py3-sdkのコンテナに同梱されているので、別途インストールは要りません。
docker run -it --rm --net=host nvcr.io/nvidia/tritonserver:26.09-py3-sdk
perf_analyzer -m doubler --concurrency-range 1:8
同時接続数を1から8まで上げながら、秒あたりの推論数と遅延が出力されます。同時接続数を増やしても推論数が伸びず遅延だけが増える点が、その設定の上限です。設定を1つ変えるたびに同じコマンドで測り直し、数字で比べてください。LLMの負荷試験に使われてきたgenai-perfは非推奨となり、後継のAIPerfへの移行が案内されています。
instance_groupで実行インスタンスを増やすときのGPUメモリの見積もり方
instance_groupのcountを2にすると、同じモデルの実行インスタンスが2つ並び、前のリクエストの処理中にも次を受けられます。kind: KIND_GPUなら、指定がない限り各GPUにインスタンスが置かれます。
見落としやすいのはGPUメモリです。インスタンスごとにモデルを読み込むため、1インスタンスで6GBを使うモデルをcount: 3にすれば、およそ18GBに加えて作業領域が要ります。インスタンスを増やす前に、次の節のメトリクスで「キューで待っているのか、計算で詰まっているのか」を見分けてください。キュー待ちが長いならインスタンスやバッチを増やす価値があり、計算時間が長いならモデル側の高速化が先です。
8002番のPrometheusメトリクスでキュー待ちと推論時間を分けて見る
メトリクスの仕様では、http://localhost:8002/metricsにPrometheus形式で出力されます。監視の起点にするのは次の5つです。
nv_inference_queue_duration_us:キューで待った累計時間。伸びたらインスタンスかバッチの上限を見直すnv_inference_compute_infer_duration_us:推論の実行に使った累計時間nv_inference_request_success:成功したリクエストの累計数。上の2つをこれで割ると1件あたりになるnv_gpu_utilization:GPU使用率(0.0〜1.0)nv_gpu_memory_used_bytes:GPUメモリの使用量
どれも累計値なので、PrometheusのrateでN秒あたりに直して見ます。応答時間の目標をどう置くかはオンライン推論の遅延とコストの設計で扱っています。
本番運用のモデル管理:EXPLICITモードでの入れ替えとPOLLを避ける理由
NONE・POLL・EXPLICITの3モードの挙動の違いと、本番での選び方
モデル管理の仕様には、モデルの読み込み方として3通りのモードが定められています。既定のNONEは起動時にリポジトリの全モデルを読み込む方式で、稼働中の変更は反映されない仕様です。POLLはリポジトリの変更を検出して自動で読み直し、EXPLICITは起動時に--load-modelで指定したものだけを読み込んで、以降はAPIの指示でのみ入れ替えます。
本番はEXPLICITにしてください。POLLは、ファイルのコピー途中の不完全な状態を読み込みうるとして、同じ仕様が本番での使用を推奨していません。モデルが1つで、入れ替えのたびにコンテナごと作り直す運用ならNONEでも足ります。
load・unloadのAPIでモデルの版を入れ替える運用手順と確認の順番
EXPLICITモードでは、リポジトリ拡張のAPIでモデルを読み込み・解放します。
tritonserver --model-repository=/models \
--model-control-mode=explicit --load-model=doubler
# 新しい版のディレクトリ(例: models/doubler/2/)を置き終えてから
curl -X POST localhost:8000/v2/repository/models/doubler/load
curl localhost:8000/v2/models/doubler/ready
順番は「ファイルを置き終える→loadを呼ぶ→readyを確かめる」です。既定の版の扱いでは、数字の大きい版が配信に使われます。旧版へ戻せるよう、直前の版ディレクトリは最低1世代残しておきます。
LLMを載せる場合の選択:vLLMバックエンド・TensorRT-LLM・単体vLLM
vLLMバックエンドのmodel.jsonとKIND_MODEL指定、メトリクスの出し方
Tritonの上でLLMを動かすときは、vLLMバックエンドを使います。コンテナはtritonserver:<xx.yy>-vllm-python-py3という別タグで、モデルの指定はconfig.pbtxtではなくmodel.jsonに書きます。サンプルはmodelにモデル名、gpu_memory_utilizationに0.5を入れ、GPUメモリの半分だけをvLLMに渡す設定です。
複数GPUにまたがるモデルでは、config.pbtxtのinstance_groupをkind: KIND_MODELにします。vLLM側のメトリクスは性能への影響から既定で出力されず、24.08以降はREPORT_CUSTOM_METRICSを"true"にすると出ます。vLLM自体の仕組みと起動オプションはvLLMのPagedAttentionと使い方を参照してください。
単体vLLM・Triton経由・TensorRT-LLMを比べる、運用面の3つの観点
3つの選択肢は、推論の速さよりも運用の形で分かれます。
| 比較観点 | 単体のvLLM | Triton+vLLMバックエンド | Triton+TensorRT-LLM |
|---|---|---|---|
| APIの形 | OpenAI互換API | KServe形式とgenerate | KServe形式とgenerate |
| 他形式のモデルとの同居 | 不可 | 同じサーバーで可 | 同じサーバーで可 |
| 事前の変換作業 | 不要 | 不要 | エンジンのビルドが要る |
TensorRT-LLMはNVIDIA GPU向けにエンジンを事前に作る方式なので、その準備の手間が必要です。26.09ではTensorRT-LLMバックエンドのコンテナが同梱されていないため、採用する場合は26.08以前のタグか後続の版を確かめてから固定します。変換の手順と向く場面はTensorRT-LLMの仕組みと採用判断で扱っています。
Triton Inference Serverを採用する条件と見送る場面、委託時の確認事項
ここからは判断を言い切ります。
採用してよい条件:複数形式の混在、GPUの共有、KServe互換の推論API
次のどれかに当てはまるなら採用してください。1つ目は、TensorRT・ONNX・Pythonなど形式の違うモデルを3本以上配信する場合。形式ごとにFlaskやFastAPIのサーバーを書くと、ヘルスチェックとメトリクスの実装がモデルの数だけ増えます。
2つ目は、1枚のGPUに複数のモデルを同居させて稼働率を上げたい場合です。instance_groupと動的バッチで、モデルごとに並列度を調整できます。3つ目は、KServeを使うKubernetes基盤へ将来載せる予定がある場合。最初からV2推論プロトコルで呼んでおけば、クライアントのコードを変えずに移せます。
見送る場面:LLM単独の配信と、GPUを持たない小規模な推論API
配信するのがLLM1本だけなら、Tritonは挟みません。OpenAI互換APIをそのまま持つ単体のvLLMのほうが、既存のSDKから呼べて部品も1つ少なく済みます。
scikit-learnのモデルを1つ、CPUで1秒に数件だけ返す社内APIも見送りです。tritonserverのコンテナはバックエンド一式を抱えた大きなイメージで、FastAPIで数十行書くほうが起動も更新も軽く済みます。夜間にまとめて推論するだけなら、常時起動のサーバー自体が要りません。その設計はバッチ推論のジョブ分割と再実行の設計が向いています。
推論基盤の構築を外部に任せるとき、見積書で確かめる成果物の範囲
Tritonでの推論基盤を委託するなら、納品物にモデルリポジトリ一式(config.pbtxtを含む)、固定したコンテナのタグ、perf_analyzerの測定条件と結果、メトリクスの監視設定の4点を含めるよう、見積段階で指定してください。測定条件が残っていれば、モデルを差し替えた後に同じコマンドで性能を測り直し、劣化を数字で確かめられます。
学習済みモデルの作り込みから推論APIへの組み込みまで一括で相談したい場合は、機械学習モデル開発で要件の整理から引き受けています。依頼前に、1秒あたりの想定リクエスト数と許容できる応答時間を書き出しておくと、GPUの台数とバッチ設定の初期値をすぐ見積もれます。
よくある質問
Triton Inference Serverの導入時によく出る疑問を5つ取り上げ、設定と判断の基準とあわせて回答します。
Triton Inference Serverは無料で使えますか?
使えます。本体はBSD-3-ClauseのOSSで、NGCのコンテナイメージも無償で取得できます。自社のサービスに組み込んで顧客へ提供する使い方も、ライセンス上の制約はありません。障害対応の保守契約や長期サポート版が必要な場合は、NVIDIA AI Enterpriseの有償ライセンスに含まれる版を選びます。
GPUがなくてもTriton Inference Serverは動きますか?
動きます。docker runから--gpusを外し、config.pbtxtのinstance_groupをKIND_CPUにすればCPUで推論します。PythonバックエンドやONNX、OpenVINOのモデルはCPUで実用になりますが、TensorRTのモデルはNVIDIA GPUが前提です。検証はCPUで済ませ、本番の性能測定だけGPU環境で行う分担もできます。
Dynamo-TritonとTriton Inference Serverは別の製品ですか?
同じ製品です。NVIDIAの製品ページは「Dynamo-Triton(旧称Triton Inference Server)」と表記しており、GitHubのリポジトリ名やコンテナ名は従来のtritonserverのままです。別製品なのはNVIDIA Dynamoのほうで、こちらはLLMの分散推論に特化しています。Dynamo-Tritonと補い合う位置づけです。
config.pbtxtは必ず書く必要がありますか?
ONNX・TensorRTなどモデル自体から入出力を読み取れる形式では、省略しても自動で補われます。Pythonバックエンドは入出力を読み取れないため、config.pbtxtへの明示的な記述が必要です。本番では--disable-auto-complete-configを付け、明示した設定だけで動かすと、版の更新で設定が変わる事故を防げます。
Tritonとvllmはどちらを使えばよいですか?
LLMだけを配信し、OpenAI互換APIで呼びたいならvLLMを単体で使います。画像や表形式のモデルと同じ基盤でLLMも配信したい、監視とモデル管理を1つに揃えたい場合は、TritonにvLLMバックエンドを載せます。推論エンジンはどちらもvLLMなので、生成の速さそのものは大きく変わりません。
関連記事
- LLM推論とは?仕組みと高速化の手法・推論基盤の選び方を実装視点で解説【2026年】:TritonでLLMを配信する前に押さえる、推論の仕組みと基盤の選び方を解説しています。
- Text Generation Inference(TGI)とは?メンテナンスモード後の採用判断とvLLM移行【2026年版】:LLM配信サーバーの別の選択肢と、保守終了時の移行判断を比較できます。
- 推論パラメータとは?temperatureとtop_pの決め方・推論モデルでの非対応を実装目線で解説【2026年版】:vLLMバックエンドへ送る生成パラメータの決め方の参考になります。