opção
LarLar Skill DevOps e CI/CD tao-run-inference-service

tao-run-inference-service

NVIDIA/skills 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 tudo
1
Tempo atualizado 27 de Setembro de 2026

Microsserviço de Inferência TAO

Instruções

Para iniciar um serviço de inferência:

  1. Reúna as entradas necessárias (Seção 1) e resolva a imagem do contêiner (Seção 2).
  2. Crie a carga útil da tarefa e o comando interno (Seções 3–4.1); use references/code-templates.yaml → job_payload_builder.
  3. Read skills/platform//SKILL.md e inicie o contêiner (Seção 4.2).
  4. Grave no registro de serviços e verifique a disponibilidade (Seção 4.3); use references/code-templates.yaml → registry_write. e readiness_check.

Para enviar uma solicitação de inferência:

  1. Determine qual serviço receberá a solicitação, conforme a Seção 6.0 (por job_id, por network_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 de references/code-templates.yaml → request.registry_read com o endpoint determinado job_id.
  2. 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.
  3. 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//SKILL.mde, 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:

  1. Informe ao usuário qual variável de ambiente deve ser definida (por exemplo, export HF_TOKEN=...).
  2. 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:

  1. Leia {network_arch}.config.json e selecione api_params.image (por exemplo, COSMOS_RL). Essa é uma chave no arquivo docker_image_defaults.mapping em references/service.yaml.
  2. 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.
  3. O valor mapeado é normalmente uma chave com pontos no arquivo versions.yaml (por exemplo, tao_toolkit.cosmos_rl). Resolva-a em um nvcr.io/... , consultando versions.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 em references/code-templates.yaml.
  4. Se o arquivo de configuração estiver ausente ou api_params.image estiver vazio, recorra à COSMOS_RL chave.

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=nvidia com NVIDIA_DRIVER_CAPABILITIES=all e NVIDIA_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//SKILL.md 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: fresh uuid.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 '' --docker_env_vars '' blob; json.dumps(...) + shlex.quote(...). env_payload contém TAO_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 sinalizador cosmos_predict inference_microservice start ... --port 8080 (sem setup. prefixo; utiliza tyro.conf.OmitArgPrefixes). --job/--docker_env_vars não são aceitos. Traduzir model_path para --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_TOKEN para 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_BASED não são utilizados e podem ser omitidos.

4.2 Delegar a execução à habilidade da plataforma

Leia skills/platform//SKILL.md 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 :8080 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//SKILL.md 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:

  1. O usuário forneceu um job_id explícito → use-o. Verifique se ele existe no state.
  2. 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 suas started_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.
  3. Sem job_id e sem network_arch → conte as entradas que não"latest" entradas em state:
    • 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:

  1. Liste todos os campos aplicáveis com seu tipo e valor padrão.
  2. Permita que o usuário pule ou aceite qualquer campo para adotar o valor padrão desse campo — nunca é necessário inserir um valor.
  3. 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": "", "message": ""}}. Consulte container_response_shapes em references/request.yaml para as cadeias de caracteres dos tipos de erro.

Ver no GitHub
---
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.

Instalar tao-run-inference-service

Baixe e extraia os arquivos de habilidades para o diretório .claude/skills/.

Baixar ZIP

Clone 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 Copiar
Configuração rápida: Copie a pasta da habilidade para .claude/skills/ O Claude detectará e utilizará automaticamente a habilidade
Repositório NVIDIA/skills

Habilidades relacionadas

klingai-upgrade-migration
Tempo atualizado 3 de Julho de 2026
Verification &amp; Quality Assurance
Tempo atualizado 29 de Junho de 2026
base44-cli
Tempo atualizado 29 de Junho de 2026
Railway CLI Management
Tempo atualizado 2 de Julho de 2026
OR