DEEP 129 · 第十一辑 · 服务与训练工具逐函数 · LEARN NOTES

收进学习手册 · 2026-09-11 · duck.whatled.com

解读 129 · hf_jobs.py:云训练入口

解读对象:microduck-replica/upstream/microduck_rl/src/mjlab_microduck/hf_jobs.py(483 行)
需要的前置:解读 32(导出与部署)、解读 70(重训全链路)

在做什么

本地没有 GPU 也能训练:train <任务名> ... --hf-jobs 会把整个训练搬到 Hugging Face Jobs 的云容器里跑。真正被调用的是本文件的 submit()(hf_jobs.py:241)——--hf-jobs 参数由 train_hook.py 拦截转发到这里;而容器内的环境变量 MICRODUCK_IN_HF_JOB=1(:324)会把拦截 disarm 掉,保证云上的 uv run train 只在本地训练,不会递归再提交一个云任务。

三个默认值定下一个"标准训练舱":镜像 pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime(:41)、硬件 l4x1(:42)、超时 12 小时(:43),分别可被 --image/--flavor/--timeout 覆盖。

提交流程与 BOOTSTRAP 脚本

submit() 的流程是:打 tar 包 → 上传 → 提交 → 盯到结束。开头先由 _pick_namespace()(:171)确定命名空间(个人账号或 org;--namespace 跳过交互提示,非 tty 环境回落个人账号)。

  1. _build_tarball()(:151)用 git ls-files -co --exclude-standard 列文件:已跟踪但未提交的修改也进包,被 ignore 的垃圾(.venv、logs、*.onnx)不进;返回短 SHA 供追溯。
  2. tar 上传到私有 HF dataset 仓库(默认 <namespace>/mjlab-microduck-src,:318),容器里只读挂载到 /src(:347)。
  3. api.run_job(...) 执行内嵌 shell 脚本 BOOTSTRAP(:47):装基础工具、装钉死版本的 uv 0.11.30(浮动 latest 读到旧版缓存条目曾让 sync 必现失败,2026-07-21)、UV_LINK_MODE=copy;uv sync 失败就清缓存自愈重试一次;然后 nohup 拉起 checkpoint 上传看护 scripts/hf/uploader.py,跑训练;训练正常结束且 AUTO_EXPORT=1(默认开)时顺手导出 ONNX 并上传(:96-118)——省得再开一个要付全额 bootstrap 的导出任务。
  4. _await_scheduling()(:214)以 1200 秒预算轮询调度阶段(镜像拉取冷启动约 5 分钟;卷挂载失败约 7 分钟才暴露),末尾再循环跟日志;Ctrl-C 只是脱离,任务继续跑(:481-483)。调度期"卷挂载失败"是已知偶发,自动重提、最多 3 次(:402)。

--dry-run、费用与 Token 卫生

你带走的收获

延伸

什么鸭 WHATDUCK · 复刻学习笔记 ← 全部手册 · 首页