Merge remote-tracking branch 'origin/main' into feat/smolvla-on-steerable

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	src/lerobot/configs/train.py
#	src/lerobot/datasets/__init__.py
#	src/lerobot/policies/factory.py
#	src/lerobot/policies/groot/groot_n1.py
#	src/lerobot/scripts/lerobot_eval.py
#	src/lerobot/scripts/lerobot_train.py
#	uv.lock
This commit is contained in:
pepijn
2026-07-08 10:31:40 +00:00
245 changed files with 32689 additions and 8703 deletions
+68
View File
@@ -0,0 +1,68 @@
# 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.
import pytest
import lerobot.configs.train as tc
from lerobot.configs.train import TrainPipelineConfig
class _FakeHTTPError(tc.HfHubHTTPError):
"""HfHubHTTPError that can be raised without a real HTTP response object."""
def __init__(self):
pass
def test_from_pretrained_falls_back_to_latest_checkpoint_config(tmp_path, monkeypatch):
"""A Hub repo with no root train_config.json (an interrupted run that only pushed
checkpoints/) resolves via the latest checkpoint's config."""
# A real train_config.json written by save_pretrained, to be returned by the fallback.
parsed = tc.draccus.parse(TrainPipelineConfig, args=["--dataset.repo_id", "u/d"])
cfg_file = tmp_path / "train_config.json"
parsed._save_pretrained(tmp_path)
assert cfg_file.is_file()
calls = []
def fake_hf_hub_download(filename=None, **kwargs):
calls.append(filename)
if filename == "train_config.json":
raise _FakeHTTPError() # no root config
if filename == "checkpoints/000010/pretrained_model/train_config.json":
return str(cfg_file)
raise AssertionError(f"unexpected filename {filename}")
monkeypatch.setattr(tc, "hf_hub_download", fake_hf_hub_download)
monkeypatch.setattr(
tc, "find_latest_hub_checkpoint", lambda repo_id, token=None, revision=None: "checkpoints/000010"
)
loaded = TrainPipelineConfig.from_pretrained("user/interrupted-run")
assert loaded.dataset.repo_id == "u/d"
# Tried the root config first, then fell back to the latest checkpoint's config.
assert calls == ["train_config.json", "checkpoints/000010/pretrained_model/train_config.json"]
def test_from_pretrained_raises_when_no_root_config_and_no_checkpoints(monkeypatch):
"""No root config AND no checkpoints → a clear FileNotFoundError, not the raw HTTP error."""
def fake_hf_hub_download(filename=None, **kwargs):
raise _FakeHTTPError()
monkeypatch.setattr(tc, "hf_hub_download", fake_hf_hub_download)
monkeypatch.setattr(tc, "find_latest_hub_checkpoint", lambda repo_id, token=None, revision=None: None)
with pytest.raises(FileNotFoundError, match="train_config.json not found"):
TrainPipelineConfig.from_pretrained("user/empty-repo")