关于 tao-run-platform
tao-run-platform 是用于 NVIDIA TAO 工作流的 Python 执行技能,面向需要跨平台提交和监控作业的用户。它通过统一 SDK 处理作业状态、日志及输入输出。
主要功能
- 01跨平台创建和管理作业
- 02查询状态并流式查看日志
- 03分析失败原因
- 04处理 S3 输入与输出
- 05持久化作业状态
适用场景
- 01提交 TAO 模型训练或推理作业
- 02监控排队中的长时运行任务
- 03在多个作业间保存并恢复状态
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nvidia/ skills --skill tao-run-platform安装后在 Claude Code 中输入/tao-run-platform确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
BENCHMARK.mdskill-card.mdskill.oms.sigconfig/skillspector-baseline.yamlevals/evals.jsonreferences/error-patterns.mdorchestration-patterns.mdplatform-notes.mdscope.mdspec-construction.md详细介绍
TAO 执行 SDK
单独安装? 如果此会话不是由 TAO 技能库插件初始化的,请先运行
tao-setup技能(主机预检、凭据、跨技能发现)。
对于需要作业句柄、S3 I/O 封装或平台专属功能(SLURM/Lustre 队列、Kubernetes Jobs、本地 Docker 调试、复用 Brev 实例)的用户,SDK 提供了可选的 Python 层。大多数 TAO 技能只需运行 docker run,无需使用 SDK。以下情况可以使用 SDK:
- 需要通过
Job句柄轮询状态并持续流式传输日志。 - 需要在入口点中内置支持 S3 的输入下载 / 输出上传。
- 需要串联多个作业并持久化状态。
预检
使用此平台前,请安装 nvidia-tao-sdk[all]——[all] 附加项会引入所有平台专属依赖(Brev、S3 工具等)。如果尚未安装,默认在当前 Python 环境中安装,然后重新运行导入检查:
python -c "import tao_sdk" 2>/dev/null || {
echo "Installing missing Python requirement: nvidia-tao-sdk[all]"
python -m pip install "nvidia-tao-sdk[all]"
}
python -c "import tao_sdk"
软件包索引因环境而异——预期运行器/容器已配置可用的 pip(例如 ~/.pip/pip.conf、PIP_INDEX_URL、PIP_EXTRA_INDEX_URL 或代理)。如果安装因索引/网络问题失败,这是运行器配置问题;此技能不依赖特定的软件包仓库。
默认情况下,缺少的 pip 依赖会自动安装,并在运行日志中报告。非 pip/系统级前置依赖仍需通过常规预检失败提示,并向用户说明如何解决。
设置
凭据来自环境变量——从会话环境中读取(启动前在 shell 中导出)。
from tao_sdk.platforms.brev import BrevSDK # Brev GPU instances
sdk = BrevSDK() # reads BREV_API_TOKEN (optional — falls back to brev login)
SDK 会在首次使用时惰性验证凭据;如果缺少必需的环境变量,会抛出 CredentialError 并给出明确提示。必需的环境变量:
| 平台 | 必需 | 可选 |
|---|---|---|
| Brev | —(手动运行 brev login 也可) | BREV_API_TOKEN |
| S3 I/O(任何平台) | S3_BUCKET_NAME、ACCESS_KEY、SECRET_KEY | S3_ENDPOINT_URL、CLOUD_REGION |
| 容器环境 | NGC_KEY | HF_TOKEN |
Agent 不会读取凭据值——只会通过 [ -n "$VAR_NAME" ] 检查变量是否存在。
工作流启动信息收集
启动任何 TAO 工作流或操作前,先确认用户目标。然后在询问凭据或启动详情前, 询问平台和监控偏好。应从打包的辅助工具生成支持的平台选项,而不是 扫描平台文档或文件夹:
${TAO_SKILL_BANK_PATH:-~/tao-skills-external}/scripts/list_tao_platforms.py \
--skill-bank ${TAO_SKILL_BANK_PATH:-~/tao-skills-external} --format text
询问:
- 此工作流应在哪个支持的平台上运行?
- 是否应保持启用长时间运行监控?默认:启用。这意味着
Agent 会保持连接并持续发布状态,直到进入终止状态,包括
长时间等待
PENDING队列。 - 状态更新间隔多少分钟?默认:5 分钟。
确定模型/操作后,从打包的元数据中解析默认容器镜像,并在创建运行器文件前
询问用户是确认该镜像,还是提供 image=<override>:
${TAO_SKILL_BANK_PATH:-~/tao-skills-external}/scripts/resolve_tao_image.py \
--skill-bank ${TAO_SKILL_BANK_PATH:-~/tao-skills-external} \
--model <network_arch> --action <action> --format text
对于支持训练的模型工作流,在创建普通训练作业前,检查模型级 AutoML 元数据:
${TAO_SKILL_BANK_PATH:-~/tao-skills-external}/scripts/list_tao_models.py \
--skill-bank ${TAO_SKILL_BANK_PATH:-~/tao-skills-external} \
--scope automl --format json
如果所选模型的 automl_enabled: true 且具有有效的 train schema,
默认通过 skills/applications/tao-run-automl 执行训练,并设置
automl_policy: on。只有当其运行设置中包含
automl_policy: off、用户明确要求普通运行,或模型元数据表明已启用 AutoML 但尚未打包 train schema 时,工作流才应绕过 AutoML。
选定平台后,获取凭据筛选结果:
${TAO_SKILL_BANK_PATH:-~/tao-skills-external}/scripts/list_tao_platforms.py \
--skill-bank ${TAO_SKILL_BANK_PATH:-~/tao-skills-external} \
--platform <platform> --format text
只询问所选平台所需的凭据。例如,SLURM
需要 SLURM_USER 和 SLURM_HOSTNAME;不需要 Brev 凭据。
Kubernetes 和本地 Docker 不需要 Brev 或 SLURM 凭据。只有当所选平台以及数据/结果 URI 需要时,才询问 S3 密钥等存储凭据。
核心 API
所有平台 SDK 都实现相同的核心结构:
sdk.create_job(image, command, gpu_count=1, env_vars=None, inputs=None, outputs=None, **kwargs) -> Job
sdk.get_job_status(job_id) -> JobStatus
sdk.get_job_logs(job_id, tail=None) -> str
sdk.cancel_job(job_id) -> bool
sdk.get_failure_analysis(job_id) -> dict | None
sdk.get_job_results_dir(job_id) -> str
sdk.check_path(remote_path) -> bool
sdk.list_path(remote_path) -> list[str]
仅 Brev 支持:
sdk.delete_instance(instance_id)— 清理临时实例。sdk.list_instances()— 列出活动实例。
提交作业
Agent 在调用 create_job 之前,始终会先通过 build_entrypoint 构造容器命令。Agent 会从 skill_info.yaml 中读取操作的架构(command、mode、config_format、inputs、outputs、upload_excludes),并将这些字段作为 kwargs 传入。随后,build_entrypoint 会封装:
- 容器内的
script_runner运行时(以内嵌的 base64 heredoc 形式提供——无需在容器中安装tao_sdk)。 - CLI 调用。该调用将在容器运行时执行以下操作:下载声明的输入(S3 / HF-Hub / NGC),在
{config_path}写入 spec 文件,并将远程 URI 重写为本地路径;运行用户命令;上传输出。
输出目的地会在运行时根据 SDK 注入的环境变量解析(见下文“输出写入位置”)。平台 SDK 的 create_job 会原样运行生成的命令——不接收 inputs/outputs kwargs,也不会隐式封装。数据流在 Agent 的代码中清晰可见。
输出写入位置(运行时解析——Agent 无需管理)
SDK 会向容器环境注入 TAO_JOB_ID(与 Job.id 匹配);如果挂载了持久化卷,还会注入 TAO_RESULTS_ROOT。在容器内,script_runner 会解析输出目的地:
| 容器环境 | 结果 |
|---|---|
已设置 TAO_RESULTS_ROOT(Lustre / PVC / bind / NFS) | 输出写入 {TAO_RESULTS_ROOT}/<job_id>/<key>/;不上传 |
已设置 S3_BUCKET_NAME(云端,无挂载) | 输出写入 s3://{bucket}/results/<job_id>/<key>/;运行结束时上传 |
| 两者均未设置 | 输出写入 /results/<job_id>/<key>/(容器临时存储),并在运行结束时发出醒目警告 |
各平台策略:
| SDK | 注入内容 |
|---|---|
SlurmSDK | TAO_RESULTS_ROOT={SLURM_BASE_RESULTS_DIR}/results(始终如此——使用 Lustre,绝不使用 S3,避免调度器在 GPU 空闲时终止作业) |
KubernetesSDK / DockerSDK / BrevSDK | 如果挂载点位于 /results,则设置 TAO_RESULTS_ROOT=/results;否则回退到 S3 |
如果 Agent 需要自定义目的地,可以直接在输出 spec 键中填写 s3://... URI 或绝对路径——显式值会覆盖自动填充值。否则,script_runner 会自动重写模型自然默认值,例如 cosmos-rl 的 output_dir: "output" 或 DINO 的空 results_dir。
spec 是嵌套字典,而不是扁平的点分隔键
构造 spec 时,最常见的错误就是这一点。skill_info.yaml 的 inputs: / outputs: 块中出现的点分隔表示法(例如 section.subsection.key)表示指向嵌套 spec 中的路径——script_runner 会按该路径查找值。它并非 spec 自身的结构。spec 应与模型容器所需的结构一致(通常是嵌套的 TOML/YAML)。
# ✓ CORRECT — nested dicts
specs = {
"section": {
"subsection": {"key": "value"},
},
}
# ✗ WRONG — flat top-level key with dots. TOML/YAML emits this as a
# quoted bare-string key, the model sees an empty `section` table, and
# any input declared at "section.subsection.key" silently fails to
# download because _get_nested(specs, "section.subsection.key") → None.
specs = {
"section.subsection.key": "value",
}
这两种结构表面上看起来相似,含义却不同。如有疑问,请查看模型的 references/ 目录(例如默认 spec 的 TOML 或 YAML 文件)——那就是 spec 字典必须遵循的实际嵌套结构。skill_info.yaml 中的 inputs: / outputs: 声明表示的是指向嵌套 spec 中的路径,而不是键名。
构建规范 / 参数
技能的操作会在 skill_info.yaml 的 actions.<action>.mode 字段中声明其配置机制。缺少 mode 应视为无效元数据,应修复技能,而不是推断默认值。先读取 actions.<action>.mode,再将相应的参数形状传递给 build_entrypoint:
| 声明的模式 | Agent 传递的内容 |
|---|---|
config | 使用按规范键组织的 inputs / outputs 传递 specs=...;辅助函数会写入规范文件、重写 URI 并运行命令 |
args | 传递 args=...,并可选地传递按规范键组织的 inputs / outputs;辅助函数会将 CLI 参数替换到命令模板中 |
passthrough | 传递按路径键组织的 inputs=... 和/或 outputs=...;辅助函数会将文件下载到指定路径、运行命令并上传指定的输出 |
不要根据缺失的元数据推断模式。缺少 mode 表示技能契约已过时。
请参阅 references/spec-construction.md,了解各模式的构建策略、推荐的决策顺序,以及针对规范驱动任务(配置文件)和按路径键组织的任务(无配置文件)的 build_entrypoint 示例。
解析容器映像
技能可以通过键(tao_toolkit.pyt)或绝对 URI(nvcr.io/...)声明映像。使用 resolve_container_image() 处理这两种情况:
from tao_sdk.versions import resolve_container_image
image = resolve_container_image(skill_info["container_image"])
在后台,该函数会遍历 versions.yaml 查找键;绝对 URI 则会原样返回。
监控
status = sdk.get_job_status(job.id)
print(status.status) # Pending, Running, Complete, Error, Canceled
print(status.message) # platform-specific detail
logs = sdk.get_job_logs(job.id, tail=200)
print(logs)
发生故障时,get_failure_analysis() 会对根本原因进行分类:
analysis = sdk.get_failure_analysis(job.id)
if analysis:
print(analysis["err_class"]) # ERR_PROGRAM, ERR_INFRA, etc.
print(analysis["suggestion"]) # human-readable fix
for event in analysis.get("job_failure_by_node_event", []):
print(event["node_event_name"], event["message"]) # OOM, GPU error, etc.
轮询模式
对于用户希望实时查看的交互式运行:
import time
status_interval_minutes = status_interval_minutes or 5
while True:
status = sdk.get_job_status(job.id)
if status.status in ("Complete", "Error", "Canceled"):
break
print(f" {status.status}")
time.sleep(status_interval_minutes * 60)
if status.status == "Error":
print(sdk.get_job_logs(job.id, tail=100))
print(sdk.get_failure_analysis(job.id))
启用长时间运行监控后,不要在 30 分钟后或几次状态没有变化的轮询后停止。应持续按 status_interval_minutes 发出更新,直到任务完成、失败、取消,或用户要求分离/停止。如果聊天/运行时无法保持打开这么久,请明确说明,并提供可持久访问的工作流/日志路径,以便手动刷新状态。
对于尚未进入终态的受监控任务,不要发送最终回复。完成本轮会使聊天监控器分离。请通过进度更新发送非终态状态消息并继续轮询;仅在任务进入终态、用户明确要求分离/停止,或确实遇到阻止继续轮询的运行时限制时,才结束本轮。
对于后台运行,请持久化保存 job.id 和 state_file 路径;之后可通过构建相同的 SDK 并调用 get_job_status(job_id) 重新连接——任务状态会从磁盘存储中读取。
编排模式
多步骤工作流、并行扫描,以及通过 ActionWorkflow 实现的运行文件夹持久化,详见
references/orchestration-patterns.md。
在串联 create_job 调用、扫描参数或跨上下文中断持久化运行状态前,请先阅读该文档。
数据集工具
当技能文档中记录的文件名与用户的目录结构不匹配时,请列出数据集以进行确认:
assert sdk.check_path("s3://my-bucket/coco/")
files = sdk.list_path("s3://my-bucket/coco/train/")
# Use the actual paths to set spec fields.
对于 S3 路径,拼接时请去掉末尾的斜杠,避免出现 //:
base = dataset_uri.rstrip("/")
specs["dataset"]["train_csv"] = f"{base}/train.csv" # nested — see "spec is nested dicts"
平台特定说明
请参阅 references/platform-notes.md,了解各平台的行为、关键字参数和凭证范围:Brev(instance_id/gpu_type/cloud_cred_id/workspace_group_id、就绪等待超时)、SLURM(通过 SSH 使用 sbatch、Lustre 路径、队列默认值)、Kubernetes(kubeconfig、GPU Operator)以及本地 Docker(单主机、多 GPU)。
错误模式
SDK 错误 → 根本原因 → 修复方法的映射见
references/error-patterns.md。遇到 CredentialError、映像拉取失败、任务卡在 Pending 状态或类似问题时,请阅读该文档——其中的条目会将异常文本映射到根本原因。
SDK 不负责的内容
SDK 不会读取或解读技能、独立运行 AutoML、决定规格内容、选择平台或编排多步骤工作流——这些仍由 Agent 负责。完整的范围约束请参阅 references/scope.md,其中包括模型级 AutoML 策略(automl_enabled: true → skills/applications/tao-run-automl,除非 automl_policy: off 或用户要求进行普通的单次运行)。