mirror of
https://github.com/huggingface/lerobot.git
synced 2026-05-16 09:09:48 +00:00
feat(processor): multiple improvements to the pipeline porting (#1749)
* [Port codebase pipeline] General fixes for RL and scripts (#1748) * Refactor dataset configuration in documentation and codebase - Updated dataset configuration keys from `dataset_root` to `root` and `num_episodes` to `num_episodes_to_record` for consistency. - Adjusted replay episode handling by renaming `episode` to `replay_episode`. - Enhanced documentation - added specific processor to transform from policy actions to delta actions * Added Robot action to tensor processor Added new processor script for dealing with gym specific action processing * removed RobotAction2Tensor processor; imrpoved choosing observations in actor * nit in delta action * added missing reset functions to kinematics * Adapt teleoperate and replay to pipeline similar to record * refactor(processors): move to inheritance (#1750) * fix(teleoperator): improvements phone implementation (#1752) * fix(teleoperator): protect shared state in phone implementation * refactor(teleop): separate classes in phone * fix: solve breaking changes (#1753) * refactor(policies): multiple improvements (#1754) * refactor(processor): simpler logic in device processor (#1755) * refactor(processor): euclidean distance in delta action processor (#1757) * refactor(processor): improvements to joint observations processor migration (#1758) * refactor(processor): improvements to tokenizer migration (#1759) * refactor(processor): improvements to tokenizer migration * fix(tests): tokenizer tests regression from #1750 * fix(processors): fix float comparison and config in hil processors (#1760) * chore(teleop): remove unnecessary callbacks in KeyboardEndEffectorTeleop (#1761) * refactor(processor): improvements normalize pipeline migration (#1756) * refactor(processor): several improvements normalize processor step * refactor(processor): more improvements normalize processor * refactor(processor): more changes to normalizer * refactor(processor): take a different approach to DRY * refactor(processor): final design * chore(record): revert comment and continue deleted (#1764) * refactor(examples): pipeline phone examples (#1769) * refactor(examples): phone teleop + teleop script * refactor(examples): phone replay + replay * chore(examples): rename phone example files & folders * feat(processor): fix improvements to the pipeline porting (#1796) * refactor(processor): enhance tensor device handling in normalization process (#1795) * refactor(tests): remove unsupported device detection test for complementary data (#1797) * chore(tests): update ToBatchProcessor test (#1798) * refactor(tests): remove in-place mutation tests for actions and complementary data in batch processor * test(tests): add tests for action and task processing in batch processor * add names for android and ios phone (#1799) * use _tensor_stats in normalize processor (#1800) * fix(normalize_processor): correct device reference for tensor epsilon handling (#1801) * add point 5 add missing feature contracts (#1806) * Fix PR comments 1452 (#1807) * use key to determine image * Address rest of PR comments * use PolicyFeatures in transform_features --------- Co-authored-by: Pepijn <138571049+pkooij@users.noreply.github.com> --------- Co-authored-by: Michel Aractingi <michel.aractingi@huggingface.co> Co-authored-by: Adil Zouitine <adilzouitinegm@gmail.com> Co-authored-by: Pepijn <138571049+pkooij@users.noreply.github.com>
This commit is contained in:
@@ -603,24 +603,6 @@ def test_action_dtype_preservation():
|
||||
assert result[TransitionKey.ACTION].shape == (1, 4)
|
||||
|
||||
|
||||
def test_action_in_place_mutation():
|
||||
"""Test that the processor mutates the transition in place for actions."""
|
||||
processor = ToBatchProcessor()
|
||||
|
||||
action = torch.randn(4)
|
||||
transition = create_transition(action=action)
|
||||
|
||||
# Store reference to original transition
|
||||
original_transition = transition
|
||||
|
||||
# Process
|
||||
result = processor(transition)
|
||||
|
||||
# Should be the same object (in-place mutation)
|
||||
assert result is original_transition
|
||||
assert result[TransitionKey.ACTION].shape == (1, 4)
|
||||
|
||||
|
||||
def test_empty_action_tensor():
|
||||
"""Test handling of empty action tensors."""
|
||||
processor = ToBatchProcessor()
|
||||
@@ -851,27 +833,6 @@ def test_task_comprehensive_string_cases():
|
||||
processed_comp_data = result[TransitionKey.COMPLEMENTARY_DATA]
|
||||
assert processed_comp_data["task"] == task_list
|
||||
assert isinstance(processed_comp_data["task"], list)
|
||||
assert processed_comp_data["task"] is task_list # Should be same object (in-place)
|
||||
|
||||
|
||||
def test_task_in_place_mutation():
|
||||
"""Test that the processor mutates complementary_data in place for tasks."""
|
||||
processor = ToBatchProcessor()
|
||||
|
||||
complementary_data = {"task": "sort_objects"}
|
||||
transition = create_transition(complementary_data=complementary_data)
|
||||
|
||||
# Store reference to original transition and complementary_data
|
||||
original_transition = transition
|
||||
original_comp_data = complementary_data
|
||||
|
||||
# Process
|
||||
result = processor(transition)
|
||||
|
||||
# Should be the same objects (in-place mutation)
|
||||
assert result is original_transition
|
||||
assert result[TransitionKey.COMPLEMENTARY_DATA] is original_comp_data
|
||||
assert original_comp_data["task"] == ["sort_objects"]
|
||||
|
||||
|
||||
def test_task_preserves_other_keys():
|
||||
@@ -1127,3 +1088,49 @@ def test_empty_index_tensor():
|
||||
|
||||
# Should remain unchanged (already 1D)
|
||||
assert result[TransitionKey.COMPLEMENTARY_DATA]["index"].shape == (0,)
|
||||
|
||||
|
||||
def test_action_processing_creates_new_transition():
|
||||
"""Test that the processor creates a new transition object with correctly processed action."""
|
||||
processor = ToBatchProcessor()
|
||||
|
||||
action = torch.randn(4)
|
||||
transition = create_transition(action=action)
|
||||
|
||||
# Store reference to original transition
|
||||
original_transition = transition
|
||||
|
||||
# Process
|
||||
result = processor(transition)
|
||||
|
||||
# Should be a different object (functional design, not in-place mutation)
|
||||
assert result is not original_transition
|
||||
# Original transition should remain unchanged
|
||||
assert original_transition[TransitionKey.ACTION].shape == (4,)
|
||||
# Result should have correctly processed action with batch dimension
|
||||
assert result[TransitionKey.ACTION].shape == (1, 4)
|
||||
assert torch.equal(result[TransitionKey.ACTION][0], action)
|
||||
|
||||
|
||||
def test_task_processing_creates_new_transition():
|
||||
"""Test that the processor creates a new transition object with correctly processed task."""
|
||||
processor = ToBatchProcessor()
|
||||
|
||||
complementary_data = {"task": "sort_objects"}
|
||||
transition = create_transition(complementary_data=complementary_data)
|
||||
|
||||
# Store reference to original transition and complementary_data
|
||||
original_transition = transition
|
||||
original_comp_data = complementary_data
|
||||
|
||||
# Process
|
||||
result = processor(transition)
|
||||
|
||||
# Should be different transition object (functional design)
|
||||
assert result is not original_transition
|
||||
# But complementary_data is the same reference (current implementation behavior)
|
||||
assert result[TransitionKey.COMPLEMENTARY_DATA] is original_comp_data
|
||||
# The task should be processed correctly (wrapped in list)
|
||||
assert result[TransitionKey.COMPLEMENTARY_DATA]["task"] == ["sort_objects"]
|
||||
# Original complementary data is also modified (current behavior)
|
||||
assert original_comp_data["task"] == ["sort_objects"]
|
||||
|
||||
Reference in New Issue
Block a user