DEEP 21 · 第三辑 · 训练代码 · LEARN NOTES

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

解读 21 · tasks/init.py:任务注册表

解读对象:microduck-replica/upstream/microduck_rl/src/mjlab_microduck/tasks/__init__.py(278 行)
需要的前置:解读 22(配置工厂长什么样);懂「cfg」指 dataclass 配置对象即可

这个文件是整个训练包的"门面"。mjlab 的插件加载器只认 mjlab_microduck 这一个包名,
而它 import 时执行的第一段代码,就把本仓库所有任务(33 个 task_id)注册进了全局任务表。
/train 命令行里敲的每个任务名,都是在这里挂上去的。

一个刻意为之的 import 顺序

文件第 1 行 import 的是 maybe_submit_to_hf_jobs,第 7 行就调用它(__init__.py:7)。
注释(3–6 行)解释了原因:带 --hf-jobs 时,训练任务要在任何环境配置 import 之前
就被拦截并提交到 HF Jobs 后退出——本模块是插件加载器唯一必经之路,是"任何安装顺序都抢不走"
的拦截点。这是一个把副作用写在 import 路径最前面的实战案例。

注册什么:register_mjlab_task 的五个参数

每个任务调用一次 register_mjlab_task(从 mjlab.tasks.registry import,第 9 行),
以第一个任务为例(__init__.py:81-87):

train/play 双份配置是刻意的:训练开域随机化,play 关掉推搡(interval 缩短)便于肉眼观察。

文件共 18 个直接注册:Velocity Flat/Rough、VelStand、StandUp、SitStand、GroundPick、
BallKick、Rollers、Swizzle、RollerCrouch、RollerSlope、RollerStandUp、Spin、Roulade 各按
flat/rough(部分只有 flat)展开,全部共用同一个 MicroduckOnPolicyRunner。

MicroduckOnPolicyRunner:一个只修序列化的子类

第 13–23 行的 MicroduckOnPolicyRunner 继承 mjlab 的 VelocityOnPolicyRunner,唯一做的事:
resolve_symmetry_config 会把 _env(环境对象)原地塞进 train_cfg["algorithm"]["symmetry_cfg"],
与 PPO 内部共享同一个 dict;而 dump_yaml 要序列化这份配置时 MjSpec 不可 pickle。子类把
alg["symmetry_cfg"] 换成一个剔除 _env 的副本(20–23 行),不动 PPO 持有的原引用。
典型的"只差一行"的框架补丁写法。

表驱动批量注册:15 个 Backlash 变体

第 254–270 行的 _BACKLASH_TASKS 是一个 15 元组表,每项 (task_id, make_fn, make_kwargs, rl_cfg, robot_cfg),第 271–278 行一个 for 循环统一注册,task_id 在基础名里插 -Backlash。
make_backlash_variant(cfg, robot_cfg)(import 于第 78 行)给配置换上带齿隙的机器人模型;
三种机器人配置按任务家族分配(251–253 行):_BL_WALK(走路模型)、_BL_GROUNDCONTACT
(地面接触模型)、_BL_ROLLERS(轮子模型)。同一张表让"加一种齿隙变体"变成加一行。

你带走的收获

延伸

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