Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions docs/sphinx/source/en/2-user_guide/3-backends/2-motrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ Motrix is an optional backend installed through the `motrix` extra, which
delegates to `unisim-core[motrix]`: the runtime pin lives in UniSim's
`pyproject.toml`, and the adapter lives under `unisim.backend.motrix`.

Motrix is a CPU-authoritative packed HOST_BRIDGE backend. Issue #2054 restores
it to the tensor-only Manager runtime for exactly two canonical training
workloads:
Motrix is a CPU-authoritative packed HOST_BRIDGE backend. Issue #2054 restored
it to the tensor-only Manager runtime with these canonical training workloads:

```bash
uv run --extra motrix train --algo appo --task go2_joystick_flat --sim motrix
uv run --extra motrix train --algo sac --task g1_walk_flat --sim motrix
uv run --extra motrix train --algo flashsac --task g1_motion_tracking --sim motrix
```

Other Motrix owners remain out of scope and do not constitute production
support claims.
support claims. The Go2 APPO owner is restored as a configured training path;
its current evidence is bounded smoke training, not a performance benchmark.

The public tensor lifecycle exposes:

Expand All @@ -38,7 +39,7 @@ uv sync --extra motrix

## When To Use It

- The workload is one of the two canonical owners above.
- The workload is one of the canonical owners above.
- You need a CPU-authoritative packed HOST_BRIDGE comparison/reference path.
- The generated support matrix marks the entrypoint/task/backend combination as
configured or tested.
Expand Down
6 changes: 3 additions & 3 deletions docs/sphinx/source/en/5-reference/5-support_matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ This table is derived from UniSim's SDK-free public static inventory. It describ

| Entrypoint | Task owner | MuJoCo | Motrix | Drake | mjwarp | Newton | SuperDex | Genesis |
|------------|------------|---|---|---|---|---|---|---|
| PPO (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | - | Configured | - | - | Configured | - |
| PPO (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | Registered | Configured | - | - | Configured | - |
| PPO (torch) | `g1_walk_flat` (G1 walk flat) | Tested | Registered | - | Tested | Registered | - | Configured |
| PPO (torch) | `g1_motion_tracking` (G1 motion tracking) | Tested | Registered | - | Registered | Registered | - | Registered |
| APPO (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | - | Registered | - | - | Registered | - |
| APPO (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | Tested | Registered | - | - | Registered | - |
| APPO (torch) | `g1_walk_flat` (G1 walk flat) | Tested | Registered | - | Registered | Registered | - | Registered |
| APPO (torch) | `g1_motion_tracking` (G1 motion tracking) | Tested | Registered | - | Registered | Registered | - | Registered |
| SAC (torch) | `g1_walk_flat` (G1 walk flat) | Tested | Tested | - | Tested | Tested | - | Tested |
| SAC (torch) | `g1_motion_tracking` (G1 motion tracking) | Tested | Registered | - | Configured | Registered | - | Configured |
| FlashSAC (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | - | Registered | - | - | Registered | - |
| FlashSAC (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | Registered | Registered | - | - | Registered | - |
| FlashSAC (torch) | `g1_walk_flat` (G1 walk flat) | Tested | Registered | - | Configured | Registered | - | Registered |
| FlashSAC (torch) | `g1_motion_tracking` (G1 motion tracking) | Tested | Tested | - | Configured | Configured | - | Configured |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ Motrix 是一个可选后端,通过 `motrix` extra 安装。该 extra 委托
中,适配层位于 `unisim.backend.motrix` 下。

Motrix 是 CPU-authoritative packed HOST_BRIDGE 后端。issue #2054 将其恢复
进 tensor-only Manager runtime,但范围仅限两个 canonical workload:
进 tensor-only Manager runtime,当前包含这些 canonical workload:

```bash
uv run --extra motrix train --algo appo --task go2_joystick_flat --sim motrix
uv run --extra motrix train --algo sac --task g1_walk_flat --sim motrix
uv run --extra motrix train --algo flashsac --task g1_motion_tracking --sim motrix
```

其他 Motrix owner 仍不在支持范围内,也不构成生产支持声明。
Go2 APPO owner 是已恢复的 configured 训练路径;当前证据仅限 bounded smoke
training,不构成性能 benchmark。

public tensor lifecycle 提供:

Expand All @@ -35,7 +38,7 @@ uv sync --extra motrix

## 何时使用

- workload 是上述两个 canonical owner 之一。
- workload 是上述 canonical owner 之一。
- 需要 CPU-authoritative packed HOST_BRIDGE 对比/参考路径。
- 所生成的支持矩阵将你的 entrypoint/task/backend 组合标记为 configured 或 tested。

Expand Down
6 changes: 3 additions & 3 deletions docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ uv run scripts/generate_support_matrix.py --write

| Entrypoint | Task owner | MuJoCo | Motrix | Drake | mjwarp | Newton | SuperDex | Genesis |
|------------|------------|---|---|---|---|---|---|---|
| PPO (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | - | Configured | - | - | Configured | - |
| PPO (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | Registered | Configured | - | - | Configured | - |
| PPO (torch) | `g1_walk_flat` (G1 walk flat) | Tested | Registered | - | Tested | Registered | - | Configured |
| PPO (torch) | `g1_motion_tracking` (G1 motion tracking) | Tested | Registered | - | Registered | Registered | - | Registered |
| APPO (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | - | Registered | - | - | Registered | - |
| APPO (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | Tested | Registered | - | - | Registered | - |
| APPO (torch) | `g1_walk_flat` (G1 walk flat) | Tested | Registered | - | Registered | Registered | - | Registered |
| APPO (torch) | `g1_motion_tracking` (G1 motion tracking) | Tested | Registered | - | Registered | Registered | - | Registered |
| SAC (torch) | `g1_walk_flat` (G1 walk flat) | Tested | Tested | - | Tested | Tested | - | Tested |
| SAC (torch) | `g1_motion_tracking` (G1 motion tracking) | Tested | Registered | - | Configured | Registered | - | Configured |
| FlashSAC (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | - | Registered | - | - | Registered | - |
| FlashSAC (torch) | `go2_joystick_flat` (Go2 joystick) | Tested | Registered | Registered | - | - | Registered | - |
| FlashSAC (torch) | `g1_walk_flat` (G1 walk flat) | Tested | Registered | - | Configured | Registered | - | Registered |
| FlashSAC (torch) | `g1_motion_tracking` (G1 motion tracking) | Tested | Tested | - | Configured | Configured | - | Configured |

Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ newton = [
]
motrix = ["unisim-core[motrix]>=1.7.11"]
genesis = ["genesis-world==1.3.3"]
uni_rl = ["unilab-rl==1.4.6"]
uni_rl = ["unilab-rl==1.4.8"]
# Wheels are CPython 3.12/3.13 Linux x86_64 only; the marker keeps uv lock
# resolvable for the other required-environments.
superdex = [
Expand All @@ -117,7 +117,7 @@ superdex = [
[dependency-groups]
# Dev/CI exercises the APPO/off-policy/multi-GPU paths, so the optional
# unilab-rl runtime stays installed in the dev environment.
dev = ["pytest", "pytest-cov", "ruff", "mypy", "pyright>=1.1.408", "unilab-rl==1.4.6"]
dev = ["pytest", "pytest-cov", "ruff", "mypy", "pyright>=1.1.408", "unilab-rl==1.4.8"]

[[tool.uv.index]]
name = "r2-cu130"
Expand Down
21 changes: 21 additions & 0 deletions src/unilab/conf/appo/task/go2_joystick_flat/motrix.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# @package _global_
defaults:
- /task/go2_joystick_flat/base
- _self_

training:
task_name: Go2JoystickFlat
sim_backend: motrix
algo:
num_envs: 512
steps_per_env: 24
max_iterations: 180
env:
# Motrix's packed HOST_BRIDGE uses the canonical tensor selected-reset terms.
events:
reset_scene_to_default:
func: unilab.envs.mdp.reset_scene_to_default_tensor
reset_root_state_uniform:
func: unilab.envs.mdp.reset_root_state_uniform_tensor
# Motrix tensor selected reset does not support PD-gain randomization.
pd_gains: null
3 changes: 3 additions & 0 deletions src/unilab/scripts/train_appo.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ def build_appo_runner_kwargs(
nan_guard_cfg = resolve_nan_guard_cfg(cfg.training)
if nan_guard_cfg is not None:
runner_kwargs["nan_guard_cfg"] = nan_guard_cfg
from unilab.training.tensor_runtime_hooks import build_tensor_nan_guard_factory

runner_kwargs["nan_guard_factory"] = build_tensor_nan_guard_factory()
return runner_kwargs


Expand Down
1 change: 1 addition & 0 deletions src/unilab/tasks/locomotion/go2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

registry.register_env_config("Go2JoystickFlat", ManagerBasedRlEnvCfg)
registry.register_env("Go2JoystickFlat", make_manager_based_rl_env, sim_backend="mujoco")
registry.register_env("Go2JoystickFlat", make_manager_based_rl_env, sim_backend="motrix")
registry.register_env("Go2JoystickFlat", make_manager_based_rl_env, sim_backend="superdex")
registry.register_env("Go2JoystickFlat", make_manager_based_rl_env, sim_backend="drake")

Expand Down
1 change: 1 addition & 0 deletions tests/algos/test_appo_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def test_appo_runner_learn_two_iterations(env_name):
env_factory=registry_env_factory(env_name, "mujoco"),
env_cfg_overrides=env_cfg_overrides,
rl_cfg=cfg,
device="cpu",
num_envs=128,
steps_per_env=8,
)
Expand Down
21 changes: 20 additions & 1 deletion tests/envs/locomotion/go2/test_manager_based_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@
False,
id="appo-mujoco",
),
pytest.param(
"appo",
("task=go2_joystick_flat/motrix",),
"motrix",
0.25,
False,
True,
False,
id="appo-motrix",
),
pytest.param(
"flashsac",
("task=go2_joystick_flat/mujoco",),
Expand Down Expand Up @@ -228,7 +238,7 @@ def test_go2_flat_registry_is_manager_only() -> None:
assert bare_cfg.rewards == {}
assert registry.list_registered_envs()["Go2JoystickFlat"] == {
"config_factory": "ManagerBasedRlEnvCfg",
"available_backends": ["mujoco", "superdex", "drake"],
"available_backends": ["mujoco", "motrix", "superdex", "drake"],
}


Expand All @@ -255,6 +265,15 @@ def test_go2_flat_drake_owner_keeps_policy_io_and_disables_unsupported_dr() -> N
]


def test_go2_flat_motrix_owner_uses_tensor_reset_events() -> None:
registry.ensure_registries()
_, env_cfg, _ = _materialize("appo", ("task=go2_joystick_flat/motrix",))

assert env_cfg.events["reset_scene_to_default"].func is mdp.reset_scene_to_default_tensor
assert env_cfg.events["reset_root_state_uniform"].func is mdp.reset_root_state_uniform_tensor
assert env_cfg.events["pd_gains"] is None


@pytest.mark.parametrize(
("backend", "owner"),
(("mujoco", "task=go2_joystick_flat/mujoco"),),
Expand Down
4 changes: 3 additions & 1 deletion tests/scripts/test_support_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ def test_support_matrix_marks_go2_ppo_backends_as_tested():

assert row.cells["mujoco"].level == EvidenceLevel.TESTED
assert row.cells["mjwarp"].level == EvidenceLevel.MISSING
assert row.cells["motrix"].level is EvidenceLevel.MISSING
assert row.cells["motrix"].level is EvidenceLevel.REGISTERED
appo_row = _row("APPO (torch)", "go2_joystick_flat")
assert appo_row.cells["motrix"].level is EvidenceLevel.TESTED


def test_support_matrix_marks_validated_g1_mjwarp_entrypoints_as_tested():
Expand Down
30 changes: 30 additions & 0 deletions tests/scripts/test_train_script_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
"g1_motion_tracking/mujoco",
]

APPO_MOTRIX_SMOKE_TASKS = [
"go2_joystick_flat/motrix",
]

APPO_MOTION_SMOKE_TASKS = {
"g1_motion_tracking/mujoco",
}
Expand Down Expand Up @@ -97,6 +101,32 @@ def test_appo_task_configs_load(task, tmp_path):
assert result.returncode == 0, f"APPO {task} failed:\n{result.stderr}"


@pytest.mark.slow
@pytest.mark.parametrize("task", APPO_MOTRIX_SMOKE_TASKS)
def test_appo_motrix_task_configs_load(task, tmp_path):
"""APPO can complete a bounded Motrix training smoke."""
pytest.importorskip("motrixsim", reason="motrix extra not available")
result = subprocess.run(
[
sys.executable,
"src/unilab/scripts/train_appo.py",
f"task={task}",
"algo.num_envs=16",
"algo.steps_per_env=4",
"algo.max_iterations=1",
"algo.save_interval=100",
"training.no_play=true",
f"training.log_root={tmp_path}",
],
capture_output=True,
text=True,
timeout=180,
)
assert result.returncode == 0, f"APPO {task} failed:\n{result.stderr}"
checkpoints = list(tmp_path.glob("Go2JoystickFlat/*/model_1.pt"))
assert len(checkpoints) == 1, checkpoints


@pytest.mark.slow
@pytest.mark.parametrize(
("algo", "task"),
Expand Down
1 change: 1 addition & 0 deletions tests/tasks/test_go2_tensor_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ def test_go2_runtime_does_not_add_backend_registrations() -> None:
registry.ensure_registries()
assert registry.list_registered_envs()["Go2JoystickFlat"]["available_backends"] == [
"mujoco",
"motrix",
"superdex",
"drake",
]
Expand Down
10 changes: 5 additions & 5 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading