mirror of
https://github.com/huggingface/lerobot.git
synced 2026-05-22 03:59:42 +00:00
fix(docker): add libero_plus install workaround to generic Dockerfile.benchmark
The generic Dockerfile.benchmark was using a plain `uv pip install ".[libero_plus]"` which silently fails to make `libero` importable due to an upstream LIBERO-plus packaging bug. Port the dedicated clone + .pth workaround from Dockerfile.eval-libero-plus so `docker build --build-arg BENCHMARK=libero_plus` produces working containers. Also fix eval worker using nonexistent `parser.parse()` — use `draccus.parse()`. Made-with: Cursor
This commit is contained in:
@@ -39,6 +39,7 @@ ARG BENCHMARK=libero
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
MUJOCO_GL=egl \
|
||||
PATH=/lerobot/.venv/bin:$PATH \
|
||||
CMAKE_POLICY_VERSION_MINIMUM=3.5 \
|
||||
CUDA_VISIBLE_DEVICES=0 \
|
||||
DEVICE=cuda \
|
||||
BENCHMARK=${BENCHMARK}
|
||||
@@ -82,7 +83,7 @@ ENV HOME=/home/user_lerobot \
|
||||
TORCH_HOME=/home/user_lerobot/.cache/torch \
|
||||
TRITON_CACHE_DIR=/home/user_lerobot/.cache/triton
|
||||
|
||||
RUN uv venv --python python${PYTHON_VERSION}
|
||||
RUN uv venv --seed --python python${PYTHON_VERSION}
|
||||
|
||||
# Copy only the dependency manifests first so Docker can cache this layer
|
||||
# independently of source-code changes.
|
||||
@@ -96,8 +97,29 @@ RUN if [ "$UNBOUND_DEPS" = "true" ]; then \
|
||||
fi
|
||||
|
||||
# Install lerobot core + the selected benchmark extra.
|
||||
# Git-based deps (libero_plus, robomme) require network access at build time.
|
||||
RUN uv pip install --no-cache ".[${BENCHMARK}]"
|
||||
# LIBERO-plus needs a dedicated install path because the upstream package is
|
||||
# import-broken when installed via the extras chain alone.
|
||||
RUN case "${BENCHMARK}" in \
|
||||
libero_plus) \
|
||||
PATH=/usr/bin:/bin:/lerobot/.venv/bin:$PATH /lerobot/.venv/bin/python -m pip install --no-cache-dir \
|
||||
"hf-libero>=0.1.3,<0.2.0" \
|
||||
"hf-egl-probe>=1.0.1" \
|
||||
"transformers>=5.3.0,<6.0.0" \
|
||||
"scipy>=1.14.0,<2.0.0" \
|
||||
"bddl>=1.0.1,<2.0.0" \
|
||||
"future" \
|
||||
"easydict>=1.9" \
|
||||
"wand" \
|
||||
"scikit-image>=0.20.0" \
|
||||
"gym>=0.25.0,<0.27.0" \
|
||||
&& git clone --depth 1 https://github.com/sylvestf/LIBERO-plus.git /tmp/LIBERO-plus \
|
||||
&& PATH=/usr/bin:/bin:/lerobot/.venv/bin:$PATH /lerobot/.venv/bin/python -m pip install --no-cache-dir --no-deps /tmp/LIBERO-plus \
|
||||
&& /lerobot/.venv/bin/python -c "import pathlib, site; pathlib.Path(site.getsitepackages()[0], 'libero_plus_repo.pth').write_text('/tmp/LIBERO-plus\n')" \
|
||||
&& /lerobot/.venv/bin/python -m pip install --no-cache-dir . \
|
||||
&& /lerobot/.venv/bin/python -c "import libero, robosuite, bddl" ;; \
|
||||
*) \
|
||||
uv pip install --no-cache ".[${BENCHMARK}]" ;; \
|
||||
esac
|
||||
|
||||
# Triton requires its ptxas binary to be executable (NVIDIA-specific).
|
||||
RUN if [ -f /lerobot/.venv/lib/python${PYTHON_VERSION}/site-packages/triton/backends/nvidia/bin/ptxas ]; then \
|
||||
|
||||
@@ -39,10 +39,10 @@ import urllib.request
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
import draccus
|
||||
import numpy as np
|
||||
|
||||
from lerobot import envs # noqa: F401 — registers all env subclasses
|
||||
from lerobot.configs import parser
|
||||
from lerobot.envs.configs import EnvConfig
|
||||
from lerobot.envs.factory import make_env
|
||||
from lerobot.envs.utils import add_envs_task, preprocess_observation
|
||||
@@ -184,7 +184,7 @@ def worker_main(cfg: EvalWorkerConfig) -> None:
|
||||
|
||||
def main() -> None:
|
||||
init_logging()
|
||||
cfg = parser.parse(EvalWorkerConfig)
|
||||
cfg = draccus.parse(config_class=EvalWorkerConfig)
|
||||
worker_main(cfg)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright 2025 The HuggingFace Inc. team. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from lerobot.scripts import lerobot_eval_worker
|
||||
|
||||
|
||||
def test_worker_main_writes_results(monkeypatch, tmp_path: Path):
|
||||
cfg = lerobot_eval_worker.EvalWorkerConfig(
|
||||
env="pusht", # type: ignore[arg-type]
|
||||
instance_id=3,
|
||||
output_path=tmp_path / "worker.json",
|
||||
)
|
||||
|
||||
monkeypatch.setattr(lerobot_eval_worker, "run_worker", lambda _cfg: {"per_task": []})
|
||||
|
||||
lerobot_eval_worker.worker_main(cfg)
|
||||
|
||||
assert cfg.output_path.exists()
|
||||
assert cfg.output_path.read_text().strip() == '{\n "per_task": []\n}'
|
||||
Reference in New Issue
Block a user