运行任务
从 sync 到 submit,再到 logs、stop、resume 和 delete 的完整任务生命周期。
运行任务可以按一条主线理解:
sync -> submit -> logs -> get/describe -> stop/resume/delete同步代码与环境
runwhere sync -f train.yamlsync 会读取 YAML,扫描当前目录,只上传变化文件,并准备环境和模型。
示例:
Uploading ---------------------------------------- 2/2 files ?
✓ 上传 2 个文件(0.0 MB),跳过 0 个未变化文件
✓ 存储路径已就绪:.| 参数 | 说明 |
|---|---|
-f, --file <yaml> | 任务 YAML 文件。 |
--status | 只查看最近一次同步状态。 |
查看最近一次同步:
runwhere sync -f train.yaml --statussync 会做这些事:
| 步骤 | 动作 |
|---|---|
| 1 | 解析 YAML,读取任务名、环境、模型和存储声明。 |
| 2 | 扫描当前目录,应用默认忽略规则和 .runwignore。 |
| 3 | 计算 diff,只上传新增或变化文件。 |
| 4 | 根据 conda、requirements、models 声明准备运行依赖。 |
| 5 | 保存最近一次 sync id,供后续查询。 |
默认会排除 .git/、.venv/、node_modules/、__pycache__/ 和常见缓存目录。项目里有额外大文件时,建议写进 .runwignore。
提交任务
runwhere submit -f train.yaml示例:
✓ 任务 job-efa79e36 已提交(BYOA)
→ ¥36.44/hr
→ 预计 ~3 分钟后开始运行(含节点创建)如果 gpuType 无法解析到可用 Offer(型号拼写错误,或比价数据暂不可用),提交会直接失败并给出明确提示,而不是卡住等待:
✗ 无法为 gpuType='t4' 自动选机(未知型号或比价服务暂不可达)
→ 检查 GPU 型号拼写,或在 YAML 填 resources.gpuSkuKey 指定具体 Offer(runwhere price list 查 SKU KEY)提交时 CLI 会:
- 解析 YAML。
- 检查登录状态。
- 检查上次 sync 后是否有本地代码变化。
- 根据
gpuSkuKey或gpuType选择 Offer。 - 按
kind创建 Training、Inference 或 Notebook。 - 提交任务并进入实时事件流。
资源选择规则:
| YAML 填写情况 | 行为 |
|---|---|
只填 resources.gpuType | 自动选择合适 Offer。 |
只填 resources.gpuSkuKey | 直接使用指定 Offer。 |
| 两者都填 | 以 gpuSkuKey 为准。 |
| 两者都不填 | 报错,提示先查看可用 GPU。 |
脚本或 CI 中建议使用 JSON 输出:
runwhere --json submit -f train.yaml查看日志
历史日志:
runwhere logs <name>实时跟随:
runwhere logs <name> -f查看最近 N 行:
runwhere logs <name> --tail 500任务准备阶段也会通过日志流显示平台事件:
[runwhere] 正在创建 GPU 节点...
[runwhere] 节点启动中,加入集群...
[runwhere] GPU 就绪,部署任务...
[runwhere] 任务运行中
Epoch 1/10, step 100, loss=2.341Notebook 和 Inference 的服务地址也会通过日志事件显示。
任务刚提交、还在准备阶段时,logs 可能暂时没有输出:
暂无日志(任务尚未产生输出,或日志已过期)查看任务
列出任务:
runwhere get jobs示例:
┌────────────────────────┬──────────┬─────────┬─────┬──────────┬─────┐
│ 名称 │ 类型 │ 状态 │ GPU │ 运行时长 │ URL │
├────────────────────────┼──────────┼─────────┼─────┼──────────┼─────┤
│ claude-cli-docs-verify │ training │ running │ 1×? │ - │ - │
└────────────────────────┴──────────┴─────────┴─────┴──────────┴─────┘没有任何任务时:
暂无作业筛选:
runwhere get jobs --status running
runwhere get jobs --kind Training查看详情:
runwhere describe job <name>详情通常包含状态、运行时长、资源信息和服务 URL。训练任务可能包含 GPU 利用率、显存峰值和温度峰值。
✓ 作业: claude-cli-docs-verify
ID: job-efa79e36
类型: training
状态: running--json 输出字段更完整(价格、Offer、计费、节点等):
{"id": "job-efa79e36", "job_id": "job-efa79e36", "name": "claude-cli-docs-verify", "job_type": "training", "platform": "aliyun", "status": "running", "url": null, "gpu_count": 1, "sku_key": "ecs.gn7i.2xlarge", "offer_key": "aliyun/cn-hangzhou/cn-hangzhou-i/on_demand/ecs.gn7i.2xlarge", "node_id": "node-1f661ea4", "price_per_hour": "36.4400", "estimated_cost": "0.0000", "final_cost": null, "billed_seconds": 0, "created_at": "2026-07-25T00:24:38+00:00", "started_at": null, "ended_at": null, "gpu_metrics": null}注意
sku_key(如ecs.gn7i.2xlarge,实例规格本身)和offer_key(如aliyun/cn-hangzhou/cn-hangzhou-i/on_demand/ecs.gn7i.2xlarge,完整链路 key)是两个不同字段,别混淆——写回 YAML 的resources.gpuSkuKey应该用offer_key这个值。
停止与恢复
停止:
runwhere stop job <name>示例:
✓ 作业 job-efa79e36 已停止,GPU 已释放,计费停止不同类型的停止语义:
| 类型 | 行为 |
|---|---|
| Training | 停止任务并释放 GPU。checkpoint 和工作目录保留。 |
| Inference | 停止服务并释放资源,访问 URL 不再可用。 |
| Notebook | 挂起交互环境并释放 GPU,后续可恢复。 |
恢复:
runwhere resume <name>训练任务可以指定 step:
runwhere resume <name> --from-step 12000训练能否真正从断点继续,取决于训练代码是否在 checkpoint 路径保存并在启动时恢复。具体写法见 Checkpoint 最佳实践。
删除记录
runwhere delete job <name>示例:
✓ 作业 job-efa79e36 已删除如果任务仍在运行,需要显式强制:
runwhere delete job <name> --force建议先 stop,确认资源释放后再 delete。删除作业记录不应作为正常停机替代。
删除后再 describe/logs 同一个任务名会明确报错,而不是静默返回旧数据:
✗ 任务不存在或无权访问常见问题
| 现象 | 处理 |
|---|---|
| submit 前提示本地代码有变化 | 先执行 runwhere sync -f <yaml>。 |
| YAML 文件不存在 | 检查 -f 路径。 |
| 未登录 | 执行 runwhere login --endpoint <url>。 |
| 没有指定 GPU | 先运行 runwhere price recommend -f <yaml>,或填写 gpuType。 |
| 日志为空 | 任务可能还在准备,先看 runwhere describe job <name> 或用 -f 跟随。 |