tao-run-inference-service
NVIDIA/skills
Starten, abfragen und stoppen Sie einen TAO-Inferenz-Mikroservice für eine bestimmte Netzwerkarchitektur, indem Sie die Containerausführung an die entsprechende Plattformfunktion delegieren.
...Alle erweiternTAO-Inferenz-Mikroservice
Anleitung
So starten Sie einen Inferenzdienst:
- Sammeln Sie die erforderlichen Eingaben (Abschnitt 1) und stellen Sie das Container-Image bereit (Abschnitt 2).
- Erstellen Sie die Job-Nutzlast und den inneren Befehl (Abschnitte 3–4.1); verwenden Sie
references/code-templates.yaml→job_payload_builder. - „Read“
skills/platform/und starten Sie den Container (Abschnitt 4.2)./SKILL.md - Schreiben Sie den Dienst in das Register und prüfen Sie die Betriebsbereitschaft (Abschnitt 4.3); verwenden Sie
references/code-templates.yaml→registry_write.undreadiness_check.
So senden Sie eine Inferenzanfrage:
- Ermitteln Sie gemäß Abschnitt 6.0, welcher Dienst die Anfrage erhält (durch
job_id, durchnetwork_arch, oder durch explizite Benutzerauswahl, wenn mehrere Dienste laufen – niemals stillschweigend auf"latest"zurückgreifen, wenn mehr als ein Dienst existiert), dann den Endpunkt ausreferences/code-templates.yaml→request.registry_readmit dem ermitteltenjob_id. - Bevor der Anfragetext erstellt wird, fragen Sie den Benutzer nach den vLLM-typischen Sampling-Parametern ab (Abschnitt 6.1). Zeigen Sie
max_tokens,top_p,temperature(sowie etwaige architekturabhängige Zusätze) mit ihren Standardwerten an; lassen Sie den Benutzer jeden Wert überschreiben oder überspringen, um den Standardwert zu übernehmen. Verwenden Sie Standardwerte niemals stillschweigend. - Erstellen und senden Sie den Hauptteil gemäß Abschnitt 6.2; verarbeiten Sie die Antwort gemäß Abschnitt 6.3.
Um einen Dienst zu beenden: Lesen Sie references/code-templates.yaml → stop.registry_read , um die `job_id` aufzulösen, lesen Sie skills/platform/und befolgen Sie anschließend Abschnitt 5.
Referenzdaten (Schemas, Zuordnungen, gültige Werte – keine Anweisungen):
references/service.yaml— Image-Zuordnungen, gültigenetwork_archNamen, Schema der Job-Nutzdaten, Namen von Umgebungsvariablen, Klassifizierung von Geheimnissen.references/request.yaml— Endpunktdefinition, Schema der Anfragefelder, Antwortformate, Code-Beispiele.references/code-templates.yaml— Python-Vorlagen für die Erstellung von Nutzdaten, Registrierungsschreibvorgänge, Bereitschaftsprüfungen sowie Stopp- und Anforderungsabläufe.
Regel für Geheimnisse (gilt für jeden generierten Codeblock in diesem Skill)
Fordern Sie den Benutzer niemals auf, einen geheimen Wert in eine Eingabeaufforderung einzugeben. Für jeden geheimen Wert gilt:
- Teilen Sie dem Benutzer mit, welche Umgebungsvariable er setzen soll (z. B.
export HF_TOKEN=...). - Generieren Sie Code, der diesen Wert mit
os.environ["VAR_NAME"]— den Wert niemals fest einbinden, interpolieren oder abfragen.
Geheime Umgebungsvariablen (vollständige Liste unter references/service.yaml → secrets_handling):
HF_TOKEN, WANDB_API_KEY, CLEARML_API_ACCESS_KEY, CLEARML_API_SECRET_KEY, TAO_API_KEY, TAO_USER_KEY.
In der Eingabeaufforderung sicher abzufragen: network_arch, model_path, num_gpus, Eingabeaufforderungstext, WANDB_* Konfigurations-URLs, CLEARML_*_HOST URLs.
1. Was vom Benutzer erfasst werden soll
| Eingabe | Rolle |
|---|---|
network_arch |
Wählt das Container-Image sowie die architekturspezifische Form des Befehls (references/service.yaml → container_commands.) sowie neural_network_name gegebenenfalls im Job-JSON. Muss mit einem Basisnamen in valid_network_arch_config_basenames in references/service.yaml (z. B. cosmos-rl, cosmos-predict2.5). |
model_path |
Der Checkpoint des trainierten Modells. Gültige Formate: hf_model:// (HuggingFace Hub – festlegen HF_TOKEN für Gated-Modelle) oder ein lokaler Pfad im Dateisystem des Containers. Cloud-URIs (s3://, gs://, az://) werden NICHT unterstützt – der Inferenzdienst ist nicht auf Cloud-Speicher angewiesen. Fragen Sie immer den Benutzer; ersetzen Sie niemals einen Platzhalter. Siehe references/service.yaml → model_path_protocols. |
platform |
Rechenplattform: local-docker, brev, slurmoder kubernetes. |
num_gpus |
Standardwert ist 1; Mindestwert 1 für die Inferenz. |
2. Bildauflösung
Jedes network_arch verfügt über eine Sidecar-Konfigurationsdatei mit dem Namen {network_arch}.config.json. Lösen Sie das Container-Image wie folgt auf:
- Lesen
{network_arch}.config.jsonund übernehmen Sieapi_params.image(z. B.COSMOS_RL). Dies ist ein Schlüssel indocker_image_defaults.mappinginreferences/service.yaml. - Suche diesen Schlüssel in der Zuordnung. Wenn die Host-Umgebungsvariable
IMAGE_gesetzt ist (z. B.IMAGE_COSMOS_RL), überschreibt sie den zugeordneten Standardwert. - Der zugeordnete Wert ist normalerweise ein durch Punkte getrennter Schlüssel im Repo-Root-
versions.yaml(z. B.tao_toolkit.cosmos_rl). Leiten Sie daraus eine konkretenvcr.io/...Image-URI auf, indem duversions.yaml→images.. Absolute URIs werden unverändert weitergeleitet, sodass eine. IMAGE_Überschreibung über eine Umgebungsvariable, die eine vollständige URI enthält, weiterhin funktioniert. Der Python-Helper hierfür befindet sich inreferences/code-templates.yaml. - Falls die Konfigurationsdatei fehlt oder
api_params.imageleer ist, greife auf denCOSMOS_RLSchlüssel.
Die Konfigurationsdatei enthält außerdem spec_params.inference.model_path , der die Unterscheidung zwischen Ordner- und Dateipfad steuert: Enthält der Wert die Teilzeichenfolge folder, behandelt der Container den Pfad als Verzeichnis.
3. Umgebungsvariablen (keine Callbacks)
Diese werden in env_payload vor der Kodierung env_json. Nicht setzen TAO_LOGGING_SERVER_URL oder TAO_ADMIN_KEY.
TAO_EXECUTION_BACKEND — muss mit der Plattform übereinstimmen:
| Plattform | TAO_EXECUTION_BACKEND Wert |
|---|---|
| local-docker | local-docker |
| brev | local-docker |
| slurm | slurm |
| Kubernetes | local-k8s |
CLOUD_BASED — immer "False" für diese Skill (deaktiviert das Senden von Callbacks an TAO_LOGGING_SERVER_URL).
GPU-Umgebungsvariablen — nur erforderlich, wenn das Plattform-Skill die GPU-Einbindung nicht automatisch übernimmt:
- Tegra / Jetson:
--runtime=nvidiamitNVIDIA_DRIVER_CAPABILITIES=allundNVIDIA_VISIBLE_DEVICES=. - Standard-x86 + nvidia-container-toolkit: Docker verwenden
device_requests. Das Plattform-Skill übernimmt dies.
4. Plattformübergreifende Ausführung
Die Job-Nutzlast und der innere Befehl (Abschnitte 1–3) sind plattformunabhängig. Lesen Sie für jede Plattform unter skills/platform/ die Informationen zu Vorabprüfungen und Anmeldedaten, bevor Sie Ausführungscode generieren.
4.1 Erstellen des inneren Befehls (pro Architektur)
Die Struktur des inneren Befehls richtet sich nach network_arch – es gibt keine einheitliche Vorlage. Suchen Sie den Eintrag für die jeweilige Architektur in references/service.yaml → container_commands.; falls dieser nicht vorhanden ist, wird die Architektur nicht unterstützt – brechen Sie den Vorgang ab und fragen Sie nach. Wählen Sie den passenden Unterblock in references/code-templates.yaml → job_payload_builder.. Setzen Sie dem Befehl das Präfix umask 0 && und halten Sie ihn plattformübergreifend identisch (local-docker, brev, slurm, kubernetes).
Gemeinsam für alle Architekturen:
job_id: freshuuid.uuid4()– wird zum Containernamen und zum Registrierungsschlüssel.image: Auflösung gemäß Abschnitt 2.- Geheimnisse (
access_key,secret_key,HF_TOKENusw.) werden zur Laufzeit aus Umgebungsvariablen gelesen – niemals fest einprogrammieren, niemals protokollieren oder ausgeben.
Architekturspezifische Hinweise (ausführliche Details in references/service.yaml → container_commands):
cosmos-rl— einzelner--job 'Blob;' --docker_env_vars ' ' json.dumps(...)+shlex.quote(...).env_payloadenthältTAO_EXECUTION_BACKEND(gemäß Tabelle in Abschnitt 3),TAO_API_JOB_ID,CLOUD_BASED=False. Der Inferenzdienst ist nicht vom Cloud-Speicher abhängig;HF_TOKENist die einzige Umgebungsvariable für Anmeldeinformationen, die jemals zum Tragen kommt (für gated HuggingFace-Modelle).cosmos-predict2.5— im Flag-Stilcosmos_predict inference_microservice start ... --port 8080(keinsetup.Präfix; verwendettyro.conf.OmitArgPrefixes).--job/--docker_env_varswerden nicht akzeptiert. Übersetzenmodel_pathin--checkpoint-path(lokaler Pfad) oder--model(hf_model://); Cloud-URIs werden abgelehnt. Die einzige Umgebungsvariable für Anmeldeinformationen, die jemals zum Tragen kommt, istHF_TOKENfür gated HuggingFace-Modelle. Parameter pro Anfrage (prompt, inference_type, num_output_frames, guidance, seed, num_steps, negative_prompt) gehören in den Request-Body, nicht beim Start.TAO_EXECUTION_BACKEND/TAO_API_JOB_ID/CLOUD_BASEDwerden nicht verwendet und können weggelassen werden.
4.2 Ausführung an die Plattform-Skill delegieren
Lies „skills/platform/“ und befolge die Anweisungen, um den Container zu starten.
Basisparameter (alle Plattformen):
| Parameter | Wert |
|---|---|
image |
aufgelöstes Container-Image (Abschnitt 2) |
command |
inner — die in Abschnitt 4.1 erstellte Shell-Zeichenkette |
gpu_count |
num_gpus |
env_vars |
env_payload |
| Auftrags-/Containername | job_id — muss mit der UUID aus Abschnitt 4.1 übereinstimmen, damit die Registry darauf verweisen kann |
host_port (local-docker, brev) |
Host-Port zur Verbindung mit dem Container-Port 8080. Standardwert 8080, muss jedoch pro gleichzeitigem Dienst eindeutig sein – siehe die Regel zur Portzuweisung weiter unten. |
Plattformspezifische zusätzliche Eingaben:
| Plattform | Zusätzliche Eingaben |
|---|---|
| local-docker | Keine über die Basis hinaus |
| brev | instance_id (optional – eine vorhandene Instanz wiederverwenden); bei Konten mit mehreren Anmeldedaten bzw. mehreren Arbeitsbereichen zusätzlich cloud_cred_id und workspace_group_id bei der erstmaligen Erstellung – siehe skills/platform/tao-run-on-brev/SKILL.md |
| slurm | partition und account – SLURM_PARTITION/SLURM_ACCOUNT Umgebungsvariablen; frage den Benutzer, falls nicht gesetzt |
| Kubernetes | namespace (Standard: default); image_pull_secret (erforderlich für nvcr.io Images) |
Port-Bindung (local-docker und brev): Verwende direkten Docker-Befehl (nicht DockerSDK), damit -p übergeben werden können und der Containername job_id genau übereinstimmt.
Regel zur Portzuweisung (local-docker und brev, ERFORDERLICH für gleichzeitige Dienste): Vor dem Starten eines Dienstes die Registry auslesen (/tmp/tao-inf-ms-state.json) und die Menge der host_port Werte aus jedem vorhandenen Eintrag auf derselben Plattform (und bei „brev“ auch auf derselben instance_id). Wähle den niedrigsten freien Port ab 8080 aus, der nicht in dieser Menge enthalten ist – z. B. host_port = next(p for p in range(8080, 8200) if p not in used_ports). Die Standardeinstellung 8080 gilt nur, wenn kein anderer Dienst läuft. Dadurch funktioniert „3 Dienste starten, die jeweils unter einer unterschiedlichen host_url“ funktioniert; ohne diesen Schritt schlagen die Dienste 2 und 3 mit bind: address already in use. SLURM und Kubernetes erhalten eindeutige Endpunkte über ihre eigenen Plattformmechanismen und benötigen diesen Schritt nicht.
4.3 Nach dem Start: Dienstregister und Endpunkt
Tragen Sie den Dienst in das Dienstregister ein, sobald die Plattform bestätigt, dass der Container läuft. Das Register (/tmp/tao-inf-ms-state.json) ist so indiziert, dass job_id; "latest" verweist immer auf den zuletzt gestarteten Dienst.
Siehe references/code-templates.yaml → registry_write. für die Python-Vorlage.
| Plattform | host_url |
platform_job_id |
Zusätzlicher Schritt vor dem Schreiben |
|---|---|---|---|
| local-docker | http://localhost:{host_port} |
— | Keine |
| brev | http://{brev_ip}:{host_port} |
— | brev ls → Instanz-IP abrufen (localhost ist auf einer Remote-VM ungültig) |
| slurm | http://localhost:{host_port} |
SLURM-Scheduler-Job-ID | Warten, bis der Job läuft; SSH-Portweiterleitung localhost:{host_port}→{node}:8080 |
| Kubernetes | http://{external_ip}:8080 |
k8s-Jobname | kubectl expose job … --type=LoadBalancer; auf externe IP warten |
Nach dem Schreiben in die Registry die Job-ID und die URL ausgeben:
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.")
Anschließend auf Bereitschaft prüfen – siehe references/code-templates.yaml → readiness_check. Der Container lädt das Modell im Hintergrund; sende keine Anfragen, bevor er den Status 200 zurückgibt.
5. Beenden des Inferenzdienstes
Fragen Sie den Benutzer nach dem job_id , der gestoppt werden soll. Wenn keine angegeben wird, verwende standardmäßig state["latest"] und bestätigen Sie, welche `job_id` gestoppt wird. Lesen Sie die Registry mithilfe von references/code-templates.yaml → stop.registry_read, lesen Sie anschließend „skills/platform/“ aus und nutzen Sie dessen Abbruch-/Stoppmechanismus.
| Plattform- | Identifikator, der übergeben werden soll | Zusätzliche Bereinigung |
|---|---|---|
| local-docker | job_id_to_stop — Containername |
Keine |
| brev | job_id_to_stop — Containername |
Keine |
| slurm | entry["platform_job_id"] — SLURM-Job-ID |
pkill -f "ssh.*-L.*{entry['host_port']}" |
| kubernetes | entry["platform_job_id"] — k8s-Jobname |
kubectl delete svc {entry["platform_job_id"]} -n |
wobei entry = state[job_id_to_stop]. Nach dem Beenden die Registry bereinigen: references/code-templates.yaml → stop.registry_cleanup.
6. Senden von Inferenzanfragen
6.0 Ermitteln, welcher Dienst diese Anfrage empfängt (ERFORDERLICH)
Jede Anfrage muss an den spezifischen Dienst weitergeleitet werden, auf dem das passende Modell ausgeführt wird. Die Weiterleitung erfolgt durch job_id — die Registrierung speichert network_arch pro Eintrag, sodass Sie ein Ziel anhand der Architektur ermitteln können, wenn der Benutzer ein Modell anstelle eines job_id. Wenden Sie diese Regeln in der folgenden Reihenfolge an:
- Der Benutzer hat einen expliziten
job_idangegeben → diesen verwenden. Überprüfen, ob er instate. - Der Benutzer hat ein „
network_arch“ angegeben (z. B. „sende dies an den cosmos-rl-Dienst“) → suche nach passenden Einträgen:candidates = [j for j, e in state.items() if j != "latest" and isinstance(e, dict) and e["network_arch"] == arch].- Genau eine Übereinstimmung → verwende diese.
- Mehrere Übereinstimmungen → den Benutzer mit den in Frage kommenden
job_idund derenstarted_at; keine automatische Auswahl vornehmen. - Keine Übereinstimmung → Abbruch und Hinweis an den Benutzer, dass für diese Architektur kein Dienst läuft.
- Kein „
job_id“ und kein „network_arch“ → Zähle die Einträge ohne"latest"Einträge instate:- Genau ein laufender Dienst → diesen verwenden.
- Zwei oder mehr → nicht stillschweigend auf „
state["latest"]“ zurückgreifen. Dem Benutzer die vollständige Liste anzeigen (job_id,network_arch,host_url) und eine explizite Auswahl verlangen. Der"latest"Zeiger dient der Vereinfachung bei Workflows mit einem einzigen Dienst und ist kein Ausweichmechanismus für das Routing, wenn mehrere Dienste nebeneinander bestehen. - Null → Brechen Sie den Vorgang ab und weisen Sie den Benutzer an, zunächst einen Dienst zu starten.
Nach der Auflösung den Endpunkt aus der Registrierung auslesen (references/code-templates.yaml → request.registry_read) auslesen und den aufgelösten job_id als user_provided_job_id. Bestätige dem Benutzer: „Senden an job_id=… arch=… url=…“. Falls der Dienst möglicherweise noch geladen wird, prüfe zunächst die Bereitschaft (references/code-templates.yaml → readiness_check).
Vor dem Senden abgleichen: Wenn der vom Benutzer bereitgestellte Request-Body architektur-spezifische Felder enthält (z. B. guidance / num_steps / seed / negative_prompt → cosmos-predict2.5; erforderliche image_url/video_url Inhaltselemente → cosmos-rl), überprüfen Sie, ob diese mit state[job_id]["network_arch"]. Bei Nichtübereinstimmung abbrechen und nachfragen – das Senden eines „cosmos-predict2.5“-Hauptteils an einen „cosmos-rl“-Dienst schlägt am Container mit einem 4xx/5xx-Fehler fehl, der schwerer zu diagnostizieren ist, als ihn hier abzufangen.
6.1 Stichprobenparameter – ERFORDERLICHE Benutzerabfrage vor jeder Anfrage
Bevor Sie den Anfragetext erstellen, MÜSSEN Sie den Benutzer ausdrücklich zur Eingabe der vLLM-typischen Stichprobenparameter auffordern. Wenden Sie Standardwerte nicht stillschweigend an. Verwenden Sie eine strukturierte Abfrage – eine Frage pro Feld –, die:
- jedes relevante Feld mit seinem Typ und seinem Standardwert auflistet.
- dem Benutzer ermöglicht, jedes Feld zu überspringen oder zu akzeptieren, um den Standardwert dieses Feldes zu übernehmen – die Eingabe eines Werts ist niemals erforderlich.
- alle Felder in einem Durchgang erfasst.
Wenden Sie nach der Abfrage jeden vom Benutzer eingegebenen Wert wörtlich an und ersetzen Sie übersprungene Felder durch den Standardwert. Erfinden Sie keine Werte und nehmen Sie keine stillschweigenden Begrenzungen vor.
Feldliste, Standardwerte und Anwendbarkeit pro Architektur: references/request.yaml → chat_completions_request_body (Basis-Stichprobenfelder: max_tokens, top_p, temperature) sowie network_arch_constraints. (Architektur-spezifische Überschreibungen und Zusätze wie guidance/num_steps/seed/negative_prompt für cosmos-predict2.5). Wenn ein Feld für die aktive Architektur als nicht unterstützt markiert ist, darf keine Abfrage dazu erfolgen und es darf nicht in den Hauptteil aufgenommen werden.
6.2 Format der Anfrage
Senden Sie eine POST an {BASE_URL}/v1/chat/completions mit Content-Type: application/json und einer Zeitüberschreitung von mindestens 300 s. Der Textkörper ist OpenAI-kompatibel (vLLM-Chat-Vervollständigungen); siehe references/request.yaml → chat_completions_request_body für das vollständige Feldschema und die Formate der Inhaltselemente (text / image_url / video_url) sowie code_examples hier finden Sie einsatzbereite Python- und curl-Beispiele.
Einschränkungen: Es wird nur die erste Benutzernachricht verarbeitet. Keine geheimen Werte im Request-Body. Netzwerkspezifische Einschränkungen (z. B. erfordert „cosmos-rl“, dass jede Anfrage ein Bild oder Video enthält; „cosmos-rl“ lehnt data: URIs) sind in references/request.yaml → network_arch_constraints.
6.3 Umgang mit Antworten
| HTTP-Status | Bedeutung | Aktion |
|---|---|---|
| 200 | Erfolg – choices[0].message.content enthält den generierten Text |
Ergebnis lesen |
| 202 | Server wird noch initialisiert oder Modell wird noch geladen | Versuchen Sie es nach einer Wartezeit erneut |
| 503 | Initialisierung fehlgeschlagen, Laden des Modells fehlgeschlagen oder Modell noch nicht bereit | Überprüfen error.type: model_not_ready → erneut versuchen; initialization_error / model_load_error → aufgeben und Protokolle überprüfen |
| 400 | Fehlender oder leerer JSON-Body | Anfrage korrigieren |
| 500 | Unbehandelte Ausnahme während der Inferenz | Container-Protokolle überprüfen |
Bei den Fehlern 202 und 503 enthält der Body {"error": {"type": ". Siehe container_response_shapes in references/request.yaml für die Fehlertyp-Zeichenfolgen.
---
name: tao-run-inference-service
description: Start, query, and stop a TAO inference microservice for a specific network architecture by delegating container execution to the appropriate platform skill.
license: Apache-2.0
---
# TAO Inference Microservice
## Instructions
**To start an inference service:**
1. Collect required inputs (Section 1) and resolve the container image (Section 2).
2. Build the job payload and inner command (Sections 3–4.1); use `references/code-templates.yaml` → `job_payload_builder`.
3. Read `skills/platform/<platform>/SKILL.md` and start the container (Section 4.2).
4. Write the service registry and poll readiness (Section 4.3); use `references/code-templates.yaml` → `registry_write.<platform>` and `readiness_check`.
**To send an inference request:**
1. Resolve which service receives the request per Section 6.0 (by `job_id`, by `network_arch`, or by explicit user choice when multiple services run — **never silently default to `"latest"` when more than one service exists**), then read the endpoint from `references/code-templates.yaml` → `request.registry_read` with the resolved `job_id`.
2. **Before building the request body, prompt the user for the vLLM-style sampling parameters (Section 6.1).** Present `max_tokens`, `top_p`, `temperature` (and any per-arch extras) with their defaults; let the user override or skip each one to accept the default. Never silently use defaults.
3. Build and send the body per Section 6.2; handle the response per Section 6.3.
**To stop a service:** Read `references/code-templates.yaml` → `stop.registry_read` to resolve the job_id, read `skills/platform/<platform>/SKILL.md`, then follow Section 5.
**Reference data** (schemas, mappings, valid values — no instructions):
- **`references/service.yaml`** — image mappings, valid `network_arch` names, job payload schema, env var names, secrets classification.
- **`references/request.yaml`** — endpoint definition, request field schema, response shapes, code examples.
- **`references/code-templates.yaml`** — Python templates for payload building, registry writes, readiness checks, and stop/request flows.
---
## Secrets rule (applies to every generated code block in this skill)
**Never ask the user to type a secret value into a prompt.** For every secret value:
1. Tell the user which environment variable to set (e.g. `export HF_TOKEN=...`).
2. Generate code that reads it with `os.environ["VAR_NAME"]` — never hard-code, interpolate, or prompt for the value.
**Secret env vars** (full list in `references/service.yaml` → `secrets_handling`):
`HF_TOKEN`, `WANDB_API_KEY`, `CLEARML_API_ACCESS_KEY`, `CLEARML_API_SECRET_KEY`, `TAO_API_KEY`, `TAO_USER_KEY`.
**Safe to collect in the prompt:** `network_arch`, `model_path`, `num_gpus`, prompt text, `WANDB_*` config URLs, `CLEARML_*_HOST` URLs.
---
## 1. What to collect from the user
| Input | Role |
|--------|------|
| **`network_arch`** | Chooses container image, the per-arch inner command shape (`references/service.yaml` → `container_commands.<network_arch>`), and `neural_network_name` in the job JSON when applicable. Must match a basename in `valid_network_arch_config_basenames` in `references/service.yaml` (e.g. `cosmos-rl`, `cosmos-predict2.5`). |
| **`model_path`** | The trained model checkpoint. Valid forms: `hf_model://<org>/<model>` (HuggingFace Hub — set `HF_TOKEN` for gated models) or a local container filesystem path. Cloud URIs (`s3://`, `gs://`, `az://`) are NOT supported — the inference service has no cloud-storage dependency. Always ask the user; never substitute a placeholder. See `references/service.yaml` → `model_path_protocols`. |
| **`platform`** | Compute platform: `local-docker`, `brev`, `slurm`, or `kubernetes`. |
| **`num_gpus`** | Defaults to **1**; minimum **1** for inference. |
---
## 2. Image resolution
Each `network_arch` has a sidecar config file named `{network_arch}.config.json`. Resolve the container image as follows:
1. Read `{network_arch}.config.json` and take `api_params.image` (e.g. `COSMOS_RL`). This is a key into `docker_image_defaults.mapping` in `references/service.yaml`.
2. Look up that key in the mapping. If the host env var `IMAGE_<KEY>` is set (e.g. `IMAGE_COSMOS_RL`), it overrides the mapped default.
3. The mapped value is normally a dotted key into the repo-root `versions.yaml` manifest (e.g. `tao_toolkit.cosmos_rl`). Resolve it to a concrete `nvcr.io/...` image URI by looking up `versions.yaml` → `images.<group>.<name>`. Absolute URIs pass through unchanged, so an `IMAGE_<KEY>` env-var override that contains a full URI still works. The Python helper for this lives in `references/code-templates.yaml`.
4. If the config file is missing or `api_params.image` is empty, fall back to the `COSMOS_RL` key.
The config file also has `spec_params.inference.model_path` which drives **folder vs file** path semantics: if the value contains the substring `folder`, the container treats the path as a directory.
---
## 3. Environment variables (no callbacks)
Set these in `env_payload` before encoding `env_json`. Do **not** set `TAO_LOGGING_SERVER_URL` or `TAO_ADMIN_KEY`.
**`TAO_EXECUTION_BACKEND`** — must match the platform:
| Platform | `TAO_EXECUTION_BACKEND` value |
|----------|-------------------------------|
| local-docker | `local-docker` |
| brev | `local-docker` |
| slurm | `slurm` |
| kubernetes | `local-k8s` |
**`CLOUD_BASED`** — always `"False"` for this skill (disables callback posting to `TAO_LOGGING_SERVER_URL`).
**GPU env vars** — only needed when the platform skill does not handle GPU injection automatically:
- Tegra / Jetson: `--runtime=nvidia` with `NVIDIA_DRIVER_CAPABILITIES=all` and `NVIDIA_VISIBLE_DEVICES=<ids>`.
- Standard x86 + nvidia-container-toolkit: use Docker `device_requests`. The platform skill handles this.
---
## 4. Executing across platforms
The job payload and inner command (Sections 1–3) are **platform-agnostic**. For each platform, read **`skills/platform/<name>/SKILL.md`** for preflight checks and credentials **before** generating any execution code.
### 4.1 Build the inner command (per arch)
The inner-command shape is **per `network_arch`** — there is no uniform template. Look up the per-arch entry in `references/service.yaml` → `container_commands.<network_arch>`; if not present, the arch is unsupported — stop and ask. Pick the matching sub-block in `references/code-templates.yaml` → `job_payload_builder.<network_arch>`. Prefix the command with `umask 0 &&` and keep it **identical across platforms** (local-docker, brev, slurm, kubernetes).
Common across arches:
- `job_id`: fresh `uuid.uuid4()` — becomes the container name and registry key.
- `image`: resolve per Section 2.
- Secrets (`access_key`, `secret_key`, `HF_TOKEN`, etc.) are read from env vars at runtime — never hard-code, never log or print.
Arch-specific notes (full details in `references/service.yaml` → `container_commands`):
- **`cosmos-rl`** — single `--job '<JOB_JSON>' --docker_env_vars '<ENV_JSON>'` blob; `json.dumps(...)` + `shlex.quote(...)`. `env_payload` carries `TAO_EXECUTION_BACKEND` (per Section 3 table), `TAO_API_JOB_ID`, `CLOUD_BASED=False`. The inference service has no cloud-storage dependency; `HF_TOKEN` is the only cred env var that ever applies (for gated HuggingFace models).
- **`cosmos-predict2.5`** — flag-style `cosmos_predict inference_microservice start ... --port 8080` (no `setup.` prefix; uses `tyro.conf.OmitArgPrefixes`). `--job`/`--docker_env_vars` are **not** accepted. Translate `model_path` to `--checkpoint-path` (local path) or `--model <registered_key>` (`hf_model://`); cloud URIs are rejected. The only cred env var that ever applies is `HF_TOKEN` for gated HuggingFace models. Per-request params (prompt, inference_type, num_output_frames, guidance, seed, num_steps, negative_prompt) go in the request body, not at startup. `TAO_EXECUTION_BACKEND`/`TAO_API_JOB_ID`/`CLOUD_BASED` are unused and may be omitted.
### 4.2 Delegate execution to the platform skill
Read **`skills/platform/<platform>/SKILL.md`** and follow it to start the container.
**Base parameters (all platforms):**
| Parameter | Value |
|-----------|-------|
| `image` | resolved container image (Section 2) |
| `command` | `inner` — the shell string built in Section 4.1 |
| `gpu_count` | `num_gpus` |
| `env_vars` | `env_payload` |
| job / container name | `job_id` — must equal the UUID from 4.1 so the registry can reference it |
| `host_port` *(local-docker, brev)* | host-side port to bind to container port 8080. Default `8080`, but **must be unique per concurrent service** — see the port-allocation rule below. |
**Platform-specific additional inputs:**
| Platform | Additional inputs |
|----------|------------------|
| **local-docker** | None beyond base |
| **brev** | `instance_id` (optional — reuse an existing instance); on multi-credential / multi-workspace accounts also `cloud_cred_id` and `workspace_group_id` for first-create — see `skills/platform/tao-run-on-brev/SKILL.md` |
| **slurm** | `partition` and `account` — check `SLURM_PARTITION`/`SLURM_ACCOUNT` env vars; ask user if unset |
| **kubernetes** | `namespace` (default: `default`); `image_pull_secret` (required for `nvcr.io` images) |
**Port binding (local-docker and brev):** use **direct docker run** (not DockerSDK) so that `-p <host_port>:8080` can be passed and the container name equals `job_id` exactly.
**Port allocation rule (local-docker and brev, REQUIRED for concurrent services):** Before starting a service, read the registry (`/tmp/tao-inf-ms-state.json`) and collect the set of `host_port` values from every existing entry on the same platform (and, for brev, the same `instance_id`). Pick the **lowest free port starting from 8080** that is not in that set — e.g. `host_port = next(p for p in range(8080, 8200) if p not in used_ports)`. The default `8080` only applies when no other service is running. This is what makes "start 3 services, each reachable at a distinct `host_url`" work; without it, services 2 and 3 fail with `bind: address already in use`. SLURM and kubernetes get distinct endpoints from their own platform mechanisms and do not need this step.
### 4.3 After start: service registry and endpoint
Write the service registry immediately after the platform confirms the container is running. The registry (`/tmp/tao-inf-ms-state.json`) is keyed by `job_id`; `"latest"` always points to the most recently started service.
See `references/code-templates.yaml` → `registry_write.<platform>` for the Python template.
| Platform | `host_url` | `platform_job_id` | Extra step before writing |
|----------|-----------|-------------------|--------------------------|
| **local-docker** | `http://localhost:{host_port}` | — | None |
| **brev** | `http://{brev_ip}:{host_port}` | — | `brev ls` → get instance IP (`localhost` is invalid on remote VM) |
| **slurm** | `http://localhost:{host_port}` | SLURM scheduler job ID | Wait until Running; SSH port-forward `localhost:{host_port}→{node}:8080` |
| **kubernetes** | `http://{external_ip}:8080` | k8s job name | `kubectl expose job … --type=LoadBalancer`; wait for external IP |
After writing the registry, print the job_id and URL:
```python
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.")
```
Then poll for readiness — see `references/code-templates.yaml` → `readiness_check`. The container loads the model in the background; do not send requests before it returns 200.
---
## 5. Stopping the inference service
Ask the user for the `job_id` to stop. If they don't provide one, default to `state["latest"]` and confirm which job_id is being stopped. Read the registry using `references/code-templates.yaml` → `stop.registry_read`, then read **`skills/platform/<platform>/SKILL.md`** and use its cancellation / stop mechanism.
| Platform | Identifier to pass | Extra cleanup |
|----------|--------------------|---------------|
| **local-docker** | `job_id_to_stop` — container name | None |
| **brev** | `job_id_to_stop` — container name | None |
| **slurm** | `entry["platform_job_id"]` — SLURM job ID | `pkill -f "ssh.*-L.*{entry['host_port']}"` |
| **kubernetes** | `entry["platform_job_id"]` — k8s job name | `kubectl delete svc {entry["platform_job_id"]} -n <namespace>` |
where `entry = state[job_id_to_stop]`. After stopping, clean up the registry: `references/code-templates.yaml` → `stop.registry_cleanup`.
---
## 6. Sending inference requests
### 6.0 Resolve which service receives this request (REQUIRED)
Each request must be routed to the **specific** service that runs the matching model. Routing happens by `job_id` — the registry stores `network_arch` per entry, so you can resolve a target by arch when the user names a model instead of a `job_id`. Apply these rules in order:
1. **User provided an explicit `job_id`** → use it. Verify it exists in `state`.
2. **User named a `network_arch`** (e.g. "send this to the cosmos-rl service") → look up matching entries: `candidates = [j for j, e in state.items() if j != "latest" and isinstance(e, dict) and e["network_arch"] == arch]`.
- Exactly one match → use it.
- Multiple matches → **prompt the user** with the candidate `job_id`s and their `started_at`; do not auto-pick.
- No match → stop and tell the user no service for that arch is running.
3. **No `job_id` and no `network_arch`** → count non-`"latest"` entries in `state`:
- Exactly one running service → use it.
- Two or more → **do not silently default to `state["latest"]`**. Prompt the user with the full list (`job_id`, `network_arch`, `host_url`) and require an explicit choice. The `"latest"` pointer is a convenience for single-service workflows, not a routing fallback when multiple services coexist.
- Zero → stop and tell the user to start a service first.
After resolving, read the endpoint from the registry (`references/code-templates.yaml` → `request.registry_read`), passing the resolved `job_id` as `user_provided_job_id`. Confirm to the user: "Sending to job_id=… arch=… url=…". If the service may still be loading, poll readiness first (`references/code-templates.yaml` → `readiness_check`).
**Cross-check before sending:** if the user-supplied request body contains arch-specific fields (e.g. `guidance` / `num_steps` / `seed` / `negative_prompt` → cosmos-predict2.5; required `image_url`/`video_url` content items → cosmos-rl), verify they are consistent with `state[job_id]["network_arch"]`. On mismatch, stop and ask — sending a cosmos-predict2.5 body to a cosmos-rl service will fail at the container with a 4xx/5xx that is harder to diagnose than catching it here.
### 6.1 Sampling parameters — REQUIRED user prompt before each request
Before constructing the request body, you **MUST** explicitly prompt the user for the vLLM-style sampling parameters. Do **not** silently apply defaults. Use a structured prompt, one question per field, that:
1. Lists every applicable field with its **type** and **default value**.
2. Lets the user skip / accept any field to take that field's default — entering a value is never required.
3. Collects all fields in one round.
After the prompt, apply each user-entered value verbatim and substitute the default for any skipped field. Do not invent values or silently clamp.
**Field list, defaults, and per-arch applicability:** `references/request.yaml` → `chat_completions_request_body` (base sampling fields: `max_tokens`, `top_p`, `temperature`) and `network_arch_constraints.<network_arch>` (per-arch overrides and extras such as `guidance`/`num_steps`/`seed`/`negative_prompt` for `cosmos-predict2.5`). If a field is marked unsupported for the active arch, do **not** prompt for it and do **not** include it in the body.
### 6.2 Request format
Send a `POST` to `{BASE_URL}/v1/chat/completions` with `Content-Type: application/json` and a timeout of **at least 300 s**. The body is OpenAI-compatible (vLLM chat completions); see `references/request.yaml` → `chat_completions_request_body` for the full field schema and content-item shapes (text / image_url / video_url), and `code_examples` for ready-to-run Python and curl samples.
**Constraints:** only the first user message is processed. No secret values in request bodies. **Per-network constraints** (e.g. cosmos-rl requires every request to include an image or video; cosmos-rl rejects `data:` URIs) are in `references/request.yaml` → `network_arch_constraints`.
### 6.3 Response handling
| HTTP status | Meaning | Action |
|-------------|---------|--------|
| **200** | Success — `choices[0].message.content` has the generated text | Read result |
| **202** | Server still initializing or model still loading | Retry after a delay |
| **503** | Initialization failed, model load failed, **or model not yet ready** | Inspect `error.type`: `model_not_ready` → retry; `initialization_error` / `model_load_error` → give up and check logs |
| **400** | Missing or empty JSON body | Fix request |
| **500** | Unhandled exception during inference | Check container logs |
For 202 and 503, the body contains `{"error": {"type": "<error_type>", "message": "<reason>"}}`. See `container_response_shapes` in `references/request.yaml` for error type strings.
Alle Dateien
11 Dateientao-run-inference-service installieren
Laden Sie die Skill-Dateien herunter und entpacken Sie sie in Ihr Verzeichnis „.claude/skills/“.
ZIP herunterladenKlonen Sie das Repository und kopieren Sie die Skill-Dateien in Ihr Projekt.
git clone https://github.com/NVIDIA/skills/tree/main/skills/tao-run-inference-service # Copy SKILL.md to your .claude/skills/ directory
Kopieren





Heim
