From 7da5c0fc377a60ef1b56c6123d21d878e20805c2 Mon Sep 17 00:00:00 2001 From: zilch <147668916@qq.com> Date: Mon, 28 Sep 2026 21:52:57 +0800 Subject: [PATCH 1/3] build(core): demote numba/scipy/imageio to optional extras (#83) Deployment-side installs (motrix-deploy and backend plugins) only use the config, registry and input layers of motrix-env-core, but its hard dependencies pulled in numba, scipy and imageio/imageio-ffmpeg (hundreds of MB) on every robot deployment target. - core dependencies narrowed to numpy, omegaconf, typing-extensions, gymnasium and array-api-compat (both small and on the bare import path) - numba + scipy -> motrix-env-core[numba] extra (scipy is only needed at numba compile time for np.linalg in kernels) - imageio + imageio-ffmpeg -> motrix-env-core[video] extra - aggregate motrix-env-core[all] extra for training-side installs - renderer.py imports imageio lazily so headless installs without the video extra can still import the env frontends - motrix_envs and motrix_rl now depend on motrix-env-core[numba,video]; simulator backend and deploy packages keep the bare dependency --- motrix_env_core/pyproject.toml | 26 ++++- .../src/motrix_env_core/renderer.py | 6 +- motrix_env_core/tests/test_rendering.py | 7 +- motrix_envs/pyproject.toml | 2 +- motrix_rl/pyproject.toml | 2 +- uv.lock | 94 +++++++++++-------- 6 files changed, 89 insertions(+), 48 deletions(-) diff --git a/motrix_env_core/pyproject.toml b/motrix_env_core/pyproject.toml index 8cf18212..47391952 100644 --- a/motrix_env_core/pyproject.toml +++ b/motrix_env_core/pyproject.toml @@ -10,19 +10,37 @@ authors = [{ name = "Motphys", email = "developers@motphys.com" }] requires-python = "==3.10.*" readme = "README.md" license = "Apache-2.0" +# Heavy runtime deps (numba/scipy for manager kernel compilation, imageio for +# video recording) are optional extras so deployment-side installs +# (motrix-deploy and its backend plugins) only pull the lightweight config, +# registry and input layers of this package. gymnasium stays in the base +# dependencies because ``motrix_env_core.base`` (on the bare package import +# path) types observation/action spaces with it, and it is a small +# pure-Python distribution. array-api-compat is only used by the frontend +# helper module and is likewise small. dependencies = [ "array-api-compat==1.15.0", "gymnasium==1.1.1", - "imageio>=2.30", - "imageio-ffmpeg>=0.5", - "numba==0.61.2", "numpy>=1.26", - "scipy==1.15.3", # numba requires scipy at compile time for np.linalg in kernels "omegaconf>=2.3,<2.4", "typing-extensions>=4.1", ] [project.optional-dependencies] +# Manager kernel compilation and numba-accelerated mdp terms. +numba = [ + "numba==0.61.2", + "scipy==1.15.3", # numba requires scipy at compile time for np.linalg in kernels +] +# Headless video recording via VideoRecorder. +video = [ + "imageio>=2.30", + "imageio-ffmpeg>=0.5", +] +# Everything the training-side workspace needs from this package. +all = [ + "motrix-env-core[numba,video]", +] # TBB threading layer for numba parallel kernels: on many-core machines the # default OpenMP layer pays a per-region thread-wakeup storm that dominates # short kernels. The wheel drops libtbb.so.12 into /lib, so the runtime diff --git a/motrix_env_core/src/motrix_env_core/renderer.py b/motrix_env_core/src/motrix_env_core/renderer.py index 82470fa6..508a426d 100644 --- a/motrix_env_core/src/motrix_env_core/renderer.py +++ b/motrix_env_core/src/motrix_env_core/renderer.py @@ -11,7 +11,6 @@ from pathlib import Path from typing import Protocol -import imageio.v2 as imageio import numpy as np from motrix_env_core.base import EnvCfg @@ -104,6 +103,11 @@ def close(self) -> None: def _write_frame(self, frame: np.ndarray) -> None: if self._writer is None: + # imageio is an optional dependency (``motrix-env-core[video]``): + # importing it lazily keeps this module importable in installs + # that only run headless training without video recording. + import imageio.v2 as imageio + self._path.parent.mkdir(parents=True, exist_ok=True) # macro_block_size=None keeps the configured frame size untouched; # the yuv420p pixel format still requires even dimensions, which diff --git a/motrix_env_core/tests/test_rendering.py b/motrix_env_core/tests/test_rendering.py index d236653d..f1618b94 100644 --- a/motrix_env_core/tests/test_rendering.py +++ b/motrix_env_core/tests/test_rendering.py @@ -13,7 +13,6 @@ import numpy as np import pytest -from motrix_env_core import renderer as core_renderer from motrix_env_core.renderer import VideoRecorder, create_renderer from motrix_env_core.sim.backend import RenderConfig, SimRenderer @@ -58,7 +57,11 @@ def test_video_recorder_paces_frames_and_closes_frame_source(tmp_path, monkeypat frames.capture.return_value = np.zeros((4, 4, 3), dtype=np.uint8) writer = MagicMock() get_writer = MagicMock(return_value=writer) - monkeypatch.setattr(core_renderer, "imageio", MagicMock(get_writer=get_writer)) + # renderer imports imageio lazily inside _write_frame, so patch the real + # module attribute the function resolves on import. + import imageio.v2 as imageio + + monkeypatch.setattr(imageio, "get_writer", get_writer) recorder = VideoRecorder( frames, diff --git a/motrix_envs/pyproject.toml b/motrix_envs/pyproject.toml index 31adf752..b26b0b51 100644 --- a/motrix_envs/pyproject.toml +++ b/motrix_envs/pyproject.toml @@ -12,7 +12,7 @@ readme = "README.md" license = "Apache-2.0" dependencies = [ "gymnasium==1.1.1", - "motrix-env-core", + "motrix-env-core[numba,video]", "motrix-env-motrixsim", "numpy>=1.26", "omegaconf>=2.3,<2.4", diff --git a/motrix_rl/pyproject.toml b/motrix_rl/pyproject.toml index f92d6036..7a55bca9 100644 --- a/motrix_rl/pyproject.toml +++ b/motrix_rl/pyproject.toml @@ -13,7 +13,7 @@ license = "Apache-2.0" dependencies = [ "gymnasium==1.1.1", "python-abc>=0.2.0", - "motrix-env-core", + "motrix-env-core[numba,video]", "motrix-env-motrixsim", "rich>=13", "hydra-core>=1.3,<1.4", diff --git a/uv.lock b/uv.lock index b8683223..0620df32 100644 --- a/uv.lock +++ b/uv.lock @@ -1,11 +1,12 @@ version = 1 -revision = 3 +revision = 2 requires-python = "==3.10.*" resolution-markers = [ "platform_machine == 'x86_64' and sys_platform == 'linux' and extra != 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm'", "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra != 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_machine == 'aarch64' and platform_python_implementation != 'CPython' and extra != 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra != 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')", "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux' and extra != 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm'", - "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm') or (platform_python_implementation != 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm')", + "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm')", + "platform_machine == 'aarch64' and platform_python_implementation != 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm'", "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm'", "sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm'", "extra != 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm'", @@ -988,34 +989,45 @@ source = { editable = "motrix_env_core" } dependencies = [ { name = "array-api-compat" }, { name = "gymnasium" }, - { name = "imageio" }, - { name = "imageio-ffmpeg" }, - { name = "numba" }, { name = "numpy" }, { name = "omegaconf" }, - { name = "scipy" }, { name = "typing-extensions" }, ] [package.optional-dependencies] +all = [ + { name = "imageio" }, + { name = "imageio-ffmpeg" }, + { name = "numba" }, + { name = "scipy" }, +] +numba = [ + { name = "numba" }, + { name = "scipy" }, +] tbb = [ { name = "tbb" }, ] +video = [ + { name = "imageio" }, + { name = "imageio-ffmpeg" }, +] [package.metadata] requires-dist = [ { name = "array-api-compat", specifier = "==1.15.0" }, { name = "gymnasium", specifier = "==1.1.1" }, - { name = "imageio", specifier = ">=2.30" }, - { name = "imageio-ffmpeg", specifier = ">=0.5" }, - { name = "numba", specifier = "==0.61.2" }, + { name = "imageio", marker = "extra == 'video'", specifier = ">=2.30" }, + { name = "imageio-ffmpeg", marker = "extra == 'video'", specifier = ">=0.5" }, + { name = "motrix-env-core", extras = ["numba", "video"], marker = "extra == 'all'", editable = "motrix_env_core" }, + { name = "numba", marker = "extra == 'numba'", specifier = "==0.61.2" }, { name = "numpy", specifier = ">=1.26" }, { name = "omegaconf", specifier = ">=2.3,<2.4" }, - { name = "scipy", specifier = "==1.15.3" }, + { name = "scipy", marker = "extra == 'numba'", specifier = "==1.15.3" }, { name = "tbb", marker = "extra == 'tbb'", specifier = "==2021.13.0" }, { name = "typing-extensions", specifier = ">=4.1" }, ] -provides-extras = ["tbb"] +provides-extras = ["numba", "video", "all", "tbb"] [[package]] name = "motrix-env-motrixsim" @@ -1057,7 +1069,7 @@ version = "0.4.0b0" source = { editable = "motrix_envs" } dependencies = [ { name = "gymnasium" }, - { name = "motrix-env-core" }, + { name = "motrix-env-core", extra = ["numba", "video"] }, { name = "motrix-env-motrixsim" }, { name = "numpy" }, { name = "omegaconf" }, @@ -1072,7 +1084,7 @@ deploy = [ requires-dist = [ { name = "gymnasium", specifier = "==1.1.1" }, { name = "motrix-deploy", marker = "extra == 'deploy'", editable = "motrix_deploy" }, - { name = "motrix-env-core", editable = "motrix_env_core" }, + { name = "motrix-env-core", extras = ["numba", "video"], editable = "motrix_env_core" }, { name = "motrix-env-motrixsim", editable = "motrix_env_motrixsim" }, { name = "numpy", specifier = ">=1.26" }, { name = "omegaconf", specifier = ">=2.3,<2.4" }, @@ -1096,10 +1108,10 @@ dependencies = [ [package.optional-dependencies] cuda = [ { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "torchaudio", version = "2.7.0", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_python_implementation != 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "torchaudio", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_python_implementation != 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "torchvision", version = "0.22.0", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_python_implementation != 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "torchvision", version = "0.22.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_python_implementation != 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "torchaudio", version = "2.7.0", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "torchaudio", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine == 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "torchvision", version = "0.22.0", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "torchvision", version = "0.22.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine == 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, ] docs = [ { name = "autodocsumm" }, @@ -1195,7 +1207,7 @@ dependencies = [ { name = "gymnasium" }, { name = "hydra-core" }, { name = "motrix-deploy" }, - { name = "motrix-env-core" }, + { name = "motrix-env-core", extra = ["numba", "video"] }, { name = "motrix-env-motrixsim" }, { name = "numpy" }, { name = "nvidia-ml-py" }, @@ -1235,7 +1247,7 @@ requires-dist = [ { name = "hydra-core", specifier = ">=1.3,<1.4" }, { name = "jax", extras = ["cuda12"], marker = "sys_platform == 'linux' and extra == 'skrl-jax'", specifier = "==0.4.34" }, { name = "motrix-deploy", editable = "motrix_deploy" }, - { name = "motrix-env-core", editable = "motrix_env_core" }, + { name = "motrix-env-core", extras = ["numba", "video"], editable = "motrix_env_core" }, { name = "motrix-env-motrixsim", editable = "motrix_env_motrixsim" }, { name = "numpy", specifier = ">=1.26" }, { name = "nvidia-ml-py", specifier = ">=13.610.43" }, @@ -1534,7 +1546,7 @@ name = "nvidia-cudnn-cu12" version = "9.7.1.26" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32' or extra != 'extra-10-motrix-lab-cuda' or (extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c1/2e/ec5dda717eeb1de3afbbbb611ca556f9d6d057470759c6abd36d72f0063b/nvidia_cudnn_cu12-9.7.1.26-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:848a61d40ef3b32bd4e1fadb599f0cf04a4b942fbe5fb3be572ad75f9b8c53ef", size = 725862213, upload-time = "2025-02-06T22:14:57.169Z" }, @@ -1573,7 +1585,7 @@ name = "nvidia-cufft-cu12" version = "11.3.3.41" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32' or extra != 'extra-10-motrix-lab-cuda' or (extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/72/95/6157cb45a49f5090a470de42353a22a0ed5b13077886dca891b4b0e350fe/nvidia_cufft_cu12-11.3.3.41-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68509dcd7e3306e69d0e2d8a6d21c8b25ed62e6df8aac192ce752f17677398b5", size = 193108626, upload-time = "2025-01-23T17:55:49.192Z" }, @@ -1639,9 +1651,9 @@ name = "nvidia-cusolver-cu12" version = "11.7.2.55" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32' or extra != 'extra-10-motrix-lab-cuda' or (extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32' or extra != 'extra-10-motrix-lab-cuda' or (extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32' or extra != 'extra-10-motrix-lab-cuda' or (extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/8c/ce/4214a892e804b20bf66d04f04a473006fc2d3dac158160ef85f1bc906639/nvidia_cusolver_cu12-11.7.2.55-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:0fd9e98246f43c15bee5561147ad235dfdf2d037f5d07c9d41af3f7f72feb7cc", size = 260094827, upload-time = "2025-01-23T17:58:17.586Z" }, @@ -1667,7 +1679,7 @@ name = "nvidia-cusparse-cu12" version = "12.5.7.53" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32' or extra != 'extra-10-motrix-lab-cuda' or (extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/2e/a2/313db0453087f5324a5900380ca2e57e050c8de76f407b5e11383dc762ae/nvidia_cusparse_cu12-12.5.7.53-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d869c6146ca80f4305b62e02d924b4aaced936f8173e3cef536a67eed2a91af1", size = 291963692, upload-time = "2025-01-23T17:59:40.325Z" }, @@ -2195,8 +2207,8 @@ dependencies = [ { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, { name = "torch", version = "2.11.0", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'x86_64' and sys_platform == 'linux' and extra != 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and sys_platform != 'win32') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra != 'extra-10-motrix-lab-cuda') or (sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform == 'linux' and extra != 'extra-10-motrix-lab-cuda' and extra != 'extra-10-motrix-lab-rocm')" }, { name = "torch", version = "2.11.0+rocm7.2", source = { registry = "https://download.pytorch.org/whl/rocm7.2" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-rocm') or (platform_machine != 'x86_64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "torchvision", version = "0.22.0", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_python_implementation != 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "torchvision", version = "0.22.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_python_implementation != 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "torchvision", version = "0.22.0", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "torchvision", version = "0.22.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine == 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, { name = "torchvision", version = "0.26.0", source = { registry = "https://pypi.org/simple" }, marker = "(sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, { name = "torchvision", version = "0.26.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "extra == 'extra-10-motrix-lab-rocm' or extra != 'extra-10-motrix-lab-cuda'" }, ] @@ -2610,7 +2622,8 @@ name = "torch" version = "2.7.0+cu128" source = { registry = "https://download.pytorch.org/whl/cu128" } resolution-markers = [ - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or sys_platform == 'win32'", + "(platform_machine != 'aarch64' and sys_platform == 'linux') or sys_platform == 'win32'", + "platform_machine == 'aarch64' and platform_python_implementation != 'CPython' and sys_platform == 'linux'", "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux'", ] dependencies = [ @@ -2701,10 +2714,11 @@ name = "torchaudio" version = "2.7.0" source = { registry = "https://download.pytorch.org/whl/cu128" } resolution-markers = [ + "platform_machine == 'aarch64' and platform_python_implementation != 'CPython' and sys_platform == 'linux'", "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux'", ] dependencies = [ - { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux'" }, + { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "platform_machine == 'aarch64' and sys_platform == 'linux'" }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cu128/torchaudio-2.7.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:dba5b20318d6f39753fc49b6b7267d7adb2c748997f716ef7838d5f048798f06", upload-time = "2025-04-22T18:30:29Z" }, @@ -2715,10 +2729,10 @@ name = "torchaudio" version = "2.7.0+cu128" source = { registry = "https://download.pytorch.org/whl/cu128" } resolution-markers = [ - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or sys_platform == 'win32'", + "(platform_machine != 'aarch64' and sys_platform == 'linux') or sys_platform == 'win32'", ] dependencies = [ - { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or sys_platform == 'win32'" }, + { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or sys_platform == 'win32'" }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cu128/torchaudio-2.7.0%2Bcu128-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:d62b6e9b792ad37af6d1289ba283e1029e71b4ff9cd3c6cf7f0e7776f23254b2", upload-time = "2025-04-22T18:30:28Z" }, @@ -2730,12 +2744,13 @@ name = "torchvision" version = "0.22.0" source = { registry = "https://download.pytorch.org/whl/cu128" } resolution-markers = [ + "platform_machine == 'aarch64' and platform_python_implementation != 'CPython' and sys_platform == 'linux'", "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux'", ] dependencies = [ - { name = "numpy", marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_python_implementation != 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "pillow", marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_python_implementation != 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_python_implementation != 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "numpy", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "pillow", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine != 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cu128/torchvision-0.22.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:566224d7b4f00bc6366bed1d62f834ca80f8e57fe41e10e4a5636bfa3ffb984e", upload-time = "2025-04-22T18:30:20Z" }, @@ -2746,12 +2761,12 @@ name = "torchvision" version = "0.22.0+cu128" source = { registry = "https://download.pytorch.org/whl/cu128" } resolution-markers = [ - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or sys_platform == 'win32'", + "(platform_machine != 'aarch64' and sys_platform == 'linux') or sys_platform == 'win32'", ] dependencies = [ - { name = "numpy", marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_python_implementation != 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "pillow", marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_python_implementation != 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, - { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_python_implementation != 'CPython' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "numpy", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine == 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "pillow", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine == 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, + { name = "torch", version = "2.7.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-10-motrix-lab-cuda') or (platform_machine == 'aarch64' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm') or (sys_platform == 'win32' and extra == 'extra-10-motrix-lab-cuda') or (sys_platform != 'linux' and extra == 'extra-10-motrix-lab-cuda' and extra == 'extra-10-motrix-lab-rocm')" }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cu128/torchvision-0.22.0%2Bcu128-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:59df5a550113a80ce523047066eaaedb168c69482da88c3ab246716ab45ba092", upload-time = "2025-04-22T18:30:20Z" }, @@ -2828,7 +2843,8 @@ name = "triton" version = "3.3.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or sys_platform == 'win32'", + "(platform_machine != 'aarch64' and sys_platform == 'linux') or sys_platform == 'win32'", + "platform_machine == 'aarch64' and platform_python_implementation != 'CPython' and sys_platform == 'linux'", "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux'", ] dependencies = [ From 93765793db8ef13055dfec6f32bae889ec521669 Mon Sep 17 00:00:00 2001 From: zilch <147668916@qq.com> Date: Mon, 28 Sep 2026 22:34:48 +0800 Subject: [PATCH 2/3] test(core): friendly missing-video error and skip without the extra Address review feedback on the optional video dependencies: - VideoRecorder._write_frame raises an ImportError that points to `motrix-env-core[video]` when imageio is missing - the pacing test uses pytest.importorskip so minimal core installs skip instead of hard-failing --- motrix_env_core/src/motrix_env_core/renderer.py | 8 +++++++- motrix_env_core/tests/test_rendering.py | 7 +++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/motrix_env_core/src/motrix_env_core/renderer.py b/motrix_env_core/src/motrix_env_core/renderer.py index 508a426d..9d466337 100644 --- a/motrix_env_core/src/motrix_env_core/renderer.py +++ b/motrix_env_core/src/motrix_env_core/renderer.py @@ -106,7 +106,13 @@ def _write_frame(self, frame: np.ndarray) -> None: # imageio is an optional dependency (``motrix-env-core[video]``): # importing it lazily keeps this module importable in installs # that only run headless training without video recording. - import imageio.v2 as imageio + try: + import imageio.v2 as imageio + except ImportError as e: + raise ImportError( + "VideoRecorder requires the optional video dependencies; " + "install them with `pip install motrix-env-core[video]`" + ) from e self._path.parent.mkdir(parents=True, exist_ok=True) # macro_block_size=None keeps the configured frame size untouched; diff --git a/motrix_env_core/tests/test_rendering.py b/motrix_env_core/tests/test_rendering.py index f1618b94..480b8436 100644 --- a/motrix_env_core/tests/test_rendering.py +++ b/motrix_env_core/tests/test_rendering.py @@ -58,8 +58,11 @@ def test_video_recorder_paces_frames_and_closes_frame_source(tmp_path, monkeypat writer = MagicMock() get_writer = MagicMock(return_value=writer) # renderer imports imageio lazily inside _write_frame, so patch the real - # module attribute the function resolves on import. - import imageio.v2 as imageio + # module attribute the function resolves on import. imageio is optional + # (motrix-env-core[video]); skip cleanly on minimal core installs. + imageio = pytest.importorskip( + "imageio.v2", reason="video recording requires motrix-env-core[video]" + ) monkeypatch.setattr(imageio, "get_writer", get_writer) From 916f43c9842ff353894463718c39ad491ea676e9 Mon Sep 17 00:00:00 2001 From: zilch Date: Thu, 1 Oct 2026 12:24:19 +0800 Subject: [PATCH 3/3] style(core): collapse importorskip to one line for ruff format --- motrix_env_core/tests/test_rendering.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/motrix_env_core/tests/test_rendering.py b/motrix_env_core/tests/test_rendering.py index 480b8436..dbcefd97 100644 --- a/motrix_env_core/tests/test_rendering.py +++ b/motrix_env_core/tests/test_rendering.py @@ -60,9 +60,7 @@ def test_video_recorder_paces_frames_and_closes_frame_source(tmp_path, monkeypat # renderer imports imageio lazily inside _write_frame, so patch the real # module attribute the function resolves on import. imageio is optional # (motrix-env-core[video]); skip cleanly on minimal core installs. - imageio = pytest.importorskip( - "imageio.v2", reason="video recording requires motrix-env-core[video]" - ) + imageio = pytest.importorskip("imageio.v2", reason="video recording requires motrix-env-core[video]") monkeypatch.setattr(imageio, "get_writer", get_writer)