tao-run-inference-service
NVIDIA/skills
Запускать, запрашивать и останавливать микросервис TAO для вывода по конкретной сетевой архитектуре, делегируя выполнение контейнера соответствующему навыку платформы.
...Расширить всеМикросервис TAO Inference
Инструкции
Чтобы запустить службу инференции:
- Соберите необходимые входные данные (раздел 1) и определите образ контейнера (раздел 2).
- Соберите полезную нагрузку задания и внутреннюю команду (разделы 3–4.1); используйте
references/code-templates.yaml→job_payload_builder. - Read
skills/platform/и запустите контейнер (раздел 4.2)./SKILL.md - Запишите службу в реестр и проверьте готовность (раздел 4.3); используйте
references/code-templates.yaml→registry_write.иreadiness_check.
Чтобы отправить запрос на вывод:
- Определите, какой сервис принимает запрос, в соответствии с разделом 6.0 (путем
job_id, либоnetwork_arch, либо по явному выбору пользователя, если запущено несколько служб — никогда не переключайтесь по умолчанию на"latest", если существует более одной службы), затем считывайте конечную точку изreferences/code-templates.yaml→request.registry_readс использованием полученногоjob_id. - Перед формированием тела запроса предложите пользователю ввести параметры выборки в стиле vLLM (раздел 6.1). Представьте
max_tokens,top_p,temperature(а также любые дополнительные параметры для конкретной архитектуры) с их значениями по умолчанию; предоставьте пользователю возможность переопределить или пропустить каждый из них, чтобы принять значение по умолчанию. Никогда не используйте значения по умолчанию без уведомления. - Сформируйте и отправьте тело запроса в соответствии с разделом 6.2; обработайте ответ в соответствии с разделом 6.3.
Чтобы остановить службу: прочитайте references/code-templates.yaml → stop.registry_read для определения job_id, прочитайте skills/platform/, затем действуйте в соответствии с разделом 5.
Справочные данные (схемы, сопоставления, допустимые значения — без инструкций):
references/service.yaml— сопоставления образов, допустимыеnetwork_archимена, схема полезных данных задания, имена переменных среды, классификация секретов.references/request.yaml— определение конечных точек, схема полей запроса, форматы ответов, примеры кода.references/code-templates.yaml— Шаблоны на Python для построения полезных данных, записей в реестр, проверок готовности и потоков остановки/запросов.
Правило в отношении секретов (применяется ко всем сгенерированным блокам кода в данном навыке)
Никогда не просите пользователя вводить значение секрета в командной строке. Для каждого значения секрета:
- сообщите пользователю, какую переменную среды необходимо установить (например,
export HF_TOKEN=...). - Сгенерируйте код, который считывает его с помощью
os.environ["VAR_NAME"]— никогда не используйте жестко заданные значения, не интерполируйте и не запрашивайте значение в командной строке.
Секретные переменные окружения (полный список в references/service.yaml → secrets_handling):
HF_TOKEN, WANDB_API_KEY, CLEARML_API_ACCESS_KEY, CLEARML_API_SECRET_KEY, TAO_API_KEY, TAO_USER_KEY.
Безопасно для сбора в окне запроса: network_arch, model_path, num_gpus, текст запроса, WANDB_* URL-адресы конфигурации, CLEARML_*_HOST URL-адресах.
1. Что нужно запросить у пользователя
| Ввод | Роль |
|---|---|
network_arch |
Выбор образа контейнера, внутренней структуры команды для каждой архитектуры (references/service.yaml → container_commands.), а также 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. Определите образ контейнера следующим образом:
- Прочитайте
{network_arch}.config.jsonи возьмитеapi_params.image(например,COSMOS_RL). Это ключ вdocker_image_defaults.mappingвreferences/service.yaml. - Найдите этот ключ в таблице сопоставления. Если переменная среды хоста
IMAGE_задана (например,IMAGE_COSMOS_RL), она переопределяет сопоставленное значение по умолчанию. - Сопоставленное значение обычно представляет собой ключ в формате «точка-ключ» в корневом файле
versions.yaml(например,tao_toolkit.cosmos_rl). Преобразуйте его в конкретныйnvcr.io/...URI образа, выполнив поискversions.yaml→images.. Абсолютные URI пропускаются без изменений, поэтому. IMAGE_переопределение через переменную среды, содержащее полный URI, по-прежнему работает. Вспомогательная функция Python для этого находится вreferences/code-templates.yaml. - Если конфигурационный файл отсутствует или
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/, чтобы узнать о предварительных проверках и учетных данных перед генерацией любого кода выполнения.
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: freshuuid.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/» и следуйте его инструкциям для запуска контейнера.
Базовые параметры (для всех платформ):
| Параметр | Значение |
|---|---|
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 можно было передать, а имя контейнера точно соответствовало 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/ и воспользуйтесь его механизмом отмены/остановки.
| Идентификатор платформы | для передачи | Дополнительная очистка |
|---|---|---|
| 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. Применяйте эти правила в указанном порядке:
- Пользователь явно указал
job_id→ используйте его. Проверьте, существует ли он вstate. - Пользователь указал
network_arch(например, «отправить это в службу cosmos-rl») → найдите соответствующие записи:candidates = [j for j, e in state.items() if j != "latest" and isinstance(e, dict) and e["network_arch"] == arch].- Точно одно совпадение → используйте его.
- Несколько совпадений → предложить пользователю варианты
job_idвариантов и ихstarted_at; не выбирайте автоматически. - Совпадений нет → остановиться и сообщить пользователю, что для данной архитектуры не запущен ни один сервис.
- Нет записей «
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. Не применяйте значения по умолчанию без уведомления. Используйте структурированный запрос — по одному вопросу на каждое поле, в котором:
- перечисляет все применимые поля с указанием их типа и значения по умолчанию;
- позволяет пользователю пропустить или принять любое поле, чтобы использовать значение по умолчанию для этого поля — ввод значения никогда не является обязательным.
- собирает все поля за один раз.
После запроса применяйте каждое введенное пользователем значение дословно, а для пропущенных полей подставляйте значения по умолчанию. Не придумывайте значения и не ограничивайте их значения автоматически.
Список полей, значения по умолчанию и применимость для каждой архитектуры: 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": ". См. container_response_shapes в references/request.yaml для строк, описывающих типы ошибок.
---
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.
Все файлы
11 файловУстановить 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
Копировать





Дом
