feat(data): add recipe-driven language supervision (#4182)

* feat(data): add recipe-driven language supervision

* test(collate): expect preserved language columns

* Address PR review feedback

* Address Claude review feedback
This commit is contained in:
Pepijn
2026-08-04 16:48:47 +02:00
committed by GitHub
parent f66e5128ec
commit 64b23178d5
28 changed files with 1062 additions and 79 deletions
+7
View File
@@ -38,6 +38,13 @@ def test_dataset_config_empty_episodes_ok():
DatasetConfig(repo_id="user/repo", episodes=[])
def test_dataset_config_ignores_negative_excluded_episodes(caplog):
config = DatasetConfig(repo_id="user/repo", exclude_episodes=[-2, 1, -1, 3])
assert config.exclude_episodes == [1, 3]
assert "Ignoring negative exclude_episodes entries: [-2, -1]" in caplog.text
def test_dataset_config_bucket_streaming_ok():
DatasetConfig(repo_id="user/repo", repo_type="bucket", streaming=True)
+20
View File
@@ -29,6 +29,13 @@ def test_message_recipe_validates_unknown_binding():
)
def test_canonical_recipe_loads():
"""The canonical PI052 blend YAML loads + validates."""
recipe = TrainingRecipe.from_yaml(Path("src/lerobot/configs/recipes/subtask_mem_vqa_speech.yaml"))
assert recipe.blend is not None
assert sum(c.weight for c in recipe.blend.values()) == pytest.approx(1.0)
def test_message_turn_requires_a_stream():
"""Every turn must declare a stream — None is rejected at construction.
@@ -81,6 +88,19 @@ def test_blend_component_weight_must_be_positive():
TrainingRecipe(blend={"a": TrainingRecipe(weight=0.0, messages=[_minimal_target_turn()])})
def test_recipe_route_must_be_supported():
with pytest.raises(ValueError, match="Unsupported recipe route"):
TrainingRecipe(weight=1.0, route="other", messages=[_minimal_target_turn()])
def test_route_cannot_be_set_on_blend_recipe():
with pytest.raises(ValueError, match="only be set on a message recipe"):
TrainingRecipe(
route="vqa",
blend={"a": TrainingRecipe(weight=1.0, messages=[_minimal_target_turn()])},
)
def test_blend_component_must_define_messages():
# A bare TrainingRecipe(weight=1.0) would itself raise; build it without
# going through __post_init__ to exercise the blend-level validator.