diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 1a953755..15700955 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -214,11 +214,18 @@ docker run --gpus all motphys/motrixlab:test scripts/view.py env=cartpole ### File: `pypi-publish.yml` -Publishes the `motrix-env-core`, `motrix-deploy`, and `motrix-rl` distributions -(the dependency closure of the public packages) to a Python package index. +Publishes six distributions to a Python package index: `motrix-env-core`, +`motrix-deploy`, `motrix-rl`, `motrix-rl-builtin`, `motrix-env-motrixsim`, and +`motrixlab`. The `motrixlab` workspace member is an integration package with a +thin, lazy `mxlab` CLI, distinct from the development-only root project `motrix-lab`. +Its five commands are `train`, `play`, `export-onnx`, `export-deploy`, and `deploy`. +Command implementations remain in `motrix_rl.commands` and `motrix_deploy.cli`. +It requires Python `>=3.10,<3.12` and pins all five component distributions to its own version. +It does not include the full development workspace, built-in tasks/robot assets, +SKRL/RSLRL providers, or deployment backend plugins. - **Release trigger**: publishing a GitHub Release whose `v`-prefixed tag matches the - workspace package version uploads all three packages to pypi.org. + workspace package version uploads all six packages to pypi.org. - **Manual trigger**: `workflow_dispatch` uploads to TestPyPI by default, or to pypi.org with `index=pypi`. Use a TestPyPI run to verify the full install closure before creating the production release. A manual formal-PyPI run has @@ -229,18 +236,39 @@ For production publication, the selected commit must be an ancestor of `stable` and the matching immutable tag must point exactly at that commit. Every workspace package must carry the same version before any distribution is built. A dedicated build job uploads one wheel per package as a workflow artifact, and one publishing -job per package then uploads them in dependency order (env-core → deploy → rl). -Existing immutable distributions are skipped during recovery, so a partial -failure can be retried without replacing an already-published package. - -Authentication uses PyPI Trusted Publishing (OIDC) — no API tokens are stored -in repository secrets. Before the first run, a maintainer must register a -pending publisher for each of the three project names on both pypi.org and -test.pypi.org, pointing at `Motphys/MotrixLab` with the workflow file -`pypi-publish.yml` and the matching job environment (`pypi-env-core`, -`pypi-deploy`, or `pypi-rl`). The distinct environments are required because -PyPI binds at most one project to a repository/workflow/environment -combination. +job per package then uploads them in dependency order: + +```text +env-core → deploy → rl → [rl-builtin, env-motrixsim] → motrixlab +``` + +The two bracketed jobs can run in parallel; the integration package waits for both. +Existing immutable distributions are skipped with `skip-existing: true` during +recovery, so a partial failure can be retried without replacing an +already-published package. Publishing is restricted to `Motphys/MotrixLab`, +and only publishing jobs receive `id-token: write`. + +Authentication uses PyPI Trusted Publishing (OIDC), without PyPI API-token +secrets. Before the first run, a maintainer must create the matching GitHub +environments and register Trusted Publishers separately on **both pypi.org and +test.pypi.org**, using owner `Motphys`, repository `MotrixLab`, and workflow +filename `pypi-publish.yml` (pending publishers for new projects): + +| Project | GitHub environment | +| --- | --- | +| `motrix-env-core` | `pypi-env-core` | +| `motrix-deploy` | `pypi-deploy` | +| `motrix-rl` | `pypi-rl` | +| `motrix-rl-builtin` | `pypi-rl-builtin` | +| `motrix-env-motrixsim` | `pypi-env-motrixsim` | +| `motrixlab` | `pypi-motrixlab` | + +The distinct environments are required because PyPI binds at most one project +to a repository/workflow/environment combination. These external registrations +and environment protections are not configured or verified by this repository +change. See the [release guide's clean installation verification](RELEASE.md#clean-installation-verification) +for testing all six TestPyPI wheels in a fresh Python 3.10/3.11 environment, +resolving third-party dependencies from public PyPI without mixing indexes. # Release Pipeline diff --git a/.github/workflows/RELEASE.md b/.github/workflows/RELEASE.md index 99a8fb79..d5d124d4 100644 --- a/.github/workflows/RELEASE.md +++ b/.github/workflows/RELEASE.md @@ -9,7 +9,7 @@ wheels. Docker publishing remains a separate manual operation. | Workflow | Purpose | Trigger | | --- | --- | --- | | `release.yml` | Bump workspace versions, open release PRs, tag `stable`, create GitHub Releases, and open stable-patch back-merge PRs | Manual dispatch and pushes to `main`/`stable` | -| `pypi-publish.yml` | Build and publish wheels for `motrix-env-core`, `motrix-deploy`, and `motrix-rl` | GitHub Release publication or manual dispatch | +| `pypi-publish.yml` | Build and publish wheels for `motrix-env-core`, `motrix-deploy`, `motrix-rl`, `motrix-rl-builtin`, `motrix-env-motrixsim`, and `motrixlab` | GitHub Release publication or manual dispatch | | `docker-build.yml` | Build and push the Docker image | Manual dispatch from `stable` | **Stable branch patch release** is the preferred name for a patch cut from @@ -25,15 +25,22 @@ not a separate version class. - **Pull requests: read and write** 3. Store the App client ID as the `RELEASE_APP_CLIENT_ID` repository variable and its private key as the `RELEASE_APP_PRIVATE_KEY` secret. -4. Register PyPI Trusted Publishers for all three publishable projects on both - pypi.org and test.pypi.org: +4. Create the six GitHub environments below and configure their protection + rules as appropriate. Register a Trusted Publisher for each project on both + **pypi.org and test.pypi.org** (use a pending publisher for a new project): - `motrix-env-core` with the environment `pypi-env-core` - `motrix-deploy` with the environment `pypi-deploy` - `motrix-rl` with the environment `pypi-rl` - - Use repository `Motphys/MotrixLab` and workflow `pypi-publish.yml`. The - distinct GitHub environments are required because PyPI binds at most one - project to a repository/workflow/environment combination. + - `motrix-rl-builtin` with the environment `pypi-rl-builtin` + - `motrix-env-motrixsim` with the environment `pypi-env-motrixsim` + - `motrixlab` with the environment `pypi-motrixlab` + + Use owner `Motphys`, repository `MotrixLab`, and workflow filename + `pypi-publish.yml`. The distinct GitHub environments are required because + PyPI binds at most one project to a repository/workflow/environment + combination. These registrations and environment settings are external + maintainer actions; committing this workflow does not configure or verify + them. No PyPI API token is needed. 5. For Docker publishing, configure `DOCKER_USERNAME` and `DOCKER_PASSWORD`. The workflows exchange the App credentials for a short-lived installation @@ -257,13 +264,28 @@ verifies that: - the release tag matches the workspace version; - every workspace package has the same version. -Only wheels are built. The three public distributions are published in -dependency order: +Only wheels are built. The six public distributions are published in this +order; builtin and the MotrixSim backend can publish in parallel after RL, +and the integration package waits for both: ```text motrix-env-core → motrix-deploy → motrix-rl + ├─ motrix-rl-builtin ──────┐ + └─ motrix-env-motrixsim ───┴─ motrixlab ``` +`motrixlab` is the integration workspace member, distinct from the development-only +root project `motrix-lab`. It requires Python `>=3.10,<3.12` and depends on +`motrix-env-core`, `motrix-deploy`, `motrix-rl`, `motrix-rl-builtin`, and +`motrix-env-motrixsim`, each pinned to the same version as the integration package. +Its `motrixlab` import namespace provides a thin, lazy dispatcher for the sole `mxlab` +CLI, with `train`, `play`, `export-onnx`, `export-deploy`, and `deploy` commands. +Command implementations remain in `motrix_rl.commands` and `motrix_deploy.cli`. +Its installation scope does not include built-in tasks/robot assets, SKRL/RSLRL providers, or +deployment backend plugins; use the source workspace for those components. +MotrixSim and other third-party dependencies are resolved from public PyPI, +not built by this workflow. + Publishing uses `skip-existing: true`: if one package job succeeds and a later job fails, re-running the failed path skips immutable distributions that are already present and publishes only the missing package. It never replaces a @@ -289,6 +311,71 @@ from `stable`, and the matching immutable `v*` tag must point exactly at that commit. Normal production publishing should still occur through the reviewed GitHub Release event. +### Clean installation verification + +After all six TestPyPI jobs succeed, test outside the checkout in a fresh +Python 3.10 or 3.11 virtual environment. Set `VERSION` to the exact version +from that run (including any beta suffix): + +```bash +VERSION=0.4.0b1 # Replace with the published version. +workdir="$(mktemp -d)" +cd "$workdir" +python3.10 -m venv .venv +. .venv/bin/activate +python -m pip install --upgrade pip +python -m pip download --no-deps --only-binary=:all: \ + --index-url https://test.pypi.org/simple/ --dest wheels \ + "motrix-env-core==$VERSION" "motrix-deploy==$VERSION" \ + "motrix-rl==$VERSION" "motrix-rl-builtin==$VERSION" \ + "motrix-env-motrixsim==$VERSION" "motrixlab==$VERSION" +python -m pip install --index-url https://pypi.org/simple/ wheels/*.whl +python -m pip check +python - <<'PY' +from importlib.metadata import version + +names = ( + "motrix-env-core", "motrix-deploy", "motrix-rl", + "motrix-rl-builtin", "motrix-env-motrixsim", "motrixlab", +) +versions = {name: version(name) for name in names} +assert len(set(versions.values())) == 1, versions +print(versions) +import motrix_env_core +import motrix_deploy +import motrix_rl +import motrix_rl_builtin +import motrix_env_motrixsim +from motrix_rl.frameworks import get_framework +from motrix_env_core.sim.registry import list_sim_backends, default_sim_backend_name + +# The builtin entry point registers the framework under its public name. +assert get_framework("motrix").name == "motrix" +assert "motrixsim" in list_sim_backends() +assert default_sim_backend_name() == "motrixsim" +PY +mxlab --help +mxlab train --help +mxlab play --help +mxlab export-onnx --help +mxlab export-deploy --help +mxlab deploy --help +``` + +Downloading the six exact wheels with `--no-deps` ensures these projects come +from TestPyPI; the subsequent installation resolves third-party dependencies +from PyPI. Do not use `--extra-index-url` to mix the two indexes, or an older +production package may mask a missing test artifact. This is an actual install +and import check, not a GPU simulation or training test. Record the platform, +Python version, commands, and results; repeat with Python 3.11 for both supported +interpreters. + +After production publication, use another fresh environment outside the +checkout and install `"motrixlab==$VERSION"` with +`python -m pip install --index-url https://pypi.org/simple/`, then repeat +`pip check` and the metadata/import checks above. Neither editable workspace +installs nor `--no-deps` installs validate the published dependency closure. + ## Automation and human gates | Stage | Automation | @@ -337,8 +424,8 @@ Before merging anything into `stable`: After publication: - [ ] Verify the GitHub Release and immutable tag. -- [ ] Verify all three Python publishing jobs succeeded. -- [ ] Install or inspect the published wheels. +- [ ] Verify all six Python publishing jobs succeeded. +- [ ] Run the clean published-wheel installation verification above. - [ ] Run Docker publishing manually if this release needs a new image. - [ ] For a stable branch patch release, review and merge the automatic `stable → main` back-merge PR. diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 5b3cf1d3..de1591c8 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -96,6 +96,9 @@ jobs: uv build --wheel motrix_env_core --out-dir dist/env-core uv build --wheel motrix_deploy --out-dir dist/deploy uv build --wheel motrix_rl --out-dir dist/rl + uv build --wheel motrix_rl_builtin --out-dir dist/rl-builtin + uv build --wheel motrix_env_motrixsim --out-dir dist/env-motrixsim + uv build --wheel motrixlab --out-dir dist/motrixlab - name: Upload distribution packages uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 @@ -109,7 +112,7 @@ jobs: needs: build if: github.repository == 'Motphys/MotrixLab' runs-on: ubuntu-latest - # Distinct GitHub environments keep the three Trusted Publisher registrations + # Distinct GitHub environments keep the six Trusted Publisher registrations # unique: PyPI binds at most one project to a repository/workflow/environment. environment: pypi-env-core timeout-minutes: 10 @@ -174,3 +177,72 @@ jobs: packages-dir: dist/rl repository-url: ${{ (github.event_name == 'release' || inputs.index == 'pypi') && env.PYPI_URL || env.TESTPYPI_URL }} skip-existing: true + + publish-rl-builtin: + name: Publish motrix-rl-builtin + needs: publish-rl + if: github.repository == 'Motphys/MotrixLab' + runs-on: ubuntu-latest + environment: pypi-rl-builtin + timeout-minutes: 10 + permissions: + contents: read + id-token: write # PyPI Trusted Publishing OIDC token. + steps: + - name: Download distribution packages + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + name: release-dists + path: dist/ + - name: Publish to the target index + uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 + with: + packages-dir: dist/rl-builtin + repository-url: ${{ (github.event_name == 'release' || inputs.index == 'pypi') && env.PYPI_URL || env.TESTPYPI_URL }} + skip-existing: true + + publish-env-motrixsim: + name: Publish motrix-env-motrixsim + needs: publish-rl + if: github.repository == 'Motphys/MotrixLab' + runs-on: ubuntu-latest + environment: pypi-env-motrixsim + timeout-minutes: 10 + permissions: + contents: read + id-token: write # PyPI Trusted Publishing OIDC token. + steps: + - name: Download distribution packages + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + name: release-dists + path: dist/ + - name: Publish to the target index + uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 + with: + packages-dir: dist/env-motrixsim + repository-url: ${{ (github.event_name == 'release' || inputs.index == 'pypi') && env.PYPI_URL || env.TESTPYPI_URL }} + skip-existing: true + + publish-motrixlab: + name: Publish motrixlab + needs: [publish-rl-builtin, publish-env-motrixsim] + if: github.repository == 'Motphys/MotrixLab' + runs-on: ubuntu-latest + environment: pypi-motrixlab + timeout-minutes: 10 + permissions: + contents: read + id-token: write # PyPI Trusted Publishing OIDC token. + steps: + - name: Download distribution packages + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + name: release-dists + path: dist/ + - name: Publish to the target index + uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 + with: + packages-dir: dist/motrixlab + repository-url: ${{ (github.event_name == 'release' || inputs.index == 'pypi') && env.PYPI_URL || env.TESTPYPI_URL }} + skip-existing: true diff --git a/AGENTS.md b/AGENTS.md index b6954a4f..34f5a4d0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,6 +11,7 @@ MotrixLab 是构建在 MotrixSim 仿真后端之上的强化学习框架,提 项目使用 UV workspace,包含以下 package: +- `motrixlab`:提供统一 CLI `mxlab` 与跨组件可视化的应用集成包,默认安装 core、deploy、RL、builtin provider 与 MotrixSim 环境后端 - `motrix_env_core`:backend 无关的环境框架、配置与机器人 registry - `motrix_env_motrixsim`:MotrixSim 仿真后端(SimBackend、scene compiler、renderer、torch frontend) - `motrix_env_mujoco`:仅用于编译的 MuJoCo scene 后端 @@ -26,7 +27,10 @@ MotrixLab 是构建在 MotrixSim 仿真后端之上的强化学习框架,提 - `motrix_deploy_unitree`:Unitree 硬件配置、sensor/actuation 接线与 SDK2 DDS 硬件后端插件 - `motrix_deploy_tasks`:具体部署任务实现 -`motrix_rl.commands.train` / `play` 提供安装后的 `mxtrain` / `mxplay` 入口,`scripts/` 保留可视化等工具。 +`motrixlab` 提供唯一的 `mxlab` 入口,在 `motrixlab.commands.view` 实现环境与机器人可视化,并在 `motrixlab.configs` 打包 `view.yaml`。 +`train`、`play`、`export-onnx`、`export-deploy` 分发到 `motrix_rl.commands`,`deploy` 分发到 `motrix_deploy.cli`; +组件命令实现与内部可调用 adapter 保持在各自 package 中,不提供独立模块 CLI。 +版本查询只使用 `mxlab --version`。环境与机器人可视化使用 `mxlab view`;`scripts/` 保留其他仓库辅助工具。 内置环境由环境 package 注册并通过项目 registry 暴露;simulator backend 通过项目 backend registry 选择, core package 不依赖任何具体 simulator 实现。 @@ -133,7 +137,7 @@ Python 方法,由 manager 运行时契约定义(`wiki/design/manager/runtime 项目使用 UV 管理依赖,默认 Python 3.10;不含 Unitree 硬件部署插件的仿真与训练也支持 Python 3.11。 Unitree 硬件部署插件与包含该插件的 `--all` 安装仍仅支持 Python 3.10;Unitree 机器人模型的仿真与训练不受此限制。 -可用的依赖组与 extras 见 `pyproject.toml`。 +根开发环境默认安装 `motrixlab`,提供 `mxlab` CLI。可用的依赖组与 extras 见 `pyproject.toml`。 完整开发环境(Python 3.10,全部 package、依赖组与 extras;`--gpu rocm` 切换 AMD wheel): @@ -163,20 +167,20 @@ CLI 用法与项目配置接入见 [motrix_rl/README.md](motrix_rl/README.md)。 SKRL(默认): ```bash -mxtrain task=cartpole/skrl.ppo +mxlab train task=cartpole/skrl.ppo ``` RSLRL: ```bash -mxtrain task=cartpole/rslrl.ppo +mxlab train task=cartpole/rslrl.ppo ``` 直接覆写框架运行时设置和类型化 RL 参数: ```bash -mxtrain task=cartpole/skrl.ppo num_envs=64 algo.agent.learning_rate=1e-3 -mxtrain task=cartpole/skrl.ppo logging.interval=20 checkpoint.interval=100 +mxlab train task=cartpole/skrl.ppo num_envs=64 algo.agent.learning_rate=1e-3 +mxlab train task=cartpole/skrl.ppo logging.interval=20 checkpoint.interval=100 ``` ### 环境可视化 @@ -184,37 +188,37 @@ mxtrain task=cartpole/skrl.ppo logging.interval=20 checkpoint.interval=100 不训练只查看环境: ```bash -python scripts/view.py env=cartpole +mxlab view env=cartpole ``` 查看内置机器人(不创建 RL 环境): ```bash -python scripts/view.py robot=g1-29dof +mxlab view robot=g1-29dof ``` ### 评估 ```bash -mxplay env=cartpole +mxlab play env=cartpole ``` 指定 policy 文件: ```bash -mxplay env=cartpole policy= +mxlab play env=cartpole policy= ``` ### ONNX 导出 ```bash -mxexport onnx run_dir= output=/tmp/policy.onnx +mxlab export-onnx run_dir= output=/tmp/policy.onnx ``` ### 部署 artifact 导出 ```bash -mxexport deploy run_dir= output=artifacts/policy.deploy +mxlab export-deploy run_dir= output=artifacts/policy.deploy ``` ### 渲染 @@ -222,7 +226,7 @@ mxexport deploy run_dir= output=artifacts/policy.deploy 训练时开启可视化: ```bash -mxtrain task=cartpole/skrl.ppo render=true +mxlab train task=cartpole/skrl.ppo render=true ``` ### TensorBoard @@ -274,4 +278,4 @@ prek run --all-files ## 备注 - JAX 与 PyTorch backend 均支持 CUDA。 -- MotrixSim package 使用内部 PyPI server。 +- MotrixSim(`motrixsim` / `motrixsim-core`)通过公开 PyPI 分发。 diff --git a/README.md b/README.md index d8729e06..43deb19c 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,13 @@ _Microduck locomotion policies trained with MotrixLab, rendered in MotrixRender ## 🚀 Quick Start +Choose how you want to use MotrixLab: + +- **Run built-in tasks or contribute to the framework**: follow the repository quick start below. See the [repository installation guide](https://motrixlab.readthedocs.io/en/latest/user_guide/getting_started/installation.html#installation-repository) for full setup and development options. +- **Use MotrixLab in your own project**: add `motrixlab` as a dependency with pip or uv. See [project dependency installation](https://motrixlab.readthedocs.io/en/latest/user_guide/getting_started/installation.html#installation-own-project) for commands, prerequisites, and GPU configuration. This path does not include repository tasks or robot assets. + +The following steps run a built-in task from the repository root. + ### Prerequisites | Requirement | Notes | @@ -92,13 +99,15 @@ powershell -ExecutionPolicy Bypass -File install.ps1 This auto-detects your GPU vendor (NVIDIA → CUDA, AMD → ROCm) and installs the runtime workspace packages with the matching PyTorch wheels, required SKRL Torch, and built-in FastSAC. Use `--gpu cuda|rocm` to override detection; `--rslrl` adds RSL-RL, while `--skrl-jax` adds the optional Linux-only SKRL JAX backend. `--skrl-torch` remains accepted as a compatibility flag because SKRL Torch is already required. Flags combine; see `sh install.sh --help`. +The root development environment installs `motrixlab` by default, providing the `mxlab` CLI. + ### 3. Train your first policy Activate the installed environment (Windows PowerShell: `.venv\Scripts\Activate.ps1`): ```bash source .venv/bin/activate -mxtrain task=microduck-walk-flat/motrix.fastsac play=true +mxlab train task=microduck-walk-flat/motrix.fastsac play=true ``` While training, the built-in dashboard shows live run progress, episode statistics, throughput, rewards, and system health: @@ -124,7 +133,7 @@ Training finishes in minutes: mean return and episode length typically converge Replay the latest trained policy without retraining (for example, after stopping training early with Ctrl+C): ```bash -mxplay env=microduck-walk-flat +mxlab play env=microduck-walk-flat ``` A trained microduck policy replayed in the viewer: @@ -142,7 +151,7 @@ MotrixLab ships 50+ built-in simulation environments spanning basic control, qua | g1-wbt-dance | Whole-body tracking (WBT) | `g1-wbt-dance` · `k1-wbt-freekick` · `g1-29dof-wbt-largebox` | ```bash -python scripts/view.py env=go2-walk-rough +mxlab view env=go2-walk-rough ``` See the [full environment gallery](https://motrixlab.readthedocs.io/en/latest/user_guide/envs/index.html) for all registered environments and their supported training algorithms. @@ -162,7 +171,7 @@ Seven reusable robot models are registered out of the box and can be combined in | microduck | `microduck` | Humanoid | 14 | ```bash -python scripts/view.py robot=go2 +mxlab view robot=go2 ``` Use the public configuration API to compose a model directly: @@ -182,6 +191,7 @@ MotrixLab is a [uv](https://docs.astral.sh/uv/) workspace with the following pac | Package | PyPI name | Description | | --- | --- | --- | +| **motrixlab** | `motrixlab` | Application integration with the unified `mxlab` CLI and environment/robot visualization | | **motrix_deploy** | `motrix-deploy` | Artifacts, control sessions, runtime contracts, and deployment CLI | | **motrix_deploy_mujoco** | `motrix-deploy-mujoco` | MuJoCo deployment backend plugin | | **motrix_deploy_motrixsim** | `motrix-deploy-motrixsim` | Native MotrixSim deployment backend plugin | diff --git a/README.zh-CN.md b/README.zh-CN.md index 8b5f624a..778d1ccd 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -52,6 +52,13 @@ _使用 MotrixLab 训练的 microduck 行走策略,由 MotrixRender 实时渲 ## 🚀 快速开始 +根据你的使用场景选择: + +- **运行内置任务或参与框架开发**:按照下方步骤在仓库中开始使用。完整安装与开发选项见[仓库安装说明](https://motrixlab.readthedocs.io/zh-cn/latest/user_guide/getting_started/installation.html#installation-repository)。 +- **在自己的项目中使用 MotrixLab**:通过 pip 或 uv 添加 `motrixlab` 依赖。命令、前置条件和 GPU 配置见[项目依赖安装说明](https://motrixlab.readthedocs.io/zh-cn/latest/user_guide/getting_started/installation.html#installation-own-project)。此方式不包含仓库内置任务和机器人资产。 + +以下步骤在仓库根目录中运行内置任务。 + ### 前置条件 | 要求 | 说明 | @@ -92,13 +99,15 @@ powershell -ExecutionPolicy Bypass -File install.ps1 脚本会自动探测 GPU 厂商(NVIDIA → CUDA,AMD → ROCm),安装运行环境所需的 workspace package、对应的 PyTorch wheel、必需的 SKRL Torch 和内置 FastSAC。可用 `--gpu cuda|rocm` 显式指定 GPU;`--rslrl` 追加 RSL-RL,`--skrl-jax` 追加可选的 Linux-only SKRL JAX 后端。由于 SKRL Torch 已是必需依赖,`--skrl-torch` 仍作为兼容参数接受。参数可以组合;详见 `sh install.sh --help`。 +根开发环境默认安装 `motrixlab`,提供 `mxlab` CLI。 + ### 3. 训练第一个策略 先激活安装好的环境(Windows PowerShell:`.venv\Scripts\Activate.ps1`): ```bash source .venv/bin/activate -mxtrain task=microduck-walk-flat/motrix.fastsac play=true +mxlab train task=microduck-walk-flat/motrix.fastsac play=true ``` 训练过程中,内置面板会实时显示运行进度、回合统计、吞吐、奖励与系统健康状态: @@ -124,7 +133,7 @@ microduck 的训练数分钟内即可完成:平均回报与回合长度通常 无需重新训练即可回放最近一次训练得到的策略(例如提前 Ctrl+C 中断训练之后): ```bash -mxplay env=microduck-walk-flat +mxlab play env=microduck-walk-flat ``` 训练好的 microduck 策略在查看器中的回放效果: @@ -142,7 +151,7 @@ MotrixLab 内置 50+ 个仿真环境,覆盖基础控制、四足、人形、 | g1-wbt-dance | 全身动作跟踪(WBT) | `g1-wbt-dance` · `k1-wbt-freekick` · `g1-29dof-wbt-largebox` | ```bash -python scripts/view.py env=go2-walk-rough +mxlab view env=go2-walk-rough ``` 完整环境列表与各环境支持的训练算法见[环境总览](https://motrixlab.readthedocs.io/zh-cn/latest/user_guide/envs/index.html)。 @@ -162,7 +171,7 @@ python scripts/view.py env=go2-walk-rough | microduck | `microduck` | 人形机器人 | 14 | ```bash -python scripts/view.py robot=go2 +mxlab view robot=go2 ``` 通过公共配置 API 直接构造模型,用于场景组合: @@ -182,6 +191,7 @@ MotrixLab 是一个 [uv](https://docs.astral.sh/uv/) workspace,包含以下 pa | Package | PyPI 名称 | 说明 | | --- | --- | --- | +| **motrixlab** | `motrixlab` | 提供统一 `mxlab` CLI 与环境/机器人可视化的应用集成包 | | **motrix_deploy** | `motrix-deploy` | artifact、控制会话、运行时契约与部署 CLI | | **motrix_deploy_mujoco** | `motrix-deploy-mujoco` | MuJoCo 部署 backend plugin | | **motrix_deploy_motrixsim** | `motrix-deploy-motrixsim` | 原生 MotrixSim 部署 backend plugin | diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index bd827b7d..0f83998e 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -16,7 +16,8 @@ services: count: all capabilities: [gpu] command: - - mxtrain + - mxlab + - train - task=${MOTRIX_ENV:-cartpole}/skrl.ppo - task.train_backend=${MOTRIX_TRAIN_BACKEND:-jax} - num_envs=${MOTRIX_NUM_ENVS:-2048} diff --git a/docs/scripts/generate_video.py b/docs/scripts/generate_video.py index f92e2ab0..58c04b56 100644 --- a/docs/scripts/generate_video.py +++ b/docs/scripts/generate_video.py @@ -95,7 +95,7 @@ def _default_train_command(env_name: str) -> str | None: config = candidates[sorted(candidates)[0]] if config is None: return None - return f"python -m motrix_rl.commands.train task={env_name}/{config.name.removesuffix('.yaml')}" + return f"mxlab train task={env_name}/{config.name.removesuffix('.yaml')}" def _recording_path(env_name: str, output: Path | None) -> Path: diff --git a/docs/source/en/user_guide/envs/ball_balance.md b/docs/source/en/user_guide/envs/ball_balance.md index 3c284320..6f10b348 100644 --- a/docs/source/en/user_guide/envs/ball_balance.md +++ b/docs/source/en/user_guide/envs/ball_balance.md @@ -19,19 +19,19 @@ The ball-balance task keeps the 14-DoF biped robot Microduck standing on a free Preview the environment without training: ```bash -python scripts/view.py env=microduck-ball-balance +mxlab view env=microduck-ball-balance ``` Train with the built-in Motrix FastSAC config (the only training config provided for this task; `num_envs=2048`, 20000 iterations): ```bash -mxtrain task=microduck-ball-balance/motrix.fastsac +mxlab train task=microduck-ball-balance/motrix.fastsac ``` Evaluate a trained policy: ```bash -mxplay env=microduck-ball-balance +mxlab play env=microduck-ball-balance ``` ## Action space diff --git a/docs/source/en/user_guide/envs/basic/acrobot.md b/docs/source/en/user_guide/envs/basic/acrobot.md index 6aabc51b..477c36d8 100644 --- a/docs/source/en/user_guide/envs/basic/acrobot.md +++ b/docs/source/en/user_guide/envs/basic/acrobot.md @@ -63,20 +63,20 @@ Order: `upper_arm_horizontal, lower_arm_horizontal, upper_arm_vertical, lower_ar ### 1. Environment Preview ```bash -python scripts/view.py env=acrobot +mxlab view env=acrobot ``` ### 2. Start Training ```bash # Train with default parameters -mxtrain task=acrobot/skrl.ppo +mxlab train task=acrobot/skrl.ppo # Customize parallel environments -mxtrain task=acrobot/skrl.ppo num_envs=1024 +mxlab train task=acrobot/skrl.ppo num_envs=1024 # Enable rendering during training -mxtrain task=acrobot/skrl.ppo render=true +mxlab train task=acrobot/skrl.ppo render=true ``` ### 3. View Training Progress @@ -89,10 +89,10 @@ tensorboard --logdir runs/acrobot ```bash # Auto-discover best policy (recommended) -mxplay env=acrobot +mxlab play env=acrobot # Manually specify a checkpoint from a metadata-backed run -mxplay env=acrobot policy=/path/to/run/checkpoints/policy-file +mxlab play env=acrobot policy=/path/to/run/checkpoints/policy-file ``` > **Tip**: Policies are auto-selected from `runs/acrobot/`. Use `policy=...` to select a checkpoint whose parent run contains `metadata.json`. diff --git a/docs/source/en/user_guide/envs/basic/cartpole.md b/docs/source/en/user_guide/envs/basic/cartpole.md index 8eef8aca..166a70b6 100644 --- a/docs/source/en/user_guide/envs/basic/cartpole.md +++ b/docs/source/en/user_guide/envs/basic/cartpole.md @@ -15,13 +15,13 @@ CartPole is a classic control task in reinforcement learning. The goal is to kee ### 1. Environment Preview ```bash -python scripts/view.py env=cartpole +mxlab view env=cartpole ``` ### 2. Start Training ```bash -mxtrain task=cartpole/skrl.ppo +mxlab train task=cartpole/skrl.ppo ``` ### 3. View Training Progress @@ -33,7 +33,7 @@ tensorboard --logdir runs/cartpole ### 4. Test Training Results ```bash -mxplay env=cartpole +mxlab play env=cartpole ``` > **Tip**: The system finds the latest metadata-backed run under `runs/cartpole/` and loads its `best_policy` artifact. Use `policy=...` to select another checkpoint from a metadata-backed run. diff --git a/docs/source/en/user_guide/envs/basic/pendulum.md b/docs/source/en/user_guide/envs/basic/pendulum.md index a05c7086..503bb2d3 100644 --- a/docs/source/en/user_guide/envs/basic/pendulum.md +++ b/docs/source/en/user_guide/envs/basic/pendulum.md @@ -62,20 +62,20 @@ Order: `cos(theta), sin(theta), angular velocity`. ### 1. Environment Preview ```bash -python scripts/view.py env=pendulum +mxlab view env=pendulum ``` ### 2. Start Training ```bash # Train with default parameters -mxtrain task=pendulum/skrl.ppo +mxlab train task=pendulum/skrl.ppo # Customize parallel environments -mxtrain task=pendulum/skrl.ppo num_envs=1024 +mxlab train task=pendulum/skrl.ppo num_envs=1024 # Enable rendering during training -mxtrain task=pendulum/skrl.ppo render=true +mxlab train task=pendulum/skrl.ppo render=true ``` ### 3. View Training Progress @@ -88,10 +88,10 @@ tensorboard --logdir runs/pendulum ```bash # Auto-discover best policy (recommended) -mxplay env=pendulum +mxlab play env=pendulum # Manually specify a checkpoint from a metadata-backed run -mxplay env=pendulum policy=/path/to/run/checkpoints/policy-file +mxlab play env=pendulum policy=/path/to/run/checkpoints/policy-file ``` > **Tip**: Policies are auto-selected from `runs/pendulum/`. Use `policy=...` to select a checkpoint whose parent run contains `metadata.json`. diff --git a/docs/source/en/user_guide/envs/basic/stewart.md b/docs/source/en/user_guide/envs/basic/stewart.md index 89eefac9..f6f0297e 100644 --- a/docs/source/en/user_guide/envs/basic/stewart.md +++ b/docs/source/en/user_guide/envs/basic/stewart.md @@ -156,15 +156,15 @@ An episode terminates when any of the following is true: ### 1. Environment Preview ```bash -python scripts/view.py env=stewart-static -python scripts/view.py env=stewart-disturb-xy +mxlab view env=stewart-static +mxlab view env=stewart-disturb-xy ``` ### 2. Start Training ```bash -mxtrain task=stewart-static/skrl.ppo -mxtrain task=stewart-disturb-xy/skrl.ppo +mxlab train task=stewart-static/skrl.ppo +mxlab train task=stewart-disturb-xy/skrl.ppo ``` ### Training Notes @@ -183,8 +183,8 @@ tensorboard --logdir runs/stewart-disturb-xy ### 4. Test Training Results ```bash -mxplay env=stewart-static -mxplay env=stewart-disturb-xy +mxlab play env=stewart-static +mxlab play env=stewart-disturb-xy ``` --- diff --git a/docs/source/en/user_guide/envs/dm_control/bring_ball.md b/docs/source/en/user_guide/envs/dm_control/bring_ball.md index ca64e70c..d8228060 100644 --- a/docs/source/en/user_guide/envs/dm_control/bring_ball.md +++ b/docs/source/en/user_guide/envs/dm_control/bring_ball.md @@ -137,13 +137,13 @@ Default weights (from `BringBallCfg`): ### 1. Environment Preview (random actions) ```bash -python scripts/view.py env=dm-manipulator-bring-ball +mxlab view env=dm-manipulator-bring-ball ``` ### 2. Start Training ```bash -mxtrain task=dm-manipulator-bring-ball/skrl.ppo.torch +mxlab train task=dm-manipulator-bring-ball/skrl.ppo.torch ``` ### 3. View Training Progress @@ -155,7 +155,7 @@ tensorboard --logdir runs/dm-manipulator-bring-ball ### 4. Test Training Results ```bash -mxplay env=dm-manipulator-bring-ball +mxlab play env=dm-manipulator-bring-ball ``` --- diff --git a/docs/source/en/user_guide/envs/dm_control/dm_cheetah.md b/docs/source/en/user_guide/envs/dm_control/dm_cheetah.md index c55439d9..a79a9e75 100644 --- a/docs/source/en/user_guide/envs/dm_control/dm_cheetah.md +++ b/docs/source/en/user_guide/envs/dm_control/dm_cheetah.md @@ -102,13 +102,13 @@ The cheetah's reward function consists of the following parts: ### 1. Environment Preview ```bash -python scripts/view.py env=dm-cheetah +mxlab view env=dm-cheetah ``` ### 2. Start Training ```bash -mxtrain task=dm-cheetah/skrl.ppo +mxlab train task=dm-cheetah/skrl.ppo ``` ### 3. View Training Progress @@ -120,7 +120,7 @@ tensorboard --logdir runs/dm-cheetah ### 4. Test Training Results ```bash -mxplay env=dm-cheetah +mxlab play env=dm-cheetah ``` --- diff --git a/docs/source/en/user_guide/envs/dm_control/dm_finger.md b/docs/source/en/user_guide/envs/dm_control/dm_finger.md index 4987e383..70665d55 100644 --- a/docs/source/en/user_guide/envs/dm_control/dm_finger.md +++ b/docs/source/en/user_guide/envs/dm_control/dm_finger.md @@ -131,29 +131,29 @@ If `NaN` appears in the observations ### 1. Environment Preview (random actions) ```bash -python scripts/view.py env=dm-finger-spin +mxlab view env=dm-finger-spin ``` ```bash -python scripts/view.py env=dm-finger-turn-easy +mxlab view env=dm-finger-turn-easy ``` ```bash -python scripts/view.py env=dm-finger-turn-hard +mxlab view env=dm-finger-turn-hard ``` ### 2. Start Training ```bash -mxtrain task=dm-finger-spin/skrl.ppo task.train_backend=torch +mxlab train task=dm-finger-spin/skrl.ppo task.train_backend=torch ``` ```bash -mxtrain task=dm-finger-turn-easy/skrl.ppo task.train_backend=torch +mxlab train task=dm-finger-turn-easy/skrl.ppo task.train_backend=torch ``` ```bash -mxtrain task=dm-finger-turn-hard/skrl.ppo task.train_backend=torch +mxlab train task=dm-finger-turn-hard/skrl.ppo task.train_backend=torch ``` ### 3. View Training Progress @@ -164,10 +164,10 @@ tensorboard --logdir runs/dm-finger-spin ### 4. Test Training Results -`mxplay` auto-discovers the latest metadata-backed run under `runs/{env-name}/` and loads its `best_policy` artifact. Use `policy=...` to select a checkpoint explicitly: +`mxlab play` auto-discovers the latest metadata-backed run under `runs/{env-name}/` and loads its `best_policy` artifact. Use `policy=...` to select a checkpoint explicitly: ```bash -mxplay env=dm-finger-turn-hard +mxlab play env=dm-finger-turn-hard ``` --- diff --git a/docs/source/en/user_guide/envs/dm_control/dm_hopper.md b/docs/source/en/user_guide/envs/dm_control/dm_hopper.md index eecfc3d3..1390aaa3 100644 --- a/docs/source/en/user_guide/envs/dm_control/dm_hopper.md +++ b/docs/source/en/user_guide/envs/dm_control/dm_hopper.md @@ -108,15 +108,15 @@ The Hopper reward consists of the following terms: ### 1. Environment Preview ```bash -python scripts/view.py env=dm-hopper-stand -python scripts/view.py env=dm-hopper-hop +mxlab view env=dm-hopper-stand +mxlab view env=dm-hopper-hop ``` ### 2. Start Training ```bash -mxtrain task=dm-hopper-stand/skrl.ppo -mxtrain task=dm-hopper-hop/skrl.ppo +mxlab train task=dm-hopper-stand/skrl.ppo +mxlab train task=dm-hopper-hop/skrl.ppo ``` ### 3. View Training Progress @@ -128,8 +128,8 @@ tensorboard --logdir runs/dm-hopper-stand ### 4. Test Training Results ```bash -mxplay env=dm-hopper-stand -mxplay env=dm-hopper-hop +mxlab play env=dm-hopper-stand +mxlab play env=dm-hopper-hop ``` --- diff --git a/docs/source/en/user_guide/envs/dm_control/dm_humanoid.md b/docs/source/en/user_guide/envs/dm_control/dm_humanoid.md index 194a95af..b9cf10d5 100644 --- a/docs/source/en/user_guide/envs/dm_control/dm_humanoid.md +++ b/docs/source/en/user_guide/envs/dm_control/dm_humanoid.md @@ -185,17 +185,17 @@ total_reward = posture_reward * speed_reward * energy_reward * gait_reward ### 1. Environment Preview ```bash -python scripts/view.py env=dm-humanoid-stand -python scripts/view.py env=dm-humanoid-walk -python scripts/view.py env=dm-humanoid-run +mxlab view env=dm-humanoid-stand +mxlab view env=dm-humanoid-walk +mxlab view env=dm-humanoid-run ``` ### 2. Start Training ```bash -mxtrain task=dm-humanoid-stand/skrl.ppo -mxtrain task=dm-humanoid-walk/skrl.ppo -mxtrain task=dm-humanoid-run/skrl.ppo +mxlab train task=dm-humanoid-stand/skrl.ppo +mxlab train task=dm-humanoid-walk/skrl.ppo +mxlab train task=dm-humanoid-run/skrl.ppo ``` ### 3. View Training Progress @@ -207,9 +207,9 @@ tensorboard --logdir runs/dm-humanoid-walk ### 4. Test Training Results ```bash -mxplay env=dm-humanoid-stand -mxplay env=dm-humanoid-walk -mxplay env=dm-humanoid-run +mxlab play env=dm-humanoid-stand +mxlab play env=dm-humanoid-walk +mxlab play env=dm-humanoid-run ``` --- diff --git a/docs/source/en/user_guide/envs/dm_control/dm_lqr.md b/docs/source/en/user_guide/envs/dm_control/dm_lqr.md index 1305c8d0..76ab6ca2 100644 --- a/docs/source/en/user_guide/envs/dm_control/dm_lqr.md +++ b/docs/source/en/user_guide/envs/dm_control/dm_lqr.md @@ -157,15 +157,15 @@ An episode terminates and resets when any of the following conditions is met: ### 1. Environment Preview ```bash -python scripts/view.py env=dm-lqr-2-1 -python scripts/view.py env=dm-lqr-6-2 +mxlab view env=dm-lqr-2-1 +mxlab view env=dm-lqr-6-2 ``` ### 2. Start Training ```bash -mxtrain task=dm-lqr-2-1/skrl.ppo -mxtrain task=dm-lqr-6-2/skrl.ppo +mxlab train task=dm-lqr-2-1/skrl.ppo +mxlab train task=dm-lqr-6-2/skrl.ppo ``` ### 3. View Training Progress @@ -178,8 +178,8 @@ tensorboard --logdir runs/dm-lqr-6-2 ### 4. Test Training Results ```bash -mxplay env=dm-lqr-2-1 -mxplay env=dm-lqr-6-2 +mxlab play env=dm-lqr-2-1 +mxlab play env=dm-lqr-6-2 ``` --- diff --git a/docs/source/en/user_guide/envs/dm_control/dm_point_mass.md b/docs/source/en/user_guide/envs/dm_control/dm_point_mass.md index 0b6eea61..9b0218f3 100644 --- a/docs/source/en/user_guide/envs/dm_control/dm_point_mass.md +++ b/docs/source/en/user_guide/envs/dm_control/dm_point_mass.md @@ -115,13 +115,13 @@ rwd = distance_reward + target_bonus + continuous_reward + path_reward - center_ ### 1. Environment Preview ```bash -python scripts/view.py env=point_mass +mxlab view env=point_mass ``` ### 2. Start Training ```bash -mxtrain task=point_mass/skrl.ppo +mxlab train task=point_mass/skrl.ppo ``` ### 3. View Training Progress @@ -133,7 +133,7 @@ tensorboard --logdir runs/point_mass ### 4. Test Training Results ```bash -mxplay env=point_mass +mxlab play env=point_mass ``` --- diff --git a/docs/source/en/user_guide/envs/dm_control/dm_quadruped.md b/docs/source/en/user_guide/envs/dm_control/dm_quadruped.md index 77ab8b7d..caf943e7 100644 --- a/docs/source/en/user_guide/envs/dm_control/dm_quadruped.md +++ b/docs/source/en/user_guide/envs/dm_control/dm_quadruped.md @@ -228,19 +228,19 @@ In addition, `fetch` uses a `stability` gate on torso uprightness and torso heig ### 1. Environment Preview ```bash -python scripts/view.py env=dm-quadruped-walk -python scripts/view.py env=dm-quadruped-run -python scripts/view.py env=dm-quadruped-escape -python scripts/view.py env=dm-quadruped-fetch +mxlab view env=dm-quadruped-walk +mxlab view env=dm-quadruped-run +mxlab view env=dm-quadruped-escape +mxlab view env=dm-quadruped-fetch ``` ### 2. Start Training ```bash -mxtrain task=dm-quadruped-walk/skrl.ppo -mxtrain task=dm-quadruped-run/skrl.ppo -mxtrain task=dm-quadruped-escape/skrl.ppo -mxtrain task=dm-quadruped-fetch/skrl.ppo +mxlab train task=dm-quadruped-walk/skrl.ppo +mxlab train task=dm-quadruped-run/skrl.ppo +mxlab train task=dm-quadruped-escape/skrl.ppo +mxlab train task=dm-quadruped-fetch/skrl.ppo ``` ### 3. View Training Progress @@ -255,10 +255,10 @@ tensorboard --logdir runs/dm-quadruped-fetch ### 4. Test Training Results ```bash -mxplay env=dm-quadruped-walk -mxplay env=dm-quadruped-run -mxplay env=dm-quadruped-escape -mxplay env=dm-quadruped-fetch +mxlab play env=dm-quadruped-walk +mxlab play env=dm-quadruped-run +mxlab play env=dm-quadruped-escape +mxlab play env=dm-quadruped-fetch ``` --- diff --git a/docs/source/en/user_guide/envs/dm_control/dm_reacher.md b/docs/source/en/user_guide/envs/dm_control/dm_reacher.md index 64cd3182..86eb79b6 100644 --- a/docs/source/en/user_guide/envs/dm_control/dm_reacher.md +++ b/docs/source/en/user_guide/envs/dm_control/dm_reacher.md @@ -102,13 +102,13 @@ terminated = True ### 1. Environment Preview ```bash -python scripts/view.py env=dm-reacher +mxlab view env=dm-reacher ``` ### 2. Start Training ```bash -mxtrain task=dm-reacher/skrl.ppo +mxlab train task=dm-reacher/skrl.ppo ``` ### 3. View Training Progress @@ -120,7 +120,7 @@ tensorboard --logdir runs/dm-reacher ### 4. Test Training Results ```bash -mxplay env=dm-reacher +mxlab play env=dm-reacher ``` ## Expected Training Results diff --git a/docs/source/en/user_guide/envs/dm_control/dm_walker.md b/docs/source/en/user_guide/envs/dm_control/dm_walker.md index c087a624..f72e1818 100644 --- a/docs/source/en/user_guide/envs/dm_control/dm_walker.md +++ b/docs/source/en/user_guide/envs/dm_control/dm_walker.md @@ -26,19 +26,19 @@ Walker2D is a 2D planar bipedal robot with multiple joints and actuators: 1. **dm-stander**: Static standing task (move_speed = 0.0) ```bash -mxtrain task=dm-stander/skrl.ppo +mxlab train task=dm-stander/skrl.ppo ``` 2. **dm-walker**: Walking task (move_speed = 1.0) ```bash -mxtrain task=dm-walker/skrl.ppo +mxlab train task=dm-walker/skrl.ppo ``` 3. **dm-runner**: Running task (move_speed = 5.0) ```bash -mxtrain task=dm-runner/skrl.ppo +mxlab train task=dm-runner/skrl.ppo ``` ## Quick Start @@ -46,17 +46,17 @@ mxtrain task=dm-runner/skrl.ppo ### 1. Environment Preview ```bash -python scripts/view.py env=dm-stander -python scripts/view.py env=dm-walker -python scripts/view.py env=dm-runner +mxlab view env=dm-stander +mxlab view env=dm-walker +mxlab view env=dm-runner ``` ### 2. Start Training ```bash -mxtrain task=dm-stander/skrl.ppo -mxtrain task=dm-walker/skrl.ppo -mxtrain task=dm-runner/skrl.ppo +mxlab train task=dm-stander/skrl.ppo +mxlab train task=dm-walker/skrl.ppo +mxlab train task=dm-runner/skrl.ppo ``` ### 3. View Training Progress @@ -68,9 +68,9 @@ tensorboard --logdir runs/dm-walker ### 4. Test Training Results ```bash -mxplay env=dm-stander -mxplay env=dm-walker -mxplay env=dm-runner +mxlab play env=dm-stander +mxlab play env=dm-walker +mxlab play env=dm-runner ``` ## Reward Function Design diff --git a/docs/source/en/user_guide/envs/humanoid_velocity_tracking.md b/docs/source/en/user_guide/envs/humanoid_velocity_tracking.md index 20fd428a..0a967f5d 100644 --- a/docs/source/en/user_guide/envs/humanoid_velocity_tracking.md +++ b/docs/source/en/user_guide/envs/humanoid_velocity_tracking.md @@ -93,16 +93,16 @@ weight and mean return may decrease; this is a change in reward scale rather tha Choose an environment ID and one of its training configs from the table, then replace `ENV_ID` and `TRAINING_CONFIG`: ```bash -python scripts/view.py env=ENV_ID num_envs=1 -mxtrain task=ENV_ID/TRAINING_CONFIG -mxplay env=ENV_ID num_envs=16 +mxlab view env=ENV_ID num_envs=1 +mxlab train task=ENV_ID/TRAINING_CONFIG +mxlab play env=ENV_ID num_envs=16 ``` For example, train the K1 uneven-terrain task with asynchronous FastSAC: ```bash -mxtrain task=k1-walk-rough/motrix.fastsac algo.asynchronous=true +mxlab train task=k1-walk-rough/motrix.fastsac algo.asynchronous=true ``` -`view.py` applies random actions and is intended for scene and model inspection. Use `mxplay` with a trained policy to +`mxlab view` applies random actions and is intended for scene and model inspection. Use `mxlab play` with a trained policy to inspect the learned gait. diff --git a/docs/source/en/user_guide/envs/humanoid_velocity_tracking/adding_robot.md b/docs/source/en/user_guide/envs/humanoid_velocity_tracking/adding_robot.md index 5f97edad..2eac7460 100644 --- a/docs/source/en/user_guide/envs/humanoid_velocity_tracking/adding_robot.md +++ b/docs/source/en/user_guide/envs/humanoid_velocity_tracking/adding_robot.md @@ -117,7 +117,7 @@ environment construction. Preview the robot and verify joint ordering, the default pose, PD parameters, sole sites, and collision-geom names: ```bash -python scripts/view.py robot= +mxlab view robot= ``` ## 4. Register the environment implementation @@ -164,11 +164,11 @@ dynamics and training behavior. Use this progression: ```bash -python scripts/view.py robot= -python scripts/view.py env=-walk-flat -python scripts/view.py env=-walk-terrain -mxtrain task=-walk-flat/motrix.fastsac -mxtrain task=-walk-flat/motrix.fastsac algo.asynchronous=false +mxlab view robot= +mxlab view env=-walk-flat +mxlab view env=-walk-terrain +mxlab train task=-walk-flat/motrix.fastsac +mxlab train task=-walk-flat/motrix.fastsac algo.asynchronous=false python -m pytest motrix_envs/tests/test_humanoid_walk.py -q python -m pytest motrix_rl/tests/test_task_configs.py -q ``` diff --git a/docs/source/en/user_guide/envs/index.md b/docs/source/en/user_guide/envs/index.md index 9885bbc4..e8efca7a 100644 --- a/docs/source/en/user_guide/envs/index.md +++ b/docs/source/en/user_guide/envs/index.md @@ -5,7 +5,7 @@ A MotrixLab Environment is a simulation task created through the Env Registry. I Preview an environment without starting training: ```bash -python scripts/view.py env= +mxlab view env= ``` ## Environment topics diff --git a/docs/source/en/user_guide/envs/manipulation/bounce_ball.md b/docs/source/en/user_guide/envs/manipulation/bounce_ball.md index 0b355cbb..ca77d80e 100644 --- a/docs/source/en/user_guide/envs/manipulation/bounce_ball.md +++ b/docs/source/en/user_guide/envs/manipulation/bounce_ball.md @@ -411,13 +411,13 @@ Target height for each environment is randomly sampled in [0.4, 0.6] m range to ### 1. Environment Preview ```bash -python scripts/view.py env=bounce_ball +mxlab view env=bounce_ball ``` ### 2. Start Training ```bash -mxtrain task=bounce_ball/skrl.ppo +mxlab train task=bounce_ball/skrl.ppo ``` ### 3. View Training Progress @@ -429,7 +429,7 @@ tensorboard --logdir runs/bounce_ball ### 4. Test Training Results ```bash -mxplay env=bounce_ball +mxlab play env=bounce_ball ``` --- diff --git a/docs/source/en/user_guide/envs/manipulation/franka_lift_cube.md b/docs/source/en/user_guide/envs/manipulation/franka_lift_cube.md index aac56c57..0e8bd7fb 100644 --- a/docs/source/en/user_guide/envs/manipulation/franka_lift_cube.md +++ b/docs/source/en/user_guide/envs/manipulation/franka_lift_cube.md @@ -233,13 +233,13 @@ Target position is randomly sampled in the following range: ### Training ```bash -mxtrain task=franka-lift-cube/skrl.ppo +mxlab train task=franka-lift-cube/skrl.ppo ``` ### Policy Evaluation ```bash -mxplay env=franka-lift-cube +mxlab play env=franka-lift-cube ``` ### TensorBoard diff --git a/docs/source/en/user_guide/envs/manipulation/franka_open_cabinet.md b/docs/source/en/user_guide/envs/manipulation/franka_open_cabinet.md index 73a953a1..c304f741 100644 --- a/docs/source/en/user_guide/envs/manipulation/franka_open_cabinet.md +++ b/docs/source/en/user_guide/envs/manipulation/franka_open_cabinet.md @@ -234,13 +234,13 @@ Cabinet is fixed on ground with drawer in closed state (joint position at 0). ### Training ```bash -mxtrain task=franka-open-cabinet/skrl.ppo +mxlab train task=franka-open-cabinet/skrl.ppo ``` ### Policy Evaluation ```bash -mxplay env=franka-open-cabinet +mxlab play env=franka-open-cabinet ``` ### TensorBoard diff --git a/docs/source/en/user_guide/envs/manipulation/rm65_insert_peg.md b/docs/source/en/user_guide/envs/manipulation/rm65_insert_peg.md index 7f3dc920..baa1f523 100644 --- a/docs/source/en/user_guide/envs/manipulation/rm65_insert_peg.md +++ b/docs/source/en/user_guide/envs/manipulation/rm65_insert_peg.md @@ -269,13 +269,13 @@ The task currently provides an Async FastSAC configuration with `2048` parallel ### Training ```bash -mxtrain task=rm65_insert_peg/motrix.fastsac +mxlab train task=rm65_insert_peg/motrix.fastsac ``` ### Policy Evaluation ```bash -mxplay env=rm65_insert_peg num_envs=16 +mxlab play env=rm65_insert_peg num_envs=16 ``` ### TensorBoard diff --git a/docs/source/en/user_guide/envs/manipulation/rm65_open_cabinet.md b/docs/source/en/user_guide/envs/manipulation/rm65_open_cabinet.md index 221a4821..2c01027a 100644 --- a/docs/source/en/user_guide/envs/manipulation/rm65_open_cabinet.md +++ b/docs/source/en/user_guide/envs/manipulation/rm65_open_cabinet.md @@ -241,13 +241,13 @@ In addition, the maximum episode length is `30s`. ### Training ```bash -mxtrain task=rm65-open-cabinet/skrl.ppo task.train_backend=torch +mxlab train task=rm65-open-cabinet/skrl.ppo task.train_backend=torch ``` ### Policy Evaluation ```bash -mxplay env=rm65-open-cabinet +mxlab play env=rm65-open-cabinet ``` ### TensorBoard diff --git a/docs/source/en/user_guide/envs/manipulation/shadow_hand_repose.md b/docs/source/en/user_guide/envs/manipulation/shadow_hand_repose.md index 94288533..64f888d4 100644 --- a/docs/source/en/user_guide/envs/manipulation/shadow_hand_repose.md +++ b/docs/source/en/user_guide/envs/manipulation/shadow_hand_repose.md @@ -308,19 +308,19 @@ The environment uses a consecutive success counter: ### Training ```bash -mxtrain task=shadow-hand-repose/skrl.ppo +mxlab train task=shadow-hand-repose/skrl.ppo ``` ### Policy Evaluation ```bash -mxplay env=shadow-hand-repose +mxlab play env=shadow-hand-repose ``` ### Environment Visualization ```bash -python scripts/view.py env=shadow-hand-repose +mxlab view env=shadow-hand-repose ``` ### TensorBoard diff --git a/docs/source/en/user_guide/envs/quadruped_locomotion/go1_rough_terrain.md b/docs/source/en/user_guide/envs/quadruped_locomotion/go1_rough_terrain.md index e7722504..554f99fe 100644 --- a/docs/source/en/user_guide/envs/quadruped_locomotion/go1_rough_terrain.md +++ b/docs/source/en/user_guide/envs/quadruped_locomotion/go1_rough_terrain.md @@ -26,7 +26,7 @@ horizontal linear-speed sum exceeds $10^8$. The default `20 s` limit produces tr physical parameters. ```bash -python scripts/view.py env=go1-stairs-terrain-walk -mxtrain task=go1-stairs-terrain-walk/skrl.ppo -mxplay env=go1-stairs-terrain-walk +mxlab view env=go1-stairs-terrain-walk +mxlab train task=go1-stairs-terrain-walk/skrl.ppo +mxlab play env=go1-stairs-terrain-walk ``` diff --git a/docs/source/en/user_guide/envs/quadruped_velocity_tracking.md b/docs/source/en/user_guide/envs/quadruped_velocity_tracking.md index 5152954d..ef8c7af7 100644 --- a/docs/source/en/user_guide/envs/quadruped_velocity_tracking.md +++ b/docs/source/en/user_guide/envs/quadruped_velocity_tracking.md @@ -114,16 +114,16 @@ sustained rough-terrain locomotion. Under the current training configs and hardw Choose an environment ID and one of its training configs from the table, then replace `ENV_ID` and `TRAINING_CONFIG`: ```bash -python scripts/view.py env=ENV_ID num_envs=1 -mxtrain task=ENV_ID/TRAINING_CONFIG -mxplay env=ENV_ID num_envs=16 +mxlab view env=ENV_ID num_envs=1 +mxlab train task=ENV_ID/TRAINING_CONFIG +mxlab play env=ENV_ID num_envs=16 ``` For example, train the Go2 rough-terrain task with RSL-RL PPO: ```bash -mxtrain task=go2-walk-rough/rslrl.ppo +mxlab train task=go2-walk-rough/rslrl.ppo ``` -`view.py` applies random actions and is intended for scene and model inspection. Use `mxplay` with a trained policy to +`mxlab view` applies random actions and is intended for scene and model inspection. Use `mxlab play` with a trained policy to inspect the learned gait. diff --git a/docs/source/en/user_guide/envs/quadruped_velocity_tracking/adding_robot.md b/docs/source/en/user_guide/envs/quadruped_velocity_tracking/adding_robot.md index f01e0bab..f5289ef6 100644 --- a/docs/source/en/user_guide/envs/quadruped_velocity_tracking/adding_robot.md +++ b/docs/source/en/user_guide/envs/quadruped_velocity_tracking/adding_robot.md @@ -68,7 +68,7 @@ rejected. Every actuator must target a joint and expose a valid control range. After registering the robot config, preview it independently: ```bash -python scripts/view.py robot= +mxlab view robot= ``` ## 2. Provide task sensors @@ -197,10 +197,10 @@ inherit the same robot's flat-ground recipe and override only `task.env`. Use this progression: ```bash -python scripts/view.py robot= -python scripts/view.py env=-walk-flat -python scripts/view.py env=-walk-rough -mxtrain task=-walk-flat/rslrl.ppo +mxlab view robot= +mxlab view env=-walk-flat +mxlab view env=-walk-rough +mxlab train task=-walk-flat/rslrl.ppo ``` During preview, inspect the default pose, action direction, all four foot contacts, foot-position reference frames, and diff --git a/docs/source/en/user_guide/envs/whole_body_tracking/adding_wbt_task.md b/docs/source/en/user_guide/envs/whole_body_tracking/adding_wbt_task.md index 480a57b9..70c51512 100644 --- a/docs/source/en/user_guide/envs/whole_body_tracking/adding_wbt_task.md +++ b/docs/source/en/user_guide/envs/whole_body_tracking/adding_wbt_task.md @@ -130,7 +130,7 @@ Task for the same robot first, and tune algorithm hyperparameters only after the Use a small smoke test for Hydra composition, registry creation, tensor shapes, and the training path: ```bash -mxtrain task=g1-wbt-dance1-subject1/motrix.fastsac \ +mxlab train task=g1-wbt-dance1-subject1/motrix.fastsac \ algo.asynchronous=true num_envs=64 algo.trainer.num_learning_iterations=100 ``` @@ -138,13 +138,13 @@ Check for missing motion, joint, or body names; systematic NaNs, joint-limit vio reset; and verify that `state.reward_terms` and `state.metrics` reach the logs. Then start the default training run: ```bash -mxtrain task=g1-wbt-dance1-subject1/motrix.fastsac algo.asynchronous=true +mxlab train task=g1-wbt-dance1-subject1/motrix.fastsac algo.asynchronous=true ``` After training creates a metadata-backed run, play the policy: ```bash -mxplay env=g1-wbt-dance1-subject1 num_envs=16 +mxlab play env=g1-wbt-dance1-subject1 num_envs=16 ``` Play mode starts at frame 0, disables reset noise and adaptive sampling, and restarts from the beginning at the clip end. A @@ -159,5 +159,5 @@ separate play environment is not required. - Small-scale observation, action, reward, terminated, and truncated shapes are correct. - Resets do not systematically produce NaNs, hard-limit violations, or immediate bad tracking. - Reward, termination, and adaptive-sampling metrics reach the logs. -- `mxplay` discovers the run and plays the policy from frame 0 through the complete clip. +- `mxlab play` discovers the run and plays the policy from frame 0 through the complete clip. - The new motion includes source and license information and is managed through Git LFS. diff --git a/docs/source/en/user_guide/envs/whole_body_tracking/index.md b/docs/source/en/user_guide/envs/whole_body_tracking/index.md index 40539578..97d4b264 100644 --- a/docs/source/en/user_guide/envs/whole_body_tracking/index.md +++ b/docs/source/en/user_guide/envs/whole_body_tracking/index.md @@ -165,20 +165,20 @@ Choose an environment ID and one of its training configs from the built-in task `TRAINING_CONFIG`: ```bash -mxtrain task=ENV_ID/TRAINING_CONFIG +mxlab train task=ENV_ID/TRAINING_CONFIG ``` For example, train the G1 dance-tracking task with asynchronous FastSAC: ```bash -mxtrain task=g1-wbt-dance/motrix.fastsac algo.asynchronous=true +mxlab train task=g1-wbt-dance/motrix.fastsac algo.asynchronous=true ``` The built-in configs use 2048 parallel environments and task-specific learning-iteration budgets. Use a small smoke test only to validate registry creation, tensor shapes, and the training entry point; it is not expected to produce a useful policy: ```bash -mxtrain task=g1-wbt-dance/motrix.fastsac \ +mxlab train task=g1-wbt-dance/motrix.fastsac \ algo.asynchronous=true num_envs=64 algo.trainer.num_learning_iterations=100 ``` @@ -189,10 +189,10 @@ adaptive-sampling statistics are written to `state.metrics`. See [Task Environme ### Play the policy ```bash -mxplay env=ENV_ID num_envs=16 +mxlab play env=ENV_ID num_envs=16 ``` -`mxplay` selects the best policy from the latest metadata-backed run for the environment. The WBT play config starts at +`mxlab play` selects the best policy from the latest metadata-backed run for the environment. The WBT play config starts at motion frame 0, disables reset noise and adaptive sampling, and removes the 10-second training time limit. At the clip end it restarts from frame 0. See [Training Artifacts: the runs Directory and Checkpoint Structure](../../tutorial/training/runs_and_checkpoints.md) for run and checkpoint selection. diff --git a/docs/source/en/user_guide/getting_started/container_deployment.md b/docs/source/en/user_guide/getting_started/container_deployment.md index 9a63ee54..62cec60f 100644 --- a/docs/source/en/user_guide/getting_started/container_deployment.md +++ b/docs/source/en/user_guide/getting_started/container_deployment.md @@ -98,7 +98,7 @@ If you only want to run the training container without using Docker Compose: docker run --gpus all \ -v $(pwd)/runs:/root/motrixlab/runs \ motphys/motrixlab:latest \ - mxtrain task=cartpole/skrl.ppo task.train_backend=jax num_envs=2048 + mxlab train task=cartpole/skrl.ppo task.train_backend=jax num_envs=2048 ``` ### Persisting Training Results diff --git a/docs/source/en/user_guide/getting_started/hello_motrixlab.md b/docs/source/en/user_guide/getting_started/hello_motrixlab.md index 62b05c79..78eb7261 100644 --- a/docs/source/en/user_guide/getting_started/hello_motrixlab.md +++ b/docs/source/en/user_guide/getting_started/hello_motrixlab.md @@ -2,14 +2,16 @@ This tutorial demonstrates the MotrixLab workflow through a simple example - loading and training a cartpole environment: -Complete [installation](installation.md) first, then activate the environment with `source .venv/bin/activate` (Windows PowerShell: `.venv\Scripts\Activate.ps1`). +This tutorial uses the repository's built-in cartpole task. First complete {ref}`Install in the MotrixLab repository `, then activate the environment with `source .venv/bin/activate` (Windows PowerShell: `.venv\Scripts\Activate.ps1`). Run all commands below from the repository root. + +After installation, use the unified `mxlab` command to train and evaluate policies. Use `mxlab --help` to list commands and `mxlab --version` to check the version. ## Environment Preview -We provide a simple script to visualize an environment without executing any training. This helps you verify that system dependencies are correctly configured: +Use `mxlab view` to visualize an environment without executing any training. This helps you verify that system dependencies are correctly configured: ```bash -python scripts/view.py env=cartpole +mxlab view env=cartpole ``` This will open a visualization window showing the cartpole physics simulation environment with random actions for demonstration. @@ -19,7 +21,7 @@ This will open a visualization window showing the cartpole physics simulation en Start training the cartpole balancing task: ```bash -mxtrain task=cartpole/skrl.ppo +mxlab train task=cartpole/skrl.ppo ``` The training process will automatically: @@ -38,7 +40,7 @@ Training results will be saved in the `runs/cartpole/` directory, including: If you want to observe the model's learning process during training, you can enable visualization rendering: ```bash -mxtrain task=cartpole/skrl.ppo render=true +mxlab train task=cartpole/skrl.ppo render=true ``` ### 🎮 Interactive Rendering Control @@ -67,10 +69,10 @@ After training is complete, test the trained policy: ```bash # Automatically find best policy for testing (recommended) -mxplay env=cartpole +mxlab play env=cartpole # Manually specify a checkpoint from a metadata-backed run -mxplay env=cartpole policy=/path/to/run/checkpoints/policy-file +mxlab play env=cartpole policy=/path/to/run/checkpoints/policy-file ``` > **Tip**: The system automatically finds the latest run and its best policy under `runs/cartpole/`. A manually selected checkpoint must belong to a run containing `metadata.json` and `task_config.yaml`. diff --git a/docs/source/en/user_guide/getting_started/installation.md b/docs/source/en/user_guide/getting_started/installation.md index b781febf..ffe16be6 100644 --- a/docs/source/en/user_guide/getting_started/installation.md +++ b/docs/source/en/user_guide/getting_started/installation.md @@ -1,110 +1,233 @@ -# Installation Environment +# Installation -This document will guide you through the installation and configuration of MotrixLab. Please read the system requirements carefully and choose the appropriate installation method based on your use case. +MotrixLab supports two ways of working. Choose the installation path that matches whether you want to run existing tasks in the repository or use the framework in your own project. -## System Requirements +| Use case | Installation path | What you get | +| -------- | ----------------- | ------------ | +| Run built-in tasks, modify tasks, or contribute to the framework | [Install in the MotrixLab repository](#installation-repository) | Repository tasks, configurations, and assets, plus the framework components and plugins selected by the installer | +| Implement environments and organize training configurations in your own project | [Install in your own project](#installation-own-project) | The `motrixlab` integration package and its default components; your project manages its own code, configurations, and assets | -- **Python Version**: {bdg-danger-line}`3.10.* / 3.11.*` +Both paths provide `mxlab` for training, playback, visualization, export, and deployment. Import Python APIs from their component packages; they are not re-exported through `motrixlab`. - Python 3.10 is the default. +## System requirements - | Python Version | Support Status | - | :------------: | :------------: | - | ≤ 3.9 | ❌ | - | 3.10 | ✅ | - | 3.11 | ✅ | - | ≥ 3.12 | ❌ | +- **Python**: 3.10 or 3.11. The repository defaults to Python 3.10. The Unitree hardware deployment plugin and the full development environment that includes it require Python 3.10. Simulation and training with Unitree robot models are not subject to this restriction. +- **Operating system and architecture**: Linux x86_64 or Windows x86_64. GPU runtime support also depends on your drivers and the selected PyTorch build. +- **Package manager**: Repository installation uses [uv](https://docs.astral.sh/uv/getting-started/installation/). Your own project can use pip or uv. +- **Git and Git LFS**: Required only for repository installation, to obtain source code and assets such as robot meshes and motion data. - Unitree hardware deployment and `--all` require Python 3.10; simulation/training with Unitree robot models can use Python 3.11. +(installation-repository)= +## Install in the MotrixLab repository -- **Package Manager**: {bdg-danger-line}`UV` +Choose this path to run the built-in tasks described in the documentation, modify repository environments and configurations, or contribute to the framework. The installer selects workspace packages and GPU dependencies for you; there is no need to install each component separately. - This project uses UV as the exclusive package management tool to provide fast, reproducible dependency management environment. For UV installation, please refer to the [official documentation](https://docs.astral.sh/uv/getting-started/installation/). +### Get the source code and assets -- **System and Architecture**: +Install Git LFS first, then clone the repository: - - {bdg-danger-line}`Windows(x86_64)` - - {bdg-danger-line}`Linux(x86_64)` +```bash +git clone https://github.com/Motphys/MotrixLab.git +cd MotrixLab +git lfs install +git lfs pull +``` + +The installer also checks for Git LFS and pulls the assets. If Git LFS is missing, install it first; repository LFS pointer files are not usable model or motion-data files. - ```{note} - Features supported on each platform: +### Install the runtime environment - | Operating System | CPU Simulation | Interactive Viewer | - | :--------------: | :------------: | :----------------: | - | Linux | ✅ | ✅ | - | Windows | ✅ | ✅ | - ``` +Linux: -## Installation Steps +```bash +sh install.sh +# Use Python 3.11 without the Unitree hardware deployment plugin: +sh install.sh --python 3.11 +``` + +Windows PowerShell: + +```powershell +.\install.ps1 +# Use Python 3.11: +.\install.ps1 --python 3.11 +``` -### Clone Project Repository +If the PowerShell execution policy blocks the script, use: + +```powershell +powershell -ExecutionPolicy Bypass -File install.ps1 +``` + +The default runtime environment includes `motrixlab`, repository tasks and the required plugins, the required SKRL Torch provider, and built-in FastSAC. The installer detects NVIDIA / AMD GPUs and selects the corresponding CUDA / ROCm PyTorch wheels. It falls back to the CUDA profile when detection is unavailable. ROCm installation is supported only on Linux. + +Linux installation enables Intel TBB by default for Numba parallel kernels. Development tools, documentation tools, RSL-RL, and SKRL JAX are not all enabled in the default runtime environment; add them using the options below when needed. + +### Activate the environment and check the installation + +Linux: ```bash -git clone https://github.com/Motphys/MotrixLab.git -cd MotrixLab +source .venv/bin/activate ``` -### Install the Runtime Environment +Windows PowerShell: -Install the runtime environment from the repository root (on Windows, run `install.ps1` in PowerShell; if the execution policy blocks it, use `powershell -ExecutionPolicy Bypass -File install.ps1`): +```powershell +.venv\Scripts\Activate.ps1 +``` + +Check the unified command entry point: ```bash -sh install.sh # Python 3.10 by default -# Python 3.11 runtime without the Unitree hardware deployment plugin: -sh install.sh --python 3.11 +mxlab --version +mxlab --help ``` -This auto-detects your GPU vendor (NVIDIA → CUDA, AMD → ROCm) and installs the runtime workspace packages, the matching PyTorch wheels, the required SKRL Torch provider, and the built-in FastSAC algorithm. On Linux, `install.sh` also installs Intel TBB by default for Numba parallel kernels, including with `--all` and either GPU profile. Other platforms do not enable TBB by default for runtime installation. Development tools, docs, RSL-RL, SKRL JAX, and other optional extras are not installed unless requested. +Then follow [Your first MotrixLab program](hello_motrixlab.md) to run a built-in task. + +```{important} +In this repository, avoid bare `uv sync` or `uv run`. CUDA and ROCm are selected through mutually exclusive extras; a bare command may switch to the default PyPI dependency branch and replace your current GPU environment. + +Run `mxlab` directly in the activated environment, or use `uv run --no-sync mxlab ...`. To change dependencies, rerun the installer with the options you need. The installer recomputes the dependency set each time rather than permanently accumulating previously selected plugins. + +This restriction applies to GPU configuration in the MotrixLab source workspace, not to every uv project. +``` -### Activate the Environment +### Development environment and optional dependencies -After installing, activate the environment before running commands (Windows PowerShell: -`.venv\Scripts\Activate.ps1`): +To contribute to the framework, run the full test suite, or build the documentation, install the full development environment: ```bash -source .venv/bin/activate +sh install.sh --all +``` + +`--all` includes the Unitree hardware plugin and therefore requires Python 3.10. It enables all workspace packages, development and test dependencies, and supported training backends and documentation tools. The ROCm profile skips CUDA-only extras such as SKRL JAX. + +You can also add only the capabilities you currently need: + +```bash +sh install.sh --rslrl +sh install.sh --skrl-jax +sh install.sh --docs ``` +When reinstalling, include any other options you still need in the same invocation. + +| Option | Description | +| ------ | ----------- | +| `--python 3.10` / `--python 3.11` | Select Python; defaults to 3.10, and `--all` requires 3.10 | +| `--gpu cuda` / `--gpu rocm` | Select a GPU dependency profile explicitly, overriding detection; ROCm is Linux-only | +| `--gpu hygon` | Linux Hygon DCU environment; preserve the external DTK accelerator stack and provide compatible Torch yourself; do not combine with `--skrl-jax` | +| `--rslrl` | Add the RSL-RL provider | +| `--skrl-jax` | Add the SKRL JAX runtime, Linux-only | +| `--skrl-torch` | Compatibility option; SKRL Torch is already a required repository dependency | +| `--tbb` | Enable Intel TBB explicitly; already enabled by the Linux installer | +| `--docs` | Add documentation tools | +| `--all` | Full development environment, Python 3.10 only | +| `--help` | Show the full installer option reference | + +On Windows, use `install.ps1` and its `--help` option to check the supported options. + +(installation-own-project)= +## Install in your own project + +This path does not require cloning the MotrixLab repository. Install `motrixlab` as a project dependency and provide your environment implementations, task configurations, and assets in your own project. + +### Default installation scope + +`motrixlab` provides the unified `mxlab` CLI and installs the following components from the same release: + +| Component | Capability | +| --------- | ---------- | +| `motrix-env-core` | Backend-neutral environment framework, configuration, and registry | +| `motrix-env-motrixsim` | MotrixSim environment backend; installs `motrixsim` as a dependency | +| `motrix-rl` | Control plane for training, playback, and export | +| `motrix-rl-builtin` | Built-in FastSAC provider | +| `motrix-deploy` | Deployment artifacts and runtime framework | + ```{note} -Avoid bare `uv sync` / `uv run`: the CUDA and ROCm wheels are selected by mutually exclusive -extras, so a bare command resolves the default PyPI fork and can replace the selected environment. -The installer computes the requested dependency set rather than appending forever; re-running it -with different options may remove packages no longer selected. Run commands from the activated -environment, or pass `--no-sync` to one-off `uv run` calls. +`motrixlab` does not include repository tasks, robot assets, SKRL / RSL-RL providers, or concrete deployment backend plugins. Installing it does not make repository examples such as `cartpole` available automatically. + +Use the repository installation path above if you want to run those tasks directly. In your own project, supply task configurations and install additional components as your use case requires. ``` -## Development Environment +The commands below install versions published on PyPI. A new version becomes installable only after publication. If only beta releases are available, use the prerelease options shown below. + +### Use pip -The runtime environment only contains what training and deployment need. To contribute to the -project (run tests, modify code, build the docs), install the full development environment: +Create an isolated environment in your project directory: ```bash -sh install.sh --all +python3.10 -m venv .venv +source .venv/bin/activate +python -m pip install motrixlab +``` + +On Windows PowerShell, create the environment with `py -3.10 -m venv .venv`, then activate it with `.venv\Scripts\Activate.ps1`. You can also choose Python 3.11. + +To allow beta releases: + +```bash +python -m pip install --pre motrixlab +``` + +Record the selected version in your project's dependency file rather than changing only the local environment without recording the dependency. + +### Use uv + +For an existing uv project, follow the steps below from the project directory. If you have not created a project yet, initialize one first: + +```bash +uv init --python 3.10 my-robot-project +cd my-robot-project +``` + +Before adding the dependency, make sure your project's `pyproject.toml` restricts Python support to versions supported by the integration package. For example: + +```toml +[project] +requires-python = ">=3.10,<3.12" +``` + +`uv init --python 3.10` selects an interpreter, but the initialized Python requirement may still have no upper bound. uv resolves dependencies for the entire Python range declared by your project. Selecting a Python 3.10 interpreter is not sufficient if the project still declares support for Python 3.12 and later. + +Then add the dependency: + +```bash +uv add motrixlab +``` + +To allow beta releases: + +```bash +uv add --prerelease allow motrixlab +``` + +`uv add` updates your project's `pyproject.toml` and `uv.lock`. Use `uv sync` to restore the environment later, and `uv run` to run project commands: + +```bash +uv run mxlab --version +uv run mxlab --help +``` + +### Check commands and configure the GPU + +With pip, run commands in the activated environment. With uv, prefix them with `uv run`: + +```bash +mxlab --help +mxlab train --help +mxlab play --help +mxlab view --help +mxlab export-onnx --help +mxlab export-deploy --help +mxlab deploy --help ``` -`--all` includes the Unitree hardware deployment plugin, so it requires Python 3.10 and cannot be combined with `--python 3.11`. -It enables everything in one go: the dev toolchain, test dependencies, all training backends -(SKRL Torch is required; `--skrl-jax` and `--rslrl` add the optional backends), and the docs tooling. -On ROCm, CUDA-only extras such as SKRL JAX are skipped. You can also select individual additions, -e.g. `sh install.sh --docs` adds only the docs toolchain. - -## Option Reference - -The runtime installs the packages required for training and deployment, including the required SKRL -Torch and builtin providers; it does not install every optional workspace plugin. `--all` installs all -workspace packages and supported development extras. Backend flags select or add to the requested set: - -| Option | Values | Description | -| ------ | ------ | ----------- | -| `--python` | `3.10`
`3.11` | Select Python; defaults to `3.10`, with `3.11` for runtime installs without the Unitree hardware deployment plugin | -| `--all` | — | Full development environment including Unitree; Python 3.10 only (dev toolchain, test dependencies, all training backends, and docs tooling) | -| *(none)* | — | Runtime environment; the GPU vendor is auto-detected (NVIDIA → CUDA, AMD → ROCm; CUDA as fallback when detection is impossible) | -| `--gpu` | `cuda`
`rocm` | Select the torch wheel flavor explicitly, overriding auto-detection | -| `--skrl-torch` | — | Compatibility flag; SKRL Torch is already required by the root package | -| `--skrl-jax` | — | Add SKRL on JAX backend, Linux only | -| `--rslrl` | — | Add RSL-RL on PyTorch backend while retaining required SKRL | -| `--tbb` | — | Explicitly install Intel TBB for Numba parallel kernels; already enabled by default in `install.sh` on Linux, auto-activates once installed | -| `--docs` | — | Add the toolchain (sphinx) needed to build the documentation locally | -| `-h`, `--help` | — | Show the help message | - -Run `sh install.sh --help` for the full option reference. +These commands check the CLI and configuration help; they do not execute simulation, training, or hardware deployment. + +Unlike the repository installer, `pip install motrixlab` and `uv add motrixlab` **do not detect your GPU vendor or select a dedicated wheel index automatically**. Default installation resolves PyTorch from the package index according to component dependencies. Your own project must manage CUDA / ROCm wheels, drivers, and related environment configuration. + +Follow the [official PyTorch installation guide](https://pytorch.org/get-started/locally/) to select a build for your hardware. With uv, declare the appropriate version constraints and index sources in your own project. Do not assume that `tool.uv.sources` settings in a dependency's repository are inherited by your project. Successful installation or a working `mxlab --help` does not establish that the GPU runtime is available. + +After installation, follow [Writing DirectEnv Environments](../tutorial/building_envs/direct_env.md) to create and register an environment, then organize your training configuration with [Task Configuration and CLI Overrides](../tutorial/training/task_config.md). Before running a Task, install its RL provider: the default integration package includes the FastSAC provider; SKRL PPO and RSL-RL PPO additionally require `motrix-rl-skrl` and `motrix-rl-rslrl`, respectively. diff --git a/docs/source/en/user_guide/robots.md b/docs/source/en/user_guide/robots.md index 32d19890..5ab4e687 100644 --- a/docs/source/en/user_guide/robots.md +++ b/docs/source/en/user_guide/robots.md @@ -21,10 +21,10 @@ ## Preview a robot -Use `view.py` to inspect a registered robot in its default pose without creating an RL environment: +Use `mxlab view` to inspect a registered robot in its default pose without creating an RL environment: ```bash -python scripts/view.py robot=go2 +mxlab view robot=go2 ``` Robot view mode builds a static standard scene. It does not sample actions or run a physics rollout. @@ -197,7 +197,7 @@ my_robot = "my_robot_package.registration:register" Construct the config through the registry and preview it before using it in a task: ```bash -python scripts/view.py robot=my-robot +mxlab view robot=my-robot python -m pytest motrix_envs/tests/test_robot_cfg.py -q ``` diff --git a/docs/source/en/user_guide/tutorial/advanced/custom_training_backend.md b/docs/source/en/user_guide/tutorial/advanced/custom_training_backend.md index efad55b3..2d76f3c8 100644 --- a/docs/source/en/user_guide/tutorial/advanced/custom_training_backend.md +++ b/docs/source/en/user_guide/tutorial/advanced/custom_training_backend.md @@ -200,7 +200,7 @@ The Task's `rllib`, `algo`, and `train_backend` values must match the framework If the backend is registered on the startup path, use the shared CLI: ```bash -mxtrain task=cartpole/myrl.ppo +mxlab train task=cartpole/myrl.ppo ``` For an external experiment package, use its Hydra config root and import the backend registration module before entering the training function. No separate Python Task registry is required. diff --git a/docs/source/en/user_guide/tutorial/advanced/export_onnx.md b/docs/source/en/user_guide/tutorial/advanced/export_onnx.md index 41208e5d..74ddcf3c 100644 --- a/docs/source/en/user_guide/tutorial/advanced/export_onnx.md +++ b/docs/source/en/user_guide/tutorial/advanced/export_onnx.md @@ -24,9 +24,9 @@ of the default runtime environment installed by `sh install.sh` (see ## Export the Model -Activate the installed environment and run `mxexport onnx` (or `python -m motrix_rl.commands.export onnx`). -`mxexport` requires an explicit `onnx` or `deploy` subcommand; there is no default. -No `task` selection or registration import is needed: export restores the policy from the saved run without creating an environment. Install the RL provider used by the run; environment-provider discovery is a separate registry concern. +Activate the installed environment and run `mxlab export-onnx` to export a standalone ONNX policy. +Use `mxlab export-deploy` instead to create a deployment artifact. +No `task` selection or registration import is needed: export restores the policy from the saved run without creating an environment. Install the RL provider used by the run before exporting. The command uses the current directory's `./configs` when present, or an explicit `--config-dir `; project files take precedence, with missing files falling back to `motrix_rl.configs`, which includes `export_onnx.yaml`. No repository checkout is required. Relative run and output paths are resolved from the current working directory. @@ -40,7 +40,7 @@ runs/cartpole/skrl/torch/ppo// Export it to an explicit output path: ```bash -mxexport onnx \ +mxlab export-onnx \ run_dir=runs/cartpole/skrl/torch/ppo/ \ output=artifacts/cartpole.onnx ``` @@ -50,7 +50,7 @@ If a path contains spaces, quote the complete Hydra argument, for example `"run_ When `output` is omitted, the model is written next to the best checkpoint as `policy.onnx`: ```bash -mxexport onnx \ +mxlab export-onnx \ run_dir=runs/cartpole/skrl/torch/ppo/ ``` @@ -112,7 +112,7 @@ In most cases, only `run_dir` and `output` are needed. Override these Hydra para For example, export with opset 17 and more validation samples: ```bash -mxexport onnx \ +mxlab export-onnx \ run_dir= \ output=policy.onnx \ opset=17 \ diff --git a/docs/source/en/user_guide/tutorial/advanced/motrix_deploy.md b/docs/source/en/user_guide/tutorial/advanced/motrix_deploy.md index 7f105b73..220f7da3 100644 --- a/docs/source/en/user_guide/tutorial/advanced/motrix_deploy.md +++ b/docs/source/en/user_guide/tutorial/advanced/motrix_deploy.md @@ -4,7 +4,7 @@ Run an exported Go2 policy in MuJoCo before attempting hardware deployment. With a bounded headless check is: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy runtime.viewer=false duration_s=2.0 +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy runtime.viewer=false duration_s=2.0 ``` The following steps create that artifact, explain interactive control, and cover the existing Unitree hardware workflow. @@ -16,7 +16,7 @@ From the repository root: ```bash sh install.sh --all source .venv/bin/activate -mxtrain task=go2-walk-flat/rslrl.ppo +mxlab train task=go2-walk-flat/rslrl.ppo ``` Training results are saved under `runs/go2-walk-flat/`. Skip training if you already have a metadata-backed run. @@ -24,8 +24,8 @@ Training results are saved under `runs/go2-walk-flat/`. Skip training if you alr ## 2. Export and inspect the artifact ```bash -mxexport deploy env=go2-walk-flat output=artifacts/go2-walk-flat.deploy -mxdeploy inspect artifact=artifacts/go2-walk-flat.deploy +mxlab export-deploy env=go2-walk-flat output=artifacts/go2-walk-flat.deploy +mxlab deploy inspect artifact=artifacts/go2-walk-flat.deploy ``` `env=go2-walk-flat` selects the latest metadata-backed run. To select a specific run, use @@ -33,15 +33,14 @@ mxdeploy inspect artifact=artifacts/go2-walk-flat.deploy the destination; when omitted, it defaults to `artifacts/.deploy`. Existing artifact directories are not overwritten. Confirm that inspection reports `valid: true`. -`mxexport` requires an explicit `onnx` or `deploy` subcommand. The equivalent module command is -`python -m motrix_rl.commands.export deploy`. Export uses the current directory's `./configs` when present, or an +`mxlab export-deploy` creates a deployment artifact; `mxlab export-onnx` exports a standalone ONNX policy. +Export uses the current directory's `./configs` when present, or an explicit `--config-dir `; project files take precedence and missing files fall back to `motrix_rl.configs`. Both `export_deploy.yaml` and `export_onnx.yaml` ship there, so export does not require a repository checkout. Deployment export keeps its numerical-check options under `validation.*` (for example `validation.atol=3e-5`), -not the ONNX subcommand's `parity.*`. +not the ONNX export command's `parity.*`. -Export runs in `motrix-rl` and requires the training provider and an installed profile compiler for the environment. -The dependency is one-way: `motrix-rl` uses `motrix-deploy` to create artifacts; `motrix-deploy` has no RL dependency. +Before export, install the training provider used by the run and the environment's profile compiler. The artifact directory is self-contained: @@ -66,7 +65,7 @@ string selector, not a nested configuration mapping or Hydra group. Use the headless command above for a bounded run, or open the viewer: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy ``` Hold `W/S` to move forward/backward, `A/D` sideways, and `Q/E` to turn. Close the window, press Esc, or press Ctrl-C to stop. @@ -96,7 +95,7 @@ Raw ONNX use requires explicit task preprocessing and action settings; the artif With `motrix-deploy-motrixsim` installed, switch the backend to `motrixsim` to reuse the same artifact and scene recipe: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ runtime.backend=motrixsim runtime.viewer=true ``` @@ -113,7 +112,7 @@ ready. Startup can physically stand the robot down before the remote Start gate. `enp5s0` with the actual interface: ```bash -mxdeploy task=go2-walk-flat/hardware \ +mxlab deploy task=go2-walk-flat/hardware \ artifact=artifacts/go2-walk-flat.deploy \ runtime.network_interface=enp5s0 ``` @@ -154,7 +153,7 @@ returns to the default pose, and closes with damping. ## Deploy the G1 WBT dance -The G1 whole-body-tracking dance task uses the same export → artifact → `mxdeploy` pipeline. The artifact embeds +The G1 whole-body-tracking dance task uses the same export → artifact → `mxlab deploy` pipeline. The artifact embeds the servo gains, action scales, preparation gains and timing, safety thresholds, and the motion clip itself (as a `payloads/motion.npz` payload with its checksum in the manifest), so deployment needs neither Torch nor an RL environment. Export needs the training provider and task environment packages, but does **not** train: @@ -162,18 +161,18 @@ Export needs the training provider and task environment packages, but does **not ```bash source .venv/bin/activate RUN=runs/g1-wbt-dance/motrix/torch/fastsac/ -mxexport deploy run_dir="$RUN" \ +mxlab export-deploy run_dir="$RUN" \ output=artifacts/g1-wbt-dance-software-pd.deploy validation.atol=3e-5 -mxdeploy task=g1-wbt-dance/sim artifact=artifacts/g1-wbt-dance.deploy +mxlab deploy task=g1-wbt-dance/sim artifact=artifacts/g1-wbt-dance.deploy ``` Headless validation and artifact inspection: ```bash -mxdeploy task=g1-wbt-dance/sim artifact=artifacts/g1-wbt-dance.deploy \ +mxlab deploy task=g1-wbt-dance/sim artifact=artifacts/g1-wbt-dance.deploy \ runtime.viewer=false -mxdeploy inspect artifact=artifacts/g1-wbt-dance.deploy +mxlab deploy inspect artifact=artifacts/g1-wbt-dance.deploy ``` The default duration comes from the embedded motion clip; shorter runs use `duration_s`, longer durations are rejected @@ -221,7 +220,7 @@ One callback can register several Env IDs, and the same compiler can serve multi Install the package, then export a matching run: ```bash -mxexport deploy run_dir=/path/to/my-walk-flat/run output=artifacts/my-walk-flat.deploy +mxlab export-deploy run_dir=/path/to/my-walk-flat/run output=artifacts/my-walk-flat.deploy ``` The first profile lookup, listing, or build loads all installed provider callbacks, once per process. @@ -265,7 +264,7 @@ Select a world with `runtime.deploy_env_id` and a robot with `runtime.robot_id`. artifact but switch its world: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ runtime.deploy_env_id=rough ``` @@ -360,7 +359,7 @@ The installed simulation recipes default to MuJoCo. With `motrix-deploy-motrixsi installed, choose the native backend using the same recipe and artifact: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ runtime.backend=motrixsim runtime.viewer=false runtime.realtime=false duration_s=1.0 ``` @@ -387,7 +386,7 @@ This illustrative command assumes you have authored `/absolute/path/to/my_app/co or copy a built-in recipe: ```bash -mxdeploy \ +mxlab deploy \ --config-path /absolute/path/to/my_app/config \ --config-name deploy \ artifact=artifacts/go2-walk-flat.deploy diff --git a/docs/source/en/user_guide/tutorial/basic_frame.md b/docs/source/en/user_guide/tutorial/basic_frame.md index 56045048..680c768b 100644 --- a/docs/source/en/user_guide/tutorial/basic_frame.md +++ b/docs/source/en/user_guide/tutorial/basic_frame.md @@ -38,6 +38,7 @@ MotrixLab is a UV workspace. The packages are grouped by ownership rather than t | Package | Loop stage | Responsibility | | --- | --- | --- | +| `motrixlab` | Application integration | Unified `mxlab` CLI and environment/robot visualization | | `motrix_env_core` | Policy–environment interaction | Backend-agnostic environment framework: `EnvCfg`, registry, frontends, lifecycle | | `motrix_env_motrixsim` | Policy–environment interaction | MotrixSim `SimBackend`, renderer, and Torch frontend | | `motrix_env_mujoco` | Scene compilation | Compile-only MuJoCo scene backend | @@ -47,9 +48,9 @@ MotrixLab is a UV workspace. The packages are grouped by ownership rather than t | `motrix_rl_builtin` | Policy training and updates | Built-in Motrix FastSAC provider | | `motrix_rl_skrl` | Policy training and updates | SKRL PPO provider for Torch (required) and optional JAX extra | | `motrix_rl_rslrl` | Policy training and updates | RSL-RL PPO provider for Torch (optional) | -| `motrix_rl.configs`, `motrix_rl.commands` | Configuration and orchestration | Packaged train/play configs and algorithm defaults; installed `mxtrain` / `mxplay` entry points | -| `configs/`, `scripts/` | Workspace recipes and tools | Concrete Task recipes and view config; view / export tools and thin train/play wrappers | -| `motrix_deploy` | Policy deployment | Framework-independent artifacts, runtime contracts, and deployment CLI | +| `motrix_rl.configs`, `motrix_rl.commands` | Configuration and orchestration | Packaged train/play/export configs and algorithm defaults; train/play/export-onnx/export-deploy command implementations | +| `configs/`, `scripts/` | Workspace recipes and tools | Concrete Task recipes and repository helper tools | +| `motrix_deploy` | Policy deployment | Framework-independent artifacts, runtime contracts, and deployment command implementation in `motrix_deploy.cli` | | `motrix_deploy_mujoco` | Policy deployment | MuJoCo deployment backend plugin | | `motrix_deploy_motrixsim` | Policy deployment | MotrixSim deployment backend plugin | | `motrix_deploy_unitree` | Policy deployment | Unitree hardware configs, sensor/actuation wiring, and SDK2 DDS backend plugin | @@ -62,22 +63,28 @@ backend, see [SimBackend: Decoupling from the Simulator](building_envs/sim_backe The configuration and command sources are laid out as follows: ```text +motrixlab/src/motrixlab/ +├── commands/ +│ └── view.py # environment and robot visualization +└── configs/ + └── view.yaml motrix_rl/src/motrix_rl/ -├── commands/ # mxtrain / mxplay +├── commands/ # training, playback, and export implementations └── configs/ ├── train.yaml ├── play.yaml └── algo_base/ configs/ -├── task/ # workspace training recipes -└── view.yaml -scripts/ # view/export tools; thin train/play wrappers +└── task/ # workspace training recipes +scripts/ # repository helper tools ``` ## One full training run +These examples use built-in repository tasks. Complete {ref}`repository installation `, activate the environment, and run the commands from the repository root. The default runtime includes the SKRL provider; before running the RSL-RL example below, install its provider with `sh install.sh --rslrl`. + ```bash -mxtrain task=cartpole/skrl.ppo num_envs=1024 +mxlab train task=cartpole/skrl.ppo num_envs=1024 ``` 1. Hydra composes `motrix_rl/src/motrix_rl/configs/train.yaml`, `motrix_rl/src/motrix_rl/configs/algo_base/skrl.ppo.yaml`, and @@ -89,8 +96,8 @@ mxtrain task=cartpole/skrl.ppo num_envs=1024 The same environment can have several Task recipes without touching the environment implementation: ```bash -mxtrain task=cartpole/skrl.ppo -mxtrain task=cartpole/rslrl.ppo +mxlab train task=cartpole/skrl.ppo +mxlab train task=cartpole/rslrl.ppo ``` ## Run an exported policy @@ -98,7 +105,7 @@ mxtrain task=cartpole/rslrl.ppo Deployment uses an artifact rather than a training environment: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy runtime.viewer=false duration_s=2.0 +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy runtime.viewer=false duration_s=2.0 ``` This runs the exported policy headlessly in MuJoCo. See [Go2 deployment](advanced/motrix_deploy.md) for export, diff --git a/docs/source/en/user_guide/tutorial/building_envs/direct_env.md b/docs/source/en/user_guide/tutorial/building_envs/direct_env.md index 811728f6..68980800 100644 --- a/docs/source/en/user_guide/tutorial/building_envs/direct_env.md +++ b/docs/source/en/user_guide/tutorial/building_envs/direct_env.md @@ -110,7 +110,7 @@ class CartPoleEnv(DirectEnv): return state.replace(obs=obs) ``` -Once registered, preview it with `python scripts/view.py env=cartpole` and start +Once registered, preview it with `mxlab view env=cartpole` and start training by creating a Task as described in [Task Configuration](../training/task_config.md). diff --git a/docs/source/en/user_guide/tutorial/building_envs/index.md b/docs/source/en/user_guide/tutorial/building_envs/index.md index 7b2e8336..97ccd969 100644 --- a/docs/source/en/user_guide/tutorial/building_envs/index.md +++ b/docs/source/en/user_guide/tutorial/building_envs/index.md @@ -11,7 +11,7 @@ An environment consists of two parts, each registered under the environment name - **Environment class**: implements the task logic, registered via `@registry.env("name")`. -Once registered, `scripts/view.py`, the trainers, and the replay flow all create the +Once registered, `mxlab view`, the trainers, and the replay flow all create the environment by name through the same registry. Installed environment packages are discovered automatically; see [Environment registration](direct_env.md#environment-registration) to publish a package for either workflow. diff --git a/docs/source/en/user_guide/tutorial/building_envs/manager_env.md b/docs/source/en/user_guide/tutorial/building_envs/manager_env.md index 94b8b7ce..2fd8ac85 100644 --- a/docs/source/en/user_guide/tutorial/building_envs/manager_env.md +++ b/docs/source/en/user_guide/tutorial/building_envs/manager_env.md @@ -310,5 +310,5 @@ def make_microduck_ball_balance_cfg() -> MicroduckBallBalanceEnvCfg: registry.env("microduck-ball-balance")(ManagerEnv) ``` -Once registered, preview it with `python scripts/view.py env=` and start training +Once registered, preview it with `mxlab view env=` and start training by creating a Task as described in [Task Configuration](../training/task_config.md). diff --git a/docs/source/en/user_guide/tutorial/building_envs/terrain.md b/docs/source/en/user_guide/tutorial/building_envs/terrain.md index 4814669d..10a63485 100644 --- a/docs/source/en/user_guide/tutorial/building_envs/terrain.md +++ b/docs/source/en/user_guide/tutorial/building_envs/terrain.md @@ -49,7 +49,7 @@ and `anymalc-walk-rough` all generate terrain through the same `NoiseTerrainGeneratorCfg(seed=0, height_scale=0.1, flip_y=True)`; preview it directly: ```bash -python scripts/view.py env=go1-walk-rough +mxlab view env=go1-walk-rough ``` ## The generator contract diff --git a/docs/source/en/user_guide/tutorial/training/index.md b/docs/source/en/user_guide/tutorial/training/index.md index a7840bce..02ba0e71 100644 --- a/docs/source/en/user_guide/tutorial/training/index.md +++ b/docs/source/en/user_guide/tutorial/training/index.md @@ -5,7 +5,7 @@ Once an environment is registered, training an RL task takes three steps: ```text Create a Task config pick the environment, RL framework, algorithm, hyperparameters ↓ -mxtrain task=... Hydra composes the config and starts training +mxlab train task=... Hydra composes the config and starts training ↓ runs/{env}/... stores metadata, logs, and checkpoints ``` diff --git a/docs/source/en/user_guide/tutorial/training/runs_and_checkpoints.md b/docs/source/en/user_guide/tutorial/training/runs_and_checkpoints.md index a966abd4..07c9201c 100644 --- a/docs/source/en/user_guide/tutorial/training/runs_and_checkpoints.md +++ b/docs/source/en/user_guide/tutorial/training/runs_and_checkpoints.md @@ -93,7 +93,7 @@ The actual checkpoint files live under the `checkpoints/` subdirectory, and `man ``` - Paths in `manifest.json` are relative to the `checkpoints/` directory. -- **`best_policy`** (`kind: policy`): used for playback / export / evaluation; this is what `mxplay` loads by default. +- **`best_policy`** (`kind: policy`): used for playback / export / evaluation; this is what `mxlab play` loads by default. - **`latest_training_state`** (`kind: training_state`): used for resume, and should contain the full state needed to continue training, such as the optimizer, observation normalizer, replay buffer, and `global_step`. - The same physical file can be **registered as both artifacts**. For example, FastSAC's `latest.pt` (a complete state dict) can be used for both playback and resume, so `best_policy` and `latest_training_state` both point to it. @@ -106,16 +106,16 @@ The actual checkpoint files live under the `checkpoints/` subdirectory, and `man ```bash # Auto-discover and play the best policy of the latest run - mxplay env=g1-walk-flat + mxlab play env=g1-walk-flat # Specify a checkpoint (must be able to locate metadata.json above it) - mxplay env=g1-walk-flat policy=/path/to/run/checkpoints/latest.pt + mxlab play env=g1-walk-flat policy=/path/to/run/checkpoints/latest.pt ``` - **Resume**: set `resume=` to a run directory or checkpoint path, and the framework resolves `latest_training_state` from it to continue training. ```bash - mxtrain task=g1-walk-flat/motrix.fastsac \ + mxlab train task=g1-walk-flat/motrix.fastsac \ resume=/path/to/run ``` diff --git a/docs/source/en/user_guide/tutorial/training/task_config.md b/docs/source/en/user_guide/tutorial/training/task_config.md index d9206dbb..516ca2bf 100644 --- a/docs/source/en/user_guide/tutorial/training/task_config.md +++ b/docs/source/en/user_guide/tutorial/training/task_config.md @@ -62,7 +62,7 @@ A Task only needs to contain values that differ from the algorithm base. It does ### Inspect and run the Task -`mxtrain` uses `./configs` in the current working directory when it exists; it does not search parent directories. Use `--config-dir /path/to/configs` to select another configuration directory. A Task must be selected explicitly; there is no default Cartpole Task. +`mxlab train` uses `./configs` in the current working directory when it exists; it does not search parent directories. Use `--config-dir /path/to/configs` to select another configuration directory. A Task must be selected explicitly; there is no default Cartpole Task. Install the environment package before running the Task; registry queries discover installed providers automatically. See [Environment registration](../building_envs/direct_env.md#environment-registration) to package a custom environment; @@ -71,19 +71,19 @@ Task YAML discovery remains separate. Print the fully composed Hydra configuration before starting training: ```bash -mxtrain --cfg job --resolve task=my-robot/skrl.ppo +mxlab train --cfg job --resolve task=my-robot/skrl.ppo ``` This command does not start training. After verifying `task.env`, `num_envs`, and `algo.trainer.timesteps`, start the run: ```bash -mxtrain task=my-robot/skrl.ppo +mxlab train task=my-robot/skrl.ppo ``` List all Tasks available in the repository with: ```bash -mxtrain --help +mxlab train --help ``` ## Adjust Task runtime settings @@ -197,7 +197,7 @@ The MotrixLab CLI uses Hydra's `key=value` syntax. CLI values apply only to the ### Override runtime settings ```bash -mxtrain \ +mxlab train \ task=my-robot/skrl.ppo \ num_envs=64 \ seed=7 \ @@ -208,7 +208,7 @@ mxtrain \ Enable training rendering and play the policy afterward: ```bash -mxtrain task=my-robot/skrl.ppo render=true play=true +mxlab train task=my-robot/skrl.ppo render=true play=true ``` ### Override algorithm settings @@ -216,7 +216,7 @@ mxtrain task=my-robot/skrl.ppo render=true play=true SKRL PPO: ```bash -mxtrain \ +mxlab train \ task=my-robot/skrl.ppo \ algo.agent.learning_rate=5e-4 \ algo.agent.learning_epochs=8 \ @@ -226,7 +226,7 @@ mxtrain \ RSLRL PPO: ```bash -mxtrain \ +mxlab train \ task=cartpole/rslrl.ppo \ algo.algorithm.learning_rate=5e-4 \ algo.algorithm.entropy_coef=0.005 \ @@ -236,7 +236,7 @@ mxtrain \ FastSAC: ```bash -mxtrain \ +mxlab train \ task=g1-walk-flat/motrix.fastsac \ algo.asynchronous=true \ algo.agent.actor_learning_rate=1e-4 \ @@ -250,20 +250,20 @@ mxtrain \ Use lowercase `true` and `false` for booleans: ```bash -mxtrain task=my-robot/skrl.ppo render=true +mxlab train task=my-robot/skrl.ppo render=true ``` Use `null` to clear nullable fields: ```bash -mxtrain task=my-robot/skrl.ppo seed=null -mxtrain task=my-robot/skrl.ppo algo.agent.learning_rate_scheduler=null +mxlab train task=my-robot/skrl.ppo seed=null +mxlab train task=my-robot/skrl.ppo algo.agent.learning_rate_scheduler=null ``` Quote lists so the shell does not interpret brackets: ```bash -mxtrain \ +mxlab train \ task=my-robot/skrl.ppo \ 'algo.models.policy.hiddens=[128,64]' \ 'algo.models.value.hiddens=[128,64]' @@ -280,7 +280,7 @@ Training uses structured schemas. Existing fields do not need a `+` prefix. Add Combine CLI overrides with `--cfg job --resolve` to inspect the exact values that would be used: ```bash -mxtrain \ +mxlab train \ --cfg job \ --resolve \ task=my-robot/skrl.ppo \ @@ -322,13 +322,13 @@ algo: Train with the JAX delta: ```bash -mxtrain task=go2-walk-flat/skrl.ppo.jax +mxlab train task=go2-walk-flat/skrl.ppo.jax ``` Overriding the backend directly also selects the JAX trainer: ```bash -mxtrain task=go2-walk-flat/skrl.ppo task.train_backend=jax +mxlab train task=go2-walk-flat/skrl.ppo task.train_backend=jax ``` This form does not load backend-specific values from `skrl.ppo.jax.yaml`. Select the `.jax` or `.torch` Task directly when a backend delta exists. @@ -349,7 +349,6 @@ motrix_rl/src/motrix_rl/configs/ └── motrix.fastsac.yaml configs/ -├── view.yaml └── task/ └── / ├── ..yaml @@ -420,18 +419,18 @@ Hydra validates field names and types against the structured schema registered b ## Play and View overrides -`mxplay` restores the saved run configuration without requiring the training Task directory. It and `scripts/view.py` use the same `key=value` syntax: +`mxlab play` restores the saved run configuration without requiring the training Task directory. It and `mxlab view` use the same `key=value` syntax: ```bash -python scripts/view.py env=cartpole num_envs=4 -mxplay env=cartpole num_envs=1 -mxplay policy=/path/to/checkpoint.pt num_envs=1 +mxlab view env=cartpole num_envs=4 +mxlab play env=cartpole num_envs=1 +mxlab play policy=/path/to/checkpoint.pt num_envs=1 ``` Play loads the `task_config.yaml` stored with a training run. To temporarily override algorithm settings, use `rl` as the algorithm root. Since `rl` starts as an empty mapping, add the path with `+`: ```bash -mxplay \ +mxlab play \ env=cartpole \ '+rl.agent.learning_rate=1e-4' ``` diff --git a/docs/source/en/user_guide/tutorial/training/training_and_result.md b/docs/source/en/user_guide/tutorial/training/training_and_result.md index a5ee204f..13b6a1a9 100644 --- a/docs/source/en/user_guide/tutorial/training/training_and_result.md +++ b/docs/source/en/user_guide/tutorial/training/training_and_result.md @@ -16,12 +16,12 @@ The training entry point requires Hydra's `task=/. **提示**:策略会从 `runs/acrobot/` 中自动选择。使用 `policy=...` 时,checkpoint 所属 run 必须包含 `metadata.json`。 diff --git a/docs/source/zh_CN/user_guide/envs/basic/cartpole.md b/docs/source/zh_CN/user_guide/envs/basic/cartpole.md index e8e7ca90..182574ed 100644 --- a/docs/source/zh_CN/user_guide/envs/basic/cartpole.md +++ b/docs/source/zh_CN/user_guide/envs/basic/cartpole.md @@ -88,13 +88,13 @@ reward = 1.0 # 每步固定奖励 ### 1. 环境预览 ```bash -python scripts/view.py env=cartpole +mxlab view env=cartpole ``` ### 2. 开始训练 ```bash -mxtrain task=cartpole/skrl.ppo +mxlab train task=cartpole/skrl.ppo ``` ### 3. 查看训练进度 @@ -106,7 +106,7 @@ tensorboard --logdir runs/cartpole ### 4. 测试训练结果 ```bash -mxplay env=cartpole +mxlab play env=cartpole ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/basic/pendulum.md b/docs/source/zh_CN/user_guide/envs/basic/pendulum.md index 5cbf1cfa..745bdd7f 100644 --- a/docs/source/zh_CN/user_guide/envs/basic/pendulum.md +++ b/docs/source/zh_CN/user_guide/envs/basic/pendulum.md @@ -64,20 +64,20 @@ ### 1. 环境预览 ```bash -python scripts/view.py env=pendulum +mxlab view env=pendulum ``` ### 2. 开始训练 ```bash # 默认参数训练 -mxtrain task=pendulum/skrl.ppo +mxlab train task=pendulum/skrl.ppo # 自定义并行环境数 -mxtrain task=pendulum/skrl.ppo num_envs=1024 +mxlab train task=pendulum/skrl.ppo num_envs=1024 # 开启训练时渲染 -mxtrain task=pendulum/skrl.ppo render=true +mxlab train task=pendulum/skrl.ppo render=true ``` ### 3. 查看训练进度 @@ -90,10 +90,10 @@ tensorboard --logdir runs/pendulum ```bash # 自动寻找最新/最优策略(推荐) -mxplay env=pendulum +mxlab play env=pendulum # 手动指定带 metadata 的 run 中的 checkpoint -mxplay env=pendulum policy=/path/to/run/checkpoints/policy-file +mxlab play env=pendulum policy=/path/to/run/checkpoints/policy-file ``` > **提示**:策略默认在 `runs/pendulum/` 下自动发现。使用 `policy=...` 时,checkpoint 所属 run 必须包含 `metadata.json`。 diff --git a/docs/source/zh_CN/user_guide/envs/basic/stewart.md b/docs/source/zh_CN/user_guide/envs/basic/stewart.md index d924ddb1..c800936d 100644 --- a/docs/source/zh_CN/user_guide/envs/basic/stewart.md +++ b/docs/source/zh_CN/user_guide/envs/basic/stewart.md @@ -156,15 +156,15 @@ reward = fall_penalty if fallen else reward ### 1. 环境预览 ```bash -python scripts/view.py env=stewart-static -python scripts/view.py env=stewart-disturb-xy +mxlab view env=stewart-static +mxlab view env=stewart-disturb-xy ``` ### 2. 开始训练 ```bash -mxtrain task=stewart-static/skrl.ppo -mxtrain task=stewart-disturb-xy/skrl.ppo +mxlab train task=stewart-static/skrl.ppo +mxlab train task=stewart-disturb-xy/skrl.ppo ``` ### 训练说明 @@ -183,8 +183,8 @@ tensorboard --logdir runs/stewart-disturb-xy ### 4. 测试训练结果 ```bash -mxplay env=stewart-static -mxplay env=stewart-disturb-xy +mxlab play env=stewart-static +mxlab play env=stewart-disturb-xy ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/bring_ball.md b/docs/source/zh_CN/user_guide/envs/dm_control/bring_ball.md index 0b280696..a004aa64 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/bring_ball.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/bring_ball.md @@ -137,7 +137,7 @@ penalty_side + penalty_hover ### 1. 环境预览(随机动作) ```bash -python scripts/view.py env=dm-manipulator-bring-ball +mxlab view env=dm-manipulator-bring-ball ``` ### 2. 开始训练 @@ -145,7 +145,7 @@ python scripts/view.py env=dm-manipulator-bring-ball 建议显式指定训练后端(JAX / PyTorch 二选一): ```bash -mxtrain task=dm-manipulator-bring-ball/skrl.ppo.torch +mxlab train task=dm-manipulator-bring-ball/skrl.ppo.torch ``` ### 3. 查看训练进度 @@ -157,7 +157,7 @@ tensorboard --logdir runs/dm-manipulator-bring-ball ### 4. 测试训练结果 ```bash -mxplay env=dm-manipulator-bring-ball +mxlab play env=dm-manipulator-bring-ball ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/dm_cheetah.md b/docs/source/zh_CN/user_guide/envs/dm_control/dm_cheetah.md index e9dcec31..595af3bc 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/dm_cheetah.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/dm_cheetah.md @@ -102,13 +102,13 @@ cheetah 的奖励函数由以下几个部分组成: ### 1. 环境预览 ```bash -python scripts/view.py env=dm-cheetah +mxlab view env=dm-cheetah ``` ### 2. 开始训练 ```bash -mxtrain task=dm-cheetah/skrl.ppo +mxlab train task=dm-cheetah/skrl.ppo ``` ### 3. 查看训练进度 @@ -120,7 +120,7 @@ tensorboard --logdir runs/dm-cheetah ### 4. 测试训练结果 ```bash -mxplay env=dm-cheetah +mxlab play env=dm-cheetah ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/dm_finger.md b/docs/source/zh_CN/user_guide/envs/dm_control/dm_finger.md index 5ff9bfca..79b81d08 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/dm_finger.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/dm_finger.md @@ -143,15 +143,15 @@ Turn 的核心是 tip 触达并对准目标点:目标点位于 spinner 周围 ### 1. 环境预览(随机动作) ```bash -python scripts/view.py env=dm-finger-spin +mxlab view env=dm-finger-spin ``` ```bash -python scripts/view.py env=dm-finger-turn-easy +mxlab view env=dm-finger-turn-easy ``` ```bash -python scripts/view.py env=dm-finger-turn-hard +mxlab view env=dm-finger-turn-hard ``` ### 2. 开始训练 @@ -159,15 +159,15 @@ python scripts/view.py env=dm-finger-turn-hard 建议显式指定训练后端(JAX / PyTorch 二选一): ```bash -mxtrain task=dm-finger-spin/skrl.ppo task.train_backend=torch +mxlab train task=dm-finger-spin/skrl.ppo task.train_backend=torch ``` ```bash -mxtrain task=dm-finger-turn-easy/skrl.ppo task.train_backend=torch +mxlab train task=dm-finger-turn-easy/skrl.ppo task.train_backend=torch ``` ```bash -mxtrain task=dm-finger-turn-hard/skrl.ppo task.train_backend=torch +mxlab train task=dm-finger-turn-hard/skrl.ppo task.train_backend=torch ``` ### 3. 查看训练进度 @@ -178,10 +178,10 @@ tensorboard --logdir runs/dm-finger-spin ### 4. 测试训练结果 -`mxplay` 默认会在 `runs/{env-name}/` 下查找最新的 metadata-backed run,并加载其 `best_policy` artifact;也可以用 `policy=...` 显式指定 checkpoint: +`mxlab play` 默认会在 `runs/{env-name}/` 下查找最新的 metadata-backed run,并加载其 `best_policy` artifact;也可以用 `policy=...` 显式指定 checkpoint: ```bash -mxplay env=dm-finger-turn-hard +mxlab play env=dm-finger-turn-hard ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/dm_hopper.md b/docs/source/zh_CN/user_guide/envs/dm_control/dm_hopper.md index a060f121..d2677160 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/dm_hopper.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/dm_hopper.md @@ -109,15 +109,15 @@ hopper 的奖励函数由以下几个部分组成: ### 1. 环境预览 ```bash -python scripts/view.py env=dm-hopper-stand -python scripts/view.py env=dm-hopper-hop +mxlab view env=dm-hopper-stand +mxlab view env=dm-hopper-hop ``` ### 2. 开始训练 ```bash -mxtrain task=dm-hopper-stand/skrl.ppo -mxtrain task=dm-hopper-hop/skrl.ppo +mxlab train task=dm-hopper-stand/skrl.ppo +mxlab train task=dm-hopper-hop/skrl.ppo ``` ### 3. 查看训练进度 @@ -129,8 +129,8 @@ tensorboard --logdir runs/dm-hopper-hop ### 4. 测试训练结果 ```bash -mxplay env=dm-hopper-stand -mxplay env=dm-hopper-hop +mxlab play env=dm-hopper-stand +mxlab play env=dm-hopper-hop ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/dm_humanoid.md b/docs/source/zh_CN/user_guide/envs/dm_control/dm_humanoid.md index 143a4204..da89591a 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/dm_humanoid.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/dm_humanoid.md @@ -185,17 +185,17 @@ total_reward = posture_reward * speed_reward * energy_reward * gait_reward ### 1. 环境预览 ```bash -python scripts/view.py env=dm-humanoid-stand -python scripts/view.py env=dm-humanoid-walk -python scripts/view.py env=dm-humanoid-run +mxlab view env=dm-humanoid-stand +mxlab view env=dm-humanoid-walk +mxlab view env=dm-humanoid-run ``` ### 2. 开始训练 ```bash -mxtrain task=dm-humanoid-stand/skrl.ppo -mxtrain task=dm-humanoid-walk/skrl.ppo -mxtrain task=dm-humanoid-run/skrl.ppo +mxlab train task=dm-humanoid-stand/skrl.ppo +mxlab train task=dm-humanoid-walk/skrl.ppo +mxlab train task=dm-humanoid-run/skrl.ppo ``` ### 3. 查看训练进度 @@ -207,9 +207,9 @@ tensorboard --logdir runs/dm-humanoid-walk ### 4. 测试训练结果 ```bash -mxplay env=dm-humanoid-stand -mxplay env=dm-humanoid-walk -mxplay env=dm-humanoid-run +mxlab play env=dm-humanoid-stand +mxlab play env=dm-humanoid-walk +mxlab play env=dm-humanoid-run ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/dm_lqr.md b/docs/source/zh_CN/user_guide/envs/dm_control/dm_lqr.md index 7760b974..6255bbbc 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/dm_lqr.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/dm_lqr.md @@ -157,15 +157,15 @@ reward -= out_of_bounds_penalty ### 1. 环境预览 ```bash -python scripts/view.py env=dm-lqr-2-1 -python scripts/view.py env=dm-lqr-6-2 +mxlab view env=dm-lqr-2-1 +mxlab view env=dm-lqr-6-2 ``` ### 2. 开始训练 ```bash -mxtrain task=dm-lqr-2-1/skrl.ppo -mxtrain task=dm-lqr-6-2/skrl.ppo +mxlab train task=dm-lqr-2-1/skrl.ppo +mxlab train task=dm-lqr-6-2/skrl.ppo ``` ### 3. 查看训练曲线 @@ -178,8 +178,8 @@ tensorboard --logdir runs/dm-lqr-6-2 ### 4. 测试训练结果 ```bash -mxplay env=dm-lqr-2-1 -mxplay env=dm-lqr-6-2 +mxlab play env=dm-lqr-2-1 +mxlab play env=dm-lqr-6-2 ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/dm_point_mass.md b/docs/source/zh_CN/user_guide/envs/dm_control/dm_point_mass.md index 7d9249c7..2feab86c 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/dm_point_mass.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/dm_point_mass.md @@ -115,13 +115,13 @@ rwd = distance_reward + target_bonus + continuous_reward + path_reward - center_ ### 1. 环境预览 ```bash -python scripts/view.py env=point_mass +mxlab view env=point_mass ``` ### 2. 开始训练 ```bash -mxtrain task=point_mass/skrl.ppo +mxlab train task=point_mass/skrl.ppo ``` ### 3. 查看训练进度 @@ -133,7 +133,7 @@ tensorboard --logdir runs/point_mass ### 4. 测试训练结果 ```bash -mxplay env=point_mass +mxlab play env=point_mass ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/dm_quadruped.md b/docs/source/zh_CN/user_guide/envs/dm_control/dm_quadruped.md index ebc26bcc..b89a8aba 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/dm_quadruped.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/dm_quadruped.md @@ -228,19 +228,19 @@ total_reward = stage_terms + ready_terms + push_terms - penalty_terms ### 1. 环境预览 ```bash -python scripts/view.py env=dm-quadruped-walk -python scripts/view.py env=dm-quadruped-run -python scripts/view.py env=dm-quadruped-escape -python scripts/view.py env=dm-quadruped-fetch +mxlab view env=dm-quadruped-walk +mxlab view env=dm-quadruped-run +mxlab view env=dm-quadruped-escape +mxlab view env=dm-quadruped-fetch ``` ### 2. 开始训练 ```bash -mxtrain task=dm-quadruped-walk/skrl.ppo -mxtrain task=dm-quadruped-run/skrl.ppo -mxtrain task=dm-quadruped-escape/skrl.ppo -mxtrain task=dm-quadruped-fetch/skrl.ppo +mxlab train task=dm-quadruped-walk/skrl.ppo +mxlab train task=dm-quadruped-run/skrl.ppo +mxlab train task=dm-quadruped-escape/skrl.ppo +mxlab train task=dm-quadruped-fetch/skrl.ppo ``` ### 3. 查看训练进度 @@ -255,10 +255,10 @@ tensorboard --logdir runs/dm-quadruped-fetch ### 4. 测试训练结果 ```bash -mxplay env=dm-quadruped-walk -mxplay env=dm-quadruped-run -mxplay env=dm-quadruped-escape -mxplay env=dm-quadruped-fetch +mxlab play env=dm-quadruped-walk +mxlab play env=dm-quadruped-run +mxlab play env=dm-quadruped-escape +mxlab play env=dm-quadruped-fetch ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/dm_reacher.md b/docs/source/zh_CN/user_guide/envs/dm_control/dm_reacher.md index ade1cc73..bf318bff 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/dm_reacher.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/dm_reacher.md @@ -93,13 +93,13 @@ reward = tolerance(|| fingertip - target ||) ### 1. 环境预览 ```bash -python scripts/view.py env=dm-reacher +mxlab view env=dm-reacher ``` ### 2. 开始训练 ```bash -mxtrain task=dm-reacher/skrl.ppo +mxlab train task=dm-reacher/skrl.ppo ``` ### 3. 查看训练进度 @@ -111,7 +111,7 @@ tensorboard --logdir runs/dm-reacher ### 4. 测试训练结果 ```bash -mxplay env=dm-reacher +mxlab play env=dm-reacher ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/dm_control/dm_walker.md b/docs/source/zh_CN/user_guide/envs/dm_control/dm_walker.md index 86266d98..5ccb09df 100644 --- a/docs/source/zh_CN/user_guide/envs/dm_control/dm_walker.md +++ b/docs/source/zh_CN/user_guide/envs/dm_control/dm_walker.md @@ -94,17 +94,17 @@ walker 的奖励函数由以下几个部分组成: ### 1. 环境预览 ```bash -python scripts/view.py env=dm-stander -python scripts/view.py env=dm-walker -python scripts/view.py env=dm-runner +mxlab view env=dm-stander +mxlab view env=dm-walker +mxlab view env=dm-runner ``` ### 2. 开始训练 ```bash -mxtrain task=dm-stander/skrl.ppo -mxtrain task=dm-walker/skrl.ppo -mxtrain task=dm-runner/skrl.ppo +mxlab train task=dm-stander/skrl.ppo +mxlab train task=dm-walker/skrl.ppo +mxlab train task=dm-runner/skrl.ppo ``` ### 3. 查看训练进度 @@ -116,9 +116,9 @@ tensorboard --logdir runs/dm-walker ### 4. 测试训练结果 ```bash -mxplay env=dm-stander -mxplay env=dm-walker -mxplay env=dm-runner +mxlab play env=dm-stander +mxlab play env=dm-walker +mxlab play env=dm-runner ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking.md b/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking.md index 91fd4649..9c029704 100644 --- a/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking.md +++ b/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking.md @@ -90,15 +90,15 @@ MotrixLab 已为下列机器人提供平地和程序化起伏高度场配置。 从“内置机器人”表格中选择 Env ID 和对应的训练配置,并替换下列命令中的 `ENV_ID` 与 `TRAINING_CONFIG`: ```bash -python scripts/view.py env=ENV_ID num_envs=1 -mxtrain task=ENV_ID/TRAINING_CONFIG -mxplay env=ENV_ID num_envs=16 +mxlab view env=ENV_ID num_envs=1 +mxlab train task=ENV_ID/TRAINING_CONFIG +mxlab play env=ENV_ID num_envs=16 ``` 例如,使用 FastSAC 异步训练 K1 起伏地形任务: ```bash -mxtrain task=k1-walk-rough/motrix.fastsac algo.asynchronous=true +mxlab train task=k1-walk-rough/motrix.fastsac algo.asynchronous=true ``` -`view.py` 使用随机动作,仅用于检查场景和模型;训练后的步态需要通过 `mxplay` 回放策略查看。 +`mxlab view` 使用随机动作,仅用于检查场景和模型;训练后的步态需要通过 `mxlab play` 回放策略查看。 diff --git a/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking/adding_robot.md b/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking/adding_robot.md index 02e31ac7..e7b54d92 100644 --- a/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking/adding_robot.md +++ b/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking/adding_robot.md @@ -113,7 +113,7 @@ asset = AssetCfg( 建议先运行机器人预览命令检查关节顺序、默认姿态、PD 参数、脚底 site 和碰撞体名称: ```bash -python scripts/view.py robot= +mxlab view robot= ``` ## 4. 注册环境实现 @@ -156,11 +156,11 @@ algo: 建议按以下顺序验证: ```bash -python scripts/view.py robot= -python scripts/view.py env=-walk-flat -python scripts/view.py env=-walk-terrain -mxtrain task=-walk-flat/motrix.fastsac -mxtrain task=-walk-flat/motrix.fastsac algo.asynchronous=false +mxlab view robot= +mxlab view env=-walk-flat +mxlab view env=-walk-terrain +mxlab train task=-walk-flat/motrix.fastsac +mxlab train task=-walk-flat/motrix.fastsac algo.asynchronous=false python -m pytest motrix_envs/tests/test_humanoid_walk.py -q python -m pytest motrix_rl/tests/test_task_configs.py -q ``` diff --git a/docs/source/zh_CN/user_guide/envs/index.md b/docs/source/zh_CN/user_guide/envs/index.md index 146fc909..42fe0488 100644 --- a/docs/source/zh_CN/user_guide/envs/index.md +++ b/docs/source/zh_CN/user_guide/envs/index.md @@ -5,7 +5,7 @@ MotrixLab Environment 定义可通过 Env Registry 创建的仿真任务,包 使用以下命令可以在不启动训练的情况下预览一个环境: ```bash -python scripts/view.py env= +mxlab view env= ``` ## 环境主题 diff --git a/docs/source/zh_CN/user_guide/envs/manipulation/bounce_ball.md b/docs/source/zh_CN/user_guide/envs/manipulation/bounce_ball.md index 8af9a4aa..1ebb67a9 100644 --- a/docs/source/zh_CN/user_guide/envs/manipulation/bounce_ball.md +++ b/docs/source/zh_CN/user_guide/envs/manipulation/bounce_ball.md @@ -411,13 +411,13 @@ $$ ### 1. 环境预览 ```bash -python scripts/view.py env=bounce_ball +mxlab view env=bounce_ball ``` ### 2. 开始训练 ```bash -mxtrain task=bounce_ball/skrl.ppo +mxlab train task=bounce_ball/skrl.ppo ``` ### 3. 查看训练进度 @@ -429,7 +429,7 @@ tensorboard --logdir runs/bounce_ball ### 4. 测试训练结果 ```bash -mxplay env=bounce_ball +mxlab play env=bounce_ball ``` --- diff --git a/docs/source/zh_CN/user_guide/envs/manipulation/franka_lift_cube.md b/docs/source/zh_CN/user_guide/envs/manipulation/franka_lift_cube.md index 755edd4b..2d9984e6 100644 --- a/docs/source/zh_CN/user_guide/envs/manipulation/franka_lift_cube.md +++ b/docs/source/zh_CN/user_guide/envs/manipulation/franka_lift_cube.md @@ -239,13 +239,13 @@ p = 1 / (1 + exp(-action)) ### 训练 ```bash -mxtrain task=franka-lift-cube/skrl.ppo +mxlab train task=franka-lift-cube/skrl.ppo ``` ### 策略评估 ```bash -mxplay env=franka-lift-cube +mxlab play env=franka-lift-cube ``` ### TensorBoard diff --git a/docs/source/zh_CN/user_guide/envs/manipulation/franka_open_cabinet.md b/docs/source/zh_CN/user_guide/envs/manipulation/franka_open_cabinet.md index 6cca0742..077851de 100644 --- a/docs/source/zh_CN/user_guide/envs/manipulation/franka_open_cabinet.md +++ b/docs/source/zh_CN/user_guide/envs/manipulation/franka_open_cabinet.md @@ -234,13 +234,13 @@ Franka Emika Panda 是一个 7 自由度机械臂,由以下主要部分组成 ### 训练 ```bash -mxtrain task=franka-open-cabinet/skrl.ppo +mxlab train task=franka-open-cabinet/skrl.ppo ``` ### 策略评估 ```bash -mxplay env=franka-open-cabinet +mxlab play env=franka-open-cabinet ``` ### TensorBoard diff --git a/docs/source/zh_CN/user_guide/envs/manipulation/rm65_insert_peg.md b/docs/source/zh_CN/user_guide/envs/manipulation/rm65_insert_peg.md index cb14231a..59595cff 100644 --- a/docs/source/zh_CN/user_guide/envs/manipulation/rm65_insert_peg.md +++ b/docs/source/zh_CN/user_guide/envs/manipulation/rm65_insert_peg.md @@ -269,13 +269,13 @@ RM65 机器人在该环境中包含以下主要部分: ### 训练 ```bash -mxtrain task=rm65_insert_peg/motrix.fastsac +mxlab train task=rm65_insert_peg/motrix.fastsac ``` ### 策略评估 ```bash -mxplay env=rm65_insert_peg num_envs=16 +mxlab play env=rm65_insert_peg num_envs=16 ``` ### TensorBoard diff --git a/docs/source/zh_CN/user_guide/envs/manipulation/rm65_open_cabinet.md b/docs/source/zh_CN/user_guide/envs/manipulation/rm65_open_cabinet.md index ccd5f27a..2c55a927 100644 --- a/docs/source/zh_CN/user_guide/envs/manipulation/rm65_open_cabinet.md +++ b/docs/source/zh_CN/user_guide/envs/manipulation/rm65_open_cabinet.md @@ -242,13 +242,13 @@ RM65 机器人在该环境中包含以下主要部分: ### 训练 ```bash -mxtrain task=rm65-open-cabinet/skrl.ppo task.train_backend=torch +mxlab train task=rm65-open-cabinet/skrl.ppo task.train_backend=torch ``` ### 策略评估 ```bash -mxplay env=rm65-open-cabinet +mxlab play env=rm65-open-cabinet ``` ### TensorBoard diff --git a/docs/source/zh_CN/user_guide/envs/manipulation/shadow_hand_repose.md b/docs/source/zh_CN/user_guide/envs/manipulation/shadow_hand_repose.md index ecba08f8..1178bb33 100644 --- a/docs/source/zh_CN/user_guide/envs/manipulation/shadow_hand_repose.md +++ b/docs/source/zh_CN/user_guide/envs/manipulation/shadow_hand_repose.md @@ -297,19 +297,19 @@ actuator_ctrls = targets ### 训练 ```bash -mxtrain task=shadow-hand-repose/skrl.ppo +mxlab train task=shadow-hand-repose/skrl.ppo ``` ### 策略评估 ```bash -mxplay env=shadow-hand-repose +mxlab play env=shadow-hand-repose ``` ### 环境可视化 ```bash -python scripts/view.py env=shadow-hand-repose +mxlab view env=shadow-hand-repose ``` ### TensorBoard diff --git a/docs/source/zh_CN/user_guide/envs/quadruped_locomotion/go1_rough_terrain.md b/docs/source/zh_CN/user_guide/envs/quadruped_locomotion/go1_rough_terrain.md index db8fe4d7..fa671a6a 100644 --- a/docs/source/zh_CN/user_guide/envs/quadruped_locomotion/go1_rough_terrain.md +++ b/docs/source/zh_CN/user_guide/envs/quadruped_locomotion/go1_rough_terrain.md @@ -24,7 +24,7 @@ $v_y$ 和 `yaw_rate` 固定为 0。 该任务不随机化物理参数。 ```bash -python scripts/view.py env=go1-stairs-terrain-walk -mxtrain task=go1-stairs-terrain-walk/skrl.ppo -mxplay env=go1-stairs-terrain-walk +mxlab view env=go1-stairs-terrain-walk +mxlab train task=go1-stairs-terrain-walk/skrl.ppo +mxlab play env=go1-stairs-terrain-walk ``` diff --git a/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking.md b/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking.md index c8eaf10e..5c51b4a9 100644 --- a/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking.md +++ b/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking.md @@ -110,15 +110,15 @@ MotrixLab 已为下列机器人提供平地和程序化粗糙高度场配置。 从“内置机器人”表格中选择 Env ID 和对应的训练配置,并替换下列命令中的 `ENV_ID` 与 `TRAINING_CONFIG`: ```bash -python scripts/view.py env=ENV_ID num_envs=1 -mxtrain task=ENV_ID/TRAINING_CONFIG -mxplay env=ENV_ID num_envs=16 +mxlab view env=ENV_ID num_envs=1 +mxlab train task=ENV_ID/TRAINING_CONFIG +mxlab play env=ENV_ID num_envs=16 ``` 例如,使用 RSL-RL PPO 训练 Go2 粗糙地形任务: ```bash -mxtrain task=go2-walk-rough/rslrl.ppo +mxlab train task=go2-walk-rough/rslrl.ppo ``` -`view.py` 使用随机动作,仅用于检查场景和模型;训练后的步态需要通过 `mxplay` 回放策略查看。 +`mxlab view` 使用随机动作,仅用于检查场景和模型;训练后的步态需要通过 `mxlab play` 回放策略查看。 diff --git a/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking/adding_robot.md b/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking/adding_robot.md index ba54219e..bc6f86d5 100644 --- a/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking/adding_robot.md +++ b/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking/adding_robot.md @@ -66,7 +66,7 @@ class MyQuadruped(QuadrupedRobotCfg): 完成 robot registry 注册后,先独立预览模型: ```bash -python scripts/view.py robot= +mxlab view robot= ``` ## 2. 提供任务传感器 @@ -191,10 +191,10 @@ SKRL 配置选择 `/algo_base@algo: skrl.ppo`,并将 `task.rllib` 设为 `skrl 建议按以下顺序验证: ```bash -python scripts/view.py robot= -python scripts/view.py env=-walk-flat -python scripts/view.py env=-walk-rough -mxtrain task=-walk-flat/rslrl.ppo +mxlab view robot= +mxlab view env=-walk-flat +mxlab view env=-walk-rough +mxlab train task=-walk-flat/rslrl.ppo ``` 预览时重点检查默认姿态、动作方向、四脚接触、足端位置参考系和粗糙地形出生高度。 diff --git a/docs/source/zh_CN/user_guide/envs/whole_body_tracking/adding_wbt_task.md b/docs/source/zh_CN/user_guide/envs/whole_body_tracking/adding_wbt_task.md index 381a8501..0d3fad65 100644 --- a/docs/source/zh_CN/user_guide/envs/whole_body_tracking/adding_wbt_task.md +++ b/docs/source/zh_CN/user_guide/envs/whole_body_tracking/adding_wbt_task.md @@ -127,7 +127,7 @@ algo: 先用小规模 smoke test 验证 Hydra composition、registry、tensor shape 和一步训练流程: ```bash -mxtrain task=g1-wbt-dance1-subject1/motrix.fastsac \ +mxlab train task=g1-wbt-dance1-subject1/motrix.fastsac \ algo.asynchronous=true num_envs=64 algo.trainer.num_learning_iterations=100 ``` @@ -135,13 +135,13 @@ mxtrain task=g1-wbt-dance1-subject1/motrix.fastsac \ `state.reward_terms` 与 `state.metrics` 能进入日志。随后使用默认规模训练: ```bash -mxtrain task=g1-wbt-dance1-subject1/motrix.fastsac algo.asynchronous=true +mxlab train task=g1-wbt-dance1-subject1/motrix.fastsac algo.asynchronous=true ``` 生成 metadata-backed run 后回放策略: ```bash -mxplay env=g1-wbt-dance1-subject1 num_envs=16 +mxlab play env=g1-wbt-dance1-subject1 num_envs=16 ``` Play 模式自动从第 0 帧开始,关闭 reset noise 和 adaptive sampler,并在 clip 结束后从头重播,无需单独注册 play 环境。 @@ -155,5 +155,5 @@ Play 模式自动从第 0 帧开始,关闭 reset noise 和 adaptive sampler, - 小规模训练的 observation、action、reward、terminated 和 truncated shape 正确。 - Reset 没有系统性 NaN、hard-limit 违规或立即 bad-tracking。 - Reward、termination 和 adaptive-sampling 指标能够写入日志。 -- `mxplay` 可以发现 run,并从第 0 帧完整回放策略。 +- `mxlab play` 可以发现 run,并从第 0 帧完整回放策略。 - 新 motion 包含来源与许可说明,并由 Git LFS 管理。 diff --git a/docs/source/zh_CN/user_guide/envs/whole_body_tracking/index.md b/docs/source/zh_CN/user_guide/envs/whole_body_tracking/index.md index 71ce0612..d60d581d 100644 --- a/docs/source/zh_CN/user_guide/envs/whole_body_tracking/index.md +++ b/docs/source/zh_CN/user_guide/envs/whole_body_tracking/index.md @@ -159,20 +159,20 @@ python scripts/motion/replay.py \ 从“内置任务”表格中选择 Env ID 和对应的训练配置,并替换下列命令中的 `ENV_ID` 与 `TRAINING_CONFIG`: ```bash -mxtrain task=ENV_ID/TRAINING_CONFIG +mxlab train task=ENV_ID/TRAINING_CONFIG ``` 例如,使用 FastSAC 异步训练 G1 舞蹈跟踪任务: ```bash -mxtrain task=g1-wbt-dance/motrix.fastsac algo.asynchronous=true +mxlab train task=g1-wbt-dance/motrix.fastsac algo.asynchronous=true ``` 内置配置默认使用 2048 个并行环境,并按任务设置学习迭代次数。只验证 registry、shape 和训练入口时,可以使用不会 生成可用策略的小规模 smoke test: ```bash -mxtrain task=g1-wbt-dance/motrix.fastsac \ +mxlab train task=g1-wbt-dance/motrix.fastsac \ algo.asynchronous=true num_envs=64 algo.trainer.num_learning_iterations=100 ``` @@ -183,9 +183,9 @@ mxtrain task=g1-wbt-dance/motrix.fastsac \ ### 回放策略 ```bash -mxplay env=ENV_ID num_envs=16 +mxlab play env=ENV_ID num_envs=16 ``` -`mxplay` 自动选择该环境最新一次 metadata-backed run 的最佳策略。WBT 的 play 配置从 motion 第 0 帧开始,关闭 +`mxlab play` 自动选择该环境最新一次 metadata-backed run 的最佳策略。WBT 的 play 配置从 motion 第 0 帧开始,关闭 reset noise 和自适应采样,并移除 10 秒训练时限;播放到 clip 末尾后从第 0 帧重新开始。训练产物和 checkpoint 选择规则见 [训练产物:runs 目录与 checkpoint 结构](../../tutorial/training/runs_and_checkpoints.md)。 diff --git a/docs/source/zh_CN/user_guide/getting_started/container_deployment.md b/docs/source/zh_CN/user_guide/getting_started/container_deployment.md index 450acc97..fcd6c6d8 100644 --- a/docs/source/zh_CN/user_guide/getting_started/container_deployment.md +++ b/docs/source/zh_CN/user_guide/getting_started/container_deployment.md @@ -98,7 +98,7 @@ docker build -t motphys/motrixlab:latest . docker run --gpus all \ -v $(pwd)/runs:/root/motrixlab/runs \ motphys/motrixlab:latest \ - mxtrain task=cartpole/skrl.ppo task.train_backend=jax num_envs=2048 + mxlab train task=cartpole/skrl.ppo task.train_backend=jax num_envs=2048 ``` ### 持久化训练结果 diff --git a/docs/source/zh_CN/user_guide/getting_started/hello_motrixlab.md b/docs/source/zh_CN/user_guide/getting_started/hello_motrixlab.md index b8690f5d..44ebd985 100644 --- a/docs/source/zh_CN/user_guide/getting_started/hello_motrixlab.md +++ b/docs/source/zh_CN/user_guide/getting_started/hello_motrixlab.md @@ -2,14 +2,16 @@ 本教程通过演示一个简单例子 - 加载倒立摆并进行训练,以此来展示 MotrixLab 工作流程: -请先完成[环境安装](installation.md),然后激活环境:`source .venv/bin/activate`(Windows PowerShell:`.venv\Scripts\Activate.ps1`)。 +本教程使用仓库内置的倒立摆任务。请先完成{ref}`在 MotrixLab 仓库中安装 `,然后激活环境:`source .venv/bin/activate`(Windows PowerShell:`.venv\Scripts\Activate.ps1`)。以下命令均在仓库根目录执行。 + +安装后通过统一的 `mxlab` 命令训练和评估策略;使用 `mxlab --help` 查看命令,`mxlab --version` 查看版本。 ## 环境预览 -我们提供了一个简单的脚本,用于可视化一个环境,而不执行任何训练,这可以帮助您检测系统的环境依赖是否配置正确: +使用 `mxlab view` 可视化环境,而不执行任何训练,这可以帮助您检测系统的环境依赖是否配置正确: ```bash -python scripts/view.py env=cartpole +mxlab view env=cartpole ``` 这将打开一个可视化窗口,显示倒立摆的物理仿真环境,使用随机动作进行演示。 @@ -19,7 +21,7 @@ python scripts/view.py env=cartpole 开始训练倒立摆平衡任务: ```bash -mxtrain task=cartpole/skrl.ppo +mxlab train task=cartpole/skrl.ppo ``` 训练过程会自动: @@ -38,7 +40,7 @@ mxtrain task=cartpole/skrl.ppo 如果您想要在训练过程中观察模型的学习过程,可以启用可视化渲染: ```bash -mxtrain task=cartpole/skrl.ppo render=true +mxlab train task=cartpole/skrl.ppo render=true ``` ### 🎮 交互式渲染控制 @@ -67,10 +69,10 @@ tensorboard --logdir runs/cartpole ```bash # 自动寻找最佳策略测试(推荐) -mxplay env=cartpole +mxlab play env=cartpole # 手动指定带 metadata 的 run 中的 checkpoint -mxplay env=cartpole policy=/path/to/run/checkpoints/policy-file +mxlab play env=cartpole policy=/path/to/run/checkpoints/policy-file ``` > **提示**:系统会自动在 `runs/cartpole/` 下寻找最新 run 的最佳策略。手动指定的 checkpoint 必须属于包含 `metadata.json` 和 `task_config.yaml` 的 run。 diff --git a/docs/source/zh_CN/user_guide/getting_started/installation.md b/docs/source/zh_CN/user_guide/getting_started/installation.md index a59d28b7..18335e3f 100644 --- a/docs/source/zh_CN/user_guide/getting_started/installation.md +++ b/docs/source/zh_CN/user_guide/getting_started/installation.md @@ -1,130 +1,233 @@ -# 安装环境 +# 安装 -本文档将引导您完成 MotrixLab 的安装与配置。请仔细阅读系统要求,并根据您的使用场景选择合适的安装方式。 +MotrixLab 支持两种使用方式。请根据你是在仓库中运行现有任务,还是在自己的项目中使用框架,选择对应的安装方式。 + +| 使用场景 | 安装方式 | 获得的内容 | +| -------- | -------- | ---------- | +| 运行仓库内置任务、修改任务或参与框架开发 | [在 MotrixLab 仓库中安装](#installation-repository) | 仓库任务、配置和资产,以及安装脚本选择的框架与插件 | +| 在自己的项目中编写环境、组织训练配置 | [在自己的项目中安装](#installation-own-project) | `motrixlab` 集成包及其默认组件,由自己的项目管理代码、配置和资产 | + +两种方式都通过 `mxlab` 使用训练、评估、可视化、导出与部署命令;Python API 从各组件包导入,不通过 `motrixlab` 重新导出。 ## 系统要求 -- **Python 版本**:{bdg-danger-line}`3.10.* / 3.11.*` +- **Python**:3.10 或 3.11。仓库默认使用 Python 3.10;Unitree 硬件部署插件及包含该插件的完整开发环境仅支持 Python 3.10。Unitree 机器人模型的仿真与训练不受此限制。 +- **系统与架构**:Linux x86_64 或 Windows x86_64。具体 GPU 运行能力还取决于驱动和所选的 PyTorch 构建。 +- **包管理工具**:仓库安装使用 [uv](https://docs.astral.sh/uv/getting-started/installation/);自己的项目可以使用 pip 或 uv。 +- **Git 与 Git LFS**:仅仓库安装需要,用于获取源码及机器人网格、运动数据等资产。 - 默认使用 Python 3.10。 +(installation-repository)= +## 在 MotrixLab 仓库中安装 - | Python 版本 | 支持状态 | - | :---------: | :------: | - | ≤ 3.9 | ❌ | - | 3.10 | ✅ | - | 3.11 | ✅ | - | ≥ 3.12 | ❌ | +这种方式适合直接运行文档中的内置任务、修改仓库内的环境与配置,或者参与框架开发。安装脚本负责选择 workspace package 和 GPU 依赖,不需要逐个安装组件。 - Unitree 硬件部署与 `--all` 仅支持 Python 3.10;Unitree 机器人模型的仿真与训练可使用 Python 3.11。 +### 获取源码和资产 -- **包管理器**:{bdg-danger-line}`UV` +先安装 Git LFS,再克隆仓库: - 本项目采用 UV 作为唯一的包管理工具,以提供快速、可复现的依赖管理环境。UV 的安装方法请参考[官方文档](https://docs.astral.sh/uv/getting-started/installation/)。 +```bash +git clone https://github.com/Motphys/MotrixLab.git +cd MotrixLab +git lfs install +git lfs pull +``` -- **系统及架构**: +安装脚本也会检查并拉取 LFS 资产。缺少 Git LFS 时,请先安装它;不要将仓库中的 LFS 指针文件当作模型或运动数据使用。 - - {bdg-danger-line}`Windows(x86_64)` - - {bdg-danger-line}`Linux(x86_64)` +### 安装运行环境 - ```{note} - 不同操作系统对 MotrixLab 各功能模块的支持情况如下: +Linux: - | 操作系统 | CPU 仿真 | 交互式查看器 | - | :------: | :------: | :----------: | - | Linux | ✅ | ✅ | - | Windows | ✅ | ✅ | - ``` +```bash +sh install.sh +# 使用 Python 3.11,不包含 Unitree 硬件部署插件: +sh install.sh --python 3.11 +``` -## 安装步骤 +Windows PowerShell: -### 克隆项目仓库 +```powershell +.\install.ps1 +# 使用 Python 3.11: +.\install.ps1 --python 3.11 +``` + +若 PowerShell 执行策略阻止脚本运行,可以使用: + +```powershell +powershell -ExecutionPolicy Bypass -File install.ps1 +``` + +默认运行环境包含 `motrixlab`、仓库任务和所需插件,以及必需的 SKRL Torch provider 和内置 FastSAC。安装脚本自动探测 NVIDIA / AMD GPU,选择对应的 CUDA / ROCm PyTorch wheel;不能自动探测时回退到 CUDA 配置。ROCm 安装仅支持 Linux。 + +Linux 安装默认启用 Intel TBB,用于 Numba 并行 kernel。开发工具、文档工具、RSL-RL 和 SKRL JAX 不会在默认运行环境中全部启用,需要时使用下面的参数追加。 + +### 激活环境并检查安装 + +Linux: ```bash -git clone https://github.com/Motphys/MotrixLab.git -cd MotrixLab +source .venv/bin/activate ``` -### 安装运行环境 +Windows PowerShell: + +```powershell +.venv\Scripts\Activate.ps1 +``` -在仓库根目录执行以下命令安装运行环境(Windows 上请在 PowerShell 中执行 `install.ps1`;若执行策略受限,改用 `powershell -ExecutionPolicy Bypass -File install.ps1`): +检查统一命令入口: ```bash -sh install.sh # 默认 Python 3.10 -# 不含 Unitree 硬件部署插件的 Python 3.11 运行环境: -sh install.sh --python 3.11 +mxlab --version +mxlab --help ``` -该命令会自动探测 GPU 厂商(NVIDIA → CUDA,AMD → ROCm),安装运行环境所需的 workspace package、对应的 -PyTorch wheel、必需的 SKRL Torch provider 以及内置的 FastSAC 算法。Linux 上,`install.sh` 默认还会为 Numba 并行 kernel 安装 Intel TBB,`--all` 和两种 GPU 配置均包含 TBB;其他平台的默认运行环境安装不会启用 TBB。开发工具、文档工具、RSL-RL、SKRL JAX 和其他可选 extra 不会自动安装。 +随后可按照[第一个 MotrixLab 程序](hello_motrixlab.md)运行内置任务。 -:::{dropdown} 配置国内镜像源(可选) -:animate: fade-in -:color: warning -:icon: desktop-download -如果您身处中国大陆,建议配置国内镜像源以加速依赖下载。修改项目根目录的 `uv.toml` 文件: +```{important} +在这个仓库中,避免裸用 `uv sync` 或 `uv run`。CUDA 与 ROCm 由互斥 extras 选择,裸命令可能切换到默认的 PyPI 依赖分支并替换当前 GPU 环境。 -```toml -[[index]] -name = "mirror" -# 请填写您选择的国内镜像源,例如: -# 清华源: "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple" -url = "" +请在激活后的环境中直接执行 `mxlab`,或使用 `uv run --no-sync mxlab ...`。需要调整依赖时,重新执行带有所需参数的安装脚本;脚本每次重新计算依赖集合,不会永久累加之前选择的插件。 + +这个限制针对 MotrixLab 源码 workspace 的 GPU 配置,不是对所有 uv 项目的通用限制。 +``` +### 开发环境与可选依赖 -[[index]] -name = "pytorch" -url = "https://download.pytorch.org/whl/cu128" -default = true +参与框架开发、运行完整测试或构建文档时,安装完整开发环境: + +```bash +sh install.sh --all ``` -然后重新执行 `sh install.sh` 即可生效。 +`--all` 包含 Unitree 硬件插件,因此只支持 Python 3.10。它启用全部 workspace package、开发与测试依赖,以及支持的训练后端和文档工具;ROCm 配置会跳过 CUDA-only extra,例如 SKRL JAX。 + +也可以只追加当前需要的能力: + +```bash +sh install.sh --rslrl +sh install.sh --skrl-jax +sh install.sh --docs +``` + +重新安装时,请同时保留仍然需要的其他参数。 + +| 参数 | 说明 | +| ---- | ---- | +| `--python 3.10` / `--python 3.11` | 选择 Python 版本;默认 3.10,`--all` 要求 3.10 | +| `--gpu cuda` / `--gpu rocm` | 显式选择 GPU 依赖配置,覆盖自动探测;ROCm 仅限 Linux | +| `--gpu hygon` | Linux 海光 DCU 环境;保留外部 DTK 加速栈,需自行提供兼容的 Torch,不与 `--skrl-jax` 组合 | +| `--rslrl` | 添加 RSL-RL provider | +| `--skrl-jax` | 添加 SKRL JAX runtime,仅 Linux | +| `--skrl-torch` | 兼容性参数;SKRL Torch 已是仓库必需依赖 | +| `--tbb` | 显式启用 Intel TBB;Linux 安装脚本默认启用 | +| `--docs` | 添加文档工具链 | +| `--all` | 完整开发环境,仅 Python 3.10 | +| `--help` | 查看脚本的完整参数说明 | -::: +Windows 安装使用 `install.ps1`,可通过其 `--help` 查看支持的选项。 -### 激活环境 +(installation-own-project)= +## 在自己的项目中安装 -安装完成后,先激活环境再运行命令(Windows PowerShell:`.venv\Scripts\Activate.ps1`): +这种方式不需要克隆 MotrixLab 仓库。将 `motrixlab` 作为项目依赖安装,由自己的项目提供环境实现、任务配置和资产。 + +### 默认安装范围 + +`motrixlab` 提供统一的 `mxlab` CLI,并安装同一发布版本的以下组件: + +| 组件 | 能力 | +| ---- | ---- | +| `motrix-env-core` | backend 无关的环境框架、配置和 registry | +| `motrix-env-motrixsim` | MotrixSim 环境后端,并依赖安装 `motrixsim` | +| `motrix-rl` | 训练、评估与导出的控制平面 | +| `motrix-rl-builtin` | 内置 FastSAC provider | +| `motrix-deploy` | 部署 artifact 与运行时框架 | + +```{note} +`motrixlab` 不包含仓库内置任务、机器人资产、SKRL / RSL-RL provider 或具体部署 backend 插件。因此,安装后不能直接假定仓库中的 `cartpole` 等示例任务已经可用。 + +如果你希望直接运行这些任务,使用前面的仓库安装方式。自己的项目则需要提供任务配置,并按实际用途安装额外组件。 +``` + +下面的命令用于安装已发布的 PyPI 版本;新版本需在发布完成后才能安装。若当前只有 beta 预发布版本,使用对应示例中的预发布选项。 + +### 使用 pip + +在自己的项目目录创建独立环境: ```bash +python3.10 -m venv .venv source .venv/bin/activate +python -m pip install motrixlab ``` -```{note} -避免裸 `uv sync` / `uv run`:CUDA 与 ROCm wheel 由互斥的 extras 选择,裸命令会解析到默认的 PyPI -分支并可能替换当前环境。安装脚本每次都会重新计算请求的依赖集合,并非永久追加;使用不同参数重新运行时, -未被新选择的 package 可能会被移除。请从激活后的环境运行命令,或对单条命令使用 `uv run --no-sync`。 +Windows PowerShell 可使用 `py -3.10 -m venv .venv` 创建环境,然后运行 `.venv\Scripts\Activate.ps1` 激活。也可以选择 Python 3.11。 + +允许安装 beta 版本时: + +```bash +python -m pip install --pre motrixlab ``` -## 开发环境安装 +在项目的依赖文件中记录选定的版本,避免只修改本地环境而没有记录项目依赖。 + +### 使用 uv -上述运行环境只包含训练与部署所需的依赖。如果你要参与开发(运行测试、修改代码、构建文档), -执行以下命令安装完整开发环境: +对于已有 uv 项目,在项目目录中执行下面的步骤。如果尚未创建项目,可以先初始化: ```bash -sh install.sh --all +uv init --python 3.10 my-robot-project +cd my-robot-project ``` -`--all` 包含 Unitree 硬件部署插件,因此仅支持 Python 3.10,不能与 `--python 3.11` 组合。 -它会把所有依赖一次性全部启用:开发工具链、测试依赖、全部训练后端 -(SKRL Torch 为必需项;`--skrl-jax` 和 `--rslrl` 添加可选后端)与文档工具。在 ROCm 下,CUDA-only -extra(例如 SKRL JAX)会被跳过。也可以按需选择额外依赖,例如 `sh install.sh --docs` 只添加文档工具链。 +在添加依赖前,确认自己项目的 `pyproject.toml` 将 Python 支持范围限制在集成包支持的版本内。例如: + +```toml +[project] +requires-python = ">=3.10,<3.12" +``` + +`uv init --python 3.10` 选择的是解释器,初始化得到的 Python 版本范围仍可能没有上界。uv 会为项目声明的整个 Python 范围解析依赖,因此不能只确认当前解释器是 3.10,而让项目仍声明支持 3.12 及以上版本。 + +然后添加依赖: + +```bash +uv add motrixlab +``` + +若要允许 beta 版本: + +```bash +uv add --prerelease allow motrixlab +``` + +`uv add` 会更新自己项目的 `pyproject.toml` 和 `uv.lock`。后续使用 `uv sync` 恢复环境,并通过 `uv run` 运行项目命令: + +```bash +uv run mxlab --version +uv run mxlab --help +``` + +### 检查命令与配置 GPU + +使用 pip 安装时,在激活的环境中运行;使用 uv 时,在命令前加上 `uv run`: + +```bash +mxlab --help +mxlab train --help +mxlab play --help +mxlab view --help +mxlab export-onnx --help +mxlab export-deploy --help +mxlab deploy --help +``` -## 安装参数参考 +这些命令用于检查 CLI 和配置帮助,不代表已经执行仿真、训练或硬件部署。 -运行环境只安装训练与部署所需的 package,其中包括必需的 SKRL Torch 与 builtin provider,不会安装所有可选 -workspace plugin;`--all` 才会安装全部 workspace package 与支持的开发 extra。后端参数负责选择或追加: +与仓库安装脚本不同,`pip install motrixlab` 和 `uv add motrixlab` **不会自动探测 GPU 厂商并选择专用 wheel 源**。默认安装按组件依赖从包索引解析 PyTorch;CUDA / ROCm wheel、驱动及相关环境配置需要由你自己的项目管理。 -| 参数 | 可选值 | 说明 | -| ---- | ------ | ---- | -| `--python` | `3.10`
`3.11` | 选择 Python 版本;默认 `3.10`,`3.11` 仅用于不含 Unitree 硬件部署插件的运行环境 | -| `--all` | — | 完整开发环境,包含 Unitree,仅支持 Python 3.10(开发工具链、测试依赖、全部训练后端与文档工具) | -| (无参数) | — | 运行环境;自动探测 GPU 厂商(NVIDIA → CUDA,AMD → ROCm,无法探测时回退 CUDA) | -| `--gpu` | `cuda`
`rocm` | 指定 torch wheel 来源,覆盖自动探测 | -| `--skrl-torch` | — | 兼容性参数;SKRL Torch 已由根项目作为必需依赖提供 | -| `--skrl-jax` | — | 添加 SKRL(JAX)训练后端,仅 Linux | -| `--rslrl` | — | 添加 RSL-RL(PyTorch)训练后端,同时保留必需的 SKRL | -| `--tbb` | — | 显式为 Numba 并行 kernel 安装 Intel TBB 线程层;Linux 上的 `install.sh` 已默认启用,安装后自动生效 | -| `--docs` | — | 追加本地构建文档所需的工具链(Sphinx) | -| `-h`、`--help` | — | 显示帮助 | +请根据 [PyTorch 官方安装指引](https://pytorch.org/get-started/locally/)选择与硬件匹配的构建。使用 uv 时,应在自己的项目中声明相应的版本约束和索引来源,不要假定依赖包仓库内的 `tool.uv.sources` 配置会传递到你的项目。仅安装成功或 `mxlab --help` 正常,不代表 GPU runtime 已可用。 -完整参数说明见 `sh install.sh --help`。 +安装完成后,先按[编写 DirectEnv 环境](../tutorial/building_envs/direct_env.md)创建并注册环境,再按[Task 配置与命令行参数覆盖](../tutorial/training/task_config.md)组织自己的训练配置。运行 Task 前,需安装它使用的 RL provider:默认集成包包含 FastSAC provider;使用 SKRL PPO 或 RSL-RL PPO 时,还需分别安装 `motrix-rl-skrl` 或 `motrix-rl-rslrl`。 diff --git a/docs/source/zh_CN/user_guide/robots.md b/docs/source/zh_CN/user_guide/robots.md index 0c1910fd..6da12c97 100644 --- a/docs/source/zh_CN/user_guide/robots.md +++ b/docs/source/zh_CN/user_guide/robots.md @@ -21,10 +21,10 @@ ## 独立预览 -使用 `view.py` 可以在默认姿态下查看已注册 robot,无需创建 RL environment: +使用 `mxlab view` 可以在默认姿态下查看已注册 robot,无需创建 RL environment: ```bash -python scripts/view.py robot=go2 +mxlab view robot=go2 ``` robot 模式会构建一个静态标准场景,不采样 action,也不执行 physics rollout。 @@ -194,7 +194,7 @@ my_robot = "my_robot_package.registration:register" 先通过 registry 构造配置并预览机器人: ```bash -python scripts/view.py robot=my-robot +mxlab view robot=my-robot python -m pytest motrix_envs/tests/test_robot_cfg.py -q ``` diff --git a/docs/source/zh_CN/user_guide/tutorial/advanced/custom_training_backend.md b/docs/source/zh_CN/user_guide/tutorial/advanced/custom_training_backend.md index 1819faa5..6b49d198 100644 --- a/docs/source/zh_CN/user_guide/tutorial/advanced/custom_training_backend.md +++ b/docs/source/zh_CN/user_guide/tutorial/advanced/custom_training_backend.md @@ -201,7 +201,7 @@ seed: 42 如果后端已经在启动路径中完成注册,可以直接用 CLI: ```bash -mxtrain task=cartpole/myrl.ppo +mxlab train task=cartpole/myrl.ppo ``` 如果是外部实验包,使用自己的 Hydra config root,并在进入训练入口前导入 backend 注册模块。无需额外的 Python task registry。 diff --git a/docs/source/zh_CN/user_guide/tutorial/advanced/export_onnx.md b/docs/source/zh_CN/user_guide/tutorial/advanced/export_onnx.md index 11961eca..3a4d2be9 100644 --- a/docs/source/zh_CN/user_guide/tutorial/advanced/export_onnx.md +++ b/docs/source/zh_CN/user_guide/tutorial/advanced/export_onnx.md @@ -23,9 +23,9 @@ SKRL/JAX checkpoint 暂不支持导出。导出命令接收完整的 run 目录 ## 导出模型 -激活已安装的环境后,运行 `mxexport onnx`(或 `python -m motrix_rl.commands.export onnx`)。 -`mxexport` 必须显式选择 `onnx` 或 `deploy` 子命令,没有默认子命令。 -不需要选择 `task` 或导入模块来触发注册:导出直接从已保存的 run 恢复策略,不创建环境。需要安装该 run 使用的 RL provider;环境 provider 发现属于独立的 registry 职责。 +激活已安装的环境后,运行 `mxlab export-onnx`。 +`mxlab export-onnx` 直接导出 ONNX 模型;部署 artifact 使用独立的 `mxlab export-deploy` 命令。 +不需要选择 `task` 或导入模块来触发注册:导出直接从已保存的 run 恢复策略,不创建环境。导出前需安装该 run 使用的 RL provider。 命令会使用当前目录下存在的 `./configs`,也可以通过 `--config-dir ` 显式指定配置目录; 项目文件优先,缺失的文件回退到 `motrix_rl.configs`,其中包含 `export_onnx.yaml`。 无需仓库 checkout,相对 run 路径和输出路径均相对于当前工作目录解析。 @@ -39,7 +39,7 @@ runs/cartpole/skrl/torch/ppo// 指定输出文件进行导出: ```bash -mxexport onnx \ +mxlab export-onnx \ run_dir=runs/cartpole/skrl/torch/ppo/ \ output=artifacts/cartpole.onnx ``` @@ -49,7 +49,7 @@ mxexport onnx \ 如果省略 `output`,模型会写入最佳 checkpoint 所在目录,文件名为 `policy.onnx`: ```bash -mxexport onnx \ +mxlab export-onnx \ run_dir=runs/cartpole/skrl/torch/ppo/ ``` @@ -111,7 +111,7 @@ print(actions) 例如,导出为 opset 17,并增加检查样本数: ```bash -mxexport onnx \ +mxlab export-onnx \ run_dir= \ output=policy.onnx \ opset=17 \ diff --git a/docs/source/zh_CN/user_guide/tutorial/advanced/motrix_deploy.md b/docs/source/zh_CN/user_guide/tutorial/advanced/motrix_deploy.md index 2a1730c8..fdeeae8f 100644 --- a/docs/source/zh_CN/user_guide/tutorial/advanced/motrix_deploy.md +++ b/docs/source/zh_CN/user_guide/tutorial/advanced/motrix_deploy.md @@ -3,7 +3,7 @@ 将导出的 Go2 策略先在 MuJoCo 中检查,再尝试真机部署。安装任务和 MuJoCo 插件后,可用以下命令进行有界无窗口检查: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy runtime.viewer=false duration_s=2.0 +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy runtime.viewer=false duration_s=2.0 ``` 下面介绍如何生成 artifact、交互控制,以及现有 Unitree 真机工作流。 @@ -15,7 +15,7 @@ mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy runtime. ```bash sh install.sh --all source .venv/bin/activate -mxtrain task=go2-walk-flat/rslrl.ppo +mxlab train task=go2-walk-flat/rslrl.ppo ``` 训练结果保存在 `runs/go2-walk-flat/`。已有包含 metadata 的 run 时可跳过训练。 @@ -23,23 +23,22 @@ mxtrain task=go2-walk-flat/rslrl.ppo ## 2. 导出并检查 artifact ```bash -mxexport deploy env=go2-walk-flat output=artifacts/go2-walk-flat.deploy -mxdeploy inspect artifact=artifacts/go2-walk-flat.deploy +mxlab export-deploy env=go2-walk-flat output=artifacts/go2-walk-flat.deploy +mxlab deploy inspect artifact=artifacts/go2-walk-flat.deploy ``` `env=go2-walk-flat` 选择最近一次包含 metadata 的 run。用 `run_dir=` 替代 `env` 可选择指定 run: `env` 与 `run_dir` 必须且只能设置一个。`output=` 可更改输出位置,省略时默认为 `artifacts/.deploy`。已有 artifact 目录不会被覆盖。确认检查结果为 `valid: true`。 -`mxexport` 必须显式选择 `onnx` 或 `deploy` 子命令。等价模块命令是 -`python -m motrix_rl.commands.export deploy`。导出会使用当前目录下存在的 `./configs`,也可通过 +`mxlab export-deploy` 直接导出部署 artifact;独立的 `mxlab export-onnx` 命令用于导出 ONNX 模型。 +导出会使用当前目录下存在的 `./configs`,也可通过 `--config-dir ` 显式指定;项目文件优先,缺失文件回退到 `motrix_rl.configs`。 其中打包了 `export_deploy.yaml` 与 `export_onnx.yaml`,因此导出不需要仓库 checkout。 部署导出的数值检查选项仍使用 `validation.*`(例如 `validation.atol=3e-5`), -而不是 ONNX 子命令的 `parity.*`。 +而不是 `mxlab export-onnx` 的 `parity.*`。 -导出由 `motrix-rl` 执行,需要训练 provider 和该环境已安装的 profile compiler。 -依赖是单向的:`motrix-rl` 使用 `motrix-deploy` 创建 artifact;`motrix-deploy` 不依赖 RL。 +导出前需安装该 run 使用的训练 provider,以及该环境对应的 profile compiler。 artifact 目录自包含: @@ -63,7 +62,7 @@ go2-walk-flat.deploy/ 使用开头的无窗口命令进行有界运行,或打开 viewer: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy ``` 按住 `W/S` 前后移动,`A/D` 横移,`Q/E` 转向。关闭窗口、按 Esc 或 Ctrl-C 退出。 @@ -93,7 +92,7 @@ runtime 负责物理推进、调度与 viewer。[进阶的显式组装](#显式 安装 `motrix-deploy-motrixsim` 后,将 backend 切换为 `motrixsim`,即可复用同一 artifact 和场景配方: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ runtime.backend=motrixsim runtime.viewer=true ``` @@ -109,7 +108,7 @@ python examples/deploy_to_sim.py --backend motrixsim 让机器人执行站下动作。先检查 artifact,再将 `enp5s0` 换成实际网卡名称: ```bash -mxdeploy task=go2-walk-flat/hardware \ +mxlab deploy task=go2-walk-flat/hardware \ artifact=artifacts/go2-walk-flat.deploy \ runtime.network_interface=enp5s0 ``` @@ -149,25 +148,25 @@ motrix-deploy-unitree joint-control enp5s0 FL_thigh_joint 0.9 \ ## 部署 G1 WBT 舞蹈 -G1 全身跟踪舞蹈任务使用同样的导出 → artifact → `mxdeploy` 流程。artifact 内嵌伺服增益、action scale、 +G1 全身跟踪舞蹈任务使用同样的导出 → artifact → `mxlab deploy` 流程。artifact 内嵌伺服增益、action scale、 preparation 增益与时序、安全阈值以及完整的 motion 片段(以 `payloads/motion.npz` payload 形式,校验和记录在 manifest 中),部署既不需要 Torch 也不需要 RL 环境。导出需要训练 provider 与任务环境包,但**不**执行训练: ```bash source .venv/bin/activate RUN=runs/g1-wbt-dance/motrix/torch/fastsac/ -mxexport deploy run_dir="$RUN" \ +mxlab export-deploy run_dir="$RUN" \ output=artifacts/g1-wbt-dance-software-pd.deploy validation.atol=3e-5 -mxdeploy task=g1-wbt-dance/sim artifact=artifacts/g1-wbt-dance.deploy +mxlab deploy task=g1-wbt-dance/sim artifact=artifacts/g1-wbt-dance.deploy ``` 无窗口验证与 artifact 检查: ```bash -mxdeploy task=g1-wbt-dance/sim artifact=artifacts/g1-wbt-dance.deploy \ +mxlab deploy task=g1-wbt-dance/sim artifact=artifacts/g1-wbt-dance.deploy \ runtime.viewer=false -mxdeploy inspect artifact=artifacts/g1-wbt-dance.deploy +mxlab deploy inspect artifact=artifacts/g1-wbt-dance.deploy ``` 默认时长来自内嵌的 motion 片段;更短的运行用 `duration_s` 缩短,超长时长会在打开 backend 前被拒绝, @@ -211,7 +210,7 @@ def register() -> None: 安装 package 后,导出对应环境的 run: ```bash -mxexport deploy run_dir=/path/to/my-walk-flat/run output=artifacts/my-walk-flat.deploy +mxlab export-deploy run_dir=/path/to/my-walk-flat/run output=artifacts/my-walk-flat.deploy ``` 首次 profile 查询、列举或构建会加载所有已安装的 provider 回调,每个进程执行一次。 @@ -253,7 +252,7 @@ spec = Go2WalkTaskSpec.model_validate(OmegaConf.to_container(cfg, resolve=True)) 保留同一 Go2 recipe 和 artifact,仅切换世界: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ runtime.deploy_env_id=rough ``` @@ -346,7 +345,7 @@ with runtime: 选择原生 backend: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ runtime.backend=motrixsim runtime.viewer=false runtime.realtime=false duration_s=1.0 ``` @@ -371,7 +370,7 @@ Headless 使用零速度指令;窗口模式在可用时使用 viewer keyboard `/absolute/path/to/my_app/config/deploy.yaml`,不是选择或复制内置 recipe: ```bash -mxdeploy \ +mxlab deploy \ --config-path /absolute/path/to/my_app/config \ --config-name deploy \ artifact=artifacts/go2-walk-flat.deploy diff --git a/docs/source/zh_CN/user_guide/tutorial/basic_frame.md b/docs/source/zh_CN/user_guide/tutorial/basic_frame.md index 9f4bdefa..182896ef 100644 --- a/docs/source/zh_CN/user_guide/tutorial/basic_frame.md +++ b/docs/source/zh_CN/user_guide/tutorial/basic_frame.md @@ -33,6 +33,7 @@ MotrixLab 是一个 UV workspace。下面按所有权而不是按单一整体运 | Package | 流程环节 | 职责 | | --- | --- | --- | +| `motrixlab` | 应用集成 | 提供统一 `mxlab` CLI 与环境/机器人可视化 | | `motrix_env_core` | 策略与环境的交互 | backend 无关的环境框架:`EnvCfg`、registry、环境前端与生命周期 | | `motrix_env_motrixsim` | 策略与环境的交互 | MotrixSim `SimBackend`、renderer 与 Torch frontend | | `motrix_env_mujoco` | 场景编译 | 仅负责编译场景的 MuJoCo backend | @@ -42,9 +43,9 @@ MotrixLab 是一个 UV workspace。下面按所有权而不是按单一整体运 | `motrix_rl_builtin` | 策略的训练与更新 | 内置 Motrix FastSAC provider | | `motrix_rl_skrl` | 策略的训练与更新 | SKRL PPO Torch provider(必需)及可选 JAX extra | | `motrix_rl_rslrl` | 策略的训练与更新 | RSL-RL PPO Torch provider(可选) | -| `motrix_rl.configs`、`motrix_rl.commands` | 配置与编排 | 打包的 train/play 配置与算法默认值;安装后的 `mxtrain` / `mxplay` 入口 | -| `configs/`、`scripts/` | Workspace 配方与工具 | 具体 Task 配方与 view 配置;view / export 工具及 train/play 薄包装 | -| `motrix_deploy` | 策略的部署 | 框架无关 artifact、运行时契约与部署 CLI | +| `motrix_rl.configs`、`motrix_rl.commands` | 配置与编排 | 打包的 train/play/export 配置与算法默认值;`mxlab train` / `mxlab play` / `mxlab export-onnx` / `mxlab export-deploy` 的命令实现 | +| `configs/`、`scripts/` | Workspace 配方与工具 | 具体 Task 配方与仓库辅助工具 | +| `motrix_deploy` | 策略的部署 | 框架无关 artifact、运行时契约与 `mxlab deploy` 的命令实现 | | `motrix_deploy_mujoco` | 策略的部署 | MuJoCo 部署 backend plugin | | `motrix_deploy_motrixsim` | 策略的部署 | MotrixSim 部署 backend plugin | | `motrix_deploy_unitree` | 策略的部署 | Unitree 硬件配置、sensor/actuation 接线与 SDK2 DDS backend plugin | @@ -56,22 +57,28 @@ MotrixLab 是一个 UV workspace。下面按所有权而不是按单一整体运 配置与命令源码的目录如下: ```text +motrixlab/src/motrixlab/ +├── commands/ +│ └── view.py # 环境与机器人可视化 +└── configs/ + └── view.yaml motrix_rl/src/motrix_rl/ -├── commands/ # mxtrain / mxplay +├── commands/ # 训练、评估与导出命令实现 └── configs/ ├── train.yaml ├── play.yaml └── algo_base/ configs/ -├── task/ # workspace 训练配方 -└── view.yaml -scripts/ # view/export 工具;train/play 薄包装 +└── task/ # workspace 训练配方 +scripts/ # 仓库辅助工具 ``` ## 一次训练的完整流程 +以下示例使用仓库内置任务,请先完成{ref}`仓库安装 `,激活环境,并在仓库根目录执行命令。默认运行环境已包含 SKRL provider;运行下面的 RSL-RL 示例前,还需通过 `sh install.sh --rslrl` 安装对应 provider。 + ```bash -mxtrain task=cartpole/skrl.ppo num_envs=1024 +mxlab train task=cartpole/skrl.ppo num_envs=1024 ``` 1. Hydra 组合 `motrix_rl/src/motrix_rl/configs/train.yaml`、`motrix_rl/src/motrix_rl/configs/algo_base/skrl.ppo.yaml` 和 @@ -83,8 +90,8 @@ mxtrain task=cartpole/skrl.ppo num_envs=1024 同一环境可以拥有多份 Task 配方,不需要修改环境实现: ```bash -mxtrain task=cartpole/skrl.ppo -mxtrain task=cartpole/rslrl.ppo +mxlab train task=cartpole/skrl.ppo +mxlab train task=cartpole/rslrl.ppo ``` ## 运行导出的策略 @@ -92,7 +99,7 @@ mxtrain task=cartpole/rslrl.ppo 部署使用 artifact,而不是训练环境: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy runtime.viewer=false duration_s=2.0 +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy runtime.viewer=false duration_s=2.0 ``` 上例在 MuJoCo 中无窗口运行导出的策略。导出、交互控制及真机操作见 [Go2 部署](advanced/motrix_deploy.md)。 diff --git a/docs/source/zh_CN/user_guide/tutorial/building_envs/direct_env.md b/docs/source/zh_CN/user_guide/tutorial/building_envs/direct_env.md index 0e2fb6e6..e3470f46 100644 --- a/docs/source/zh_CN/user_guide/tutorial/building_envs/direct_env.md +++ b/docs/source/zh_CN/user_guide/tutorial/building_envs/direct_env.md @@ -106,7 +106,7 @@ class CartPoleEnv(DirectEnv): return state.replace(obs=obs) ``` -注册完成后,`python scripts/view.py env=cartpole` 可以预览,按 +注册完成后,`mxlab view env=cartpole` 可以预览,按 [Task 配置](../training/task_config.md)创建训练 Task 即可开始训练。 从示例可以读出 DirectEnv 的三个核心要素: diff --git a/docs/source/zh_CN/user_guide/tutorial/building_envs/index.md b/docs/source/zh_CN/user_guide/tutorial/building_envs/index.md index ae91adac..c6c7f503 100644 --- a/docs/source/zh_CN/user_guide/tutorial/building_envs/index.md +++ b/docs/source/zh_CN/user_guide/tutorial/building_envs/index.md @@ -9,7 +9,7 @@ 通过 `@registry.envcfg("name")` 注册; - **环境类**:实现任务逻辑,通过 `@registry.env("name")` 注册。 -注册完成后,`scripts/view.py`、训练器与回放流程都通过同一个注册表按名字创建环境。 +注册完成后,`mxlab view`、训练器与回放流程都通过同一个注册表按名字创建环境。 已安装的环境 package 会被自动发现;两种工作流的 package 发布方式见[环境注册](direct_env.md#环境注册)。 diff --git a/docs/source/zh_CN/user_guide/tutorial/building_envs/manager_env.md b/docs/source/zh_CN/user_guide/tutorial/building_envs/manager_env.md index 44eef3bd..091b10c9 100644 --- a/docs/source/zh_CN/user_guide/tutorial/building_envs/manager_env.md +++ b/docs/source/zh_CN/user_guide/tutorial/building_envs/manager_env.md @@ -278,5 +278,5 @@ def make_microduck_ball_balance_cfg() -> MicroduckBallBalanceEnvCfg: registry.env("microduck-ball-balance")(ManagerEnv) ``` -注册完成后,`python scripts/view.py env=` 可以预览,按 +注册完成后,`mxlab view env=` 可以预览,按 [Task 配置](../training/task_config.md)创建训练 Task 即可开始训练。 diff --git a/docs/source/zh_CN/user_guide/tutorial/building_envs/terrain.md b/docs/source/zh_CN/user_guide/tutorial/building_envs/terrain.md index ffff7551..709ebf1d 100644 --- a/docs/source/zh_CN/user_guide/tutorial/building_envs/terrain.md +++ b/docs/source/zh_CN/user_guide/tutorial/building_envs/terrain.md @@ -48,7 +48,7 @@ class MyTaskEnvCfg(EnvCfg): 可以直接预览效果: ```bash -python scripts/view.py env=go1-walk-rough +mxlab view env=go1-walk-rough ``` ## 生成器契约 diff --git a/docs/source/zh_CN/user_guide/tutorial/training/index.md b/docs/source/zh_CN/user_guide/tutorial/training/index.md index 993e7811..344cf615 100644 --- a/docs/source/zh_CN/user_guide/tutorial/training/index.md +++ b/docs/source/zh_CN/user_guide/tutorial/training/index.md @@ -5,7 +5,7 @@ ```text 创建 Task 配置 指定环境、RL 框架、算法与超参数 ↓ -mxtrain task=... Hydra 组合配置并启动训练 +mxlab train task=... Hydra 组合配置并启动训练 ↓ runs/{env}/... 保存 metadata、日志与 checkpoint ``` diff --git a/docs/source/zh_CN/user_guide/tutorial/training/runs_and_checkpoints.md b/docs/source/zh_CN/user_guide/tutorial/training/runs_and_checkpoints.md index b35bec32..34cecdc4 100644 --- a/docs/source/zh_CN/user_guide/tutorial/training/runs_and_checkpoints.md +++ b/docs/source/zh_CN/user_guide/tutorial/training/runs_and_checkpoints.md @@ -93,7 +93,7 @@ runs/g1-walk-flat/motrix/torch/fastsac/26-07-06_11-37-50-376526/ ``` - `manifest.json` 里的 `path` 相对于 `checkpoints/` 目录。 -- **`best_policy`**(`kind: policy`):用于回放 / 导出 / 评测,是 `mxplay` 默认加载的产物。 +- **`best_policy`**(`kind: policy`):用于回放 / 导出 / 评测,是 `mxlab play` 默认加载的产物。 - **`latest_training_state`**(`kind: training_state`):用于续训,应包含 optimizer、观测归一化器、replay buffer、`global_step` 等继续训练所需的完整状态。 - 同一个物理文件可以**同时登记为两个 artifact**。例如 FastSAC 的 `latest.pt`(完整 state dict)既能回放又能续训,因此 `best_policy` 与 `latest_training_state` 都指向它。 @@ -106,16 +106,16 @@ runs/g1-walk-flat/motrix/torch/fastsac/26-07-06_11-37-50-376526/ ```bash # 自动发现最新 run 的最佳策略 - mxplay env=g1-walk-flat + mxlab play env=g1-walk-flat # 指定某个 checkpoint(需能向上找到 metadata.json) - mxplay env=g1-walk-flat policy=/path/to/run/checkpoints/latest.pt + mxlab play env=g1-walk-flat policy=/path/to/run/checkpoints/latest.pt ``` - **续训(resume)**:将 `resume=` 设置为 run 目录或 checkpoint 路径,框架据此解析出 `latest_training_state` 继续训练。 ```bash - mxtrain task=g1-walk-flat/motrix.fastsac \ + mxlab train task=g1-walk-flat/motrix.fastsac \ resume=/path/to/run ``` diff --git a/docs/source/zh_CN/user_guide/tutorial/training/task_config.md b/docs/source/zh_CN/user_guide/tutorial/training/task_config.md index ca2b5fa3..f02cca85 100644 --- a/docs/source/zh_CN/user_guide/tutorial/training/task_config.md +++ b/docs/source/zh_CN/user_guide/tutorial/training/task_config.md @@ -62,7 +62,7 @@ Task 只需填写与算法基础配置不同的值,不需要复制所有算法 ### 检查最终配置 -`mxtrain` 默认使用当前工作目录下存在的 `./configs`,不会向上搜索父目录。使用 `--config-dir /path/to/configs` 可指定其他配置目录。必须显式选择 Task,没有默认的 Cartpole Task。 +`mxlab train` 默认使用当前工作目录下存在的 `./configs`,不会向上搜索父目录。使用 `--config-dir /path/to/configs` 可指定其他配置目录。必须显式选择 Task,没有默认的 Cartpole Task。 运行 Task 前先安装环境 package,registry 查询会自动发现已安装的 provider。 自定义环境的打包方式见[环境注册](../building_envs/direct_env.md#环境注册);Task YAML 的发现与环境发现相互独立。 @@ -70,19 +70,19 @@ Task 只需填写与算法基础配置不同的值,不需要复制所有算法 启动训练前,可以先输出 Hydra 组合后的完整配置: ```bash -mxtrain --cfg job --resolve task=my-robot/skrl.ppo +mxlab train --cfg job --resolve task=my-robot/skrl.ppo ``` 该命令不会开始训练。确认 `task.env`、`num_envs` 和 `algo.trainer.timesteps` 符合预期后,再启动训练: ```bash -mxtrain task=my-robot/skrl.ppo +mxlab train task=my-robot/skrl.ppo ``` 运行以下命令可以查看仓库中所有可选 Task: ```bash -mxtrain --help +mxlab train --help ``` ## 调整 Task 的运行参数 @@ -196,7 +196,7 @@ MotrixLab CLI 使用 Hydra 的 `key=value` 参数语法。CLI 覆盖只影响本 ### 覆盖运行参数 ```bash -mxtrain \ +mxlab train \ task=my-robot/skrl.ppo \ num_envs=64 \ seed=7 \ @@ -207,7 +207,7 @@ mxtrain \ 开启训练渲染,并在训练完成后播放: ```bash -mxtrain task=my-robot/skrl.ppo render=true play=true +mxlab train task=my-robot/skrl.ppo render=true play=true ``` ### 覆盖算法参数 @@ -215,7 +215,7 @@ mxtrain task=my-robot/skrl.ppo render=true play=true SKRL PPO: ```bash -mxtrain \ +mxlab train \ task=my-robot/skrl.ppo \ algo.agent.learning_rate=5e-4 \ algo.agent.learning_epochs=8 \ @@ -225,7 +225,7 @@ mxtrain \ RSLRL PPO: ```bash -mxtrain \ +mxlab train \ task=cartpole/rslrl.ppo \ algo.algorithm.learning_rate=5e-4 \ algo.algorithm.entropy_coef=0.005 \ @@ -235,7 +235,7 @@ mxtrain \ FastSAC: ```bash -mxtrain \ +mxlab train \ task=g1-walk-flat/motrix.fastsac \ algo.asynchronous=true \ algo.agent.actor_learning_rate=1e-4 \ @@ -249,20 +249,20 @@ mxtrain \ 布尔值使用小写 `true` 或 `false`: ```bash -mxtrain task=my-robot/skrl.ppo render=true +mxlab train task=my-robot/skrl.ppo render=true ``` 使用 `null` 清空可空字段: ```bash -mxtrain task=my-robot/skrl.ppo seed=null -mxtrain task=my-robot/skrl.ppo algo.agent.learning_rate_scheduler=null +mxlab train task=my-robot/skrl.ppo seed=null +mxlab train task=my-robot/skrl.ppo algo.agent.learning_rate_scheduler=null ``` 列表建议使用引号,避免 shell 解释方括号: ```bash -mxtrain \ +mxlab train \ task=my-robot/skrl.ppo \ 'algo.models.policy.hiddens=[128,64]' \ 'algo.models.value.hiddens=[128,64]' @@ -279,7 +279,7 @@ mxtrain \ 将 CLI 覆盖和 `--cfg job --resolve` 组合,可以查看本次运行最终会使用的值: ```bash -mxtrain \ +mxlab train \ --cfg job \ --resolve \ task=my-robot/skrl.ppo \ @@ -321,13 +321,13 @@ algo: 使用 JAX 差异配置训练: ```bash -mxtrain task=go2-walk-flat/skrl.ppo.jax +mxlab train task=go2-walk-flat/skrl.ppo.jax ``` 直接覆盖后端也可以选择 JAX 训练器: ```bash -mxtrain task=go2-walk-flat/skrl.ppo task.train_backend=jax +mxlab train task=go2-walk-flat/skrl.ppo task.train_backend=jax ``` 这种写法不会加载 `skrl.ppo.jax.yaml` 中的后端专用参数。当后端差异文件存在时,应直接选择带 `.jax` 或 `.torch` 后缀的 Task。 @@ -348,7 +348,6 @@ motrix_rl/src/motrix_rl/configs/ └── motrix.fastsac.yaml configs/ -├── view.yaml └── task/ └── / ├── ..yaml @@ -419,18 +418,18 @@ Hydra 会根据 provider 注册的结构化 schema 检查字段名和类型。 ## Play 和 View 的参数覆盖 -`mxplay` 恢复已保存的 run 配置,不需要训练 Task 目录。它和 `scripts/view.py` 同样使用 `key=value` 语法: +`mxlab play` 恢复已保存的 run 配置,不需要训练 Task 目录。它和 `mxlab view` 同样使用 `key=value` 语法: ```bash -python scripts/view.py env=cartpole num_envs=4 -mxplay env=cartpole num_envs=1 -mxplay policy=/path/to/checkpoint.pt num_envs=1 +mxlab view env=cartpole num_envs=4 +mxlab play env=cartpole num_envs=1 +mxlab play policy=/path/to/checkpoint.pt num_envs=1 ``` Play 默认读取训练 run 中保存的 `task_config.yaml`。如需临时覆盖其中的算法参数,使用 `rl` 作为算法配置根节点。因为 `rl` 初始为空,需要用 `+` 添加路径: ```bash -mxplay \ +mxlab play \ env=cartpole \ '+rl.agent.learning_rate=1e-4' ``` diff --git a/docs/source/zh_CN/user_guide/tutorial/training/training_and_result.md b/docs/source/zh_CN/user_guide/tutorial/training/training_and_result.md index e98dd3ef..e45698b7 100644 --- a/docs/source/zh_CN/user_guide/tutorial/training/training_and_result.md +++ b/docs/source/zh_CN/user_guide/tutorial/training/training_and_result.md @@ -16,12 +16,12 @@ Task 配方只选择 RL provider,不会替你安装 provider。如果 Task 需 ```bash # 显式选择 Cartpole SKRL PPO Task -mxtrain task=cartpole/skrl.ppo +mxlab train task=cartpole/skrl.ppo # 选择其他框架或算法 -mxtrain task=cartpole/rslrl.ppo -mxtrain task=g1-walk-flat/motrix.fastsac -mxtrain task=g1-walk-flat/motrix.fastsac algo.asynchronous=false +mxlab train task=cartpole/rslrl.ppo +mxlab train task=g1-walk-flat/motrix.fastsac +mxlab train task=g1-walk-flat/motrix.fastsac algo.asynchronous=false ``` 当前内置的 RL method 与训练后端: @@ -32,28 +32,28 @@ mxtrain task=g1-walk-flat/motrix.fastsac algo.asynchronous=false | `rslrl.ppo` | `torch` | RSLRL PPO | | `motrix.fastsac` | `torch` | FastSAC;`algo.asynchronous` 选择同步或异步拓扑 | -请在仓库根目录执行这些命令:CLI 会发现当前工作目录下存在的 `./configs`,不会向上查找父目录。运行 `mxtrain --help` 可以查看当前代码中全部可选 Task。Task 文件结构和覆盖规则见 [Task 配置与命令行参数覆盖](task_config.md)。 +请在仓库根目录执行这些命令:CLI 会发现当前工作目录下存在的 `./configs`,不会向上查找父目录。运行 `mxlab train --help` 可以查看当前代码中全部可选 Task。Task 文件结构和覆盖规则见 [Task 配置与命令行参数覆盖](task_config.md)。 ### 选择训练后端与仿真后端 ```bash # 覆盖训练后端(task.train_backend 为 null 时自动选择) -mxtrain task=cartpole/skrl.ppo task.train_backend=jax -mxtrain task=cartpole/skrl.ppo task.train_backend=torch +mxlab train task=cartpole/skrl.ppo task.train_backend=jax +mxlab train task=cartpole/skrl.ppo task.train_backend=torch # 指定 manager 环境注入的仿真器 -mxtrain task=g1-wbt-dance/motrix.fastsac sim=motrixsim +mxlab train task=g1-wbt-dance/motrix.fastsac sim=motrixsim ``` ### 训练规模与随机种子 ```bash # 并行环境数量 -mxtrain task=cartpole/skrl.ppo num_envs=1024 +mxlab train task=cartpole/skrl.ppo num_envs=1024 # 固定随机种子(复现)/ 运行时选择随机种子 -mxtrain task=cartpole/skrl.ppo seed=42 -mxtrain task=cartpole/skrl.ppo seed=null +mxlab train task=cartpole/skrl.ppo seed=42 +mxlab train task=cartpole/skrl.ppo seed=null ``` ```{note} @@ -64,20 +64,20 @@ Hydra 可以直接覆盖已经声明的算法字段,例如 `algo.agent.learnin ```bash # 训练成功结束后,用本次 run 的最佳策略自动回放 -mxtrain task=g1-walk-flat/motrix.fastsac play=true +mxlab train task=g1-walk-flat/motrix.fastsac play=true # 从某个 run 目录或 checkpoint 续训 -mxtrain task=g1-walk-flat/motrix.fastsac \ +mxlab train task=g1-walk-flat/motrix.fastsac \ resume=/path/to/run # 启用渲染监控训练过程 -mxtrain task=cartpole/skrl.ppo render=true +mxlab train task=cartpole/skrl.ppo render=true ``` -训练和回放是两个独立操作:`play=true` 会在训练成功后回放本次 run 的最佳策略;稍后可使用 `mxplay` 重新打开已保存的 run。使用以下命令导出训练好的策略 artifact: +训练和回放是两个独立操作:`play=true` 会在训练成功后回放本次 run 的最佳策略;稍后可使用 `mxlab play` 重新打开已保存的 run。使用以下命令导出训练好的策略 artifact: ```bash -mxexport onnx run_dir=/path/to/run output=/tmp/policy.onnx +mxlab export-onnx run_dir=/path/to/run output=/tmp/policy.onnx ``` ### 常用 Hydra 覆盖项 @@ -115,14 +115,14 @@ tensorboard --logdir runs/cartpole ```bash # 自动发现最新 run 的最佳策略并回放(推荐) -mxplay env=cartpole +mxlab play env=cartpole # 指定某个 checkpoint(需能向上找到 metadata.json) -mxplay env=g1-walk-flat \ +mxlab play env=g1-walk-flat \ policy=/path/to/run/checkpoints/latest.pt # 指定回放环境数量 -mxplay env=cartpole num_envs=100 +mxlab play env=cartpole num_envs=100 ``` ```{note} diff --git a/motrix_deploy/README.md b/motrix_deploy/README.md index 889a5991..d25cd7c4 100644 --- a/motrix_deploy/README.md +++ b/motrix_deploy/README.md @@ -1,10 +1,12 @@ # Motrix Deploy `motrix-deploy` runs exported policies without a training framework. It provides deployment artifacts, -robot/task contracts, shared control execution, runtime plugin discovery, and the `mxdeploy` CLI. +robot/task contracts, shared control execution, runtime plugin discovery, and the implementation behind +`mxlab deploy`. Install `motrixlab` for the sole `mxlab` CLI; this component retains its Python APIs and +internal callable deployment adapter. Use `mxlab --version` to query the version. Install the task and runtime plugins needed for your target. `motrix-deploy` does not depend on `motrix-rl`: training-run export belongs to `motrix-rl`, which depends on this package, while deployment runs independently. -Create artifacts with `mxexport deploy run_dir= output=artifacts/policy.deploy`; see the +Create artifacts with `mxlab export-deploy run_dir= output=artifacts/policy.deploy`; see the [deployment tutorial](../docs/source/en/user_guide/tutorial/advanced/motrix_deploy.md) for export. Environment packages provide profile compilers through package registration callbacks in `motrix_deploy.profiles`; see [adding a profile compiler](../docs/source/en/user_guide/tutorial/advanced/motrix_deploy.md#add-a-deployment-profile-compiler) @@ -13,7 +15,7 @@ for the provider recipe and discovery requirements. With the Go2 task and a simulation backend installed: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy ``` ## Hardware API diff --git a/motrix_deploy/pyproject.toml b/motrix_deploy/pyproject.toml index 9ff4c2da..57aa5a95 100644 --- a/motrix_deploy/pyproject.toml +++ b/motrix_deploy/pyproject.toml @@ -40,9 +40,6 @@ dependencies = [ "pydantic===2.12.5", ] -[project.scripts] -mxdeploy = "motrix_deploy.cli:main" - [project.urls] Homepage = "https://github.com/Motphys/MotrixLab" Repository = "https://github.com/Motphys/MotrixLab" diff --git a/motrix_deploy/src/motrix_deploy/cli.py b/motrix_deploy/src/motrix_deploy/cli.py index 974b11f2..9dcbf153 100644 --- a/motrix_deploy/src/motrix_deploy/cli.py +++ b/motrix_deploy/src/motrix_deploy/cli.py @@ -6,7 +6,6 @@ import json import math import sys -from collections.abc import Sequence from pathlib import Path import hydra @@ -14,7 +13,6 @@ from omegaconf import DictConfig, OmegaConf from omegaconf.errors import OmegaConfBaseException -from motrix_deploy import __version__ from motrix_deploy.artifact.io import inspect_artifact, read_artifact from motrix_deploy.config import DeployRunConfig, SimRuntimeCfg from motrix_deploy.errors import ArtifactError, ValidationError @@ -115,29 +113,12 @@ def _hydra_inspect_main(cfg: DictConfig) -> None: raise SystemExit(2) from error -def main(argv: Sequence[str] | None = None) -> int | None: - """Inspect an artifact or run a Hydra-configured deployment rollout.""" - if argv is not None: - original_argv = sys.argv - sys.argv = ["mxdeploy", *argv] - try: - return main() - finally: - sys.argv = original_argv - - args = sys.argv[1:] - if args[:1] == ["inspect"]: - del sys.argv[1] +def main() -> None: + """Adapt ``mxlab deploy`` arguments to the deployment Hydra commands.""" + if sys.argv[1:2] == ["inspect"]: + sys.argv = [f"{sys.argv[0]} inspect", *sys.argv[2:]] _hydra_inspect_main() - return None - if args == ["--version"]: - print(f"mxdeploy {__version__}") - return 0 - if not args: + return + if not sys.argv[1:]: sys.argv.append("--help") _hydra_main() - return None - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/motrix_deploy/tests/test_artifact.py b/motrix_deploy/tests/test_artifact.py index e4880251..57ae6a32 100644 --- a/motrix_deploy/tests/test_artifact.py +++ b/motrix_deploy/tests/test_artifact.py @@ -85,7 +85,7 @@ def test_cli_inspect_outputs_json(tmp_path: Path, manifest_factory: Callable[[], env = dict(os.environ) env["PYTHONPATH"] = os.pathsep.join([str(tmp_path), str(Path(__file__).parent), env.get("PYTHONPATH", "")]) result = subprocess.run( - [sys.executable, "-m", "motrix_deploy.cli", "inspect", f"artifact={output}"], + [sys.executable, "-m", "motrixlab.cli", "deploy", "inspect", f"artifact={output}"], env=env, check=False, capture_output=True, diff --git a/motrix_deploy/tests/test_package.py b/motrix_deploy/tests/test_package.py index 2b9afed4..5005b144 100644 --- a/motrix_deploy/tests/test_package.py +++ b/motrix_deploy/tests/test_package.py @@ -12,7 +12,7 @@ @pytest.mark.integration def test_cli_help() -> None: result = subprocess.run( - [sys.executable, "-m", "motrix_deploy.cli", "--help"], + [sys.executable, "-m", "motrixlab.cli", "deploy", "--help"], check=False, capture_output=True, text=True, diff --git a/motrix_deploy_motrixsim/README.md b/motrix_deploy_motrixsim/README.md index f6ba701e..de36962d 100644 --- a/motrix_deploy_motrixsim/README.md +++ b/motrix_deploy_motrixsim/README.md @@ -22,7 +22,7 @@ Artifact deployment reuses the installed simulation recipes rather than introduc backend-specific task copies: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ runtime.backend=motrixsim runtime.viewer=false runtime.realtime=false duration_s=1 ``` diff --git a/motrix_deploy_mujoco/README.md b/motrix_deploy_mujoco/README.md index 00058aca..74515365 100644 --- a/motrix_deploy_mujoco/README.md +++ b/motrix_deploy_mujoco/README.md @@ -7,7 +7,7 @@ joint control, and an optional interactive viewer. With `motrix-deploy-tasks` and a matching exported artifact: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy ``` For programmatic use, see [deploy_to_sim.py](../examples/deploy_to_sim.py). diff --git a/motrix_deploy_tasks/README.md b/motrix_deploy_tasks/README.md index b974fc83..f2baa91c 100644 --- a/motrix_deploy_tasks/README.md +++ b/motrix_deploy_tasks/README.md @@ -7,7 +7,7 @@ task. It does not provide a simulation or hardware backend. Install a backend plugin and use an artifact exported for the matching task: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy ``` Use `go2-walk-rough/sim` for the rough scene, `runtime.backend=motrixsim` for native @@ -19,7 +19,7 @@ for export, configuration, and hardware safety procedures. ## G1 WBT dance: MuJoCo / MotrixSim sim2sim -Use the standard **export → artifact → `mxdeploy`** pipeline. The `g1_wbt/v1` task +Use the standard **export → artifact → `mxlab deploy`** pipeline. The `g1_wbt/v1` task embeds the actor's motion references, servo gains, action scales, preparation gains and timing, and hardware-observable termination thresholds in the artifact. Deployment requires neither Torch nor an RL environment; export needs the training provider and task @@ -28,19 +28,19 @@ environment packages, but does **not** train. ```bash source .venv/bin/activate RUN=runs/g1-wbt-dance/motrix/torch/fastsac/ -mxexport deploy run_dir="$RUN" \ +mxlab export-deploy run_dir="$RUN" \ output=artifacts/g1-wbt-dance-software-pd.deploy validation.atol=3e-5 -mxdeploy task=g1-wbt-dance/sim \ +mxlab deploy task=g1-wbt-dance/sim \ artifact=artifacts/g1-wbt-dance-software-pd.deploy ``` Headless validation and artifact inspection: ```bash -mxdeploy task=g1-wbt-dance/sim \ +mxlab deploy task=g1-wbt-dance/sim \ artifact=artifacts/g1-wbt-dance-software-pd.deploy runtime.viewer=false -mxdeploy inspect artifact=artifacts/g1-wbt-dance-software-pd.deploy +mxlab deploy inspect artifact=artifacts/g1-wbt-dance-software-pd.deploy ``` Notes: diff --git a/motrix_deploy_tasks/tests/test_cli.py b/motrix_deploy_tasks/tests/test_cli.py index 393f8982..609eb63c 100644 --- a/motrix_deploy_tasks/tests/test_cli.py +++ b/motrix_deploy_tasks/tests/test_cli.py @@ -45,7 +45,7 @@ def _rollout_result(stdout: str) -> dict[str, object]: @pytest.mark.parametrize("args", [[], ["--help"]]) def test_cli_general_help(args: list[str]) -> None: result = subprocess.run( - [sys.executable, "-m", "motrix_deploy.cli", *args], + [sys.executable, "-m", "motrixlab.cli", "deploy", *args], check=False, capture_output=True, text=True, @@ -59,8 +59,9 @@ def test_cli_help() -> None: result = subprocess.run( [ sys.executable, - "-c", - "from motrix_deploy.cli import main; raise SystemExit(main())", + "-m", + "motrixlab.cli", + "deploy", "task=go2-walk-rough/sim", "--help", ], @@ -79,8 +80,9 @@ def test_hardware_cli_help_selects_hardware_recipe() -> None: result = subprocess.run( [ sys.executable, - "-c", - "from motrix_deploy.cli import main; raise SystemExit(main())", + "-m", + "motrixlab.cli", + "deploy", "task=go2-walk-flat/hardware", "--help", ], @@ -105,7 +107,7 @@ def test_installed_recipes_compose_outside_workspace(tmp_path, task, runtime_kin if runtime_kind == "hardware": pytest.importorskip("motrix_deploy_unitree.config") result = subprocess.run( - [sys.executable, "-m", "motrix_deploy.cli", f"task={task}", "--cfg", "job"], + [sys.executable, "-m", "motrixlab.cli", "deploy", f"task={task}", "--cfg", "job"], cwd=tmp_path, check=False, capture_output=True, @@ -295,8 +297,9 @@ def test_headless_simulation_cli_runs_deterministic_onnx_fixture(tmp_path: Path, write_artifact(artifact_path, manifest, {"policy/model.onnx": policy_bytes}) command = [ sys.executable, - "-c", - "from motrix_deploy.cli import main; raise SystemExit(main())", + "-m", + "motrixlab.cli", + "deploy", f"task={task}/sim", f"runtime.backend={backend}", f"artifact={artifact_path}", @@ -357,8 +360,9 @@ def test_standard_cli_completes_four_phase_flow(tmp_path, backend, solver_iterat write_artifact(artifact, manifest, {"policy/model.onnx": payload, **profile.payloads}) command = [ sys.executable, - "-c", - "from motrix_deploy.cli import main; main()", + "-m", + "motrixlab.cli", + "deploy", "task=g1-wbt-dance/sim", f"artifact={artifact}", "runtime.viewer=false", diff --git a/motrix_deploy_unitree/README.md b/motrix_deploy_unitree/README.md index 5c4a0302..545b240e 100644 --- a/motrix_deploy_unitree/README.md +++ b/motrix_deploy_unitree/README.md @@ -26,7 +26,7 @@ motrix-deploy-unitree read-lowstate With `motrix-deploy-tasks` and a matching artifact installed: ```bash -mxdeploy task=go2-walk-flat/hardware artifact=artifacts/go2-walk-flat.deploy \ +mxlab deploy task=go2-walk-flat/hardware artifact=artifacts/go2-walk-flat.deploy \ runtime.network_interface= ``` diff --git a/motrix_envs/README.md b/motrix_envs/README.md index 55293837..aabfcb40 100644 --- a/motrix_envs/README.md +++ b/motrix_envs/README.md @@ -15,10 +15,10 @@ env = registry.make("cartpole", num_envs=1) The package includes the `basic`, `locomotion`, and `manipulation` environment families. Environment names used by training and playback commands remain unchanged. -Install the `deploy` extra to use the built-in deployment profile compilers with `mxexport deploy`: +Install the `deploy` extra to use the built-in deployment profile compilers with `mxlab export-deploy`: ```bash -mxexport deploy env=go2-walk-rough output=artifacts/go2-walk-rough.deploy +mxlab export-deploy env=go2-walk-rough output=artifacts/go2-walk-rough.deploy ``` The installed package publishes one provider for its built-in profile compilers: diff --git a/motrix_rl/README.md b/motrix_rl/README.md index e2a4b626..cad869e9 100644 --- a/motrix_rl/README.md +++ b/motrix_rl/README.md @@ -69,28 +69,28 @@ a `rocm` extra's Torch version alone does not guarantee a ROCm build. GPU select ## Usage -Installing `motrix-rl` provides `mxtrain`, `mxplay`, and `mxexport`, backed by `motrix_rl.commands.train`, -`motrix_rl.commands.play`, and the `motrix_rl.commands.export` dispatcher. `mxexport` requires an explicit -`onnx` or `deploy` subcommand; there is no default subcommand. Their primary Hydra configurations ship in +Install `motrixlab` for the `mxlab train`, `mxlab play`, `mxlab export-onnx`, and `mxlab export-deploy` +commands, backed by `motrix_rl.commands.train`, `motrix_rl.commands.play`, +`motrix_rl.commands.export_onnx`, and `motrix_rl.commands.export_deploy`. Their primary Hydra configurations ship in `motrix_rl.configs`; the commands do not require a repository checkout or a particular working directory. -For training and playback, install an environment package and the selected provider too. +For training and playback, install an environment package and the selected provider too. The application package also provides `mxlab view` for environment and robot visualization; see the [integration package README](../motrixlab/README.md). For the built-in environments, activate the installed workspace environment (`source .venv/bin/activate`) and run from the workspace root: ```bash -mxtrain task=cartpole/skrl.ppo -mxtrain task=cartpole/rslrl.ppo -mxtrain task=g1-walk-rough/motrix.fastsac -mxplay env=cartpole -mxplay env=cartpole policy=/path/to/run -mxexport onnx run_dir=/path/to/run output=artifacts/policy.onnx -mxexport deploy run_dir=/path/to/run output=artifacts/policy.deploy -mxexport deploy env=go2-walk-flat output=artifacts/go2-walk-flat.deploy +mxlab train task=cartpole/skrl.ppo +mxlab train task=cartpole/rslrl.ppo +mxlab train task=g1-walk-rough/motrix.fastsac +mxlab play env=cartpole +mxlab play env=cartpole policy=/path/to/run +mxlab export-onnx run_dir=/path/to/run output=artifacts/policy.onnx +mxlab export-deploy run_dir=/path/to/run output=artifacts/policy.deploy +mxlab export-deploy env=go2-walk-flat output=artifacts/go2-walk-flat.deploy ``` -`mxexport onnx` exports a saved run's best policy without selecting a `task` or creating an environment. Install the provider used by +`mxlab export-onnx` exports a saved run's best policy without selecting a `task` or creating an environment. Install the provider used by that run; see the [ONNX export tutorial](../docs/source/en/user_guide/tutorial/advanced/export_onnx.md) for supported -configurations. `mxexport deploy` creates a self-contained deployment artifact; specify exactly one of `run_dir` or +configurations. `mxlab export-deploy` creates a self-contained deployment artifact; specify exactly one of `run_dir` or `env` (the latter selects the latest metadata-backed run). Its numerical checks use `validation.*`, while ONNX export uses `parity.*`. The `export_onnx.yaml` and `export_deploy.yaml` configurations ship in `motrix_rl.configs` and follow the same project-first discovery described below, falling back to packaged files when the project does not provide them. @@ -99,11 +99,9 @@ Deployment profile compilers come from installed environment plugins, without ha See the [deployment tutorial](../docs/source/en/user_guide/tutorial/advanced/motrix_deploy.md#add-a-deployment-profile-compiler) for the plugin contract. `motrix-rl` depends on `motrix-deploy` for artifact creation; `motrix-deploy` does not depend on RL. -The equivalent module commands are `python -m motrix_rl.commands.train`, `python -m motrix_rl.commands.play`, and -`python -m motrix_rl.commands.export onnx` / `python -m motrix_rl.commands.export deploy`. The subcommands are implemented -in `motrix_rl.commands.export_onnx` and `motrix_rl.commands.export_deploy`; the repository's export scripts are thin -wrappers around those commands. In an already installed uv environment, use -`uv run --no-sync mxtrain ...` (or `mxplay` / `mxexport`) to avoid re-resolving GPU profiles. +`mxlab` is the sole CLI entry point; the component modules retain internal callable command adapters and Python APIs. +Use `mxlab --version` to query the version. In an already installed uv environment, use +`uv run --no-sync mxlab train ...` (or `mxlab play` / `mxlab export-onnx` / `mxlab export-deploy`) to avoid re-resolving GPU profiles. Run artifacts are written under `runs/` relative to the working directory by default. Primary train/play configurations and shared provider defaults ship in `motrix_rl.configs`, with sources under @@ -136,12 +134,12 @@ files not provided by the project fall back to the package. Hydra selects the fi same-name files from multiple directories: ```bash -mxtrain task=my-task/skrl.ppo -mxtrain --config-dir /path/to/project/configs task=my-task/skrl.ppo +mxlab train task=my-task/skrl.ppo +mxlab train --config-dir /path/to/project/configs task=my-task/skrl.ppo ``` Install the external environment package; train and play discover its registered environments automatically. -Playback uses the same discovery: `mxplay env=my-task`. See +Playback uses the same discovery: `mxlab play env=my-task`. See [Environment registration](../docs/source/en/user_guide/tutorial/building_envs/direct_env.md#environment-registration) for packaging an environment. @@ -168,5 +166,5 @@ Make `my_project.configs` an importable package (include `__init__.py`) and incl Package both `my_project` and `hydra_plugins/my_project_searchpath.py` in the installed distribution. Keep `hydra_plugins` a shared namespace package: **do not add `hydra_plugins/__init__.py`**. Hydra discovers installed plugin modules in that namespace; no custom entry point or working-directory import convention is needed. Once installed, run -`mxtrain task=my-task/skrl.ppo` from any directory. Environment callbacks only register environments; they do not +`mxlab train task=my-task/skrl.ppo` from any directory. Environment callbacks only register environments; they do not install Hydra search paths. RL provider plugins still register separately through `motrix_rl.frameworks`. diff --git a/motrix_rl/pyproject.toml b/motrix_rl/pyproject.toml index 16941634..32118d8c 100644 --- a/motrix_rl/pyproject.toml +++ b/motrix_rl/pyproject.toml @@ -46,11 +46,6 @@ dependencies = [ "torch>=2.7,<3", ] -[project.scripts] -mxtrain = "motrix_rl.commands.train:main" -mxplay = "motrix_rl.commands.play:main" -mxexport = "motrix_rl.commands.export:main" - [project.optional-dependencies] cuda = [ "torch==2.7.0; sys_platform == 'linux' or sys_platform == 'win32'", diff --git a/motrix_rl/src/motrix_rl/commands/export.py b/motrix_rl/src/motrix_rl/commands/export.py deleted file mode 100644 index 9a104590..00000000 --- a/motrix_rl/src/motrix_rl/commands/export.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright Motphys Technology Co., Ltd. 2025, 2026 -# SPDX-License-Identifier: Apache-2.0 - -"""Export training results as ONNX policies or deployment artifacts.""" - -import argparse -import sys - - -def main() -> None: - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("format", choices=("onnx", "deploy"), help="artifact format to export") - if sys.argv[1:2] in (["onnx"], ["deploy"]): - format_name = sys.argv[1] - else: - parser.parse_args(sys.argv[1:] or ["--help"]) - return - - if format_name == "onnx": - from motrix_rl.commands.export_onnx import main as export_main - else: - from motrix_rl.commands.export_deploy import main as export_main - - original_argv = sys.argv - sys.argv = [f"{original_argv[0]} {format_name}", *original_argv[2:]] - try: - export_main() - finally: - sys.argv = original_argv - - -if __name__ == "__main__": - main() diff --git a/motrix_rl/src/motrix_rl/commands/export_deploy.py b/motrix_rl/src/motrix_rl/commands/export_deploy.py index 154ef448..f54f8dd9 100644 --- a/motrix_rl/src/motrix_rl/commands/export_deploy.py +++ b/motrix_rl/src/motrix_rl/commands/export_deploy.py @@ -64,7 +64,3 @@ def _hydra_main(cfg: DictConfig) -> None: def main() -> None: run_cli(_hydra_main) - - -if __name__ == "__main__": - main() diff --git a/motrix_rl/src/motrix_rl/commands/export_onnx.py b/motrix_rl/src/motrix_rl/commands/export_onnx.py index 8261fd2f..67d1d33b 100644 --- a/motrix_rl/src/motrix_rl/commands/export_onnx.py +++ b/motrix_rl/src/motrix_rl/commands/export_onnx.py @@ -55,7 +55,3 @@ def _hydra_main(cfg: DictConfig) -> None: def main() -> None: run_cli(_hydra_main) - - -if __name__ == "__main__": - main() diff --git a/motrix_rl/src/motrix_rl/commands/play.py b/motrix_rl/src/motrix_rl/commands/play.py index 9600af8a..441f9f34 100644 --- a/motrix_rl/src/motrix_rl/commands/play.py +++ b/motrix_rl/src/motrix_rl/commands/play.py @@ -128,7 +128,3 @@ def _hydra_main(cfg: DictConfig) -> None: def main() -> None: run_cli(_hydra_main) - - -if __name__ == "__main__": - main() diff --git a/motrix_rl/src/motrix_rl/commands/train.py b/motrix_rl/src/motrix_rl/commands/train.py index eb881e41..1a44259b 100644 --- a/motrix_rl/src/motrix_rl/commands/train.py +++ b/motrix_rl/src/motrix_rl/commands/train.py @@ -53,7 +53,3 @@ def _hydra_main(cfg: DictConfig) -> None: def main() -> None: run_cli(_hydra_main) - - -if __name__ == "__main__": - main() diff --git a/motrix_rl/src/motrix_rl/config.py b/motrix_rl/src/motrix_rl/config.py index e70ae89d..e52a85b7 100644 --- a/motrix_rl/src/motrix_rl/config.py +++ b/motrix_rl/src/motrix_rl/config.py @@ -90,7 +90,7 @@ class TaskConfig: @dataclass class TrainConfig(TaskConfig): - """Top-level schema for ``mxtrain``.""" + """Top-level schema for ``mxlab train``.""" render: bool = False play: bool = False @@ -100,7 +100,7 @@ class TrainConfig(TaskConfig): @dataclass class PlayConfig: - """Top-level schema for ``mxplay``.""" + """Top-level schema for ``mxlab play``.""" env: str | None = None sim: str | None = None @@ -117,22 +117,11 @@ class PlayConfig: rl: Any = field(default_factory=dict) -@dataclass -class ViewConfig: - """Top-level schema for ``scripts/view.py``.""" - - env: str | None = None - robot: str | None = None - sim: str | None = None - num_envs: int = 1 - - def register_configs() -> None: """Register CLI schemas in Hydra's ConfigStore. Idempotent.""" cs = ConfigStore.instance() cs.store(name="train_schema", node=TrainConfig) cs.store(name="play_schema", node=PlayConfig) - cs.store(name="view_schema", node=ViewConfig) cs.store(name="export_onnx_schema", node=OnnxExportConfig) cs.store(name="export_deploy_schema", node=DeploymentExportConfig) diff --git a/motrix_rl/tests/test_rl_cli.py b/motrix_rl/tests/test_rl_cli.py index cf4f3b70..dbc49fff 100644 --- a/motrix_rl/tests/test_rl_cli.py +++ b/motrix_rl/tests/test_rl_cli.py @@ -8,48 +8,16 @@ import pytest from motrix_rl.cli import run_cli -from motrix_rl.commands.export import main as export_main - - -@pytest.mark.parametrize("format_name", ["onnx", "deploy"]) -def test_export_dispatch_preserves_hydra_arguments_and_restores_argv(monkeypatch, format_name): - import importlib - - module = importlib.import_module(f"motrix_rl.commands.export_{format_name}") - observed = [] - - def command(): - observed.append(sys.argv.copy()) - raise RuntimeError("export failed") - - monkeypatch.setattr(module, "main", command) - original = ["mxexport", format_name, "run_dir=example", "--config-dir", "/project/configs"] - monkeypatch.setattr(sys, "argv", original) - with pytest.raises(RuntimeError, match="export failed"): - export_main() - assert observed == [[f"mxexport {format_name}", *original[2:]]] - assert sys.argv is original - - -@pytest.mark.parametrize("args,code", [([], 0), (["--help"], 0), (["invalid"], 2)]) -def test_export_requires_an_explicit_format(monkeypatch, capsys, args, code): - monkeypatch.setattr(sys, "argv", ["mxexport", *args]) - with pytest.raises(SystemExit) as error: - export_main() - assert error.value.code == code - output = capsys.readouterr() - assert "onnx" in output.out + output.err - assert "deploy" in output.out + output.err def test_cli_uses_local_configs_and_restores_arguments(monkeypatch, tmp_path): (tmp_path / "configs").mkdir() monkeypatch.chdir(tmp_path) - original = ["mxtrain", "task=example/ppo"] + original = ["mxlab train", "task=example/ppo"] monkeypatch.setattr(sys, "argv", original) observed = [] run_cli(lambda: observed.append(sys.argv.copy())) - assert observed == [["mxtrain", "--config-dir", str(tmp_path / "configs"), "task=example/ppo"]] + assert observed == [["mxlab train", "--config-dir", str(tmp_path / "configs"), "task=example/ppo"]] assert sys.argv is original @@ -57,7 +25,7 @@ def test_cli_uses_local_configs_and_restores_arguments(monkeypatch, tmp_path): def test_explicit_hydra_directory_bypasses_local_default(monkeypatch, tmp_path, args): (tmp_path / "configs").mkdir() monkeypatch.chdir(tmp_path) - original = ["mxtrain", *args] + original = ["mxlab train", *args] monkeypatch.setattr(sys, "argv", original) observed = [] run_cli(lambda: observed.append(sys.argv.copy())) @@ -69,7 +37,7 @@ def test_cli_does_not_search_parent_directories(monkeypatch, tmp_path): child = tmp_path / "child" child.mkdir() monkeypatch.chdir(child) - original = ["mxplay", "--cfg", "job"] + original = ["mxlab play", "--cfg", "job"] monkeypatch.setattr(sys, "argv", original) observed = [] run_cli(lambda: observed.append(sys.argv.copy())) diff --git a/motrixlab/.gitignore b/motrixlab/.gitignore new file mode 100644 index 00000000..c2420c9b --- /dev/null +++ b/motrixlab/.gitignore @@ -0,0 +1,5 @@ +# Local setuptools build artifacts. +/build/ +/dist/ +/*.egg-info/ +/src/*.egg-info/ diff --git a/motrixlab/LICENSE b/motrixlab/LICENSE new file mode 100644 index 00000000..34bead94 --- /dev/null +++ b/motrixlab/LICENSE @@ -0,0 +1,204 @@ +Copyright Motphys Technology Co., Ltd. 2025, 2026 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/motrixlab/README.md b/motrixlab/README.md new file mode 100644 index 00000000..5831fd10 --- /dev/null +++ b/motrixlab/README.md @@ -0,0 +1,64 @@ +# MotrixLab + +MotrixLab is a reinforcement learning framework for robotics. This application integration package +provides the unified `mxlab` command, environment and robot visualization, and a single installation entry point +for the backend-neutral environment framework, policy deployment runtime, RL control plane, built-in FastSAC +provider, and MotrixSim simulation backend. + +## Installation + +Use Python 3.10 or 3.11: + +```bash +python -m pip install motrixlab +``` + +For a beta release, add `--pre`. All five component packages are pinned to the +same release version. The MotrixSim backend installs `motrixsim` from public PyPI. +PyTorch and its dependencies are installed through the component packages; +GPU-specific wheel selection and driver setup remain environment-specific. + +## Usage and scope + +`mxlab` is the command-line entry point for training, playback, environment and robot visualization, export, and deployment: + +```bash +mxlab --help +mxlab --version +mxlab train --help +mxlab play --help +mxlab view --help +mxlab export-onnx --help +mxlab export-deploy --help +mxlab deploy --help +mxlab deploy inspect artifact=/path/to/policy.deploy +``` + +With the selected environment or robot package installed, inspect an environment with random actions or a robot in its default pose: + +```bash +mxlab view env= +mxlab view robot= +``` + +Subcommands preserve their component's parameter syntax, including Hydra `key=value` +overrides and configuration-directory options. `export-deploy` creates an artifact; +`deploy` runs it. `mxlab --version` is the sole version operation. Install this package +for the CLI; the standalone component packages retain their Python APIs and internal +callable command adapters, not independent CLI entry points. + +The CLI imports only the selected command; top-level help and version do not load +Torch or a simulator. Environment and robot visualization belongs to this application package; +its `view.yaml` configuration is packaged in `motrixlab.configs`. Training, playback, export, and deployment +implementations remain in their component packages. Public Python APIs remain in `motrix_env_core`, +`motrix_deploy`, `motrix_rl`, `motrix_rl_builtin`, and `motrix_env_motrixsim`; the integration package does not re-export them. +The built-in RL provider and MotrixSim backend are discovered via package entry points. + +This installation does **not** include the repository's task environments, robot +assets, SKRL/RSLRL providers, or deployment backend plugins. Running a task requires +installing or supplying its environment and assets separately. For the full +repository task collection and GPU-aware source installation, follow the +[repository quick start](https://github.com/Motphys/MotrixLab#-quick-start). + +See the [user documentation](https://motrixlab.readthedocs.io) for framework and +training usage. diff --git a/motrixlab/pyproject.toml b/motrixlab/pyproject.toml new file mode 100644 index 00000000..6e2c7af9 --- /dev/null +++ b/motrixlab/pyproject.toml @@ -0,0 +1,51 @@ +[build-system] +requires = ["setuptools>=77,<83"] +build-backend = "setuptools.build_meta" + +[project] +name = "motrixlab" +version = "0.4.0b1" +description = "MotrixLab framework with built-in reinforcement learning and the MotrixSim backend." +authors = [{ name = "Motphys", email = "developers@motphys.com" }] +requires-python = ">=3.10,<3.12" +readme = "README.md" +license = "Apache-2.0" +license-files = ["LICENSE"] +keywords = ["reinforcement-learning", "robotics", "simulation"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering :: Artificial Intelligence", +] +dependencies = [ + "gymnasium==1.1.1", + "hydra-core>=1.3,<1.4", + "motrixsim==0.10.1", + "numpy>=1.26", + "omegaconf>=2.3,<2.4", + "motrix-env-core==0.4.0b1", + "motrix-deploy==0.4.0b1", + "motrix-rl==0.4.0b1", + "motrix-rl-builtin==0.4.0b1", + "motrix-env-motrixsim==0.4.0b1", +] + +[project.urls] +Homepage = "https://github.com/Motphys/MotrixLab" +Documentation = "https://motrixlab.readthedocs.io" +Repository = "https://github.com/Motphys/MotrixLab" +Issues = "https://github.com/Motphys/MotrixLab/issues" +Changelog = "https://github.com/Motphys/MotrixLab/releases" + +[project.scripts] +mxlab = "motrixlab.cli:main" + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.setuptools.package-data] +"motrixlab.configs" = ["*.yaml"] diff --git a/motrixlab/src/motrixlab/__init__.py b/motrixlab/src/motrixlab/__init__.py new file mode 100644 index 00000000..d8c51e4c --- /dev/null +++ b/motrixlab/src/motrixlab/__init__.py @@ -0,0 +1,4 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 + +"""MotrixLab installation and command-line integration package.""" diff --git a/motrixlab/src/motrixlab/cli.py b/motrixlab/src/motrixlab/cli.py new file mode 100644 index 00000000..0393c348 --- /dev/null +++ b/motrixlab/src/motrixlab/cli.py @@ -0,0 +1,40 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 + +"""Unified command entry point; component packages own command behavior.""" + +import argparse +import sys +from importlib import import_module +from importlib.metadata import version + +_COMMANDS = { + "train": "motrix_rl.commands.train", + "play": "motrix_rl.commands.play", + "view": "motrixlab.commands.view", + "export-onnx": "motrix_rl.commands.export_onnx", + "export-deploy": "motrix_rl.commands.export_deploy", + "deploy": "motrix_deploy.cli", +} + + +def main() -> int | None: + parser = argparse.ArgumentParser(prog="mxlab", description="MotrixLab training and deployment tools.") + parser.add_argument("--version", action="version", version=f"%(prog)s {version('motrixlab')}") + parser.add_argument("command", choices=tuple(_COMMANDS), help="command to run; use COMMAND --help for details") + if sys.argv[1:2] and sys.argv[1] in _COMMANDS: + command = sys.argv[1] + else: + parser.parse_args(sys.argv[1:] or ["--help"]) + return None + + original_argv = sys.argv + sys.argv = [f"mxlab {command}", *original_argv[2:]] + try: + return import_module(_COMMANDS[command]).main() + finally: + sys.argv = original_argv + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/motrixlab/src/motrixlab/commands/__init__.py b/motrixlab/src/motrixlab/commands/__init__.py new file mode 100644 index 00000000..a655a514 --- /dev/null +++ b/motrixlab/src/motrixlab/commands/__init__.py @@ -0,0 +1,2 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 diff --git a/scripts/view.py b/motrixlab/src/motrixlab/commands/view.py similarity index 75% rename from scripts/view.py rename to motrixlab/src/motrixlab/commands/view.py index 6ae0a66a..61ab01fd 100644 --- a/scripts/view.py +++ b/motrixlab/src/motrixlab/commands/view.py @@ -1,26 +1,29 @@ # Copyright Motphys Technology Co., Ltd. 2025, 2026 # SPDX-License-Identifier: Apache-2.0 +import argparse import time -from typing import TYPE_CHECKING +from dataclasses import dataclass +from pathlib import Path +from typing import TYPE_CHECKING, cast import gymnasium as gym import hydra import motrixsim as mtx import numpy as np +from hydra.core.config_store import ConfigStore from motrixsim.render import RenderApp, RenderClosedError, RenderSettings -from omegaconf import DictConfig +from omegaconf import DictConfig, OmegaConf from motrix_env_core import registry from motrix_env_core.array.env import ArrayEnv from motrix_env_core.base import ABEnv -from motrix_env_core.config import SimCfg -from motrix_env_core.config.scene import RobotCfg, SystemCameraCfg +from motrix_env_core.config import SimCfg, configclass +from motrix_env_core.config.scene.base import RobotCfg, SceneCfg, SceneObjsCfg, SceneVisualCfg, SystemCameraCfg +from motrix_env_core.config.scene.geometry import FlatTerrainCfg +from motrix_env_core.config.scene.light import LightCfg from motrix_env_core.renderer import RenderConfig, create_renderer from motrix_env_motrixsim.compiler import build_scene_model -from motrix_envs.config.scene import StandardSceneCfg, StandardSceneObjsCfg -from motrix_rl.cli import to_typed_config -from motrix_rl.config import ViewConfig if TYPE_CHECKING: from motrix_env_motrixsim.torch_env import TorchEnv @@ -29,6 +32,16 @@ ROBOT_VIEW_FPS = 60 +@dataclass +class ViewConfig: + """Top-level schema for environment and robot viewing.""" + + env: str | None = None + robot: str | None = None + sim: str | None = None + num_envs: int = 1 + + def _sample_random_action_np(env: ABEnv) -> np.ndarray: action_space = env.action_space if isinstance(action_space, gym.spaces.Box): @@ -56,15 +69,29 @@ def _run_np(env: ArrayEnv): time.sleep(sleep_dt) -def _make_robot_scene(robot_cfg: RobotCfg) -> StandardSceneCfg: +@configclass +class _RobotViewObjsCfg(SceneObjsCfg): + floor: FlatTerrainCfg = FlatTerrainCfg() + sun: LightCfg = LightCfg(color=(0.7, 0.7, 0.7), illuminance=10_000.0) + + +def _make_robot_scene(robot_cfg: RobotCfg) -> SceneCfg: camera = SystemCameraCfg(lookat=(0.0, 0.0, 0.75), distance=3.0, elevation=-20.0, azimuth=180.0) - return StandardSceneCfg( + return SceneCfg( system_camera=camera, - objs=StandardSceneObjsCfg(robot=robot_cfg), + visual=SceneVisualCfg( + ambient_light_color=(0.3, 0.3, 0.3), + ambient_light_brightness=1_000.0, + head_light_color=(0.6, 0.6, 0.6), + head_light_luminous_power=1_000.0, + haze=(0.1, 0.1, 0.1, 1.0), + tone_mapping="none", + ), + objs=_RobotViewObjsCfg(robot=robot_cfg), ) -def _run_robot_motrixsim(scene: StandardSceneCfg) -> None: +def _run_robot_motrixsim(scene: SceneCfg) -> None: camera = scene.system_camera model = build_scene_model(scene) data = mtx.SceneData(model, batch=[1]) @@ -97,7 +124,7 @@ def _run_robot_motrixsim(scene: StandardSceneCfg) -> None: renderer.__exit__(None, None, None) -def _run_robot_mujoco(scene: StandardSceneCfg) -> None: +def _run_robot_mujoco(scene: SceneCfg) -> None: try: import mujoco as mj import mujoco.viewer as mj_viewer @@ -203,10 +230,15 @@ def run(cfg: ViewConfig) -> None: raise TypeError(f"Unsupported environment type '{type(env).__name__}'.") -@hydra.main(version_base=None, config_path="../configs", config_name="view") -def main(cfg: DictConfig) -> None: - run(to_typed_config(cfg, ViewConfig)) +def _hydra_main(cfg: DictConfig) -> None: + run(cast(ViewConfig, OmegaConf.to_object(cfg))) -if __name__ == "__main__": - main() +def main() -> None: + ConfigStore.instance().store(name="view_schema", node=ViewConfig) + parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False) + parser.add_argument("--config-dir") + args, _ = parser.parse_known_args() + config_dir = Path(args.config_dir) if args.config_dir is not None else Path.cwd() / "configs" + config_path = str(config_dir.resolve()) if (config_dir / "view.yaml").is_file() else "../configs" + hydra.main(version_base=None, config_path=config_path, config_name="view")(_hydra_main)() diff --git a/motrixlab/src/motrixlab/configs/__init__.py b/motrixlab/src/motrixlab/configs/__init__.py new file mode 100644 index 00000000..a655a514 --- /dev/null +++ b/motrixlab/src/motrixlab/configs/__init__.py @@ -0,0 +1,2 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 diff --git a/configs/view.yaml b/motrixlab/src/motrixlab/configs/view.yaml similarity index 100% rename from configs/view.yaml rename to motrixlab/src/motrixlab/configs/view.yaml diff --git a/motrixlab/tests/test_mxlab_cli.py b/motrixlab/tests/test_mxlab_cli.py new file mode 100644 index 00000000..079d246e --- /dev/null +++ b/motrixlab/tests/test_mxlab_cli.py @@ -0,0 +1,81 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 + +"""Unified CLI routing, argument ownership, and lazy help contracts.""" + +import sys +from types import SimpleNamespace + +import pytest + +from motrixlab import cli + + +@pytest.mark.parametrize( + "command,module", + [ + ("train", "motrix_rl.commands.train"), + ("play", "motrix_rl.commands.play"), + ("view", "motrixlab.commands.view"), + ("export-onnx", "motrix_rl.commands.export_onnx"), + ("export-deploy", "motrix_rl.commands.export_deploy"), + ("deploy", "motrix_deploy.cli"), + ], +) +def test_dispatch_forwards_arguments_and_exit_status(monkeypatch, command, module): + original = ["mxlab", command, "task=example/ppo", "--config-dir", "/project/configs"] + monkeypatch.setattr(sys, "argv", original) + observed = [] + + def run(): + observed.append(sys.argv.copy()) + return 7 + + def load(name): + assert name == module + return SimpleNamespace(main=run) + + monkeypatch.setattr(cli, "import_module", load) + assert cli.main() == 7 + assert observed == [[f"mxlab {command}", *original[2:]]] + assert sys.argv is original + + +def test_dispatch_restores_arguments_on_failure(monkeypatch): + original = ["mxlab", "export-onnx", "run_dir=example"] + monkeypatch.setattr(sys, "argv", original) + + def run(): + raise SystemExit(2) + + monkeypatch.setattr(cli, "import_module", lambda name: SimpleNamespace(main=run)) + with pytest.raises(SystemExit) as error: + cli.main() + assert error.value.code == 2 + assert sys.argv is original + + +@pytest.mark.parametrize("args,code", [([], 0), (["--help"], 0), (["--version"], 0), (["unknown"], 2)]) +def test_top_level_information_never_loads_components(monkeypatch, capsys, args, code): + monkeypatch.setattr(sys, "argv", ["mxlab", *args]) + monkeypatch.setattr(cli, "version", lambda name: "1.2.3") + + def load(name): + pytest.fail(f"Top-level command imported {name}") + + monkeypatch.setattr(cli, "import_module", load) + with pytest.raises(SystemExit) as error: + cli.main() + assert error.value.code == code + output = capsys.readouterr() + assert "mxlab" in output.out + output.err + + +def test_subcommand_help_belongs_to_component(monkeypatch): + monkeypatch.setattr(sys, "argv", ["mxlab", "train", "--help"]) + observed = [] + monkeypatch.setattr( + cli, "import_module", lambda name: SimpleNamespace(main=lambda: observed.append(sys.argv.copy())) + ) + cli.main() + assert observed == [["mxlab train", "--help"]] diff --git a/pyproject.toml b/pyproject.toml index 7e96c4dc..74f29168 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,7 @@ description = "A general-purpose machine learning architecture designed for robo authors = [{ name = "Motphys", email = "developers@motphys.com" }] requires-python = ">=3.10,<3.14" dependencies = [ + "motrixlab==0.4.0b1", "motrix-deploy==0.4.0b1", "motrix-deploy-mujoco==0.4.0b1", "motrix-deploy-motrixsim==0.4.0b1", @@ -63,6 +64,7 @@ test = [ [tool.uv.workspace] members = [ + "motrixlab", "motrix_robots", "motrix_deploy", "motrix_deploy_mujoco", @@ -93,6 +95,7 @@ name = "pypi" url = "https://pypi.org/simple" [tool.uv.sources] +motrixlab = { workspace = true } motrix-robots = { workspace = true } motrix-env-core = { workspace = true } motrix-deploy = { workspace = true } @@ -114,8 +117,8 @@ version_provider = "uv" version_scheme = "pep440" tag_format = "v$version" version_files = [ - 'pyproject.toml:"motrix-[a-z0-9-]+(?:\[[^"\]]+\])?==', - '*/pyproject.toml:^version = |"motrix-[a-z0-9-]+(?:\[[^"\]]+\])?==', + 'pyproject.toml:"(?:motrix-[a-z0-9-]+|motrixlab)(?:\[[^"\]]+\])?==', + '*/pyproject.toml:^version = |"(?:motrix-[a-z0-9-]+|motrixlab)(?:\[[^"\]]+\])?==', ] [tool.pytest.ini_options] diff --git a/scripts/export_deploy.py b/scripts/export_deploy.py deleted file mode 100644 index b59d8401..00000000 --- a/scripts/export_deploy.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright Motphys Technology Co., Ltd. 2025, 2026 -# SPDX-License-Identifier: Apache-2.0 - -"""Compatibility wrapper; prefer ``mxexport deploy``.""" - -from motrix_rl.commands.export_deploy import main - -if __name__ == "__main__": - main() diff --git a/scripts/export_onnx.py b/scripts/export_onnx.py deleted file mode 100644 index 622b89f3..00000000 --- a/scripts/export_onnx.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright Motphys Technology Co., Ltd. 2025, 2026 -# SPDX-License-Identifier: Apache-2.0 - -"""Compatibility wrapper; prefer the installed ``mxexport onnx`` command.""" - -from motrix_rl.commands.export_onnx import main - -if __name__ == "__main__": - main() diff --git a/scripts/play.py b/scripts/play.py deleted file mode 100644 index fdaf036e..00000000 --- a/scripts/play.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright Motphys Technology Co., Ltd. 2025, 2026 -# SPDX-License-Identifier: Apache-2.0 - -"""Compatibility wrapper; prefer the installed ``mxplay`` command.""" - -from motrix_rl.commands.play import main - -if __name__ == "__main__": - main() diff --git a/scripts/test_all_demos.py b/scripts/test_all_demos.py index f083cfed..c9fdbeaf 100755 --- a/scripts/test_all_demos.py +++ b/scripts/test_all_demos.py @@ -44,7 +44,8 @@ def run_command(env: str, backend: str, extra_args: list[str]) -> int: cmd = [ sys.executable, "-m", - "motrix_rl.commands.train", + "motrixlab.cli", + "train", "--config-dir", str(config_dir), f"task={task_option}", @@ -86,7 +87,7 @@ def main(): "--extra-args", nargs=argparse.REMAINDER, default=[], - help="Extra arguments to pass to mxtrain", + help="Extra arguments to pass to mxlab train", ) parser.add_argument( "--stop-on-error", diff --git a/scripts/train.py b/scripts/train.py deleted file mode 100644 index 99391892..00000000 --- a/scripts/train.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright Motphys Technology Co., Ltd. 2025, 2026 -# SPDX-License-Identifier: Apache-2.0 - -"""Compatibility wrapper; prefer the installed ``mxtrain`` command.""" - -from motrix_rl.commands.train import main - -if __name__ == "__main__": - main() diff --git a/tests/test_cli_config.py b/tests/test_cli_config.py index 833c235f..f8097c2f 100644 --- a/tests/test_cli_config.py +++ b/tests/test_cli_config.py @@ -4,7 +4,8 @@ from pathlib import Path import pytest -from hydra import compose, initialize_config_dir, initialize_config_module +from hydra import compose, initialize_config_module +from hydra.core.config_store import ConfigStore from hydra.core.global_hydra import GlobalHydra from motrix_rl import frameworks @@ -24,11 +25,12 @@ def _clear_hydra(): def _compose(config_name: str, overrides: list[str]): load_plugins() - initializer = ( - initialize_config_module(version_base=None, config_module="motrix_rl.configs") - if config_name in ("train", "play", "export_onnx") - else initialize_config_dir(version_base=None, config_dir=CONFIG_DIR) - ) + if config_name == "view": + from motrixlab.commands.view import ViewConfig + + ConfigStore.instance().store(name="view_schema", node=ViewConfig) + config_module = "motrixlab.configs" if config_name == "view" else "motrix_rl.configs" + initializer = initialize_config_module(version_base=None, config_module=config_module) if config_name == "train": overrides = [f"hydra.searchpath=[file://{CONFIG_DIR}]", *overrides] with initializer: diff --git a/tests/test_doc_generate_video_script.py b/tests/test_doc_generate_video_script.py index ab7d56f7..ff42de3f 100644 --- a/tests/test_doc_generate_video_script.py +++ b/tests/test_doc_generate_video_script.py @@ -65,7 +65,7 @@ def test_missing_policy_prints_train_command(monkeypatch, tmp_path, capsys): error = capsys.readouterr().err assert "No playable policy" in error - assert "python -m motrix_rl.commands.train task=cartpole/skrl.ppo" in error + assert "mxlab train task=cartpole/skrl.ppo" in error def test_video_config_records_by_default_and_places_bare_output_in_docs_video_dir(): diff --git a/tests/test_plugin_export_integration.py b/tests/test_plugin_export_integration.py index 6a4e6729..bfe738a5 100644 --- a/tests/test_plugin_export_integration.py +++ b/tests/test_plugin_export_integration.py @@ -118,8 +118,8 @@ def test_export_command_writes_onnx_and_reports_parity_outside_workspace(tmp_pat [ sys.executable, "-m", - "motrix_rl.commands.export", - "onnx", + "motrixlab.cli", + "export-onnx", f"run_dir={run.run_dir}", f"output={output}", "parity.samples=4", diff --git a/tests/test_rl_commands.py b/tests/test_rl_commands.py index 6375090b..d08e5408 100644 --- a/tests/test_rl_commands.py +++ b/tests/test_rl_commands.py @@ -28,7 +28,7 @@ def _task(config_dir: Path, seed: int) -> None: def _compose(cwd: Path, *args: str) -> dict: result = subprocess.run( - [sys.executable, "-m", "motrix_rl.commands.train", "task=external/ppo", "--cfg", "job", *args], + [sys.executable, "-m", "motrixlab.cli", "train", "task=external/ppo", "--cfg", "job", *args], cwd=cwd, capture_output=True, text=True, @@ -65,7 +65,7 @@ def test_project_algorithm_defaults_override_package_and_explicit_dir_wins(tmp_p def test_train_help_does_not_require_task_but_training_does(tmp_path): - command = [sys.executable, "-m", "motrix_rl.commands.train"] + command = [sys.executable, "-m", "motrixlab.cli", "train"] help_result = subprocess.run([*command, "--help"], cwd=tmp_path, capture_output=True, text=True) assert help_result.returncode == 0, help_result.stderr assert "num_envs" in help_result.stdout @@ -78,7 +78,7 @@ def test_train_help_does_not_require_task_but_training_does(tmp_path): @pytest.mark.parametrize("format_name,validation", [("onnx", "parity"), ("deploy", "validation")]) def test_export_help_and_project_config_override(tmp_path, format_name, validation): - command = [sys.executable, "-m", "motrix_rl.commands.export", format_name] + command = [sys.executable, "-m", "motrixlab.cli", f"export-{format_name}"] help_result = subprocess.run([*command, "--help"], cwd=tmp_path, capture_output=True, text=True) assert help_result.returncode == 0, help_result.stderr assert "run_dir" in help_result.stdout @@ -95,9 +95,44 @@ def test_export_help_and_project_config_override(tmp_path, format_name, validati assert config["run_dir"] == "example" +def test_view_help_and_configuration_without_project_config_directory(tmp_path): + command = [sys.executable, "-m", "motrixlab.cli", "view"] + help_result = subprocess.run([*command, "--help"], cwd=tmp_path, capture_output=True, text=True) + assert help_result.returncode == 0, help_result.stderr + assert "robot" in help_result.stdout + assert "num_envs" in help_result.stdout + + result = subprocess.run( + [*command, "robot=go2", "sim=mujoco", "--cfg", "job"], + cwd=tmp_path, + capture_output=True, + text=True, + check=True, + ) + config = yaml.safe_load(result.stdout) + assert config["robot"] == "go2" + assert config["sim"] == "mujoco" + + +def test_view_project_configuration_and_explicit_directory(tmp_path): + command = [sys.executable, "-m", "motrixlab.cli", "view", "--cfg", "job"] + for directory, count in ((tmp_path / "configs", 3), (tmp_path / "other", 7)): + directory.mkdir() + (directory / "view.yaml").write_text( + f"defaults:\n - view_schema\n - _self_\nrobot: external\nnum_envs: {count}\n", + encoding="utf-8", + ) + + for args, count in (([], 3), (["--config-dir", str(tmp_path / "other")], 7)): + result = subprocess.run([*command, *args], cwd=tmp_path, capture_output=True, text=True, check=True) + config = yaml.safe_load(result.stdout) + assert config["robot"] == "external" + assert config["num_envs"] == count + + def test_play_composes_without_project_config_directory(tmp_path): result = subprocess.run( - [sys.executable, "-m", "motrix_rl.commands.play", "policy=/tmp/policy.pt", "--cfg", "job"], + [sys.executable, "-m", "motrixlab.cli", "play", "policy=/tmp/policy.pt", "--cfg", "job"], cwd=tmp_path, capture_output=True, text=True, diff --git a/tests/test_view_script.py b/tests/test_view_command.py similarity index 92% rename from tests/test_view_script.py rename to tests/test_view_command.py index 842af537..c5c38275 100644 --- a/tests/test_view_script.py +++ b/tests/test_view_command.py @@ -1,25 +1,16 @@ # Copyright Motphys Technology Co., Ltd. 2025, 2026 # SPDX-License-Identifier: Apache-2.0 -import importlib.util import sys -from pathlib import Path from types import SimpleNamespace from unittest.mock import Mock import pytest from motrix_robots.unitree import UnitreeGo2Robot +from motrixlab.commands import view +from motrixlab.commands.view import ViewConfig from motrix_env_core import registry -from motrix_rl.config import ViewConfig - -VIEW_SCRIPT = Path(__file__).resolve().parents[1] / "scripts" / "view.py" -VIEW_MODULE_SPEC = importlib.util.spec_from_file_location("motrix_test_view_script", VIEW_SCRIPT) -if VIEW_MODULE_SPEC is None or VIEW_MODULE_SPEC.loader is None: - raise ImportError(f"Unable to load {VIEW_SCRIPT}") -view = importlib.util.module_from_spec(VIEW_MODULE_SPEC) -sys.modules[VIEW_MODULE_SPEC.name] = view -VIEW_MODULE_SPEC.loader.exec_module(view) def test_default_view_target_is_cartpole(monkeypatch): diff --git a/uv.lock b/uv.lock index fd6b1069..e5ea7e0b 100644 --- a/uv.lock +++ b/uv.lock @@ -74,6 +74,7 @@ members = [ "motrix-rl-rslrl", "motrix-rl-skrl", "motrix-robots", + "motrixlab", ] [[package]] @@ -523,7 +524,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11' or sys_platform == 'darwin' or (extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (extra == 'extra-9-motrix-rl-cuda' and extra == 'extra-9-motrix-rl-rocm')" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (extra == 'extra-9-motrix-rl-cuda' and extra == 'extra-9-motrix-rl-rocm')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -1329,6 +1330,7 @@ dependencies = [ { name = "motrix-rl" }, { name = "motrix-rl-builtin" }, { name = "motrix-rl-skrl" }, + { name = "motrixlab" }, ] [package.optional-dependencies] @@ -1400,6 +1402,7 @@ requires-dist = [ { name = "motrix-rl-rslrl", marker = "extra == 'rslrl'", editable = "motrix_rl_rslrl" }, { name = "motrix-rl-skrl", editable = "motrix_rl_skrl" }, { name = "motrix-rl-skrl", extras = ["jax"], marker = "extra == 'skrl-jax'", editable = "motrix_rl_skrl" }, + { name = "motrixlab", editable = "motrixlab" }, { name = "myst-parser", marker = "extra == 'docs'" }, { name = "pydata-sphinx-theme", marker = "extra == 'docs'" }, { name = "sphinx", marker = "extra == 'docs'" }, @@ -1565,6 +1568,37 @@ dependencies = [ [package.metadata] requires-dist = [{ name = "motrix-env-core", editable = "motrix_env_core" }] +[[package]] +name = "motrixlab" +version = "0.4.0b1" +source = { editable = "motrixlab" } +dependencies = [ + { name = "gymnasium" }, + { name = "hydra-core" }, + { name = "motrix-deploy" }, + { name = "motrix-env-core" }, + { name = "motrix-env-motrixsim" }, + { name = "motrix-rl" }, + { name = "motrix-rl-builtin" }, + { name = "motrixsim" }, + { name = "numpy" }, + { name = "omegaconf" }, +] + +[package.metadata] +requires-dist = [ + { name = "gymnasium", specifier = "==1.1.1" }, + { name = "hydra-core", specifier = ">=1.3,<1.4" }, + { name = "motrix-deploy", editable = "motrix_deploy" }, + { name = "motrix-env-core", editable = "motrix_env_core" }, + { name = "motrix-env-motrixsim", editable = "motrix_env_motrixsim" }, + { name = "motrix-rl", editable = "motrix_rl" }, + { name = "motrix-rl-builtin", editable = "motrix_rl_builtin" }, + { name = "motrixsim", specifier = "==0.10.1" }, + { name = "numpy", specifier = ">=1.26" }, + { name = "omegaconf", specifier = ">=2.3,<2.4" }, +] + [[package]] name = "motrixsim" version = "0.10.1" diff --git a/wiki/design/architecture.md b/wiki/design/architecture.md index ca10e427..5567fd64 100644 --- a/wiki/design/architecture.md +++ b/wiki/design/architecture.md @@ -27,7 +27,7 @@ MotrixLab 需要同时应对以下挑战: ``` ┌─────────────────────────────────────────────────┐ │ 应用入口 │ -│ scripts/train.py · play.py · view.py │ +│ mxlab train · mxlab play · mxlab view │ ├─────────────────────────────────────────────────┤ │ RL 框架集成层(motrix_rl) │ │ Wrapper · Trainer · AgentProvider · Hydra schema │ @@ -284,13 +284,13 @@ cartpole/ ## 7. 数据流总览 -以 `uv run scripts/train.py --env cartpole --rllib skrl` 为例,数据在系统中的完整流动路径: +以 `mxlab train task=cartpole/skrl.ppo` 为例,数据在系统中的完整流动路径: ``` 命令行参数 │ ▼ -train.py: 解析 env_name, rllib +mxlab train → motrix_rl.commands.train: 组合训练配置 │ ▼ Hydra: 组合 task=cartpole/skrl.ppo → TrainConfig diff --git a/wiki/design/fastsac-async-heterogeneous-trainer.md b/wiki/design/fastsac-async-heterogeneous-trainer.md index 91df72ac..e98aaed3 100644 --- a/wiki/design/fastsac-async-heterogeneous-trainer.md +++ b/wiki/design/fastsac-async-heterogeneous-trainer.md @@ -92,9 +92,9 @@ motrix_rl/src/motrix_rl/fastsac/ **任务配置**:每个环境只保留一个 `configs/task//motrix.fastsac.yaml`。Task 固定记录 `rllib: motrix`、`algo: fastsac`;`algo.asynchronous` 默认为 `true`,需要同步 baseline 时覆盖为 `false`。 ```bash -uv run scripts/train.py task=g1-walk-flat/motrix.fastsac # 异构(默认) -uv run scripts/train.py task=g1-walk-flat/motrix.fastsac algo.asynchronous=false # 同步 baseline -# 二者产出的 checkpoint 均为 .pt,同一 scripts/play.py 可回放 +mxlab train task=g1-walk-flat/motrix.fastsac # 异构(默认) +mxlab train task=g1-walk-flat/motrix.fastsac algo.asynchronous=false # 同步 baseline +# 二者产出的 checkpoint 均为 .pt,同一 mxlab play 可回放 ``` --- @@ -230,7 +230,7 @@ TensorBoard scalar 与同步版同名(`rollout/mean_return`、`rollout/mean_ep ### 6.3 checkpoint 兼容 -learner 持有完整 `FastSacAgent`,直接复用其 `state_dict()` 与通用 checkpoint 记录逻辑。产出的 `.pt` 与同步版**结构相同**,因此:同一 `scripts/play.py` 可回放异构版 checkpoint;异构版可 resume 同步版 checkpoint,反之亦然,支持「同步预训练 + 异构继续」这类混合实验。 +learner 持有完整 `FastSacAgent`,直接复用其 `state_dict()` 与通用 checkpoint 记录逻辑。产出的 `.pt` 与同步版**结构相同**,因此:同一 `mxlab play` 可回放异构版 checkpoint;异构版可 resume 同步版 checkpoint,反之亦然,支持「同步预训练 + 异构继续」这类混合实验。 ### 6.4 关闭与容错 diff --git a/wiki/design/framework-task-split.md b/wiki/design/framework-task-split.md index fd7a3025..b0ac1321 100644 --- a/wiki/design/framework-task-split.md +++ b/wiki/design/framework-task-split.md @@ -37,7 +37,8 @@ _CONFIG_DIR = Path(__file__).resolve().parents[3] / "configs" ``` motrix_rl/src/motrix_rl/ ├── configs/ -│ └── algo_base/ ← 从仓库根 configs/algo_base/ 移入 +│ ├── train.yaml, play.yaml ← 随包发布的 RL CLI 顶层配置 +│ └── algo_base/ ← 算法基础配置 │ ├── skrl.ppo.yaml │ ├── rslrl.ppo.yaml │ └── motrix.fastsac.yaml @@ -52,10 +53,12 @@ motrix_rl/src/motrix_rl/ ``` configs/ -├── train.yaml, play.yaml, view.yaml ← CLI 顶层 Hydra 配置(留) -└── task/ ← 每 task 的 RL 调参(留) -scripts/ -└── train.py, play.py, view.py ← 薄示例脚本(留) +└── task/ ← 每 task 的 RL 调参 +scripts/ ← 其他仓库辅助工具 +motrixlab/src/motrixlab/ ← 应用集成:统一 mxlab CLI 与跨组件 view +├── commands/view.py ← 环境/机器人可视化与 ViewConfig +└── configs/view.yaml ← 随包发布的 view 配置 +motrix_rl/src/motrix_rl/commands/ ← train/play/export 内部可调用 adapter ``` ### 配置根机制 @@ -85,8 +88,8 @@ hydra: 外部用户复制这条 `searchpath` 即可让自己的 task 配置组合内置 algo 默认值。CLI 选择 task 时使用固定 group: ```bash -uv run scripts/train.py task=acrobot/skrl.ppo -uv run scripts/train.py task=acrobot/rslrl.ppo +mxlab train task=acrobot/skrl.ppo +mxlab train task=acrobot/rslrl.ppo ``` 这里 `task` 是 Hydra group,`acrobot/skrl.ppo` 是 option。不要把 env 放到 group key 里写成 `task/acrobot=skrl.ppo`;固定 group 可以让切换环境和算法时 CLI key 保持稳定。 @@ -182,9 +185,9 @@ Trainer 在分发边界仍获得精确的配置类型。 用户覆盖真实配置树: ```bash -uv run scripts/train.py task=acrobot/skrl.ppo num_envs=4096 -uv run scripts/train.py task=acrobot/skrl.ppo seed=7 -uv run scripts/train.py task=acrobot/skrl.ppo logging.interval=20 checkpoint.interval=100 +mxlab train task=acrobot/skrl.ppo num_envs=4096 +mxlab train task=acrobot/skrl.ppo seed=7 +mxlab train task=acrobot/skrl.ppo logging.interval=20 checkpoint.interval=100 ``` 因此训练入口不再需要旧式的独立 method selector 和 `+rl...` 到 `algo` 的转译层。 @@ -205,8 +208,9 @@ uv run scripts/train.py task=acrobot/skrl.ppo logging.interval=20 checkpoint.int - **`configs/train.yaml`**:defaults 增加 `task: cartpole/skrl.ppo`,训练 CLI 通过 `task=/.` 选择配方。 - **`configs/task/`**:每个 task YAML 改为 `# @package _global_`,写入 `task` 元信息,并通过 `/algo_base@algo` 组合算法默认值。 -- **`scripts/train.py`**:直接消费 `cfg.task` 和 `cfg.algo`;不再从独立的 env/method 字段二次组合 RL 配置。 -- **`scripts/play.py` / `view.py`**:继续使用各自的 Hydra config root;是否同步切到 task group 另行按各自 CLI 语义处理。 +- **`mxlab train`**:调用 `motrix_rl.commands.train`,直接消费 `cfg.task` 和 `cfg.algo`,不从独立的 env/method 字段二次组合 RL 配置。 +- **`mxlab play` / `mxlab view`**:分别承担训练策略回放与环境可视化,按各自 Hydra 配置语义运行。 +- **CLI 所有权**:`motrixlab` 提供唯一的 `mxlab` 入口;命令实现与内部可调用 adapter 保持在组件 package 中,版本查询只使用 `mxlab --version`。 - **测试**:Hydra ConfigLoader 枚举 task group option,再通过 Hydra `compose()` 逐项组合和校验。 ## 取舍 diff --git a/wiki/design/motrix-deploy.md b/wiki/design/motrix-deploy.md index 22682ac5..6424d2fd 100644 --- a/wiki/design/motrix-deploy.md +++ b/wiki/design/motrix-deploy.md @@ -17,7 +17,7 @@ sim2real vertical slice。`motrix_deploy` 是独立于训练框架的策略部 ## 1. 背景与架构定位 -现有 `scripts/play.py` 从 run metadata 和 checkpoint manifest 发现训练产物,再创建对应 RL framework 的 +`mxlab play`(实现位于 `motrix_rl.commands.play`)从 run metadata 和 checkpoint manifest 发现训练产物,再创建对应 RL framework 的 trainer 进行回放。这个入口适合在训练环境内评估策略,但它仍依赖 SKRL、RSLRL 或 FastSAC 的模型与环境 封装,不能作为稳定的跨仿真器或真机部署接口。 @@ -54,7 +54,7 @@ motrix_rl checkpoint + run metadata + task snapshot (sim2sim) (sim2real) ``` -`scripts/play.py` 继续承担训练框架内 playback,不改名、不转化为部署入口。两条路径可以消费相同的源 +`mxlab play` 承担训练框架内 playback,`mxlab deploy` 承担部署。两条路径可以消费相同的源 checkpoint,但职责不同:play 验证训练实现,deploy 验证可移植 artifact 和设备控制链路。 ## 2. 设计目标 @@ -898,7 +898,8 @@ task runtime 通过 `motrix_deploy.tasks` Python entry-point group 按版本化 task 标识发现。`available_tasks()` 只读取已安装插件元数据;`load_task_type()` 懒加载唯一 `DeployTask` 类,manifest codec 读取其 `spec_type` 而不实例化 task。`create_task()` 再将已解码的具体 `TaskSpec`、`RobotSpec`、已加载的 `Policy` 和可选 `steps` 传给该类构造完整 task controller。未知名称或重复插件报错,不按 import 顺序选择实现。 -`motrix_deploy` core 发布指向 `motrix_deploy.cli:main` 的 console script,不反向 import 具体环境、task 或 SDK; +`motrixlab` 提供唯一的 `mxlab` console script,`mxlab deploy` 惰性调用 `motrix_deploy.cli` 中的内部 adapter; +`motrix_deploy` core 不发布独立 CLI,不反向 import 具体环境、task 或 SDK; 具体部署 recipe 通过已安装 Hydra search-path plugin 提供的 `task` group 选择;外部应用也可显式指定 Hydra config path/name。 runtime 插件由 `motrix_deploy.runtime.factory` 通过 `motrix_deploy.backends` Python entry-point group 发现; @@ -1088,7 +1089,7 @@ realtime scheduler,可通过 `runtime.realtime=false` 关闭实时节奏控制 已安装仿真 recipe 默认选择 MuJoCo;使用同一 task、artifact 和完整场景切换原生 backend: ```bash -mxdeploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ +mxlab deploy task=go2-walk-flat/sim artifact=artifacts/go2-walk-flat.deploy \ runtime.backend=motrixsim runtime.viewer=false runtime.realtime=false duration_s=1.0 ``` @@ -1123,24 +1124,24 @@ motrix_deploy_motrixsim/src/motrix_deploy_motrixsim/ ## 12. CLI 设计 -package 暴露统一入口: +`motrixlab` 集成包暴露统一的 `mxlab deploy` 入口,惰性分发到 `motrix_deploy.cli`: ```bash # 只检查 artifact,不创建设备 -mxdeploy inspect artifact=path/to/go2_walk.deploy +mxlab deploy inspect artifact=path/to/go2_walk.deploy # sim2sim 有界无窗口检查 -mxdeploy task=go2-walk-flat/sim \ +mxlab deploy task=go2-walk-flat/sim \ artifact=path/to/go2_walk.deploy \ runtime.viewer=false duration_s=2.0 # 实时可视化 -mxdeploy task=go2-walk-flat/sim \ +mxlab deploy task=go2-walk-flat/sim \ artifact=path/to/go2_walk.deploy \ runtime.viewer=true # 真机入口 -mxdeploy task=go2-walk-flat/hardware \ +mxlab deploy task=go2-walk-flat/hardware \ artifact=path/to/go2_walk.deploy \ runtime.network_interface=enp5s0 ``` @@ -1202,12 +1203,14 @@ artifact 的维度以 policy tensor shapes 为唯一来源。compiler 不恢复 ### 13.4 Deployment export 入口 -`motrix_rl` 提供 `mxexport onnx` 和 `mxexport deploy` 子命令;必须显式选择格式,不按训练框架拆分子命令。 +`motrixlab` 集成包通过薄层惰性 CLI 提供 `mxlab export-onnx` 和 `mxlab export-deploy` 子命令; +命令实现仍在 `motrix_rl.commands`,部署入口 `mxlab deploy` 分发到 `motrix_deploy.cli`。 +两个导出命令直接选择输出格式,不按训练框架拆分,也不需要第三级命令。 部署导出恰好指定 `run_dir` 或 `env`,后者选择环境的最新 metadata-backed run。默认输出为 `artifacts/.deploy`: ```bash -mxexport deploy env=go2-walk-rough -mxexport deploy run_dir=/path/to/run output=artifacts/policy.deploy +mxlab export-deploy env=go2-walk-rough +mxlab export-deploy run_dir=/path/to/run output=artifacts/policy.deploy ``` 导出配置随 `motrix_rl` 发布,项目配置优先、包内配置兜底。依赖方向为 `motrix_rl -> motrix_deploy`;部署运行时 diff --git a/wiki/design/onnx-export.md b/wiki/design/onnx-export.md index cd6a3288..60cd4afe 100644 --- a/wiki/design/onnx-export.md +++ b/wiki/design/onnx-export.md @@ -265,7 +265,7 @@ source .venv/bin/activate CLI 使用 run directory,不接受脱离 metadata 的裸 checkpoint: ```bash -python scripts/export_onnx.py \ +mxlab export-onnx \ run_dir=runs/cartpole/skrl/torch/ppo/ \ output=/tmp/cartpole.onnx ``` @@ -273,7 +273,7 @@ python scripts/export_onnx.py \ 可显式覆盖验证参数: ```bash -python scripts/export_onnx.py \ +mxlab export-onnx \ run_dir= \ parity.seed=7 \ parity.samples=64 \ diff --git a/wiki/design/rl-multi-algorithm-architecture.md b/wiki/design/rl-multi-algorithm-architecture.md index 500e9287..5ffa6ae8 100644 --- a/wiki/design/rl-multi-algorithm-architecture.md +++ b/wiki/design/rl-multi-algorithm-architecture.md @@ -19,13 +19,13 @@ RL 集成层需要在同一套入口下承载多个 RL 框架和多种算法: ## 2. 设计目标 -1. **RL method 是一等 CLI 维度**:用户通过 `--algo skrl.ppo` 直接选择一套 RL 方法,而非组合多个开关。 +1. **RL method 是一等配置维度**:用户通过 `mxlab train task=cartpole/skrl.ppo` 选择环境与 RL 方法的完整训练配方。 2. **内部维度正交**:配置查找、trainer 查找、run metadata、checkpoint 发现都显式包含 `rllib / train_backend / algo`。 -3. **默认行为兼容**:不传 `--algo` 时默认 `skrl.ppo`。 +3. **训练配方显式选择**:训练必须提供 `task=...`,不隐式选择环境或算法。 4. **算法可独立演进**:每个算法可自定义模型角色、memory、agent 配置和 runtime 配置。 5. **共享通用编排**:环境创建、seed、run 目录、metadata、train/play 主流程不在每个算法里重复。 6. **配置按算法收敛**:每个算法拥有独立配置类型,字段不跨算法泄漏。 -7. **外部接入面稳定**:外部算法实现 `TrainerBase`、注册 `RlFramework`/`AgentProvider`、注册配置类后,不需要修改 `scripts/train.py`、`scripts/play.py`、checkpoint 发现或 backend 选择逻辑。 +7. **外部接入面稳定**:外部算法实现 `TrainerBase`、注册 `RlFramework`/`AgentProvider`、注册配置类后,不需要修改 `mxlab train`、`mxlab play`、checkpoint 发现或 backend 选择逻辑。 ## 3. 非目标 @@ -38,7 +38,7 @@ RL 集成层需要在同一套入口下承载多个 RL 框架和多种算法: ``` ┌─────────────────────────────────────────────┐ -│ scripts/train.py · scripts/play.py │ +│ mxlab train · mxlab play │ │ CLI 解析、自动发现、错误展示 │ ├─────────────────────────────────────────────┤ │ motrix_rl.runner │ @@ -99,16 +99,17 @@ rslrl.ppo motrix.fastsac ``` -`train.py` 用 `--algo` 承载该 method,默认 `skrl.ppo`;`--train-backend` 单独指定 train backend,未指定时自动选择。示例: +`mxlab train` 通过 Hydra 的 `task=/.` 选择完整训练配方;`task.train_backend` 可单独覆写训练后端,未指定时自动选择。激活安装环境后运行: ```bash -uv run scripts/train.py task=cartpole/skrl.ppo -uv run scripts/train.py task=cartpole/rslrl.ppo -uv run scripts/train.py task=g1-walk-flat/motrix.fastsac -uv run scripts/train.py task=g1-walk-flat/motrix.fastsac algo.asynchronous=false +mxlab train task=cartpole/skrl.ppo +mxlab train task=cartpole/rslrl.ppo +mxlab train task=g1-walk-flat/motrix.fastsac +mxlab train task=g1-walk-flat/motrix.fastsac algo.asynchronous=false ``` -`--rllib` 作为兼容开关保留:传 `--rllib skrl --algo ppo` 解析为 `skrl.ppo`;传 `--algo skrl.ppo` 时不需要 `--rllib`;两者冲突时报错。 +`mxlab` 是唯一 CLI 入口;train/play/export 的实现与内部可调用 adapter 保留在 `motrix_rl.commands`,不提供独立模块 CLI。 +版本查询只使用 `mxlab --version`。 ### 5.2 method 解析 @@ -322,7 +323,7 @@ def create_training_handle(request: TrainRequest) -> TrainerHandle: ) ``` -play 编排不引入独立 request 类型:入口(`scripts/play.py`)或 `TrainResult.play(...)` 先解析出 `RunContext`(从 metadata),再调用同一个 `create_trainer(create_trainer_context(run, ...))`,最后 `trainer.play(policy_path)`。best policy 与 resume checkpoint 的定位统一走 `motrix_rl.checkpoints`。 +play 编排不引入独立 request 类型:入口(`mxlab play`)或 `TrainResult.play(...)` 先解析出 `RunContext`(从 metadata),再调用同一个 `create_trainer(create_trainer_context(run, ...))`,最后 `trainer.play(policy_path)`。best policy 与 resume checkpoint 的定位统一走 `motrix_rl.checkpoints`。 `TrainResult` 是 run 的查询视图: @@ -551,9 +552,9 @@ MAPPO 还需 centralized critic state(`global_state | dict[agent_id, critic_st ## 17. 兼容性与不变量 -- `train.py --algo` 接受 `rllib.algo` method,默认 `skrl.ppo`;`--env cartpole` 等价于 SKRL + auto backend + PPO。 -- `--algo rslrl.ppo` 等价于 RSLRL Torch PPO;`--rllib rslrl` 作为兼容写法等价,但提示 deprecated。 -- `play.py` 不要求 `--algo`,从最新 run metadata 反推 `rllib/train_backend/algo` 选择正确 inference path,可区分 PPO/SAC 等算法。 +- `mxlab train task=cartpole/skrl.ppo` 选择 SKRL PPO,未指定训练后端时自动选择。 +- `mxlab train task=cartpole/rslrl.ppo` 选择 RSLRL Torch PPO。 +- `mxlab play` 不要求 task 配方,从 run metadata 反推 `rllib/train_backend/algo` 选择正确 inference path,可区分 PPO/SAC 等算法。 - `(env, rllib, train_backend, algo)` 可查到独立配置;`(rllib, train_backend, algo)` 可查到 `AgentProvider`。 - run metadata 记录 `env/rllib/train_backend/algo`;没有 metadata/manifest 的旧 run 不参与 play 自动发现。 - 新算法不影响现有 PPO 的默认超参数与训练路径。 diff --git a/wiki/design/user-docs-envs-part.md b/wiki/design/user-docs-envs-part.md index fc0ef7b2..97458604 100644 --- a/wiki/design/user-docs-envs-part.md +++ b/wiki/design/user-docs-envs-part.md @@ -169,7 +169,7 @@ DeepMind Control Suite 的 Humanoid 和 Quadruped 仍归入 `dm_control`。它 `envs/index.md` 不是 24 个链接的简单列表,应承担环境发现入口的职责,包含以下内容: 1. Environment、Robot 和 Training Task 的简短区别; -2. 使用 `uv run scripts/view.py env=` 预览环境的统一方式; +2. 使用 `uv run --no-sync mxlab view env=` 预览环境的统一方式; 3. 六个环境主题的卡片入口; 4. 自动生成的 Env overview 表格; 5. 指向环境开发教程、Robot 列表和训练教程的交叉链接。