tao-run-inference-service
NVIDIA/skills
Inicie, consulte e interrompa um microsserviço de inferência TAO para uma arquitetura de rede específica, delegando a execução do contêiner à habilidade de plataforma apropriada.
...Expandir tudoMicrosserviço de Inferência TAO
Instruções
Para iniciar um serviço de inferência:
- Reúna as entradas necessárias (Seção 1) e resolva a imagem do contêiner (Seção 2).
- Crie a carga útil da tarefa e o comando interno (Seções 3–4.1); use
references/code-templates.yaml→job_payload_builder. - Read
skills/platform/e inicie o contêiner (Seção 4.2)./SKILL.md - Grave no registro de serviços e verifique a disponibilidade (Seção 4.3); use
references/code-templates.yaml→registry_write.ereadiness_check.
Para enviar uma solicitação de inferência:
- Determine qual serviço receberá a solicitação, conforme a Seção 6.0 (por
job_id, pornetwork_arch, ou por escolha explícita do usuário quando vários serviços estiverem em execução — nunca defina silenciosamente como padrão"latest"quando houver mais de um serviço), em seguida, leia o endpoint dereferences/code-templates.yaml→request.registry_readcom o endpoint determinadojob_id. - Antes de construir o corpo da solicitação, solicite ao usuário os parâmetros de amostragem no estilo vLLM (Seção 6.1). Apresente
max_tokens,top_p,temperature(e quaisquer extras específicos por arquitetura) com seus valores padrão; permita que o usuário altere ou pule cada um deles para aceitar o padrão. Nunca utilize valores padrão silenciosamente. - Construa e envie o corpo conforme a Seção 6.2; trate a resposta conforme a Seção 6.3.
Para interromper um serviço: Leia references/code-templates.yaml → stop.registry_read para resolver o job_id, leia skills/platform/e, em seguida, siga a Seção 5.
Dados de referência (esquemas, mapeamentos, valores válidos — sem instruções):
references/service.yaml— mapeamentos de imagem,network_arch, esquema de carga útil da tarefa, nomes de variáveis de ambiente, classificação de segredos.references/request.yaml— definição de endpoint, esquema de campos de solicitação, formatos de resposta, exemplos de código.references/code-templates.yaml— modelos em Python para construção de carga útil, gravações no registro, verificações de prontidão e fluxos de parada/solicitação.
Regra de segredos (aplica-se a todos os blocos de código gerados nesta habilidade)
Nunca peça ao usuário para digitar um valor secreto em um prompt. Para cada valor secreto:
- Informe ao usuário qual variável de ambiente deve ser definida (por exemplo,
export HF_TOKEN=...). - Gere código que o leia com
os.environ["VAR_NAME"]— nunca codifique estaticamente, interpola ou solicite o valor por meio de prompt.
Variáveis de ambiente secretas (lista completa em references/service.yaml → secrets_handling):
HF_TOKEN, WANDB_API_KEY, CLEARML_API_ACCESS_KEY, CLEARML_API_SECRET_KEY, TAO_API_KEY, TAO_USER_KEY.
É seguro coletar no prompt: network_arch, model_path, num_gpus, texto do prompt, WANDB_* URLs de configuração, CLEARML_*_HOST URLs.
1. O que coletar do usuário
| Entrada | Função |
|---|---|
network_arch |
Escolhe a imagem do contêiner, o formato do comando interno por arquitetura (references/service.yaml → container_commands.) e neural_network_name no JSON da tarefa, quando aplicável. Deve corresponder a um nome base em valid_network_arch_config_basenames em references/service.yaml (por exemplo, cosmos-rl, cosmos-predict2.5). |
model_path |
O checkpoint do modelo treinado. Formatos válidos: hf_model:// (HuggingFace Hub — defina HF_TOKEN para modelos restritos) ou um caminho do sistema de arquivos de um contêiner local. URIs de nuvem (s3://, gs://, az://) NÃO são suportadas — o serviço de inferência não depende de armazenamento na nuvem. Sempre pergunte ao usuário; nunca substitua por um espaço reservado. Consulte references/service.yaml → model_path_protocols. |
platform |
Plataforma de computação: local-docker, brev, slurm, ou kubernetes. |
num_gpus |
O padrão é 1; mínimo de 1 para inferência. |
2. Resolução da imagem
Cada network_arch possui um arquivo de configuração sidecar chamado {network_arch}.config.json. Defina a imagem do contêiner da seguinte forma:
- Leia
{network_arch}.config.jsone selecioneapi_params.image(por exemplo,COSMOS_RL). Essa é uma chave no arquivodocker_image_defaults.mappingemreferences/service.yaml. - Procure essa chave no mapeamento. Se a variável de ambiente do host
IMAGE_estiver definida (por exemplo,IMAGE_COSMOS_RL), ela substitui o padrão mapeado. - O valor mapeado é normalmente uma chave com pontos no arquivo
versions.yaml(por exemplo,tao_toolkit.cosmos_rl). Resolva-a em umnvcr.io/..., consultandoversions.yaml→images.. URIs absolutas passam inalteradas, portanto, uma. IMAGE_substituição por variável de ambiente que contenha um URI completo ainda funciona. O auxiliar em Python para isso está localizado emreferences/code-templates.yaml. - Se o arquivo de configuração estiver ausente ou
api_params.imageestiver vazio, recorra àCOSMOS_RLchave.
O arquivo de configuração também possui spec_params.inference.model_path que determina a semântica entre caminho de pasta e caminho de arquivo: se o valor contiver a substring folder, o contêiner trata o caminho como um diretório.
3. Variáveis de ambiente (sem callbacks)
Defina-as em env_payload antes da codificação env_json. Não defina TAO_LOGGING_SERVER_URL ou TAO_ADMIN_KEY.
TAO_EXECUTION_BACKEND — deve corresponder à plataforma:
| Plataforma | TAO_EXECUTION_BACKEND valor |
|---|---|
| local-docker | local-docker |
| brev | local-docker |
| slurm | slurm |
| kubernetes | local-k8s |
CLOUD_BASED — sempre "False" para esta habilidade (desativa o envio de callback para TAO_LOGGING_SERVER_URL).
variáveis de ambiente da GPU — necessário apenas quando a habilidade da plataforma não lida com a injeção de GPU automaticamente:
- Tegra / Jetson:
--runtime=nvidiacomNVIDIA_DRIVER_CAPABILITIES=alleNVIDIA_VISIBLE_DEVICES=. - x86 padrão + nvidia-container-toolkit: use o Docker
device_requests. A habilidade da plataforma cuida disso.
4. Execução em várias plataformas
A carga útil da tarefa e o comando interno (Seções 1–3) são independentes da plataforma. Para cada plataforma, consulte skills/platform/ para verificações prévias e credenciais antes de gerar qualquer código de execução.
4.1 Construir o comando interno (por arquitetura)
O formato do comando interno segue network_arch — não há um modelo padronizado. Consulte a entrada específica para cada arquitetura em references/service.yaml → container_commands.; caso não esteja presente, a arquitetura não é suportada — pare e pergunte. Escolha o subbloco correspondente em references/code-templates.yaml → job_payload_builder.. Coloque o prefixo umask 0 && e mantenha-o idêntico em todas as plataformas (local-docker, brev, slurm, kubernetes).
Comum a todas as arquiteturas:
job_id: freshuuid.uuid4()— torna-se o nome do contêiner e a chave do registro.image: resolver conforme a Seção 2.- Segredos (
access_key,secret_key,HF_TOKEN, etc.) são lidos a partir de variáveis de ambiente em tempo de execução — nunca codifique diretamente, nunca registre em logs nem imprima.
Notas específicas da arquitetura (detalhes completos em references/service.yaml → container_commands):
cosmos-rl— um único--job 'blob;' --docker_env_vars ' ' json.dumps(...)+shlex.quote(...).env_payloadcontémTAO_EXECUTION_BACKEND(conforme a tabela da Seção 3),TAO_API_JOB_ID,CLOUD_BASED=False. O serviço de inferência não tem dependência de armazenamento em nuvem;HF_TOKENé a única variável de ambiente de credenciais que se aplica (para modelos HuggingFace com acesso restrito).cosmos-predict2.5— estilo de sinalizadorcosmos_predict inference_microservice start ... --port 8080(semsetup.prefixo; utilizatyro.conf.OmitArgPrefixes).--job/--docker_env_varsnão são aceitos. Traduzirmodel_pathpara--checkpoint-path(caminho local) ou--model(hf_model://); URIs de nuvem são rejeitadas. A única variável de ambiente de credenciais que se aplica éHF_TOKENpara modelos HuggingFace com restrições de acesso. Parâmetros por solicitação (prompt, inference_type, num_output_frames, guidance, seed, num_steps, negative_prompt) devem ser incluídos no corpo da solicitação, não na inicialização.TAO_EXECUTION_BACKEND/TAO_API_JOB_ID/CLOUD_BASEDnão são utilizados e podem ser omitidos.
4.2 Delegar a execução à habilidade da plataforma
Leia skills/platform/ e siga as instruções para iniciar o contêiner.
Parâmetros básicos (todas as plataformas):
| Parâmetro | Valor |
|---|---|
image |
imagem do contêiner resolvida (Seção 2) |
command |
inner — a string do shell criada na Seção 4.1 |
gpu_count |
num_gpus |
env_vars |
env_payload |
| nome da tarefa/do contêiner | job_id — deve ser igual ao UUID da Seção 4.1 para que o registro possa referenciá-lo |
host_port (local-docker, brev) |
porta do lado do host a ser vinculada à porta 8080 do contêiner. Padrão 8080, mas deve ser único por serviço simultâneo — consulte a regra de alocação de portas abaixo. |
Entradas adicionais específicas da plataforma:
| Plataforma | Entradas adicionais |
|---|---|
| local-docker | Nenhuma além das básicas |
| brev | instance_id (opcional — reutilizar uma instância existente); em contas com múltiplas credenciais/múltiplos espaços de trabalho, também cloud_cred_id e workspace_group_id para a primeira criação — consulte skills/platform/tao-run-on-brev/SKILL.md |
| slurm | partition e account — verifique SLURM_PARTITION/SLURM_ACCOUNT as variáveis de ambiente; pergunte ao usuário se não estiverem definidas |
| kubernetes | namespace (padrão: default); image_pull_secret (obrigatório para nvcr.io imagens) |
Vinculação de porta (local-docker e brev): use o comando direto `docker run` (não o DockerSDK) para que -p possa ser passado e o nome do contêiner seja job_id exatamente.
Regra de alocação de portas (local-docker e brev, OBRIGATÓRIA para serviços simultâneos): antes de iniciar um serviço, leia o registro (/tmp/tao-inf-ms-state.json) e colete o conjunto de host_port valores de todas as entradas existentes na mesma plataforma (e, para o brev, na mesma instance_id). Escolha a menor porta livre a partir de 8080 que não esteja nesse conjunto — por exemplo, host_port = next(p for p in range(8080, 8200) if p not in used_ports). O padrão 8080 apenas se aplica quando nenhum outro serviço está em execução. É isso que faz com que “iniciar 3 serviços, cada um acessível em um endereço distinto host_url” funcionar; sem isso, os serviços 2 e 3 falham com bind: address already in use. O SLURM e o Kubernetes obtêm endpoints distintos por meio de seus próprios mecanismos de plataforma e não precisam dessa etapa.
4.3 Após a inicialização: registro de serviços e endpoint
Grave o registro de serviços imediatamente após a plataforma confirmar que o contêiner está em execução. O registro (/tmp/tao-inf-ms-state.json) é indexado por job_id; "latest" sempre aponta para o serviço iniciado mais recentemente.
Consulte references/code-templates.yaml → registry_write. para o modelo em Python.
| Plataforma | host_url |
platform_job_id |
Etapa extra antes de escrever |
|---|---|---|---|
| local-docker | http://localhost:{host_port} |
— | Nenhum |
| brev | http://{brev_ip}:{host_port} |
— | brev ls → obter o IP da instância (localhost não é válido em VM remota) |
| slurm | http://localhost:{host_port} |
ID da tarefa no agendador SLURM | Aguarde até que esteja em execução; redirecionamento de porta via SSH localhost:{host_port}→{node}:8080 |
| kubernetes | http://{external_ip}:8080 |
Nome da tarefa no k8s | kubectl expose job … --type=LoadBalancer; aguardar o IP externo |
Após gravar no registro, exiba o job_id e a 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.")
Em seguida, verifique se está pronto — consulte references/code-templates.yaml → readiness_check. O contêiner carrega o modelo em segundo plano; não envie solicitações antes que ele retorne o código 200.
5. Parando o serviço de inferência
Peça ao usuário o job_id a ser interrompido. Se ele não fornecer um, use como padrão state["latest"] e confirme qual job_id está sendo interrompido. Leia o registro usando references/code-templates.yaml → stop.registry_read, depois acesse skills/platform/ e utilize seu mecanismo de cancelamento/parada.
| Identificador da | Identificador a ser passado | Limpeza adicional |
|---|---|---|
| local-docker | job_id_to_stop — nome do contêiner |
Nenhum |
| brev | job_id_to_stop — nome do contêiner |
Nenhum |
| slurm | entry["platform_job_id"] — ID da tarefa SLURM |
pkill -f "ssh.*-L.*{entry['host_port']}" |
| kubernetes | entry["platform_job_id"] — nome da tarefa no k8s |
kubectl delete svc {entry["platform_job_id"]} -n |
onde entry = state[job_id_to_stop]. Após a interrupção, limpe o registro: references/code-templates.yaml → stop.registry_cleanup.
6. Envio de solicitações de inferência
6.0 Determinar qual serviço recebe essa solicitação (OBRIGATÓRIO)
Cada solicitação deve ser encaminhada ao serviço específico que executa o modelo correspondente. O encaminhamento ocorre por meio de job_id — o registro armazena network_arch por entrada, de modo que você possa determinar um destino por arquitetura quando o usuário especificar um modelo em vez de um job_id. Aplique estas regras na seguinte ordem:
- O usuário forneceu um
job_idexplícito → use-o. Verifique se ele existe nostate. - O usuário indicou um
network_arch(por exemplo, “enviar isso para o serviço cosmos-rl”) → procure entradas correspondentes:candidates = [j for j, e in state.items() if j != "latest" and isinstance(e, dict) and e["network_arch"] == arch].- Exatamente uma correspondência → use-a.
- Várias correspondências → apresente ao usuário as opções
job_ide suasstarted_at; não selecione automaticamente. - Nenhuma correspondência → interromper e informar ao usuário que nenhum serviço para essa arquitetura está em execução.
- Sem
job_ide semnetwork_arch→ conte as entradas que não"latest"entradas emstate:- Exatamente um serviço em execução → use-o.
- Dois ou mais → não defina “
state["latest"]” como padrão silenciosamente. Apresente ao usuário a lista completa (job_id,network_arch,host_url) e exija uma escolha explícita. O"latest"ponteiro é uma facilidade para fluxos de trabalho com um único serviço, não um recurso alternativo de roteamento quando vários serviços coexistem. - Nenhum → interrompa e avise o usuário para iniciar um serviço primeiro.
Após a resolução, leia o endpoint do registro (references/code-templates.yaml → request.registry_read), passando o end job_id como user_provided_job_id. Confirme com o usuário: “Enviando para job_id=… arch=… url=…”. Se o serviço ainda estiver carregando, verifique primeiro se está pronto (references/code-templates.yaml → readiness_check).
Verifique novamente antes de enviar: se o corpo da solicitação fornecido pelo usuário contiver campos específicos da arquitetura (por exemplo, guidance / num_steps / seed / negative_prompt → cosmos-predict2.5; itens de conteúdo obrigatórios image_url/video_url itens de conteúdo → cosmos-rl), verifique se eles são consistentes com state[job_id]["network_arch"]. Em caso de incompatibilidade, interrompa e pergunte — enviar um corpo cosmos-predict2.5 para um serviço cosmos-rl resultará em falha no contêiner com um código 4xx/5xx, o que é mais difícil de diagnosticar do que detectar aqui.
6.1 Parâmetros de amostragem — solicitação OBRIGATÓRIA ao usuário antes de cada solicitação
Antes de construir o corpo da solicitação, você DEVE solicitar explicitamente ao usuário os parâmetros de amostragem no estilo vLLM. Não aplique valores padrão silenciosamente. Use uma solicitação estruturada, com uma pergunta por campo, que:
- Liste todos os campos aplicáveis com seu tipo e valor padrão.
- Permita que o usuário pule ou aceite qualquer campo para adotar o valor padrão desse campo — nunca é necessário inserir um valor.
- Reúna todos os campos em uma única rodada.
Após a solicitação, aplique cada valor inserido pelo usuário literalmente e substitua por valor padrão qualquer campo ignorado. Não invente valores nem limite valores silenciosamente.
Lista de campos, valores padrão e aplicabilidade por arquitetura: references/request.yaml → chat_completions_request_body (campos de amostragem básicos: max_tokens, top_p, temperature) e network_arch_constraints. (substituições específicas por arquitetura e itens extras, como guidance/num_steps/seed/negative_prompt para cosmos-predict2.5). Se um campo estiver marcado como não suportado para a arquitetura ativa, não solicite esse campo e não o inclua no corpo da mensagem.
6.2 Formato da solicitação
Envie um POST para {BASE_URL}/v1/chat/completions com Content-Type: application/json e um tempo de espera de pelo menos 300 s. O corpo é compatível com OpenAI (completações de chat vLLM); consulte references/request.yaml → chat_completions_request_body para o esquema completo dos campos e os formatos dos itens de conteúdo (text / image_url / video_url), e code_examples aqui para exemplos prontos para execução em Python e curl.
Restrições: apenas a primeira mensagem do usuário é processada. Não são permitidos valores secretos nos corpos das solicitações. Restrições específicas por rede (por exemplo, o cosmos-rl exige que toda solicitação inclua uma imagem ou vídeo; o cosmos-rl rejeita data: URIs) estão em references/request.yaml → network_arch_constraints.
6.3 Tratamento da resposta
| Status HTTP | Significado | Ação |
|---|---|---|
| 200 | Sucesso — choices[0].message.content contém o texto gerado |
Resultado da leitura |
| 202 | O servidor ainda está sendo inicializado ou o modelo ainda está sendo carregado | Tente novamente após um intervalo |
| 503 | Falha na inicialização, falha no carregamento do modelo ou modelo ainda não pronto | Verificar error.type: model_not_ready → tente novamente; initialization_error / model_load_error → desista e verifique os logs |
| 400 | Corpo JSON ausente ou vazio | Corrigir a solicitação |
| 500 | Exceção não tratada durante a inferência | Verifique os logs do contêiner |
Para os códigos 202 e 503, o corpo contém {"error": {"type": ". Consulte container_response_shapes em references/request.yaml para as cadeias de caracteres dos tipos de erro.
---
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.
Todos os arquivos
11 arquivosInstalar tao-run-inference-service
Baixe e extraia os arquivos de habilidades para o diretório .claude/skills/.
Baixar ZIPClone o repositório e copie os arquivos da habilidade para o seu projeto.
git clone https://github.com/NVIDIA/skills/tree/main/skills/tao-run-inference-service # Copy SKILL.md to your .claude/skills/ directory
Copiar





Lar
