tao-run-inference-service について
tao-run-inference-serviceは、ローカルDocker、Brev、Lepton、SLURM、KubernetesでTAO推論サービスを起動・管理し、推論リクエストを送る手順を案内するエージェントスキルです。アーキテクチャ別のイメージ解決、サービス登録、準備状況の確認を定め、サンプリングパラメーターの明示的な選択を求めます。
主な機能
- 01モデル、アーキテクチャ、プラットフォームの入力収集
- 02ネットワークアーキテクチャ別のイメージとコマンド解決
- 035つのプラットフォームで推論コンテナを起動
- 04サービス登録と準備状況の確認
- 05サービスIDまたはアーキテクチャによる送信先選択
- 06レジストリ情報を使ったサービス停止
活用シーン
- 01TAO推論サービスを起動して登録
- 02選択したサービスに推論リクエストを送信
- 03異なるポートで複数サービスを同時稼働
- 04指定した稼働中サービスを停止
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ promptingcompany/ nv-skills --skill tao-run-inference-serviceインストール後、Claude Code で/tao-run-inference-serviceを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
BENCHMARK.mdskill-card.mdskill.oms.sigevals/evals.jsonreferences/code-templates.yamlcosmos-predict2.5.config.jsonrequest.yamlservice.yamlskill_info.yamltao-dataservices.config.json詳細
TAO 推論マイクロサービス
手順
推論サービスを開始するには:
- 必要な入力を収集し(セクション 1)、コンテナイメージを解決します(セクション 2)。
- ジョブのペイロードと内部コマンドを組み立てます(セクション 3~4.1)。
references/code-templates.yaml→job_payload_builderを使用します。 skills/platform/<platform>/SKILL.mdを読み、コンテナを開始します(セクション 4.2)。- サービスレジストリを書き込み、準備状況をポーリングします(セクション 4.3)。
references/code-templates.yaml→registry_write.<platform>およびreadiness_checkを使用します。
推論リクエストを送信するには:
- セクション 6.0 に従って、リクエストを受け取るサービスを解決します(
job_id、network_arch、または複数のサービスが実行中の場合はユーザーが明示的に選択します。複数のサービスが存在する場合に"latest"を暗黙的に既定値として選択することは絶対にしないでください)。次に、解決済みのjob_idを使ってreferences/code-templates.yaml→request.registry_readからエンドポイントを読み取ります。 - リクエスト本文を作成する前に、vLLM 形式のサンプリングパラメーター(セクション 6.1)をユーザーに確認してください。
max_tokens、top_p、temperature(およびアーキテクチャごとの追加パラメーター)と既定値を提示し、それぞれについて、ユーザーが値を変更するか、既定値を受け入れるためにスキップできるようにします。既定値を暗黙的に使用してはいけません。 - セクション 6.2 に従って本文を作成して送信し、セクション 6.3 に従って応答を処理します。
サービスを停止するには: references/code-templates.yaml → stop.registry_read を読み取って job_id を解決し、skills/platform/<platform>/SKILL.md を読んでから、セクション 5 に従います。
参照データ(スキーマ、マッピング、有効な値。手順は含みません):
references/service.yaml— イメージマッピング、有効なnetwork_arch名、ジョブペイロードのスキーマ、環境変数名、シークレットの分類。references/request.yaml— エンドポイント定義、リクエストフィールドのスキーマ、応答形式、コード例。references/code-templates.yaml— ペイロードの作成、レジストリへの書き込み、準備状況の確認、停止/リクエストフローのための Python テンプレート。
シークレットのルール(このスキルで生成するすべてのコードブロックに適用)
シークレットの値をプロンプトに入力するようユーザーに求めてはいけません。 シークレットの値ごとに、次の手順に従います。
- 設定する環境変数をユーザーに伝えます(例:
export HF_TOKEN=...)。 os.environ["VAR_NAME"]で値を読み取るコードを生成します。値をハードコード、文字列への埋め込み、またはプロンプトでの入力要求をしてはいけません。
シークレットの環境変数(一覧は references/service.yaml → secrets_handling を参照):
HF_TOKEN、WANDB_API_KEY、CLEARML_API_ACCESS_KEY、CLEARML_API_SECRET_KEY、TAO_API_KEY、TAO_USER_KEY。
プロンプトで収集しても安全な値: network_arch、model_path、num_gpus、プロンプトのテキスト、WANDB_* 設定 URL、CLEARML_*_HOST URL。
1. ユーザーから収集する情報
| 入力 | 役割 |
|---|---|
network_arch | コンテナイメージ、アーキテクチャごとの内部コマンド形式(references/service.yaml → container_commands.<network_arch>)、および該当する場合はジョブ JSON の neural_network_name を選択します。references/service.yaml の valid_network_arch_config_basenames にあるベース名(例:cosmos-rl、cosmos-predict2.5)と一致する必要があります。 |
model_path | 学習済みモデルのチェックポイントです。有効な形式は hf_model://<org>/<model>(HuggingFace Hub。アクセス制限のあるモデルでは HF_TOKEN を設定します)またはローカルのコンテナファイルシステムのパスです。クラウド URI(s3://、gs://、az://)には対応していません。推論サービスはクラウドストレージに依存しないためです。必ずユーザーに確認し、プレースホルダーで置き換えてはいけません。references/service.yaml → model_path_protocols を参照してください。 |
platform | コンピューティングプラットフォーム:local-docker、brev、lepton、slurm、または kubernetes。 |
num_gpus | 既定値は 1 です。推論に必要な最小値は 1 です。 |
2. イメージの解決
各 network_arch には、{network_arch}.config.json というサイドカーファイルがあります。コンテナイメージを次のように解決します。
{network_arch}.config.jsonを読み込み、api_params.image(例:COSMOS_RL)を取得します。これはreferences/service.yamlのdocker_image_defaults.mappingにあるキーです。- マッピングでそのキーを検索します。ホストの環境変数
IMAGE_<KEY>(例:IMAGE_COSMOS_RL)が設定されている場合は、マッピングされたデフォルト値を上書きします。 - マッピングされた値は通常、リポジトリルートの
versions.yamlマニフェストにあるドット区切りのキー(例:tao_toolkit.cosmos_rl)です。versions.yaml→images.<group>.<name>を検索して、具体的なnvcr.io/...イメージ URI に解決します。絶対 URI は変更せずにそのまま渡されるため、完全な URI を含むIMAGE_<KEY>環境変数による上書きも機能します。この処理を行う Python ヘルパーはreferences/code-templates.yamlにあります。 - 設定ファイルがない場合、または
api_params.imageが空の場合は、COSMOS_RLキーにフォールバックします。
設定ファイルには spec_params.inference.model_path もあり、フォルダーとファイルのパスの扱いを決定します。この値に folder という部分文字列が含まれている場合、コンテナはパスをディレクトリとして扱います。
3. 環境変数(コールバックなし)
env_json をエンコードする前に、これらを env_payload に設定します。TAO_LOGGING_SERVER_URL または TAO_ADMIN_KEY は設定しないでください。
TAO_EXECUTION_BACKEND — プラットフォームと一致する必要があります。
| プラットフォーム | TAO_EXECUTION_BACKEND の値 |
|---|---|
| local-docker | local-docker |
| brev | local-docker |
| lepton | lepton |
| slurm | slurm |
| kubernetes | local-k8s |
CLOUD_BASED — このスキルでは常に "False" にします(TAO_LOGGING_SERVER_URL へのコールバック投稿を無効にします)。
GPU 環境変数 — プラットフォームスキルが GPU の注入を自動で処理しない場合にのみ必要です。
- Tegra/Jetson:
NVIDIA_DRIVER_CAPABILITIES=allおよびNVIDIA_VISIBLE_DEVICES=<ids>を指定して、--runtime=nvidiaを使用します。 - 標準的な x86 + nvidia-container-toolkit:Docker の
device_requestsを使用します。プラットフォームスキルがこれを処理します。
4. プラットフォーム間での実行
ジョブペイロードと内部コマンド(セクション 1~3)はプラットフォームに依存しません。各プラットフォームについて、実行コードを生成する前に、事前チェックと認証情報を確認するため、skills/platform/<name>/SKILL.md を読みます。
4.1 内部コマンドの構築(アーキテクチャごと)
内部コマンドの形式は network_arch ごとに異なり、統一されたテンプレートはありません。references/service.yaml → container_commands.<network_arch> にあるアーキテクチャごとの項目を確認してください。項目がない場合、そのアーキテクチャはサポート対象外です。そこで作業を止め、確認を求めてください。references/code-templates.yaml → job_payload_builder.<network_arch> にある該当サブブロックを選択してください。コマンドの先頭に umask 0 && を付け、プラットフォーム(local-docker、brev、lepton、slurm、kubernetes)間で同一にしてください。
アーキテクチャ共通の項目:
job_id:新しいuuid.uuid4()を使用します。コンテナ名およびレジストリーキーになります。image:セクション 2 に従って解決します。- シークレット(
access_key、secret_key、HF_TOKENなど)は実行時に環境変数から読み込みます。ハードコードしたり、ログに記録したり、出力したりしないでください。
アーキテクチャ固有の注意事項(詳細は references/service.yaml → container_commands を参照):
cosmos-rl—--job '<JOB_JSON>' --docker_env_vars '<ENV_JSON>'という単一の文字列を使用します。json.dumps(...)+shlex.quote(...)を使ってください。env_payloadにはTAO_EXECUTION_BACKEND(セクション 3 の表に従う)、TAO_API_JOB_ID、CLOUD_BASED=Falseを含めます。推論サービスはクラウドストレージに依存しません。適用されるクレデンシャル環境変数は、アクセス制限のある HuggingFace モデル用のHF_TOKENのみです。cosmos-predict2.5— フラグ形式のcosmos_predict inference_microservice start ... --port 8080を使います(setup.プレフィックスは付けません。tyro.conf.OmitArgPrefixesを使用します)。--job/--docker_env_varsは受け付けません。model_pathは--checkpoint-path(ローカルパス)または--model <registered_key>(hf_model://)に変換します。クラウド URI は拒否されます。適用されるクレデンシャル環境変数は、アクセス制限のある HuggingFace モデル用のHF_TOKENのみです。リクエストごとのパラメーター(prompt、inference_type、num_output_frames、guidance、seed、num_steps、negative_prompt)は起動時ではなく、リクエスト本文に指定します。TAO_EXECUTION_BACKEND/TAO_API_JOB_ID/CLOUD_BASEDは使用されないため、省略してかまいません。
4.2 実行をプラットフォームスキルに委任する
**skills/platform/<platform>/SKILL.md**を読み、手順に従ってコンテナを起動します。
基本パラメーター(全プラットフォーム共通):
| パラメーター | 値 |
|---|---|
image | 解決済みのコンテナイメージ(セクション 2) |
command | inner — セクション 4.1 で構築したシェル文字列 |
gpu_count | num_gpus |
env_vars | env_payload |
| ジョブ/コンテナ名 | job_id — レジストリから参照できるよう、4.1 の UUID と一致させる必要があります |
host_port (local-docker, brev) | コンテナのポート 8080 にバインドするホスト側ポート。デフォルトは 8080 ですが、同時に稼働するサービスごとに一意である必要があります — 以下のポート割り当てルールを参照してください。 |
プラットフォーム固有の追加入力:
| プラットフォーム | 追加入力 |
|---|---|
| local-docker | 基本パラメーター以外はありません |
| brev | instance_id(任意 — 既存のインスタンスを再利用);複数の認証情報/ワークスペースがあるアカウントでは、初回作成時に cloud_cred_id と workspace_group_id も指定してください — skills/platform/tao-run-on-brev/SKILL.md を参照 |
| lepton | resource_shape(GPU シェイプ ID。例:gpu.8xh100-sxm);dedicated_node_group(任意) |
| slurm | partition と account — SLURM_PARTITION/SLURM_ACCOUNT 環境変数を確認してください。未設定の場合はユーザーに確認してください |
| kubernetes | namespace(デフォルト:default);image_pull_secret(nvcr.io イメージには必須) |
ポートのバインド(local-docker および brev): -p <host_port>:8080 を渡し、コンテナ名を正確に job_id と一致させるため、DockerSDK ではなく**直接 docker run**を使用してください。
ポート割り当てルール(local-docker および brev、同時稼働するサービスでは必須): サービスを起動する前に、レジストリ(/tmp/tao-inf-ms-state.json)を読み込み、同じプラットフォーム上のすべての既存エントリー(brev の場合は同じ instance_id のもの)の host_port 値を集めます。その集合に含まれない、8080 から始まる最小の未使用ポートを選択します。例:host_port = next(p for p in range(8080, 8200) if p not in used_ports)。デフォルトの 8080 が適用されるのは、他に稼働中のサービスがない場合のみです。これにより、「3 つのサービスを起動し、それぞれ異なる host_url でアクセス可能にする」ことができます。これを行わないと、2 番目と 3 番目のサービスは bind: address already in use で失敗します。Lepton、SLURM、kubernetes では各プラットフォーム独自の仕組みでエンドポイントが個別に割り当てられるため、この手順は不要です。
4.3 起動後:サービスレジストリとエンドポイント
プラットフォームでコンテナの稼働が確認されたら、直ちにサービスレジストリに書き込みます。レジストリ(/tmp/tao-inf-ms-state.json)は job_id をキーとしており、"latest" は常に最も新しく起動したサービスを指します。
Python テンプレートについては、references/code-templates.yaml → registry_write.<platform> を参照してください。
| プラットフォーム | host_url | platform_job_id | 書き込み前の追加手順 |
|---|---|---|---|
| local-docker | http://localhost:{host_port} | — | なし |
| brev | http://{brev_ip}:{host_port} | — | brev ls → インスタンスの IP を取得します(リモート VM では localhost は無効です) |
| lepton | Lepton エンドポイント URL | job.id | sdk.get_job_status を Running になるまでポーリングします。エンドポイントはコンソールまたは lep job get <job.id> で取得します |
| slurm | http://localhost:{host_port} | SLURM スケジューラージョブ ID | Running になるまで待機します。SSH でポートフォワーディングを行います:localhost:{host_port}→{node}:8080 |
| kubernetes | http://{external_ip}:8080 | k8s ジョブ名 | kubectl expose job … --type=LoadBalancer を実行し、外部 IP が割り当てられるまで待機します |
レジストリに書き込んだ後、job_id と URL を出力します。
print(f"Inference service started.")
print(f" Job ID : {job_id}")
print(f" Arch : {network_arch}")
print(f" URL : {state[job_id]['host_url']}/v1/chat/completions")
print(f"Use this Job ID to send requests or stop the service.")
次に、準備が整うまでポーリングします — references/code-templates.yaml → readiness_check を参照してください。コンテナはバックグラウンドでモデルを読み込みます。200 が返る前にリクエストを送信しないでください。
5. 推論サービスの停止
停止する job_id をユーザーに尋ねます。指定されない場合は state["latest"] を既定値として使用し、どの job_id を停止するか確認します。references/code-templates.yaml → stop.registry_read を使用してレジストリを読み込み、その後 skills/platform/<platform>/SKILL.md を読み、そこに記載されたキャンセル/停止の方法を使用します。
| プラットフォーム | 渡す識別子 | 追加のクリーンアップ |
|---|---|---|
| local-docker | job_id_to_stop — コンテナ名 | なし |
| brev | job_id_to_stop — コンテナ名 | なし |
| lepton | entry["platform_job_id"] — Lepton ジョブ ID | なし |
| slurm | entry["platform_job_id"] — SLURM ジョブ ID | pkill -f "ssh.*-L.*{entry['host_port']}" |
| kubernetes | entry["platform_job_id"] — k8s ジョブ名 | kubectl delete svc {entry["platform_job_id"]} -n <namespace> |
ここで、entry = state[job_id_to_stop] です。停止後、レジストリをクリーンアップします:references/code-templates.yaml → stop.registry_cleanup。
6. 推論リクエストの送信
6.0 このリクエストを受け取るサービスの特定(必須)
各リクエストは、該当するモデルを実行している特定のサービスにルーティングする必要があります。ルーティングは job_id によって行います。レジストリには各エントリの network_arch が保存されているため、ユーザーが job_id ではなくモデルを指定した場合は、アーキテクチャから送信先を特定できます。次のルールを順に適用します。
- ユーザーが明示的な
job_idを指定した場合 → それを使用します。stateに存在することを確認します。 - ユーザーが
network_archを指定した場合(例:「このリクエストを cosmos-rl サービスに送信して」)→ 一致するエントリを検索します:candidates = [j for j, e in state.items() if j != "latest" and isinstance(e, dict) and e["network_arch"] == arch]。- 一致がちょうど 1 件 → それを使用します。
- 複数一致 → 候補の
job_idとstarted_atをユーザーに確認します。自動で選択しないでください。 - 一致なし → 停止し、そのアーキテクチャのサービスが実行されていないことをユーザーに伝えます。
job_idもnetwork_archも指定されていない場合 →state内の"latest"以外のエントリ数を数えます。- 実行中のサービスがちょうど 1 つ → それを使用します。
- 2 つ以上 →
state["latest"]を暗黙に既定値として使用しないでください。job_id、network_arch、host_urlの一覧全体をユーザーに提示し、明示的な選択を求めます。"latest"ポインターは単一サービスのワークフローで便利に使うためのものであり、複数のサービスが共存する場合のルーティング先として使用するものではありません。 - 0 件 → 停止し、先にサービスを起動するようユーザーに伝えます。
送信先を特定したら、レジストリからエンドポイントを読み込みます(references/code-templates.yaml → request.registry_read)。特定した job_id を user_provided_job_id として渡します。ユーザーに「job_id=… arch=… url=… に送信します」と確認します。サービスの読み込みがまだ完了していない可能性がある場合は、先に準備完了状態を確認します(references/code-templates.yaml → readiness_check)。
送信前の照合: ユーザーが指定したリクエスト本文にアーキテクチャ固有のフィールドが含まれている場合(例:guidance/num_steps/seed/negative_prompt → cosmos-predict2.5、必須の image_url/video_url コンテンツ項目 → cosmos-rl)、それらが state[job_id]["network_arch"] と一致することを確認します。一致しない場合は停止してユーザーに確認してください。cosmos-predict2.5 用の本文を cosmos-rl サービスに送信すると、コンテナで 4xx/5xx エラーが発生します。ここで事前に確認するほうが、原因の特定が容易です。
6.1 サンプリングパラメーター — リクエストごとにユーザーへの確認が必須
リクエストボディを構築する前に、vLLM 形式のサンプリングパラメーターをユーザーに明示的に確認しなければなりません。デフォルト値を黙って適用してはいけません。次のような構造化されたプロンプトを使用してください(例:Claude Code の AskUserQuestion。フィールドごとに質問を 1 つずつ提示)。
- 適用可能なすべてのフィールドについて、型とデフォルト値を示します。
- ユーザーがフィールドごとにスキップ/デフォルト値の適用を選べるようにします。値の入力は必須ではありません。
- すべてのフィールドを 1 回のやり取りで収集します。
確認後、ユーザーが入力した値はそのまま適用し、スキップされたフィールドにはデフォルト値を代入します。値を勝手に作成したり、黙って上限・下限に収めたりしてはいけません。
フィールド、デフォルト値、アーキテクチャごとの適用可否: references/request.yaml → chat_completions_request_body(基本のサンプリングフィールド:max_tokens、top_p、temperature)および network_arch_constraints.<network_arch>(cosmos-predict2.5 の guidance/num_steps/seed/negative_prompt など、アーキテクチャごとのオーバーライドと追加フィールド)。フィールドがアクティブなアーキテクチャでサポート対象外と示されている場合、そのフィールドについて確認してはならず、ボディにも含めてはいけません。
6.2 リクエスト形式
Content-Type: application/json を指定し、タイムアウトを300 秒以上に設定して、{BASE_URL}/v1/chat/completions に POST を送信します。ボディは OpenAI 互換(vLLM チャット補完)です。フィールドスキーマ全体とコンテンツアイテムの形式(text/image_url/video_url)については references/request.yaml → chat_completions_request_body を、すぐに実行できる Python および curl のサンプルについては code_examples を参照してください。
制約: 処理されるのは最初のユーザーメッセージのみです。リクエストボディにシークレット値を含めてはいけません。ネットワークごとの制約(例:cosmos-rl ではすべてのリクエストに画像または動画を含める必要があり、data: URI は拒否されます)については、references/request.yaml → network_arch_constraints を参照してください。
6.3 レスポンスの処理
| HTTP ステータス | 意味 | 対応 |
|---|---|---|
| 200 | 成功 — choices[0].message.content に生成されたテキストが含まれます | 結果を読み取る |
| 202 | サーバーの初期化中、またはモデルの読み込み中です | 少し待ってから再試行する |
| 503 | 初期化の失敗、モデルの読み込み失敗、またはモデルの準備未完了 | error.type を確認します。model_not_ready → 再試行します。initialization_error/model_load_error → 中止してログを確認します |
| 400 | JSON ボディがない、または空です | リクエストを修正する |
| 500 | 推論中に未処理の例外が発生しました | コンテナログを確認する |
202 および 503 の場合、ボディには {"error": {"type": "<error_type>", "message": "<reason>"}} が含まれます。エラータイプの文字列については、references/request.yaml の container_response_shapes を参照してください。