Skip to content

Commit e574928

Browse files
SyncBotryhalabi
authored andcommitted
- Adds shared deployment mode enums in gr00t/deployment/modes.py and wires them into ONNX export, TRT build, verification, and benchmark CLIs.
- Tightens TRT export/build behavior: BF16-only pipeline config, static batch-size docs, ViT exported/built as FP32 while the rest stays BF16, strongly-typed precision validation, per-component precision inference from ONNX names, and full-pipeline build failure when any ONNX input/engine is missing. - Refactors TRT runtime lifecycle: trt_torch.Engine now has explicit close() cleanup instead of an atexit hook. - Simplifies video decoding to torchcodec-only, removing ffmpeg/decord/opencv/pyav dispatch paths, video_backend config/CLI args, av dependencies, and related obsolete tests. - Reworks rollout video recording to stream frames through ffmpeg, stabilize caption buffer height, support explicit record_video_keys, and avoid shape changes during H.264 encoding. - Hardens eval wrappers: env-prefix-to-embodiment mapping now fails with actionable errors, and MultiStepWrapper uses a typed AggregateMethod with fail-fast validation. - Updates N1.7 model processing: letterbox padding is disabled by default and made optional, image transform inputs are validated more strictly, single-model tyro union parsing is fixed, and Qwen3-VL RoPE inv_freq buffers are recomputed after load for deterministic behavior. - Adds explicit PolicyServer / PolicyClient cleanup and context-manager support, including server startup usage in run_gr00t_server.py and the DROID example client. - Cleans up training/data code: hides modality configs from tyro CLI, removes dataset video_backend plumbing, deletes dead flowmatching/eval-accuracy code, and removes custom pytest log banners. - Updates Docker and platform deps: global image venv under /opt/gr00t-venv, aarch64 wheel bootstrap support, Thor wheel LFS tracking, TensorRT libs pinned to NVIDIA index, dev deps for pytest-xdist/coverage/licensing, and platform pyprojects without av. - Updates examples/docs: DROID video saving now uses imageio instead of moviepy, SimplerEnv metrics/docs are refreshed, and deployment docs remove video-backend options. - Expands tests around Qwen3 RoPE/no-weight loading, TRT precision and missing-input handling, TRT engine lifecycle, deployment mode consistency, multistep aggregation, policy service lifecycle, and torchcodec video behavior; removes obsolete PyAV/backend-dispatch tests. Co-authored-by: Jiajing Chen <jiajingc@nvidia.com> Co-authored-by: Ryan Halabi <ryhalabi@nvidia.com> id: f12a6f10fcb60bf317397fe363a50b077b88ae58
1 parent 65cc4a1 commit e574928

81 files changed

Lines changed: 3450 additions & 2257 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ demo_data/**/*.parquet filter=lfs diff=lfs merge=lfs -text
44
scripts/deployment/dgpu/wheels/*.whl filter=lfs diff=lfs merge=lfs -text
55
scripts/deployment/orin/wheels/*.whl filter=lfs diff=lfs merge=lfs -text
66
scripts/deployment/spark/wheels/*.whl filter=lfs diff=lfs merge=lfs -text
7+
scripts/deployment/thor/wheels/*.whl filter=lfs diff=lfs merge=lfs -text

.pre-commit-config.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
exclude: ^(external_dependencies/)
2+
repos:
3+
# Ruff: lint + autofix
4+
- repo: https://github.com/astral-sh/ruff-pre-commit
5+
rev: v0.12.7
6+
hooks:
7+
- id: ruff
8+
args: [--fix]
9+
- id: ruff-format
10+
11+
# Catch cross-platform pyproject pin drift (dGPU/Orin/Spark/Thor) at commit
12+
# time; a missed mirror otherwise only surfaces at install on the unsynced
13+
# platform. tomli is the 3.10 backport of stdlib tomllib (3.11+).
14+
- repo: local
15+
hooks:
16+
- id: check-manifest-alignment
17+
name: cross-platform pyproject manifest alignment
18+
entry: python tools/check_manifest_alignment.py
19+
language: python
20+
additional_dependencies: ["tomli; python_version < '3.11'"]
21+
# Mirrors MANIFESTS in tools/check_manifest_alignment.py; keep in sync when
22+
# adding a platform. A miss only drops the local trigger — the unit-test
23+
# live gate reads MANIFESTS directly and still fails CI on drift.
24+
files: ^(pyproject\.toml|scripts/deployment/(orin|spark|thor)/pyproject\.toml|tools/(check_manifest_alignment\.py|manifest_alignment\.toml))$
25+
pass_filenames: false

ATTRIBUTIONS.md

Lines changed: 186 additions & 29 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ curl -LsSf https://astral.sh/uv/install.sh | sh
136136

137137
#### dGPU (x86_64) — Default
138138

139-
Install FFmpeg (required by `torchcodec`, the default video backend):
139+
Install FFmpeg (required by `torchcodec`, the only supported video backend):
140140
```sh
141141
sudo apt-get update && sudo apt-get install -y ffmpeg
142142
```
@@ -175,7 +175,7 @@ Note: GPU dependencies (flash-attn, TensorRT) may require manual installation wi
175175
176176
> **GB300 (sm_103) Users:** Triton 3.3.1 (pinned by PyTorch 2.7) does not support the GB300 GPU architecture (sm_103). `torch.compile` will fail on GB300. Use PyTorch eager mode or TensorRT inference instead. Triton 3.5.1+ adds sm_103 support but is not yet compatible with the pinned PyTorch version.
177177
178-
> **aarch64 Video Backend:** On aarch64 platforms (Thor, Orin, Spark), `torchcodec` is the required video backend. `install_deps.sh` prefers the prebuilt aarch64 wheel under `scripts/deployment/dgpu/wheels/` (shared by Thor/Spark against FFmpeg 6; Orin uses a matching build against FFmpeg 4) and falls back to a source build only if the wheel is missing. If you encounter `NotImplementedError` from the video backend, ensure `torchcodec` was installed successfully during setup. Other backends (decord, pyav) are not supported on aarch64.
178+
> **Video Backend:** GR00T uses [`torchcodec`](https://github.com/pytorch/torchcodec) as its sole video decoding backend. Backends such as `decord` and `pyav` are no longer supported. `torchcodec` requires FFmpeg and supports H.264 on all platforms; AV1 decoding is not guaranteed (convert AV1 datasets to H.264 with `examples/SimplerEnv/convert_av1_to_h264.py`). On aarch64 platforms (Thor, Orin), `torchcodec` is built from source during `install_deps.sh` because pre-built wheels are not available — if you encounter a `NotImplementedError`, ensure the build completed successfully.
179179
180180
<details>
181181
<summary><strong>DGX Spark</strong> (tested with DGX Spark GB10)</summary>
@@ -240,7 +240,7 @@ See the [Orin setup guide](scripts/deployment/README.md#jetson-orin-setup) for D
240240
> destroy the platform-specific environment.
241241
242242
243-
For a containerized setup that avoids system-level dependency conflicts, see our [Docker Setup Guide](docker/README.md).
243+
For a containerized setup that avoids system-level dependency conflicts, see our [Docker Setup Guide](docker/README.md). The recommended container workflow is to start the image first, then clone or pull the repo inside the running container so your checkout uses the image's prebuilt dependency environment.
244244
245245
---
246246
@@ -310,6 +310,8 @@ See the full [Data Preparation Guide](getting_started/data_preparation.md) for s
310310
311311
## Inference
312312
313+
> **Prefer an interactive walkthrough?** The [`getting_started/GR00T_inference.ipynb`](getting_started/GR00T_inference.ipynb) notebook steps through loading the model and predicting actions from observations on a sample dataset.
314+
313315
### Zero-Shot Inference (Base Model)
314316
315317
The included `demo_data/droid_sample` dataset works with the base model out of the box — no finetuning or checkpoint download needed:
@@ -326,8 +328,6 @@ uv run python scripts/deployment/standalone_inference_script.py \
326328
327329
This runs open-loop inference on 2 DROID episodes, comparing predicted actions against ground truth. The base model downloads automatically from HuggingFace on first run (~6 GB).
328330
329-
The standalone inference script defaults to the `ffmpeg` video backend so this demo works on systems with newer FFmpeg releases. If you explicitly use `--video-backend torchcodec`, make sure your installed `torchcodec` wheel is compatible with your system FFmpeg version.
330-
331331
### Finetuned Inference
332332
333333
For posttrain embodiments, use a finetuned checkpoint. Most finetuned checkpoints (e.g., DROID, SimplerEnv) have a flat file structure and can be passed directly as a HuggingFace model ID — no manual download needed:

docker/Dockerfile

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# syntax=docker/dockerfile:1
22
# GR00T Docker image (x86_64 + aarch64)
33
#
4-
# Single Dockerfile for both architectures. On aarch64 (GB200, Grace Hopper)
5-
# flash-attn and torchcodec are installed from prebuilt wheels under
6-
# scripts/deployment/dgpu/wheels/ via pyproject.toml path sources.
4+
# Single Dockerfile for both architectures. On aarch64 (GB200, Grace Hopper),
5+
# flash-attn and torchcodec are installed from wheels under
6+
# scripts/deployment/dgpu/wheels/ via pyproject.toml path sources. If those
7+
# wheels are missing, the Docker build bootstraps them from source first.
78
#
89
# Build:
910
# docker build -f docker/Dockerfile -t gr00t .
@@ -17,6 +18,8 @@ SHELL ["/bin/bash", "-c"]
1718

1819
ENV DEBIAN_FRONTEND=noninteractive \
1920
NVIDIA_DRIVER_CAPABILITIES=graphics,utility,compute \
21+
GR00T_GLOBAL_VENV=/opt/gr00t-venv \
22+
UV_PROJECT_ENVIRONMENT=/opt/gr00t-venv \
2023
PYTHON=/usr/bin/python \
2124
CUDA_HOME=/usr/local/cuda \
2225
PATH=/usr/local/cuda/bin:${PATH} \
@@ -68,7 +71,18 @@ apt_install_retry() {
6871
python3-pip \
6972
python-is-python3 \
7073
software-properties-common \
74+
cmake \
75+
ninja-build \
76+
pkg-config \
77+
pybind11-dev \
7178
ffmpeg \
79+
libavdevice-dev \
80+
libavfilter-dev \
81+
libavformat-dev \
82+
libavcodec-dev \
83+
libavutil-dev \
84+
libswresample-dev \
85+
libswscale-dev \
7286
libegl1; then
7387
return 0
7488
fi
@@ -98,50 +112,57 @@ pip_install_retry
98112
curl --retry 5 --retry-delay 10 --retry-max-time 300 -LsSf https://astral.sh/uv/0.8.14/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh
99113
INNEREOF
100114

101-
WORKDIR /workspace
115+
WORKDIR /tmp/gr00t-venv-build
102116

103117
# Install Python dependencies from lockfile
104118
# The wheels/ dir must be present before `uv sync` because pyproject.toml
105119
# references them as path sources for aarch64 flash-attn and torchcodec.
106120
COPY pyproject.toml uv.lock ./
121+
COPY scripts/deployment/dgpu/bootstrap_wheels.sh ./scripts/deployment/dgpu/bootstrap_wheels.sh
107122
COPY scripts/deployment/dgpu/wheels/ ./scripts/deployment/dgpu/wheels/
108123

109124
RUN <<INNEREOF
110125
set -euo pipefail
111126

112-
uv_sync_retry() {
127+
uv_lock_retry() {
113128
for attempt in 1 2 3 4 5; do
114-
if UV_PREVIEW=1 UV_HTTP_TIMEOUT=300 UV_CONCURRENT_DOWNLOADS=4 uv sync --frozen --no-install-project --extra dev --no-cache; then
129+
if UV_PREVIEW=1 UV_HTTP_TIMEOUT=300 UV_CONCURRENT_DOWNLOADS=4 uv lock; then
115130
return 0
116131
fi
117132
sleep $((attempt * 10))
118133
done
119134
return 1
120135
}
121136

122-
uv_sync_retry
123-
INNEREOF
124-
125-
# Install the gr00t project itself
126-
COPY . .
127-
RUN <<INNEREOF
128-
set -euo pipefail
129-
130-
uv_pip_install_retry() {
137+
uv_sync_retry() {
131138
for attempt in 1 2 3 4 5; do
132-
if uv pip install --python /workspace/.venv/bin/python -e . --no-deps; then
139+
if UV_PREVIEW=1 UV_HTTP_TIMEOUT=300 UV_CONCURRENT_DOWNLOADS=4 uv sync --frozen --no-install-project --extra dev --no-cache; then
133140
return 0
134141
fi
135142
sleep $((attempt * 10))
136143
done
137144
return 1
138145
}
139146

140-
uv_pip_install_retry
147+
if [ "$(uname -m)" = "aarch64" ]; then
148+
bash scripts/deployment/dgpu/bootstrap_wheels.sh
149+
uv_lock_retry
150+
fi
151+
152+
uv_sync_retry
153+
sha256sum uv.lock | awk '{print $1}' > "${GR00T_GLOBAL_VENV}/.gr00t-uv-lock.sha256"
154+
mkdir -p /opt/gr00t-image-metadata
155+
cp pyproject.toml uv.lock /opt/gr00t-image-metadata/
156+
cd /
157+
rm -rf /tmp/gr00t-venv-build
141158
INNEREOF
142159

143-
ENV PATH="/workspace/.venv/bin:${PATH}" \
144-
VIRTUAL_ENV="/workspace/.venv"
160+
WORKDIR /
161+
RUN mkdir -p /workspace && ln -sfn "${GR00T_GLOBAL_VENV}" /workspace/.venv
162+
WORKDIR /workspace
163+
164+
ENV PATH="${GR00T_GLOBAL_VENV}/bin:${PATH}" \
165+
VIRTUAL_ENV="${GR00T_GLOBAL_VENV}"
145166

146167
# EGL/Vulkan setup for headless rendering (MuJoCo, PyOpenGL)
147168
RUN mkdir -p /usr/share/glvnd/egl_vendor.d && \
@@ -169,7 +190,8 @@ ENV MUJOCO_GL="egl" \
169190
PYOPENGL_PLATFORM="egl" \
170191
__EGL_VENDOR_LIBRARY_FILENAMES="/usr/share/glvnd/egl_vendor.d/10_nvidia.json"
171192

172-
# torchcodec and flash-attn for aarch64 are installed from prebuilt wheels
173-
# by `uv sync` above via pyproject.toml path sources — no source build needed.
193+
# torchcodec and flash-attn for aarch64 are installed from build-context wheels
194+
# by `uv sync` above via pyproject.toml path sources. Missing wheels are built
195+
# from source before sync, then committed back to the repo.
174196

175197
CMD ["/bin/bash"]

docker/README.md

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,49 @@ From the repository root:
1818
bash docker/build.sh
1919
```
2020

21-
This builds from `nvidia/cuda:12.8.0-devel-ubuntu22.04`, installs all dependencies via `uv sync`, and sets up the GR00T codebase at `/workspace/`.
21+
This builds from `nvidia/cuda:12.8.0-devel-ubuntu22.04` and installs all dependencies into `/opt/gr00t-venv`. The image does not include a working source checkout; for normal use, start the image and then clone or pull the repo you want to run inside the container.
2222

2323
## Running the Container
2424

25-
**Interactive shell (uses code baked into image):**
25+
**Recommended workflow: run the image, then clone or update the repo inside it.**
26+
27+
Start an interactive shell:
28+
2629
```bash
2730
docker run -it --rm --gpus all \
2831
--ipc=host --ulimit memlock=-1 --ulimit stack=67108864 \
2932
gr00t
3033
```
3134

32-
**Development mode (mounts local codebase for live editing):**
35+
Then, inside the container:
36+
37+
```bash
38+
git clone --recurse-submodules https://github.com/NVIDIA/Isaac-GR00T /workspace/Isaac-GR00T
39+
cd /workspace/Isaac-GR00T
40+
export PYTHONPATH="$PWD${PYTHONPATH:+:$PYTHONPATH}"
41+
python -c "import gr00t; print('GR00T ready')"
42+
```
43+
44+
The image venv is active by default (`/opt/gr00t-venv`; `/workspace/.venv` is a compatibility symlink), and uv is configured with `UV_PROJECT_ENVIRONMENT=/opt/gr00t-venv`. After setting `PYTHONPATH` to the checked-out repo, both `python ...` and `uv run ...` use the global image venv instead of creating a checkout-local `.venv`. If you are working on an existing checkout in the container, run `git pull --ff-only` from that checkout instead of cloning again.
45+
46+
The global venv records the `uv.lock` hash it was built from. If your checked-out repo uses a different lockfile, create a checkout-local venv before running commands. Reusing a uv cache keeps this path from starting cold:
47+
48+
```bash
49+
export UV_CACHE_DIR="${UV_CACHE_DIR:-/workspace/uv-cache}"
50+
export UV_LINK_MODE=copy
51+
UV_PROJECT_ENVIRONMENT="$PWD/.venv" uv sync
52+
source .venv/bin/activate
53+
```
54+
55+
Do not run a bare `uv sync` unless you intend to update the global image venv. Use `UV_PROJECT_ENVIRONMENT="$PWD/.venv" uv sync` when you want an isolated per-checkout environment.
56+
57+
Avoid bind-mounting over `/workspace`, because that can hide the image's `/workspace/.venv` compatibility symlink. If you need to mount local source for live editing, mount it under a subdirectory:
58+
3359
```bash
3460
docker run -it --rm --gpus all \
3561
--ipc=host --ulimit memlock=-1 --ulimit stack=67108864 \
36-
-v $(pwd):/workspace \
37-
gr00t bash -c "uv pip install -e . && bash"
62+
-v "$(pwd):/workspace/Isaac-GR00T" \
63+
gr00t bash -c 'cd /workspace/Isaac-GR00T && export PYTHONPATH="$PWD${PYTHONPATH:+:$PYTHONPATH}" && bash'
3864
```
3965

4066
## Edge Device Containers

examples/DROID/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ NUM_GPUS=8 MAX_STEPS=20000 GLOBAL_BATCH_SIZE=640 SAVE_STEPS=1000 uv run bash exa
9999

100100
2. Install dependencies for the GR00T control script in the environment from step 1:
101101
```bash
102-
pip install tyro moviepy==1.0.3 pydantic numpy==1.26.4
102+
pip install tyro pydantic numpy==1.26.4
103103
```
104104

105105
3. Enter the camera IDs for your ZED cameras in `examples/DROID/main_gr00t.py`.

examples/DROID/main_gr00t.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,16 @@ def _load_runtime_deps():
104104
try:
105105
import imageio
106106
from droid.robot_env import RobotEnv
107-
from moviepy.editor import ImageSequenceClip
108107
from server_client import PolicyClient
109108
from utils import resize_with_pad
110109
except ModuleNotFoundError as exc:
111110
raise ModuleNotFoundError(
112111
"examples/DROID/main_gr00t.py requires the DROID robot-control environment. "
113112
"Follow examples/DROID/README.md and install the DROID package plus "
114-
"`pip install tyro moviepy==1.0.3 pydantic numpy==1.26.4` before running."
113+
"`pip install tyro pydantic numpy==1.26.4` before running."
115114
) from exc
116115

117-
return RobotEnv, PolicyClient, ImageSequenceClip, imageio, resize_with_pad
116+
return RobotEnv, PolicyClient, imageio, resize_with_pad
118117

119118

120119
# We are using Ctrl+C to optionally terminate rollouts early -- however, if we press Ctrl+C while the policy server is
@@ -140,7 +139,7 @@ def handler(signum, frame):
140139

141140

142141
def main(args: Args):
143-
RobotEnv, PolicyClient, ImageSequenceClip, imageio, resize_with_pad = _load_runtime_deps()
142+
RobotEnv, PolicyClient, imageio, resize_with_pad = _load_runtime_deps()
144143

145144
assert args.external_camera in ["left", "right"], (
146145
f"Invalid exterior camera: {args.exterior_camera}"
@@ -380,9 +379,9 @@ def main(args: Args):
380379
save_filename = os.path.join(
381380
results_dir, "videos", f"{sanitized_instruction}_video_" + timestamp
382381
)
383-
ImageSequenceClip(list(video), fps=args.render_fps).write_videofile(
384-
save_filename + ".mp4", codec="libx264"
385-
)
382+
with imageio.get_writer(save_filename + ".mp4", fps=args.render_fps) as writer:
383+
for frame in video:
384+
writer.append_data(frame)
386385

387386
if args.debug:
388387
model_wrist_image_writer.close()

examples/DROID/server_client.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ def __init__(
282282
strict: bool = False,
283283
):
284284
super().__init__(strict=strict)
285+
self._closed = False
285286
self.context = zmq.Context()
286287
self.host = host
287288
self.port = port
@@ -335,10 +336,39 @@ def call_endpoint(
335336
raise RuntimeError(f"Server error: {response['error']}")
336337
return response
337338

339+
def close(self) -> None:
340+
"""Release the REQ socket and ZMQ context. Idempotent.
341+
342+
Mirrors ``gr00t.policy.server_client.PolicyClient.close()`` so the
343+
DROID example demonstrates the explicit-lifecycle pattern.
344+
"""
345+
if getattr(self, "_closed", True):
346+
return
347+
self._closed = True
348+
socket = getattr(self, "socket", None)
349+
if socket is not None:
350+
try:
351+
socket.close(linger=0)
352+
except Exception:
353+
pass
354+
context = getattr(self, "context", None)
355+
if context is not None:
356+
try:
357+
context.term()
358+
except Exception:
359+
pass
360+
361+
def __enter__(self):
362+
return self
363+
364+
def __exit__(self, exc_type, exc, tb):
365+
self.close()
366+
338367
def __del__(self):
339-
"""Cleanup resources on destruction"""
340-
self.socket.close()
341-
self.context.term()
368+
try:
369+
self.close()
370+
except Exception:
371+
pass
342372

343373
def _get_action(
344374
self, observation: dict[str, Any], options: dict[str, Any] | None = None

examples/SimplerEnv/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ Provided checkpoints:
3636
| Task | N1.6 success rate | N1.7 success rate |
3737
| --- | ---: | ---: |
3838
| `google_robot_pick_coke_can` | 95/100 (95.0%) | 100/100 (100.0%) |
39-
| `google_robot_pick_object` | 87/100 (87.0%) | 96/100 (96.0%) |
40-
| `google_robot_move_near` | 81/100 (81.0%) | 96/100 (96.0%) |
41-
| `google_robot_open_drawer` | 0/100 (0.0%) | 36/100 (36.0%) |
42-
| `google_robot_close_drawer` | 44/100 (44.0%) | 63/100 (63.0%) |
43-
| `google_robot_place_in_closed_drawer` | 5/100 (5.0%) | 21/100 (21.0%) |
44-
| **Average** | **52.0%** | **68.7%** |
39+
| `google_robot_pick_object` | 87/100 (87.0%) | 94/100 (94.0%) |
40+
| `google_robot_move_near` | 81/100 (81.0%) | 100/100 (100.0%) |
41+
| `google_robot_open_drawer` | 0/100 (0.0%) | 65/100 (65.0%) |
42+
| `google_robot_close_drawer` | 44/100 (44.0%) | 69/100 (69.0%) |
43+
| `google_robot_place_in_closed_drawer` | 5/100 (5.0%) | 7/100 (7.0%) |
44+
| **Average** | **52.0%** | **72.5%** |
4545

4646
# Fine-tune Simpler Env bridge dataset (WidowX robot)
4747

@@ -74,7 +74,7 @@ uv run hf download \
7474

7575
# Copy the patches and run the finetune script
7676
cp -r examples/SimplerEnv/fractal_modality.json examples/SimplerEnv/fractal20220817_data_lerobot/meta/modality.json
77-
uv run python examples/SimplerEnv/convert_av1_to_h264.py examples/SimplerEnv/fractal20220817_data_lerobot --jobs 16 # (Optional) if AV1 doesn't work on your machine
77+
uv run python examples/SimplerEnv/convert_av1_to_h264.py --root examples/SimplerEnv/fractal20220817_data_lerobot --jobs 16
7878
```
7979

8080
```bash

0 commit comments

Comments
 (0)