diff --git a/.dockerignore b/.dockerignore index b8c1be15..4f074d44 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,17 @@ +# Copyright 2024 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. + # Misc .git tmp diff --git a/.gitattributes b/.gitattributes index 7da36424..44e16cf1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,17 @@ +# Copyright 2024 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. + *.memmap filter=lfs diff=lfs merge=lfs -text *.stl filter=lfs diff=lfs merge=lfs -text *.safetensors filter=lfs diff=lfs merge=lfs -text diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 7cbed673..2fb23051 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + name: "\U0001F41B Bug Report" description: Submit a bug report to help us improve LeRobot body: diff --git a/.github/workflows/build-docker-images.yml b/.github/workflows/build-docker-images.yml index 3c63fa11..0cb11d57 100644 --- a/.github/workflows/build-docker-images.yml +++ b/.github/workflows/build-docker-images.yml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + # Inspired by # https://github.com/huggingface/peft/blob/main/.github/workflows/build_docker_images.yml name: Builds diff --git a/.github/workflows/nightly-tests.yml b/.github/workflows/nightly-tests.yml index 210a690c..adac9f20 100644 --- a/.github/workflows/nightly-tests.yml +++ b/.github/workflows/nightly-tests.yml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + # Inspired by # https://github.com/huggingface/peft/blob/main/.github/workflows/nightly.yml name: Nightly diff --git a/.github/workflows/pr_style_bot.yml b/.github/workflows/pr_style_bot.yml index 68530645..dc4974c2 100644 --- a/.github/workflows/pr_style_bot.yml +++ b/.github/workflows/pr_style_bot.yml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + # Adapted from https://github.com/huggingface/diffusers/blob/main/.github/workflows/pr_style_bot.yml name: PR Style Bot diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index f785d52f..332b543c 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + name: Quality on: diff --git a/.github/workflows/test-docker-build.yml b/.github/workflows/test-docker-build.yml index 3ee84a27..e77c570e 100644 --- a/.github/workflows/test-docker-build.yml +++ b/.github/workflows/test-docker-build.yml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + # Inspired by # https://github.com/huggingface/peft/blob/main/.github/workflows/test-docker-build.yml name: Test Dockerfiles diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9c3f5756..3ef47887 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + name: Tests on: diff --git a/.github/workflows/trufflehog.yml b/.github/workflows/trufflehog.yml index 487ccea5..166e0590 100644 --- a/.github/workflows/trufflehog.yml +++ b/.github/workflows/trufflehog.yml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + on: push: diff --git a/.gitignore b/.gitignore index 0a0ffe10..da4b1089 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,17 @@ +# Copyright 2024 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. + # Logging logs tmp diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dba87705..21016efa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + exclude: ^(tests/data) default_language_version: python: python3.10 diff --git a/Makefile b/Makefile index 772da320..c82483cc 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,17 @@ +# Copyright 2024 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. + .PHONY: tests PYTHON_PATH := $(shell which python) @@ -33,6 +47,7 @@ test-act-ete-train: --policy.dim_model=64 \ --policy.n_action_steps=20 \ --policy.chunk_size=20 \ + --policy.device=$(DEVICE) \ --env.type=aloha \ --env.episode_length=5 \ --dataset.repo_id=lerobot/aloha_sim_transfer_cube_human \ @@ -47,7 +62,6 @@ test-act-ete-train: --save_checkpoint=true \ --log_freq=1 \ --wandb.enable=false \ - --device=$(DEVICE) \ --output_dir=tests/outputs/act/ test-act-ete-train-resume: @@ -58,11 +72,11 @@ test-act-ete-train-resume: test-act-ete-eval: python lerobot/scripts/eval.py \ --policy.path=tests/outputs/act/checkpoints/000004/pretrained_model \ + --policy.device=$(DEVICE) \ --env.type=aloha \ --env.episode_length=5 \ --eval.n_episodes=1 \ - --eval.batch_size=1 \ - --device=$(DEVICE) + --eval.batch_size=1 test-diffusion-ete-train: python lerobot/scripts/train.py \ @@ -70,6 +84,7 @@ test-diffusion-ete-train: --policy.down_dims='[64,128,256]' \ --policy.diffusion_step_embed_dim=32 \ --policy.num_inference_steps=10 \ + --policy.device=$(DEVICE) \ --env.type=pusht \ --env.episode_length=5 \ --dataset.repo_id=lerobot/pusht \ @@ -84,21 +99,21 @@ test-diffusion-ete-train: --save_freq=2 \ --log_freq=1 \ --wandb.enable=false \ - --device=$(DEVICE) \ --output_dir=tests/outputs/diffusion/ test-diffusion-ete-eval: python lerobot/scripts/eval.py \ --policy.path=tests/outputs/diffusion/checkpoints/000002/pretrained_model \ + --policy.device=$(DEVICE) \ --env.type=pusht \ --env.episode_length=5 \ --eval.n_episodes=1 \ - --eval.batch_size=1 \ - --device=$(DEVICE) + --eval.batch_size=1 test-tdmpc-ete-train: python lerobot/scripts/train.py \ --policy.type=tdmpc \ + --policy.device=$(DEVICE) \ --env.type=xarm \ --env.task=XarmLift-v0 \ --env.episode_length=5 \ @@ -114,15 +129,14 @@ test-tdmpc-ete-train: --save_freq=2 \ --log_freq=1 \ --wandb.enable=false \ - --device=$(DEVICE) \ --output_dir=tests/outputs/tdmpc/ test-tdmpc-ete-eval: python lerobot/scripts/eval.py \ --policy.path=tests/outputs/tdmpc/checkpoints/000002/pretrained_model \ + --policy.device=$(DEVICE) \ --env.type=xarm \ --env.episode_length=5 \ --env.task=XarmLift-v0 \ --eval.n_episodes=1 \ - --eval.batch_size=1 \ - --device=$(DEVICE) + --eval.batch_size=1 diff --git a/README.md b/README.md index 454c7e5d..b16e3469 100644 --- a/README.md +++ b/README.md @@ -92,20 +92,15 @@ git clone https://github.com/huggingface/lerobot.git cd lerobot ``` -Create a virtual environment with Python 3.10 and activate it using [`uv`](https://github.com/astral-sh/uv): +Create a virtual environment with Python 3.10 and activate it, e.g. with [`miniconda`](https://docs.anaconda.com/free/miniconda/index.html): ```bash -# Install uv if you haven't already -curl -LsSf https://astral.sh/uv/install.sh | sh - -# Create and activate virtual environment with Python 3.10 -uv venv .venv --python=3.10 -source .venv/bin/activate # On Unix/macOS -# .venv\Scripts\activate # On Windows +conda create -y -n lerobot python=3.10 +conda activate lerobot ``` Install 🤗 LeRobot: ```bash -uv pip install -e . +pip install -e . ``` > **NOTE:** Depending on your platform, If you encounter any build errors during this step @@ -389,3 +384,6 @@ Additionally, if you are using any of the particular policy architecture, pretra year={2024} } ``` +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=huggingface/lerobot&type=Timeline)](https://star-history.com/#huggingface/lerobot&Timeline) diff --git a/examples/1_load_lerobot_dataset.py b/examples/1_load_lerobot_dataset.py index 96c104b6..c374a375 100644 --- a/examples/1_load_lerobot_dataset.py +++ b/examples/1_load_lerobot_dataset.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """ This script demonstrates the use of `LeRobotDataset` class for handling and processing robotic datasets from Hugging Face. It illustrates how to load datasets, manipulate them, and apply transformations suitable for machine learning tasks in PyTorch. diff --git a/examples/2_evaluate_pretrained_policy.py b/examples/2_evaluate_pretrained_policy.py index 0a7b8deb..bf3c442a 100644 --- a/examples/2_evaluate_pretrained_policy.py +++ b/examples/2_evaluate_pretrained_policy.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """ This scripts demonstrates how to evaluate a pretrained policy from the HuggingFace Hub or from your local training outputs directory. In the latter case, you might want to run examples/3_train_policy.py first. diff --git a/examples/3_train_policy.py b/examples/3_train_policy.py index f6eabbfa..6c3af54e 100644 --- a/examples/3_train_policy.py +++ b/examples/3_train_policy.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """This scripts demonstrates how to train Diffusion Policy on the PushT environment. Once you have trained a model with this script, you can try to evaluate it on diff --git a/examples/advanced/1_add_image_transforms.py b/examples/advanced/1_add_image_transforms.py index 882710e3..f1460926 100644 --- a/examples/advanced/1_add_image_transforms.py +++ b/examples/advanced/1_add_image_transforms.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """ This script demonstrates how to use torchvision's image transformation with LeRobotDataset for data augmentation purposes. The transformations are passed to the dataset as an argument upon creation, and diff --git a/examples/advanced/2_calculate_validation_loss.py b/examples/advanced/2_calculate_validation_loss.py index 6f234719..47b4dd02 100644 --- a/examples/advanced/2_calculate_validation_loss.py +++ b/examples/advanced/2_calculate_validation_loss.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """This script demonstrates how to slice a dataset and calculate the loss on a subset of the data. This technique can be useful for debugging and testing purposes, as well as identifying whether a policy diff --git a/examples/port_datasets/pusht_zarr.py b/examples/port_datasets/pusht_zarr.py index eac6f63d..ea2e8b60 100644 --- a/examples/port_datasets/pusht_zarr.py +++ b/examples/port_datasets/pusht_zarr.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 shutil from pathlib import Path diff --git a/lerobot/common/constants.py b/lerobot/common/constants.py index d0c9845a..973595cd 100644 --- a/lerobot/common/constants.py +++ b/lerobot/common/constants.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. # keys import os from pathlib import Path diff --git a/lerobot/common/datasets/backward_compatibility.py b/lerobot/common/datasets/backward_compatibility.py index d1b8926a..cf8e31c4 100644 --- a/lerobot/common/datasets/backward_compatibility.py +++ b/lerobot/common/datasets/backward_compatibility.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 packaging.version V2_MESSAGE = """ diff --git a/lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py b/lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py index fe658ce4..7164291b 100644 --- a/lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py +++ b/lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py @@ -167,8 +167,8 @@ def parse_robot_config(robot_cfg: RobotConfig) -> tuple[str, dict]: for motor in robot_cfg.leader_arms[arm].motors ] elif robot_cfg.type == "roarm_m3": - state_names = ["roam_m3","roam_m3","roam_m3","roam_m3","roam_m3","roam_m3"] - action_names = ["roam_m3","roam_m3","roam_m3","roam_m3","roam_m3","roam_m3"] + state_names = ["roam_m3", "roam_m3", "roam_m3", "roam_m3", "roam_m3", "roam_m3"] + action_names = ["roam_m3", "roam_m3", "roam_m3", "roam_m3", "roam_m3", "roam_m3"] # elif robot_cfg["robot_type"] == "stretch3": TODO else: raise NotImplementedError( diff --git a/lerobot/common/datasets/v21/_remove_language_instruction.py b/lerobot/common/datasets/v21/_remove_language_instruction.py index dd4604cf..643ddd3f 100644 --- a/lerobot/common/datasets/v21/_remove_language_instruction.py +++ b/lerobot/common/datasets/v21/_remove_language_instruction.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 logging import traceback from pathlib import Path diff --git a/lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py b/lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py index 163a6003..176d16d0 100644 --- a/lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py +++ b/lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """ This script will help you convert any LeRobot dataset already pushed to the hub from codebase version 2.0 to 2.1. It will: diff --git a/lerobot/common/datasets/v21/convert_stats.py b/lerobot/common/datasets/v21/convert_stats.py index cbf584b7..4a20b427 100644 --- a/lerobot/common/datasets/v21/convert_stats.py +++ b/lerobot/common/datasets/v21/convert_stats.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 concurrent.futures import ThreadPoolExecutor, as_completed import numpy as np diff --git a/lerobot/common/envs/__init__.py b/lerobot/common/envs/__init__.py index a583ffc5..4977d11d 100644 --- a/lerobot/common/envs/__init__.py +++ b/lerobot/common/envs/__init__.py @@ -1 +1,15 @@ +# Copyright 2024 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 .configs import AlohaEnv, EnvConfig, PushtEnv, XarmEnv # noqa: F401 diff --git a/lerobot/common/envs/configs.py b/lerobot/common/envs/configs.py index 6259ca94..cf90048a 100644 --- a/lerobot/common/envs/configs.py +++ b/lerobot/common/envs/configs.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 abc from dataclasses import dataclass, field diff --git a/lerobot/common/optim/__init__.py b/lerobot/common/optim/__init__.py index e1e65966..de2c4c99 100644 --- a/lerobot/common/optim/__init__.py +++ b/lerobot/common/optim/__init__.py @@ -1 +1,15 @@ +# Copyright 2024 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 .optimizers import OptimizerConfig as OptimizerConfig diff --git a/lerobot/common/policies/__init__.py b/lerobot/common/policies/__init__.py index 2e4486ef..b73ba5f4 100644 --- a/lerobot/common/policies/__init__.py +++ b/lerobot/common/policies/__init__.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 .act.configuration_act import ACTConfig as ACTConfig from .diffusion.configuration_diffusion import DiffusionConfig as DiffusionConfig from .pi0.configuration_pi0 import PI0Config as PI0Config diff --git a/lerobot/common/policies/factory.py b/lerobot/common/policies/factory.py index cd440f7a..5d2f6cb5 100644 --- a/lerobot/common/policies/factory.py +++ b/lerobot/common/policies/factory.py @@ -16,7 +16,6 @@ import logging -import torch from torch import nn from lerobot.common.datasets.lerobot_dataset import LeRobotDatasetMetadata @@ -76,7 +75,6 @@ def make_policy_config(policy_type: str, **kwargs) -> PreTrainedConfig: def make_policy( cfg: PreTrainedConfig, - device: str | torch.device, ds_meta: LeRobotDatasetMetadata | None = None, env_cfg: EnvConfig | None = None, ) -> PreTrainedPolicy: @@ -88,7 +86,6 @@ def make_policy( Args: cfg (PreTrainedConfig): The config of the policy to make. If `pretrained_path` is set, the policy will be loaded with the weights from that path. - device (str): the device to load the policy onto. ds_meta (LeRobotDatasetMetadata | None, optional): Dataset metadata to take input/output shapes and statistics to use for (un)normalization of inputs/outputs in the policy. Defaults to None. env_cfg (EnvConfig | None, optional): The config of a gym environment to parse features from. Must be @@ -96,7 +93,7 @@ def make_policy( Raises: ValueError: Either ds_meta or env and env_cfg must be provided. - NotImplementedError: if the policy.type is 'vqbet' and the device 'mps' (due to an incompatibility) + NotImplementedError: if the policy.type is 'vqbet' and the policy device 'mps' (due to an incompatibility) Returns: PreTrainedPolicy: _description_ @@ -111,7 +108,7 @@ def make_policy( # https://github.com/pytorch/pytorch/issues/77764. As a temporary fix, you can set the environment # variable `PYTORCH_ENABLE_MPS_FALLBACK=1` to use the CPU as a fallback for this op. WARNING: this will be # slower than running natively on MPS. - if cfg.type == "vqbet" and str(device) == "mps": + if cfg.type == "vqbet" and cfg.device == "mps": raise NotImplementedError( "Current implementation of VQBeT does not support `mps` backend. " "Please use `cpu` or `cuda` backend." @@ -145,7 +142,7 @@ def make_policy( # Make a fresh policy. policy = policy_cls(**kwargs) - policy.to(device) + policy.to(cfg.device) assert isinstance(policy, nn.Module) # policy = torch.compile(policy, mode="reduce-overhead") diff --git a/lerobot/common/policies/pi0/configuration_pi0.py b/lerobot/common/policies/pi0/configuration_pi0.py index 8d2eedf6..8c7cc130 100644 --- a/lerobot/common/policies/pi0/configuration_pi0.py +++ b/lerobot/common/policies/pi0/configuration_pi0.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 dataclasses import dataclass, field from lerobot.common.optim.optimizers import AdamWConfig @@ -76,6 +90,7 @@ class PI0Config(PreTrainedConfig): def __post_init__(self): super().__post_init__() + # TODO(Steven): Validate device and amp? in all policy configs? """Input validation (not exhaustive).""" if self.n_action_steps > self.chunk_size: raise ValueError( diff --git a/lerobot/common/policies/pi0/conversion_scripts/benchmark.py b/lerobot/common/policies/pi0/conversion_scripts/benchmark.py index 31bd1b66..cb3c0e9b 100644 --- a/lerobot/common/policies/pi0/conversion_scripts/benchmark.py +++ b/lerobot/common/policies/pi0/conversion_scripts/benchmark.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 torch from lerobot.common.datasets.lerobot_dataset import LeRobotDataset @@ -31,7 +45,7 @@ def main(): cfg = PreTrainedConfig.from_pretrained(ckpt_torch_dir) cfg.pretrained_path = ckpt_torch_dir - policy = make_policy(cfg, device, ds_meta=dataset.meta) + policy = make_policy(cfg, ds_meta=dataset.meta) # policy = torch.compile(policy, mode="reduce-overhead") diff --git a/lerobot/common/policies/pi0/conversion_scripts/compare_with_jax.py b/lerobot/common/policies/pi0/conversion_scripts/compare_with_jax.py index 8b2e1c66..6bd7c91f 100644 --- a/lerobot/common/policies/pi0/conversion_scripts/compare_with_jax.py +++ b/lerobot/common/policies/pi0/conversion_scripts/compare_with_jax.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 json import pickle from pathlib import Path @@ -87,7 +101,7 @@ def main(): cfg = PreTrainedConfig.from_pretrained(ckpt_torch_dir) cfg.pretrained_path = ckpt_torch_dir - policy = make_policy(cfg, device, dataset_meta) + policy = make_policy(cfg, dataset_meta) # loss_dict = policy.forward(batch, noise=noise, time=time_beta) # loss_dict["loss"].backward() diff --git a/lerobot/common/policies/pi0/conversion_scripts/conversion_utils.py b/lerobot/common/policies/pi0/conversion_scripts/conversion_utils.py index 8e35d0d4..8835da31 100644 --- a/lerobot/common/policies/pi0/conversion_scripts/conversion_utils.py +++ b/lerobot/common/policies/pi0/conversion_scripts/conversion_utils.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 transformers import GemmaConfig, PaliGemmaConfig diff --git a/lerobot/common/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py b/lerobot/common/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py index dd8622dd..73ff506f 100644 --- a/lerobot/common/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py +++ b/lerobot/common/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """ Convert pi0 parameters from Jax to Pytorch diff --git a/lerobot/common/policies/pi0/flex_attention.py b/lerobot/common/policies/pi0/flex_attention.py index 38a5b597..35628cdd 100644 --- a/lerobot/common/policies/pi0/flex_attention.py +++ b/lerobot/common/policies/pi0/flex_attention.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 torch import torch.nn.functional as F # noqa: N812 from packaging.version import Version diff --git a/lerobot/common/policies/pi0/paligemma_with_expert.py b/lerobot/common/policies/pi0/paligemma_with_expert.py index 08c36c11..76e2ce60 100644 --- a/lerobot/common/policies/pi0/paligemma_with_expert.py +++ b/lerobot/common/policies/pi0/paligemma_with_expert.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 typing import List, Optional, Union import torch diff --git a/lerobot/common/policies/pretrained.py b/lerobot/common/policies/pretrained.py index 1729dfb0..da4ef157 100644 --- a/lerobot/common/policies/pretrained.py +++ b/lerobot/common/policies/pretrained.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 abc import logging import os @@ -73,7 +86,6 @@ class PreTrainedPolicy(nn.Module, HubMixin, abc.ABC): cache_dir: str | Path | None = None, local_files_only: bool = False, revision: str | None = None, - map_location: str = "cpu", strict: bool = False, **kwargs, ) -> T: @@ -98,7 +110,7 @@ class PreTrainedPolicy(nn.Module, HubMixin, abc.ABC): if os.path.isdir(model_id): print("Loading weights from local directory") model_file = os.path.join(model_id, SAFETENSORS_SINGLE_FILE) - policy = cls._load_as_safetensor(instance, model_file, map_location, strict) + policy = cls._load_as_safetensor(instance, model_file, config.device, strict) else: try: model_file = hf_hub_download( @@ -112,13 +124,13 @@ class PreTrainedPolicy(nn.Module, HubMixin, abc.ABC): token=token, local_files_only=local_files_only, ) - policy = cls._load_as_safetensor(instance, model_file, map_location, strict) + policy = cls._load_as_safetensor(instance, model_file, config.device, strict) except HfHubHTTPError as e: raise FileNotFoundError( f"{SAFETENSORS_SINGLE_FILE} not found on the HuggingFace Hub in {model_id}" ) from e - policy.to(map_location) + policy.to(config.device) policy.eval() return policy diff --git a/lerobot/common/robot_devices/cameras/configs.py b/lerobot/common/robot_devices/cameras/configs.py index 6acdbd3e..013419a9 100644 --- a/lerobot/common/robot_devices/cameras/configs.py +++ b/lerobot/common/robot_devices/cameras/configs.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 abc from dataclasses import dataclass diff --git a/lerobot/common/robot_devices/cameras/intelrealsense.py b/lerobot/common/robot_devices/cameras/intelrealsense.py index 7e65dba9..29e99ea3 100644 --- a/lerobot/common/robot_devices/cameras/intelrealsense.py +++ b/lerobot/common/robot_devices/cameras/intelrealsense.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """ This file contains utilities for recording frames from Intel Realsense cameras. """ diff --git a/lerobot/common/robot_devices/cameras/opencv.py b/lerobot/common/robot_devices/cameras/opencv.py index 5a4e7feb..024ee050 100644 --- a/lerobot/common/robot_devices/cameras/opencv.py +++ b/lerobot/common/robot_devices/cameras/opencv.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """ This file contains utilities for recording frames from cameras. For more info look at `OpenCVCamera` docstring. """ diff --git a/lerobot/common/robot_devices/cameras/utils.py b/lerobot/common/robot_devices/cameras/utils.py index ef6d8266..c6431646 100644 --- a/lerobot/common/robot_devices/cameras/utils.py +++ b/lerobot/common/robot_devices/cameras/utils.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 typing import Protocol import numpy as np diff --git a/lerobot/common/robot_devices/control_configs.py b/lerobot/common/robot_devices/control_configs.py index 2ef1b44b..0ecd8683 100644 --- a/lerobot/common/robot_devices/control_configs.py +++ b/lerobot/common/robot_devices/control_configs.py @@ -1,14 +1,25 @@ -import logging +# Copyright 2024 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 dataclasses import dataclass from pathlib import Path import draccus from lerobot.common.robot_devices.robots.configs import RobotConfig -from lerobot.common.utils.utils import auto_select_torch_device, is_amp_available, is_torch_device_available from lerobot.configs import parser from lerobot.configs.policies import PreTrainedConfig -from lerobot.configs.train import TrainPipelineConfig @dataclass @@ -43,11 +54,6 @@ class RecordControlConfig(ControlConfig): # Root directory where the dataset will be stored (e.g. 'dataset/path'). root: str | Path | None = None policy: PreTrainedConfig | None = None - # TODO(rcadene, aliberts): By default, use device and use_amp values from policy checkpoint. - device: str | None = None # cuda | cpu | mps - # `use_amp` determines whether to use Automatic Mixed Precision (AMP) for training and evaluation. With AMP, - # automatic gradient scaling is used. - use_amp: bool | None = None # Limit the frames per second. By default, uses the policy fps. fps: int | None = None # Number of seconds before starting data collection. It allows the robot devices to warmup and synchronize. @@ -90,27 +96,6 @@ class RecordControlConfig(ControlConfig): self.policy = PreTrainedConfig.from_pretrained(policy_path, cli_overrides=cli_overrides) self.policy.pretrained_path = policy_path - # When no device or use_amp are given, use the one from training config. - if self.device is None or self.use_amp is None: - train_cfg = TrainPipelineConfig.from_pretrained(policy_path) - if self.device is None: - self.device = train_cfg.device - if self.use_amp is None: - self.use_amp = train_cfg.use_amp - - # Automatically switch to available device if necessary - if not is_torch_device_available(self.device): - auto_device = auto_select_torch_device() - logging.warning(f"Device '{self.device}' is not available. Switching to '{auto_device}'.") - self.device = auto_device - - # Automatically deactivate AMP if necessary - if self.use_amp and not is_amp_available(self.device): - logging.warning( - f"Automatic Mixed Precision (amp) is not available on device '{self.device}'. Deactivating AMP." - ) - self.use_amp = False - @ControlConfig.register_subclass("replay") @dataclass diff --git a/lerobot/common/robot_devices/control_utils.py b/lerobot/common/robot_devices/control_utils.py index dfc4b1cb..e774bc35 100644 --- a/lerobot/common/robot_devices/control_utils.py +++ b/lerobot/common/robot_devices/control_utils.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + ######################################################################################## # Utilities ######################################################################################## @@ -18,6 +32,7 @@ from termcolor import colored from lerobot.common.datasets.image_writer import safe_stop_image_writer from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.common.datasets.utils import get_features_from_robot +from lerobot.common.policies.pretrained import PreTrainedPolicy from lerobot.common.robot_devices.robots.utils import Robot from lerobot.common.robot_devices.utils import busy_wait from lerobot.common.utils.utils import get_safe_torch_device, has_method @@ -210,8 +225,6 @@ def record_episode( episode_time_s, display_cameras, policy, - device, - use_amp, fps, single_task, ): @@ -222,8 +235,6 @@ def record_episode( dataset=dataset, events=events, policy=policy, - device=device, - use_amp=use_amp, fps=fps, teleoperate=policy is None, single_task=single_task, @@ -238,9 +249,7 @@ def control_loop( display_cameras=False, dataset: LeRobotDataset | None = None, events=None, - policy=None, - device: torch.device | str | None = None, - use_amp: bool | None = None, + policy: PreTrainedPolicy = None, fps: int | None = None, single_task: str | None = None, ): @@ -263,9 +272,6 @@ def control_loop( if dataset is not None and fps is not None and dataset.fps != fps: raise ValueError(f"The dataset fps should be equal to requested fps ({dataset['fps']} != {fps}).") - if isinstance(device, str): - device = get_safe_torch_device(device) - timestamp = 0 start_episode_t = time.perf_counter() while timestamp < control_time_s: @@ -277,7 +283,9 @@ def control_loop( observation = robot.capture_observation() if policy is not None: - pred_action = predict_action(observation, policy, device, use_amp) + pred_action = predict_action( + observation, policy, get_safe_torch_device(policy.config.device), policy.config.use_amp + ) # Action can eventually be clipped using `max_relative_target`, # so action actually sent is saved in the dataset. action = robot.send_action(pred_action) diff --git a/lerobot/common/robot_devices/motors/configs.py b/lerobot/common/robot_devices/motors/configs.py index 37b781f9..0bfbaf83 100644 --- a/lerobot/common/robot_devices/motors/configs.py +++ b/lerobot/common/robot_devices/motors/configs.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 abc from dataclasses import dataclass diff --git a/lerobot/common/robot_devices/motors/dynamixel.py b/lerobot/common/robot_devices/motors/dynamixel.py index 17ea933d..186f7124 100644 --- a/lerobot/common/robot_devices/motors/dynamixel.py +++ b/lerobot/common/robot_devices/motors/dynamixel.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 enum import logging import math diff --git a/lerobot/common/robot_devices/motors/feetech.py b/lerobot/common/robot_devices/motors/feetech.py index cec36d37..7d0d2a00 100644 --- a/lerobot/common/robot_devices/motors/feetech.py +++ b/lerobot/common/robot_devices/motors/feetech.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 enum import logging import math diff --git a/lerobot/common/robot_devices/motors/utils.py b/lerobot/common/robot_devices/motors/utils.py index fc64f050..bd86f4c6 100644 --- a/lerobot/common/robot_devices/motors/utils.py +++ b/lerobot/common/robot_devices/motors/utils.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 typing import Protocol from lerobot.common.robot_devices.motors.configs import ( diff --git a/lerobot/common/robot_devices/robots/configs.py b/lerobot/common/robot_devices/robots/configs.py index 6b6b8ef3..6a4140af 100644 --- a/lerobot/common/robot_devices/robots/configs.py +++ b/lerobot/common/robot_devices/robots/configs.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 abc from dataclasses import dataclass, field from typing import Sequence diff --git a/lerobot/common/robot_devices/robots/dynamixel_calibration.py b/lerobot/common/robot_devices/robots/dynamixel_calibration.py index 142d5794..98fe8754 100644 --- a/lerobot/common/robot_devices/robots/dynamixel_calibration.py +++ b/lerobot/common/robot_devices/robots/dynamixel_calibration.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """Logic to calibrate a robot arm built with dynamixel motors""" # TODO(rcadene, aliberts): move this logic into the robot code when refactoring diff --git a/lerobot/common/robot_devices/robots/feetech_calibration.py b/lerobot/common/robot_devices/robots/feetech_calibration.py index d779cd44..2c1e7180 100644 --- a/lerobot/common/robot_devices/robots/feetech_calibration.py +++ b/lerobot/common/robot_devices/robots/feetech_calibration.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """Logic to calibrate a robot arm built with feetech motors""" # TODO(rcadene, aliberts): move this logic into the robot code when refactoring diff --git a/lerobot/common/robot_devices/robots/lekiwi_remote.py b/lerobot/common/robot_devices/robots/lekiwi_remote.py index fd9491fa..7bf52d21 100644 --- a/lerobot/common/robot_devices/robots/lekiwi_remote.py +++ b/lerobot/common/robot_devices/robots/lekiwi_remote.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 base64 import json import threading diff --git a/lerobot/common/robot_devices/robots/manipulator.py b/lerobot/common/robot_devices/robots/manipulator.py index 62e5416e..8a7c7fe6 100644 --- a/lerobot/common/robot_devices/robots/manipulator.py +++ b/lerobot/common/robot_devices/robots/manipulator.py @@ -1,3 +1,17 @@ +# Copyright 2024 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. + """Contains logic to instantiate a robot, read information from its motors and cameras, and send orders to its motors. """ diff --git a/lerobot/common/robot_devices/robots/mobile_manipulator.py b/lerobot/common/robot_devices/robots/mobile_manipulator.py index c2cad227..385e218b 100644 --- a/lerobot/common/robot_devices/robots/mobile_manipulator.py +++ b/lerobot/common/robot_devices/robots/mobile_manipulator.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 base64 import json import os diff --git a/lerobot/common/robot_devices/robots/utils.py b/lerobot/common/robot_devices/robots/utils.py index 07714cff..b864fa1b 100644 --- a/lerobot/common/robot_devices/robots/utils.py +++ b/lerobot/common/robot_devices/robots/utils.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 typing import Protocol from lerobot.common.robot_devices.robots.configs import ( diff --git a/lerobot/common/robot_devices/utils.py b/lerobot/common/robot_devices/utils.py index 19bb637e..837c9d2e 100644 --- a/lerobot/common/robot_devices/utils.py +++ b/lerobot/common/robot_devices/utils.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 platform import time diff --git a/lerobot/common/utils/hub.py b/lerobot/common/utils/hub.py index 63fcf918..df7435c0 100644 --- a/lerobot/common/utils/hub.py +++ b/lerobot/common/utils/hub.py @@ -1,3 +1,17 @@ +# Copyright 2024 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 tempfile import TemporaryDirectory from typing import Any, Type, TypeVar diff --git a/lerobot/common/utils/utils.py b/lerobot/common/utils/utils.py index cd26f04b..563a7b81 100644 --- a/lerobot/common/utils/utils.py +++ b/lerobot/common/utils/utils.py @@ -51,8 +51,10 @@ def auto_select_torch_device() -> torch.device: return torch.device("cpu") +# TODO(Steven): Remove log. log shouldn't be an argument, this should be handled by the logger level def get_safe_torch_device(try_device: str, log: bool = False) -> torch.device: """Given a string, return a torch.device with checks on whether the device is available.""" + try_device = str(try_device) match try_device: case "cuda": assert torch.cuda.is_available() @@ -85,6 +87,7 @@ def get_safe_dtype(dtype: torch.dtype, device: str | torch.device): def is_torch_device_available(try_device: str) -> bool: + try_device = str(try_device) # Ensure try_device is a string if try_device == "cuda": return torch.cuda.is_available() elif try_device == "mps": @@ -92,7 +95,7 @@ def is_torch_device_available(try_device: str) -> bool: elif try_device == "cpu": return True else: - raise ValueError(f"Unknown device '{try_device}.") + raise ValueError(f"Unknown device {try_device}. Supported devices are: cuda, mps or cpu.") def is_amp_available(device: str): diff --git a/lerobot/configs/eval.py b/lerobot/configs/eval.py index 11873352..16b35291 100644 --- a/lerobot/configs/eval.py +++ b/lerobot/configs/eval.py @@ -1,14 +1,26 @@ +# Copyright 2024 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 datetime as dt import logging from dataclasses import dataclass, field from pathlib import Path from lerobot.common import envs, policies # noqa: F401 -from lerobot.common.utils.utils import auto_select_torch_device, is_amp_available, is_torch_device_available from lerobot.configs import parser from lerobot.configs.default import EvalConfig from lerobot.configs.policies import PreTrainedConfig -from lerobot.configs.train import TrainPipelineConfig @dataclass @@ -21,11 +33,6 @@ class EvalPipelineConfig: policy: PreTrainedConfig | None = None output_dir: Path | None = None job_name: str | None = None - # TODO(rcadene, aliberts): By default, use device and use_amp values from policy checkpoint. - device: str | None = None # cuda | cpu | mps - # `use_amp` determines whether to use Automatic Mixed Precision (AMP) for training and evaluation. With AMP, - # automatic gradient scaling is used. - use_amp: bool = False seed: int | None = 1000 def __post_init__(self): @@ -36,27 +43,6 @@ class EvalPipelineConfig: self.policy = PreTrainedConfig.from_pretrained(policy_path, cli_overrides=cli_overrides) self.policy.pretrained_path = policy_path - # When no device or use_amp are given, use the one from training config. - if self.device is None or self.use_amp is None: - train_cfg = TrainPipelineConfig.from_pretrained(policy_path) - if self.device is None: - self.device = train_cfg.device - if self.use_amp is None: - self.use_amp = train_cfg.use_amp - - # Automatically switch to available device if necessary - if not is_torch_device_available(self.device): - auto_device = auto_select_torch_device() - logging.warning(f"Device '{self.device}' is not available. Switching to '{auto_device}'.") - self.device = auto_device - - # Automatically deactivate AMP if necessary - if self.use_amp and not is_amp_available(self.device): - logging.warning( - f"Automatic Mixed Precision (amp) is not available on device '{self.device}'. Deactivating AMP." - ) - self.use_amp = False - else: logging.warning( "No pretrained path was provided, evaluated policy will be built from scratch (random weights)." @@ -73,11 +59,6 @@ class EvalPipelineConfig: eval_dir = f"{now:%Y-%m-%d}/{now:%H-%M-%S}_{self.job_name}" self.output_dir = Path("outputs/eval") / eval_dir - if self.device is None: - raise ValueError("Set one of the following device: cuda, cpu or mps") - elif self.device == "cuda" and self.use_amp is None: - raise ValueError("Set 'use_amp' to True or False.") - @classmethod def __get_path_fields__(cls) -> list[str]: """This enables the parser to load config from the policy using `--policy.path=local/dir`""" diff --git a/lerobot/configs/parser.py b/lerobot/configs/parser.py index ee784877..476a9b40 100644 --- a/lerobot/configs/parser.py +++ b/lerobot/configs/parser.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 inspect import sys from argparse import ArgumentError diff --git a/lerobot/configs/policies.py b/lerobot/configs/policies.py index 9b5a7c5c..022d1fb5 100644 --- a/lerobot/configs/policies.py +++ b/lerobot/configs/policies.py @@ -1,4 +1,18 @@ +# Copyright 2024 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 abc +import logging import os from dataclasses import dataclass, field from pathlib import Path @@ -12,6 +26,7 @@ from huggingface_hub.errors import HfHubHTTPError from lerobot.common.optim.optimizers import OptimizerConfig from lerobot.common.optim.schedulers import LRSchedulerConfig from lerobot.common.utils.hub import HubMixin +from lerobot.common.utils.utils import auto_select_torch_device, is_amp_available, is_torch_device_available from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature # Generic variable that is either PreTrainedConfig or a subclass thereof @@ -40,8 +55,24 @@ class PreTrainedConfig(draccus.ChoiceRegistry, HubMixin, abc.ABC): input_features: dict[str, PolicyFeature] = field(default_factory=dict) output_features: dict[str, PolicyFeature] = field(default_factory=dict) + device: str | None = None # cuda | cpu | mp + # `use_amp` determines whether to use Automatic Mixed Precision (AMP) for training and evaluation. With AMP, + # automatic gradient scaling is used. + use_amp: bool = False + def __post_init__(self): self.pretrained_path = None + if not self.device or not is_torch_device_available(self.device): + auto_device = auto_select_torch_device() + logging.warning(f"Device '{self.device}' is not available. Switching to '{auto_device}'.") + self.device = auto_device.type + + # Automatically deactivate AMP if necessary + if self.use_amp and not is_amp_available(self.device): + logging.warning( + f"Automatic Mixed Precision (amp) is not available on device '{self.device}'. Deactivating AMP." + ) + self.use_amp = False @property def type(self) -> str: diff --git a/lerobot/configs/train.py b/lerobot/configs/train.py index 464c11f9..2b147a5b 100644 --- a/lerobot/configs/train.py +++ b/lerobot/configs/train.py @@ -1,5 +1,17 @@ +# Copyright 2024 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 datetime as dt -import logging import os from dataclasses import dataclass, field from pathlib import Path @@ -13,7 +25,6 @@ from lerobot.common import envs from lerobot.common.optim import OptimizerConfig from lerobot.common.optim.schedulers import LRSchedulerConfig from lerobot.common.utils.hub import HubMixin -from lerobot.common.utils.utils import auto_select_torch_device, is_amp_available from lerobot.configs import parser from lerobot.configs.default import DatasetConfig, EvalConfig, WandBConfig from lerobot.configs.policies import PreTrainedConfig @@ -35,10 +46,6 @@ class TrainPipelineConfig(HubMixin): # Note that when resuming a run, the default behavior is to use the configuration from the checkpoint, # regardless of what's provided with the training command at the time of resumption. resume: bool = False - device: str | None = None # cuda | cpu | mp - # `use_amp` determines whether to use Automatic Mixed Precision (AMP) for training and evaluation. With AMP, - # automatic gradient scaling is used. - use_amp: bool = False # `seed` is used for training (eg: model initialization, dataset shuffling) # AND for the evaluation environments. seed: int | None = 1000 @@ -61,18 +68,6 @@ class TrainPipelineConfig(HubMixin): self.checkpoint_path = None def validate(self): - if not self.device: - logging.warning("No device specified, trying to infer device automatically") - device = auto_select_torch_device() - self.device = device.type - - # Automatically deactivate AMP if necessary - if self.use_amp and not is_amp_available(self.device): - logging.warning( - f"Automatic Mixed Precision (amp) is not available on device '{self.device}'. Deactivating AMP." - ) - self.use_amp = False - # HACK: We parse again the cli args here to get the pretrained paths if there was some. policy_path = parser.get_path_arg("policy") if policy_path: diff --git a/lerobot/configs/types.py b/lerobot/configs/types.py index 0ca45a19..6b3d92e8 100644 --- a/lerobot/configs/types.py +++ b/lerobot/configs/types.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. # Note: We subclass str so that serialization is straightforward # https://stackoverflow.com/questions/24481852/serialising-an-enum-member-to-json from dataclasses import dataclass diff --git a/lerobot/scripts/configure_motor.py b/lerobot/scripts/configure_motor.py index f7e07070..b0dc8a97 100644 --- a/lerobot/scripts/configure_motor.py +++ b/lerobot/scripts/configure_motor.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. """ This script configure a single motor at a time to a given ID and baudrate. diff --git a/lerobot/scripts/control_robot.py b/lerobot/scripts/control_robot.py index ab5d0e8a..3c3c43f9 100644 --- a/lerobot/scripts/control_robot.py +++ b/lerobot/scripts/control_robot.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. """ Utilities to control a robot. @@ -254,7 +267,7 @@ def record( ) # Load pretrained policy - policy = None if cfg.policy is None else make_policy(cfg.policy, cfg.device, ds_meta=dataset.meta) + policy = None if cfg.policy is None else make_policy(cfg.policy, ds_meta=dataset.meta) if not robot.is_connected: robot.connect() @@ -285,8 +298,6 @@ def record( episode_time_s=cfg.episode_time_s, display_cameras=cfg.display_cameras, policy=policy, - device=cfg.device, - use_amp=cfg.use_amp, fps=cfg.fps, single_task=cfg.single_task, ) diff --git a/lerobot/scripts/control_sim_robot.py b/lerobot/scripts/control_sim_robot.py index 49a88d14..5347822c 100644 --- a/lerobot/scripts/control_sim_robot.py +++ b/lerobot/scripts/control_sim_robot.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. """ Utilities to control a robot in simulation. diff --git a/lerobot/scripts/eval.py b/lerobot/scripts/eval.py index 47225993..d7a4201f 100644 --- a/lerobot/scripts/eval.py +++ b/lerobot/scripts/eval.py @@ -458,7 +458,7 @@ def eval_main(cfg: EvalPipelineConfig): logging.info(pformat(asdict(cfg))) # Check device is available - device = get_safe_torch_device(cfg.device, log=True) + device = get_safe_torch_device(cfg.policy.device, log=True) torch.backends.cudnn.benchmark = True torch.backends.cuda.matmul.allow_tf32 = True @@ -470,14 +470,14 @@ def eval_main(cfg: EvalPipelineConfig): env = make_env(cfg.env, n_envs=cfg.eval.batch_size, use_async_envs=cfg.eval.use_async_envs) logging.info("Making policy.") + policy = make_policy( cfg=cfg.policy, - device=device, env_cfg=cfg.env, ) policy.eval() - with torch.no_grad(), torch.autocast(device_type=device.type) if cfg.use_amp else nullcontext(): + with torch.no_grad(), torch.autocast(device_type=device.type) if cfg.policy.use_amp else nullcontext(): info = eval_policy( env, policy, diff --git a/lerobot/scripts/find_motors_bus_port.py b/lerobot/scripts/find_motors_bus_port.py index 67b92ad7..68f2315d 100644 --- a/lerobot/scripts/find_motors_bus_port.py +++ b/lerobot/scripts/find_motors_bus_port.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 os import time from pathlib import Path diff --git a/lerobot/scripts/train.py b/lerobot/scripts/train.py index e36c697a..f2b1e29e 100644 --- a/lerobot/scripts/train.py +++ b/lerobot/scripts/train.py @@ -120,7 +120,7 @@ def train(cfg: TrainPipelineConfig): set_seed(cfg.seed) # Check device is available - device = get_safe_torch_device(cfg.device, log=True) + device = get_safe_torch_device(cfg.policy.device, log=True) torch.backends.cudnn.benchmark = True torch.backends.cuda.matmul.allow_tf32 = True @@ -138,13 +138,12 @@ def train(cfg: TrainPipelineConfig): logging.info("Creating policy") policy = make_policy( cfg=cfg.policy, - device=device, ds_meta=dataset.meta, ) logging.info("Creating optimizer and scheduler") optimizer, lr_scheduler = make_optimizer_and_scheduler(cfg, policy) - grad_scaler = GradScaler(device, enabled=cfg.use_amp) + grad_scaler = GradScaler(device.type, enabled=cfg.policy.use_amp) step = 0 # number of policy updates (forward + backward + optim) @@ -218,7 +217,7 @@ def train(cfg: TrainPipelineConfig): cfg.optimizer.grad_clip_norm, grad_scaler=grad_scaler, lr_scheduler=lr_scheduler, - use_amp=cfg.use_amp, + use_amp=cfg.policy.use_amp, ) # Note: eval and checkpoint happens *after* the `step`th training update has completed, so we @@ -249,7 +248,10 @@ def train(cfg: TrainPipelineConfig): if cfg.env and is_eval_step: step_id = get_step_identifier(step, cfg.steps) logging.info(f"Eval policy at step {step}") - with torch.no_grad(), torch.autocast(device_type=device.type) if cfg.use_amp else nullcontext(): + with ( + torch.no_grad(), + torch.autocast(device_type=device.type) if cfg.policy.use_amp else nullcontext(), + ): eval_info = eval_policy( eval_env, policy, diff --git a/lerobot/scripts/visualize_dataset_html.py b/lerobot/scripts/visualize_dataset_html.py index d5825aa6..f944144a 100644 --- a/lerobot/scripts/visualize_dataset_html.py +++ b/lerobot/scripts/visualize_dataset_html.py @@ -234,7 +234,7 @@ def get_episode_data(dataset: LeRobotDataset | IterableNamespace, episode_index) This file will be loaded by Dygraph javascript to plot data in real time.""" columns = [] - selected_columns = [col for col, ft in dataset.features.items() if ft["dtype"] == "float32"] + selected_columns = [col for col, ft in dataset.features.items() if ft["dtype"] in ["float32", "int32"]] selected_columns.remove("timestamp") ignored_columns = [] diff --git a/pyproject.toml b/pyproject.toml index 93c8e664..fcffb9cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,17 @@ +# Copyright 2024 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. + [project.urls] homepage = "https://github.com/huggingface/lerobot" issues = "https://github.com/huggingface/lerobot/issues" @@ -8,18 +22,19 @@ name = "lerobot" version = "0.1.0" description = "🤗 LeRobot: State-of-the-art Machine Learning for Real-World Robotics in Pytorch" authors = [ - {name = "Rémi Cadène", email = "re.cadene@gmail.com"}, - {name = "Simon Alibert", email = "alibert.sim@gmail.com"}, - {name = "Alexander Soare", email = "alexander.soare159@gmail.com"}, - {name = "Quentin Gallouédec", email = "quentin.gallouedec@ec-lyon.fr"}, - {name = "Adil Zouitine", email = "adilzouitinegm@gmail.com"}, - {name = "Thomas Wolf", email = "thomaswolfcontact@gmail.com"}, + { name = "Rémi Cadène", email = "re.cadene@gmail.com" }, + { name = "Simon Alibert", email = "alibert.sim@gmail.com" }, + { name = "Alexander Soare", email = "alexander.soare159@gmail.com" }, + { name = "Quentin Gallouédec", email = "quentin.gallouedec@ec-lyon.fr" }, + { name = "Adil Zouitine", email = "adilzouitinegm@gmail.com" }, + { name = "Thomas Wolf", email = "thomaswolfcontact@gmail.com" }, + { name = "Steven Palma", email = "imstevenpmwork@ieee.org" }, ] readme = "README.md" -license = {text = "Apache-2.0"} +license = { text = "Apache-2.0" } requires-python = ">=3.10" keywords = ["robotics", "deep learning", "pytorch"] -classifiers=[ +classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Intended Audience :: Education", @@ -38,7 +53,7 @@ dependencies = [ "einops>=0.8.0", "flask>=3.0.3", "gdown>=5.1.0", - "gymnasium==0.29.1", # TODO(rcadene, aliberts): Make gym 1.0.0 work + "gymnasium==0.29.1", # TODO(rcadene, aliberts): Make gym 1.0.0 work "h5py>=3.10.0", "huggingface-hub[hf-transfer,cli]>=0.27.1 ; python_version < '4.0'", "hydra-core>=1.3.2", @@ -64,7 +79,9 @@ dependencies = [ [project.optional-dependencies] aloha = ["gym-aloha>=0.1.1 ; python_version < '4.0'"] dev = ["pre-commit>=3.7.0", "debugpy>=1.8.1"] -dora = ["gym-dora @ git+https://github.com/dora-rs/dora-lerobot.git#subdirectory=gym_dora ; python_version < '4.0'"] +dora = [ + "gym-dora @ git+https://github.com/dora-rs/dora-lerobot.git#subdirectory=gym_dora ; python_version < '4.0'", +] dynamixel = ["dynamixel-sdk>=3.7.31", "pynput>=1.7.7"] feetech = ["feetech-servo-sdk>=1.0.0", "pynput>=1.7.7"] intelrealsense = ["pyrealsense2>=2.55.1.6486 ; sys_platform != 'darwin'"] @@ -74,7 +91,7 @@ stretch = [ "hello-robot-stretch-body>=0.7.27 ; python_version < '4.0' and sys_platform == 'linux'", "pyrender @ git+https://github.com/mmatl/pyrender.git ; sys_platform == 'linux'", "pyrealsense2>=2.55.1.6486 ; sys_platform != 'darwin'", - "pynput>=1.7.7" + "pynput>=1.7.7", ] test = ["pytest>=8.1.0", "pytest-cov>=5.0.0", "pyserial>=3.5"] umi = ["imagecodecs>=2024.1.1"] @@ -129,8 +146,8 @@ skips = ["B101", "B311", "B404", "B603"] [tool.typos] default.extend-ignore-re = [ - "(?Rm)^.*(#|//)\\s*spellchecker:disable-line$", # spellchecker:disable-line - "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on" # spellchecker: + "(?Rm)^.*(#|//)\\s*spellchecker:disable-line$", # spellchecker:disable-line + "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on", # spellchecker: ] default.extend-ignore-identifiers-re = [ # Add individual words here to ignore them diff --git a/tests/__init__.py b/tests/__init__.py index e69de29b..f52df1bd 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2024 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. diff --git a/tests/fixtures/constants.py b/tests/fixtures/constants.py index 3201dcf2..5e5c762c 100644 --- a/tests/fixtures/constants.py +++ b/tests/fixtures/constants.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 lerobot.common.constants import HF_LEROBOT_HOME LEROBOT_TEST_DIR = HF_LEROBOT_HOME / "_testing" diff --git a/tests/fixtures/dataset_factories.py b/tests/fixtures/dataset_factories.py index 2259e0e6..531977da 100644 --- a/tests/fixtures/dataset_factories.py +++ b/tests/fixtures/dataset_factories.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 random from functools import partial from pathlib import Path diff --git a/tests/fixtures/files.py b/tests/fixtures/files.py index 4ef12e49..678d1f38 100644 --- a/tests/fixtures/files.py +++ b/tests/fixtures/files.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 json from pathlib import Path diff --git a/tests/fixtures/hub.py b/tests/fixtures/hub.py index ae309cb4..aa2768e4 100644 --- a/tests/fixtures/hub.py +++ b/tests/fixtures/hub.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 import datasets diff --git a/tests/fixtures/optimizers.py b/tests/fixtures/optimizers.py index 1a9b9d11..65488566 100644 --- a/tests/fixtures/optimizers.py +++ b/tests/fixtures/optimizers.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 torch diff --git a/tests/mock_cv2.py b/tests/mock_cv2.py index 806e35ed..b82e7819 100644 --- a/tests/mock_cv2.py +++ b/tests/mock_cv2.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 functools import cache import numpy as np diff --git a/tests/mock_dynamixel_sdk.py b/tests/mock_dynamixel_sdk.py index a790dff0..ee399f96 100644 --- a/tests/mock_dynamixel_sdk.py +++ b/tests/mock_dynamixel_sdk.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. """Mocked classes and functions from dynamixel_sdk to allow for continuous integration and testing code logic that requires hardware and devices (e.g. robot arms, cameras) diff --git a/tests/mock_pyrealsense2.py b/tests/mock_pyrealsense2.py index 5a39fc2b..c477eb06 100644 --- a/tests/mock_pyrealsense2.py +++ b/tests/mock_pyrealsense2.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 enum import numpy as np diff --git a/tests/mock_scservo_sdk.py b/tests/mock_scservo_sdk.py index ca9233b0..37f6d0d5 100644 --- a/tests/mock_scservo_sdk.py +++ b/tests/mock_scservo_sdk.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. """Mocked classes and functions from dynamixel_sdk to allow for continuous integration and testing code logic that requires hardware and devices (e.g. robot arms, cameras) diff --git a/tests/scripts/save_policy_to_safetensors.py b/tests/scripts/save_policy_to_safetensors.py index 03726163..60fd9fc0 100644 --- a/tests/scripts/save_policy_to_safetensors.py +++ b/tests/scripts/save_policy_to_safetensors.py @@ -33,12 +33,11 @@ def get_policy_stats(ds_repo_id: str, policy_name: str, policy_kwargs: dict): # TODO(rcadene, aliberts): remove dataset download dataset=DatasetConfig(repo_id=ds_repo_id, episodes=[0]), policy=make_policy_config(policy_name, **policy_kwargs), - device="cpu", ) train_cfg.validate() # Needed for auto-setting some parameters dataset = make_dataset(train_cfg) - policy = make_policy(train_cfg.policy, ds_meta=dataset.meta, device=train_cfg.device) + policy = make_policy(train_cfg.policy, ds_meta=dataset.meta) policy.train() optimizer, _ = make_optimizer_and_scheduler(train_cfg, policy) diff --git a/tests/test_cameras.py b/tests/test_cameras.py index cfefc215..3ab74516 100644 --- a/tests/test_cameras.py +++ b/tests/test_cameras.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. """ Tests for physical cameras and their mocked versions. If the physical camera is not connected to the computer, or not working, diff --git a/tests/test_control_robot.py b/tests/test_control_robot.py index 1796291f..02041e30 100644 --- a/tests/test_control_robot.py +++ b/tests/test_control_robot.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. """ Tests for physical robots and their mocked versions. If the physical robots are not connected to the computer, or not working, @@ -39,7 +52,7 @@ from lerobot.common.robot_devices.control_configs import ( from lerobot.configs.policies import PreTrainedConfig from lerobot.scripts.control_robot import calibrate, record, replay, teleoperate from tests.test_robots import make_robot -from tests.utils import DEVICE, TEST_ROBOT_TYPES, mock_calibration_dir, require_robot +from tests.utils import TEST_ROBOT_TYPES, mock_calibration_dir, require_robot @pytest.mark.parametrize("robot_type, mock", TEST_ROBOT_TYPES) @@ -171,7 +184,7 @@ def test_record_and_replay_and_policy(tmp_path, request, robot_type, mock): replay(robot, replay_cfg) policy_cfg = ACTConfig() - policy = make_policy(policy_cfg, ds_meta=dataset.meta, device=DEVICE) + policy = make_policy(policy_cfg, ds_meta=dataset.meta) out_dir = tmp_path / "logger" @@ -216,8 +229,6 @@ def test_record_and_replay_and_policy(tmp_path, request, robot_type, mock): display_cameras=False, play_sounds=False, num_image_writer_processes=num_image_writer_processes, - device=DEVICE, - use_amp=False, ) rec_eval_cfg.policy = PreTrainedConfig.from_pretrained(pretrained_policy_path) diff --git a/tests/test_datasets.py b/tests/test_datasets.py index 003a60c9..0deaceba 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -45,7 +45,7 @@ from lerobot.common.robot_devices.robots.utils import make_robot from lerobot.configs.default import DatasetConfig from lerobot.configs.train import TrainPipelineConfig from tests.fixtures.constants import DUMMY_CHW, DUMMY_HWC, DUMMY_REPO_ID -from tests.utils import DEVICE, require_x86_64_kernel +from tests.utils import require_x86_64_kernel @pytest.fixture @@ -349,7 +349,6 @@ def test_factory(env_name, repo_id, policy_name): dataset=DatasetConfig(repo_id=repo_id, episodes=[0]), env=make_env_config(env_name), policy=make_policy_config(policy_name), - device=DEVICE, ) dataset = make_dataset(cfg) diff --git a/tests/test_delta_timestamps.py b/tests/test_delta_timestamps.py index b27cc1eb..35014642 100644 --- a/tests/test_delta_timestamps.py +++ b/tests/test_delta_timestamps.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 itertools import accumulate import datasets diff --git a/tests/test_image_writer.py b/tests/test_image_writer.py index c7fc11f2..802fe0d3 100644 --- a/tests/test_image_writer.py +++ b/tests/test_image_writer.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 queue import time from multiprocessing import queues diff --git a/tests/test_io_utils.py b/tests/test_io_utils.py index d14f7adc..c1b776db 100644 --- a/tests/test_io_utils.py +++ b/tests/test_io_utils.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 json from pathlib import Path from typing import Any diff --git a/tests/test_logging_utils.py b/tests/test_logging_utils.py index 72385496..1ba1829e 100644 --- a/tests/test_logging_utils.py +++ b/tests/test_logging_utils.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 from lerobot.common.utils.logging_utils import AverageMeter, MetricsTracker diff --git a/tests/test_motors.py b/tests/test_motors.py index 75793636..da7a5c54 100644 --- a/tests/test_motors.py +++ b/tests/test_motors.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. """ Tests for physical motors and their mocked versions. If the physical motors are not connected to the computer, or not working, diff --git a/tests/test_optimizers.py b/tests/test_optimizers.py index cf5c5b18..997e14fe 100644 --- a/tests/test_optimizers.py +++ b/tests/test_optimizers.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 torch diff --git a/tests/test_policies.py b/tests/test_policies.py index 9dab6176..f8e7359c 100644 --- a/tests/test_policies.py +++ b/tests/test_policies.py @@ -143,12 +143,11 @@ def test_policy(ds_repo_id, env_name, env_kwargs, policy_name, policy_kwargs): dataset=DatasetConfig(repo_id=ds_repo_id, episodes=[0]), policy=make_policy_config(policy_name, **policy_kwargs), env=make_env_config(env_name, **env_kwargs), - device=DEVICE, ) # Check that we can make the policy object. dataset = make_dataset(train_cfg) - policy = make_policy(train_cfg.policy, ds_meta=dataset.meta, device=DEVICE) + policy = make_policy(train_cfg.policy, ds_meta=dataset.meta) assert isinstance(policy, PreTrainedPolicy) # Check that we run select_actions and get the appropriate output. @@ -214,7 +213,6 @@ def test_act_backbone_lr(): # TODO(rcadene, aliberts): remove dataset download dataset=DatasetConfig(repo_id="lerobot/aloha_sim_insertion_scripted", episodes=[0]), policy=make_policy_config("act", optimizer_lr=0.01, optimizer_lr_backbone=0.001), - device=DEVICE, ) cfg.validate() # Needed for auto-setting some parameters @@ -222,7 +220,7 @@ def test_act_backbone_lr(): assert cfg.policy.optimizer_lr_backbone == 0.001 dataset = make_dataset(cfg) - policy = make_policy(cfg.policy, device=DEVICE, ds_meta=dataset.meta) + policy = make_policy(cfg.policy, ds_meta=dataset.meta) optimizer, _ = make_optimizer_and_scheduler(cfg, policy) assert len(optimizer.param_groups) == 2 assert optimizer.param_groups[0]["lr"] == cfg.policy.optimizer_lr diff --git a/tests/test_random_utils.py b/tests/test_random_utils.py index 8eee2b68..daf08a89 100644 --- a/tests/test_random_utils.py +++ b/tests/test_random_utils.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 random import numpy as np diff --git a/tests/test_robots.py b/tests/test_robots.py index c5734a4c..71343eba 100644 --- a/tests/test_robots.py +++ b/tests/test_robots.py @@ -1,3 +1,16 @@ +# Copyright 2024 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. """ Tests for physical robots and their mocked versions. If the physical robots are not connected to the computer, or not working, diff --git a/tests/test_schedulers.py b/tests/test_schedulers.py index e871fee1..17637663 100644 --- a/tests/test_schedulers.py +++ b/tests/test_schedulers.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 torch.optim.lr_scheduler import LambdaLR from lerobot.common.constants import SCHEDULER_STATE diff --git a/tests/test_train_utils.py b/tests/test_train_utils.py index d6ed0063..b78f6e49 100644 --- a/tests/test_train_utils.py +++ b/tests/test_train_utils.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 unittest.mock import Mock, patch diff --git a/tests/test_utils.py b/tests/test_utils.py index b2f14694..2d0efc5a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,3 +1,16 @@ +# Copyright 2024 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 torch from datasets import Dataset