вариант
ДомДом Skill DevOps и CI/CD tao-run-inference-service

tao-run-inference-service

NVIDIA/skills NVIDIA/skills

Запускать, запрашивать и останавливать микросервис TAO для вывода по конкретной сетевой архитектуре, делегируя выполнение контейнера соответствующему навыку платформы.

...Расширить все
1
Обновлено время 27 сентября 2026 г.

Микросервис TAO Inference

Инструкции

Чтобы запустить службу инференции:

  1. Соберите необходимые входные данные (раздел 1) и определите образ контейнера (раздел 2).
  2. Соберите полезную нагрузку задания и внутреннюю команду (разделы 3–4.1); используйте references/code-templates.yaml → job_payload_builder.
  3. Read skills/platform//SKILL.md и запустите контейнер (раздел 4.2).
  4. Запишите службу в реестр и проверьте готовность (раздел 4.3); используйте references/code-templates.yaml → registry_write. и readiness_check.

Чтобы отправить запрос на вывод:

  1. Определите, какой сервис принимает запрос, в соответствии с разделом 6.0 (путем job_id, либо network_arch, либо по явному выбору пользователя, если запущено несколько служб — никогда не переключайтесь по умолчанию на "latest", если существует более одной службы), затем считывайте конечную точку из references/code-templates.yaml → request.registry_read с использованием полученного job_id.
  2. Перед формированием тела запроса предложите пользователю ввести параметры выборки в стиле vLLM (раздел 6.1). Представьте max_tokens, top_p, temperature (а также любые дополнительные параметры для конкретной архитектуры) с их значениями по умолчанию; предоставьте пользователю возможность переопределить или пропустить каждый из них, чтобы принять значение по умолчанию. Никогда не используйте значения по умолчанию без уведомления.
  3. Сформируйте и отправьте тело запроса в соответствии с разделом 6.2; обработайте ответ в соответствии с разделом 6.3.

Чтобы остановить службу: прочитайте references/code-templates.yaml → stop.registry_read для определения job_id, прочитайте skills/platform//SKILL.md, затем действуйте в соответствии с разделом 5.

Справочные данные (схемы, сопоставления, допустимые значения — без инструкций):

  • references/service.yaml — сопоставления образов, допустимые network_arch имена, схема полезных данных задания, имена переменных среды, классификация секретов.
  • references/request.yaml — определение конечных точек, схема полей запроса, форматы ответов, примеры кода.
  • references/code-templates.yaml — Шаблоны на Python для построения полезных данных, записей в реестр, проверок готовности и потоков остановки/запросов.

Правило в отношении секретов (применяется ко всем сгенерированным блокам кода в данном навыке)

Никогда не просите пользователя вводить значение секрета в командной строке. Для каждого значения секрета:

  1. сообщите пользователю, какую переменную среды необходимо установить (например, export HF_TOKEN=...).
  2. Сгенерируйте код, который считывает его с помощью os.environ["VAR_NAME"] — никогда не используйте жестко заданные значения, не интерполируйте и не запрашивайте значение в командной строке.

Секретные переменные окружения (полный список в references/service.yaml → secrets_handling): HF_TOKEN, WANDB_API_KEY, CLEARML_API_ACCESS_KEY, CLEARML_API_SECRET_KEY, TAO_API_KEY, TAO_USER_KEY.

Безопасно для сбора в окне запроса: network_arch, model_path, num_gpus, текст запроса, WANDB_* URL-адресы конфигурации, CLEARML_*_HOST URL-адресах.

1. Что нужно запросить у пользователя

Ввод Роль
network_arch Выбор образа контейнера, внутренней структуры команды для каждой архитектуры (references/service.yaml → container_commands.), а также neural_network_name в JSON-файле задания, если применимо. Должно совпадать с базовым именем в valid_network_arch_config_basenames в references/service.yaml (например, cosmos-rl, cosmos-predict2.5).
model_path Контрольная точка обученной модели. Допустимые формы: hf_model:/// (HuggingFace Hub — установите HF_TOKEN для моделей с гейтами) или путь к файловой системе локального контейнера. Облачные URI (s3://, gs://, az://) НЕ поддерживаются — служба инференса не зависит от облачного хранилища. Всегда запрашивайте у пользователя; никогда не подставляйте заменяющий параметр. См. references/service.yaml → model_path_protocols.
platform Вычислительная платформа: local-docker, brev, slurm, или kubernetes.
num_gpus По умолчанию — 1; минимальное значение для инференса — 1.

2. Разрешение изображения

Каждый network_arch имеет файл конфигурации сайдкара с именем {network_arch}.config.json. Определите образ контейнера следующим образом:

  1. Прочитайте {network_arch}.config.json и возьмите api_params.image (например, COSMOS_RL). Это ключ в docker_image_defaults.mapping в references/service.yaml.
  2. Найдите этот ключ в таблице сопоставления. Если переменная среды хоста IMAGE_ задана (например, IMAGE_COSMOS_RL), она переопределяет сопоставленное значение по умолчанию.
  3. Сопоставленное значение обычно представляет собой ключ в формате «точка-ключ» в корневом файле versions.yaml (например, tao_toolkit.cosmos_rl). Преобразуйте его в конкретный nvcr.io/... URI образа, выполнив поиск versions.yaml → images... Абсолютные URI пропускаются без изменений, поэтому IMAGE_ переопределение через переменную среды, содержащее полный URI, по-прежнему работает. Вспомогательная функция Python для этого находится в references/code-templates.yaml.
  4. Если конфигурационный файл отсутствует или api_params.image пуст, используйте резервный вариант COSMOS_RL ключ.

В конфигурационном файле также есть spec_params.inference.model_path , который определяет семантику «папка» или «путь к файлу»: если значение содержит подстроку folder, контейнер рассматривает путь как каталог.

3. Переменные среды (без обратных вызовов)

Укажите их в env_payload перед кодированием env_json. Не устанавливайте TAO_LOGGING_SERVER_URL или TAO_ADMIN_KEY.

TAO_EXECUTION_BACKEND — должны соответствовать платформе:

Платформа TAO_EXECUTION_BACKEND значение
local-docker local-docker
brev local-docker
slurm slurm
kubernetes local-k8s

CLOUD_BASED — всегда "False" для данного навыка (отключает отправку обратного вызова в TAO_LOGGING_SERVER_URL).

переменных окружения GPU — требуется только в том случае, если навык платформы не обрабатывает вставку GPU автоматически:

  • Tegra / Jetson: --runtime=nvidia с NVIDIA_DRIVER_CAPABILITIES=all и NVIDIA_VISIBLE_DEVICES=.
  • Стандартный x86 + nvidia-container-toolkit: используйте Docker device_requests. Скилл платформы сам об этом позаботится.

4. Выполнение на разных платформах

Полезная нагрузка задания и внутренняя команда (разделы 1–3) не зависят от платформы. Для каждой платформы ознакомьтесь со статьёй skills/platform//SKILL.md, чтобы узнать о предварительных проверках и учетных данных перед генерацией любого кода выполнения.

4.1 Создание внутренней команды (для каждой архитектуры)

Формат внутренней команды определяется в соответствии с network_arch — универсального шаблона нет. Найдите запись для соответствующей архитектуры в references/service.yaml → container_commands.; если его нет, значит, эта архитектура не поддерживается — остановитесь и обратитесь за разъяснениями. Выберите соответствующий подблок в references/code-templates.yaml → job_payload_builder.. Добавьте к команде префикс umask 0 && и сохраняйте его одинаковым на всех платформах (local-docker, brev, slurm, kubernetes).

Общее для всех архитектур:

  • job_id: fresh uuid.uuid4() — становится именем контейнера и ключом в реестре.
  • image: разрешается в соответствии с разделом 2.
  • Секреты (access_key, secret_key, HF_TOKENи т. д.) считываются из переменных среды во время выполнения — никогда не используйте жесткую кодировку, никогда не записывайте в журнал и не выводите на экран.

Примечания, относящиеся к конкретной архитектуре (полная информация в references/service.yaml → container_commands):

  • cosmos-rl — один --job '' --docker_env_vars '' блоке; json.dumps(...) + shlex.quote(...). env_payload содержит TAO_EXECUTION_BACKEND (согласно таблице в разделе 3), TAO_API_JOB_ID, CLOUD_BASED=False. Сервис инференса не зависит от облачного хранилища; HF_TOKEN это единственная переменная среды авторизации, которая когда-либо применяется (для моделей HuggingFace с ограниченным доступом).
  • cosmos-predict2.5 — в стиле флага cosmos_predict inference_microservice start ... --port 8080 (без setup. префикса; используются tyro.conf.OmitArgPrefixes). --job/--docker_env_vars не принимаются. Переведите model_path в --checkpoint-path (локальный путь) или --model (hf_model://); облачные URI отклоняются. Единственная переменная среды авторизации, которая когда-либо применяется, — это HF_TOKEN для моделей HuggingFace с ограниченным доступом. Параметры, задаваемые для каждого запроса (prompt, inference_type, num_output_frames, guidance, seed, num_steps, negative_prompt), указываются в теле запроса, а не при запуске. TAO_EXECUTION_BACKEND/TAO_API_JOB_ID/CLOUD_BASED не используются и могут быть опущены.

4.2 Делегирование выполнения навыку платформы

Ознакомьтесь с документом «skills/platform//SKILL.md» и следуйте его инструкциям для запуска контейнера.

Базовые параметры (для всех платформ):

Параметр Значение
image разрешённый образ контейнера (раздел 2)
command inner — строка оболочки, сгенерированная в разделе 4.1
gpu_count num_gpus
env_vars env_payload
имя задания / контейнера job_id — должно совпадать с UUID из раздела 4.1, чтобы реестр мог на него ссылаться
host_port (local-docker, brev) порт на хосте для привязки к порту контейнера 8080. По умолчанию 8080, но должен быть уникальным для каждого одновременно работающего сервиса — см. правило распределения портов ниже.

Дополнительные параметры, зависящие от платформы:

Платформа Дополнительные параметры
local-docker Ничего, кроме базовых
brev instance_id (опционально — повторное использование существующего экземпляра); для учетных записей с несколькими наборами учетных данных или несколькими рабочими пространствами также cloud_cred_id и workspace_group_id при первом создании — см. skills/platform/tao-run-on-brev/SKILL.md
slurm partition и account — проверьте SLURM_PARTITION/SLURM_ACCOUNT переменные среды; спросить пользователя, если они не заданы
kubernetes namespace (по умолчанию: default); image_pull_secret (требуется для nvcr.io образов)

Привязка портов (local-docker и brev): использовать прямой запуск Docker (а не DockerSDK), чтобы -p :8080 можно было передать, а имя контейнера точно соответствовало job_id точно совпадало.

Правило распределения портов (local-docker и brev, ОБЯЗАТЕЛЬНО для параллельных сервисов): перед запуском сервиса считывайте данные из реестра (/tmp/tao-inf-ms-state.json) и соберите набор host_port значений из каждой существующей записи на той же платформе (а для brev — на том же instance_id). Выберите самый низкий свободный порт, начиная с 8080, который отсутствует в этом наборе — например, host_port = next(p for p in range(8080, 8200) if p not in used_ports). По умолчанию 8080 применяется только в том случае, если не запущено ни одного другого сервиса. Именно это позволяет «запустить 3 сервиса, каждый из которых доступен по отдельному host_url» — без него службы 2 и 3 завершают работу с ошибкой bind: address already in use. SLURM и Kubernetes получают отдельные конечные точки с помощью собственных механизмов платформы и не нуждаются в этом шаге.

4.3 После запуска: реестр сервисов и конечная точка

Запишите реестр сервисов сразу после того, как платформа подтвердит, что контейнер запущен. Реестр (/tmp/tao-inf-ms-state.json) индексируется по job_id; "latest" всегда указывает на последнюю запущенную службу.

См. references/code-templates.yaml → registry_write. шаблон на языке Python.

Платформа host_url platform_job_id Дополнительный шаг перед написанием
local-docker http://localhost:{host_port} — Нет
brev http://{brev_ip}:{host_port} — brev ls → получить IP-адрес экземпляра (localhost недействительно для удалённой виртуальной машины)
slurm http://localhost:{host_port} Идентификатор задания планировщика SLURM Дождаться перехода в состояние «Running»; перенаправление порта по SSH localhost:{host_port}→{node}:8080
kubernetes http://{external_ip}:8080 Имя задания k8s kubectl expose job … --type=LoadBalancer; дождаться получения внешнего IP

После записи в реестр выведите job_id и URL:

print(f"Inference service started.")
print(f"  Job ID : {job_id}")
print(f"  Arch   : {network_arch}")
print(f"  URL    : {state[job_id]['host_url']}/v1/chat/completions")
print(f"Use this Job ID to send requests or stop the service.")

Затем проверьте готовность — см. references/code-templates.yaml → readiness_check. Контейнер загружает модель в фоновом режиме; не отправляйте запросы, пока он не вернет код 200.

5. Остановка службы инференса

Спросите у пользователя job_id для остановки. Если он не указал его, по умолчанию используйте state["latest"] и подтвердите, какой job_id будет остановлен. Прочитайте реестр с помощью references/code-templates.yaml → stop.registry_read, затем обратитесь к skills/platform//SKILL.md и воспользуйтесь его механизмом отмены/остановки.

Идентификатор платформы для передачи Дополнительная очистка
local-docker job_id_to_stop — имя контейнера Нет
brev job_id_to_stop — имя контейнера Нет
slurm entry["platform_job_id"] — Идентификатор задания SLURM pkill -f "ssh.*-L.*{entry['host_port']}"
kubernetes entry["platform_job_id"] — имя задания k8s kubectl delete svc {entry["platform_job_id"]} -n

где entry = state[job_id_to_stop]. После остановки очистите реестр: references/code-templates.yaml → stop.registry_cleanup.

6. Отправка запросов на инференцию

6.0 Определение, какой сервис принимает данный запрос (ОБЯЗАТЕЛЬНО)

Каждый запрос должен быть направлен к конкретному сервису, на котором запущена соответствующая модель. Маршрутизация осуществляется посредством job_id — реестр хранит network_arch для каждой записи, поэтому вы можете определить целевую службу по архитектуре, когда пользователь указывает модель вместо job_id. Применяйте эти правила в указанном порядке:

  1. Пользователь явно указал job_id → используйте его. Проверьте, существует ли он в state.
  2. Пользователь указал network_arch (например, «отправить это в службу cosmos-rl») → найдите соответствующие записи: candidates = [j for j, e in state.items() if j != "latest" and isinstance(e, dict) and e["network_arch"] == arch].
    • Точно одно совпадение → используйте его.
    • Несколько совпадений → предложить пользователю варианты job_idвариантов и их started_at; не выбирайте автоматически.
    • Совпадений нет → остановиться и сообщить пользователю, что для данной архитектуры не запущен ни один сервис.
  3. Нет записей «job_id» и «network_arch» → подсчитать количество записей, не"latest" записей в state:
    • Ровно одна работающая служба → использовать её.
    • Две или более → не переключаться по умолчанию на state["latest"] без предупреждения. Предложить пользователю полный список (job_id, network_arch, host_url) и требуйте явного выбора. Указатель "latest" Указатель предназначен для удобства при работе с одним сервисом, а не в качестве резервного варианта маршрутизации при сосуществовании нескольких сервисов.
    • Ноль → остановитесь и сообщите пользователю, что сначала необходимо запустить службу.

После разрешения прочтите конечную точку из реестра (references/code-templates.yaml → request.registry_read), передавая разрешенный job_id в качестве user_provided_job_id. Подтвердите пользователю: «Отправка на job_id=… arch=… url=…». Если сервис может ещё загружаться, сначала проверьте его готовность (references/code-templates.yaml → readiness_check).

Перед отправкой проверить: содержит ли тело запроса, предоставленное пользователем, поля, зависящие от архитектуры (например, guidance / num_steps / seed / negative_prompt → cosmos-predict2.5; обязательные image_url/video_url элементы содержимого → cosmos-rl), убедитесь, что они согласуются с state[job_id]["network_arch"]. В случае несоответствия остановитесь и запросите уточнение — отправка тела запроса cosmos-predict2.5 на сервис cosmos-rl приведёт к сбою на уровне контейнера с кодом ошибки 4xx/5xx, который сложнее диагностировать, чем обнаружить здесь.

6.1 Параметры выборки — ОБЯЗАТЕЛЬНЫЙ запрос у пользователя перед каждым запросом

Перед формированием тела запроса вы ДОЛЖНЫ явно запросить у пользователя параметры выборки в стиле vLLM. Не применяйте значения по умолчанию без уведомления. Используйте структурированный запрос — по одному вопросу на каждое поле, в котором:

  1. перечисляет все применимые поля с указанием их типа и значения по умолчанию;
  2. позволяет пользователю пропустить или принять любое поле, чтобы использовать значение по умолчанию для этого поля — ввод значения никогда не является обязательным.
  3. собирает все поля за один раз.

После запроса применяйте каждое введенное пользователем значение дословно, а для пропущенных полей подставляйте значения по умолчанию. Не придумывайте значения и не ограничивайте их значения автоматически.

Список полей, значения по умолчанию и применимость для каждой архитектуры: references/request.yaml → chat_completions_request_body (базовые поля выборки: max_tokens, top_p, temperature) и network_arch_constraints. (переопределения для конкретных архитектур и дополнительные параметры, такие как guidance/num_steps/seed/negative_prompt для cosmos-predict2.5). Если поле помечено как неподдерживаемое для активной архитектуры, не запрашивайте его и не включайте в тело запроса.

6.2 Формат запроса

Отправьте POST на адрес {BASE_URL}/v1/chat/completions с Content-Type: application/json и таймаутом не менее 300 с. Тело запроса совместимо с OpenAI (завершение фразы в чате vLLM); см. references/request.yaml → chat_completions_request_body для полной схемы полей и форматов элементов содержимого (text / image_url / video_url), а также code_examples здесь — готовые к запуску примеры на Python и curl.

Ограничения: обрабатывается только первое сообщение пользователя. В телах запросов не должно быть секретных значений. Ограничения для отдельных сетей (например, cosmos-rl требует, чтобы каждый запрос содержал изображение или видео; cosmos-rl отклоняет data: URI) приведены в references/request.yaml → network_arch_constraints.

6.3 Обработка ответов

Статус HTTP Значение Действие
200 Успех — choices[0].message.content содержит сгенерированный текст Результат чтения
202 Сервер всё ещё инициализируется или модель всё ещё загружается Повторите попытку через некоторое время
503 Сбой инициализации, сбой загрузки модели или модель ещё не готова Проверить error.type: model_not_ready → повторить попытку; initialization_error / model_load_error → отказаться и проверить журналы
400 Отсутствует или пустое тело JSON Исправить запрос
500 Необработанное исключение во время вывода Проверьте журналы контейнера

Для кодов 202 и 503 тело содержит {"error": {"type": "", "message": ""}}. См. container_response_shapes в references/request.yaml для строк, описывающих типы ошибок.

Посмотреть на 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.

Установить tao-run-inference-service

Скачайте файлы навыков и распакуйте их в каталог .claude/skills/.

Скачать ZIP

Клонируйте репозиторий и скопируйте файлы навыка в свой проект.

git clone https://github.com/NVIDIA/skills/tree/main/skills/tao-run-inference-service # Copy SKILL.md to your .claude/skills/ directory

Копировать Копировать
Быстрая настройка: Скопируйте папку со скиллом в каталог .claude/skills/ Claude автоматически обнаружит и запустит этот скилл
Репозиторий NVIDIA/skills

Похожие навыки

klingai-upgrade-migration
Обновлено время 3 июля 2026 г.
Verification &amp; Quality Assurance
Обновлено время 29 июня 2026 г.
base44-cli
Обновлено время 29 июня 2026 г.
Railway CLI Management
Обновлено время 2 июля 2026 г.
OR