Skip to content

feat: enable to use multiple rgb encoders per camera in diffusion policy - #484

Merged
danaaubakirova merged 5 commits into
huggingface:mainfrom
HiroIshida:diffusion_policy_with_multi_rgb_encoders
Oct 30, 2024
Merged

danaaubakirova merged 5 commits into
huggingface:mainfrom
HiroIshida:diffusion_policy_with_multi_rgb_encoders

Conversation

@HiroIshida

@HiroIshida HiroIshida commented Oct 24, 2024 •

Copy link
Copy Markdown
Contributor

What this does

This PR enables to configure multiple rgb encoders for each cameras, which is done in the original diffusion policy paper. Not for sure in general setting, but at least in my task, this seems to increase the success rate of deployment slightly.
Current diffusion policy shared the single RGB encoder for all cameras.
This fixes #483

How it was tested

a) regression test

Prepare the following script and check that the behavior of the policy does not change before and the after the PR by comparing the hash value of the output.

import yaml
import torch
from hashlib import sha256
from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy, DiffusionConfig

def run(camera_names, rgb_encoder_per_camera):
    torch.manual_seed(0)

    resol = 56
    input_shapes = {"observation.state": [6]}
    for name in camera_names:
        input_shapes[f"observation.image.{name}"] = [3, resol, resol]
    output_shapes = {"action": [6]}

    # determine normalizer
    normalization_mode = {"observation.state": "min_max"}
    for name in camera_names:
        normalization_mode[f"observation.image.{name}"] = "mean_std"

    # load stats
    with open('stats-diffusion.yaml', 'r') as f:
        stats = yaml.load(f, Loader=yaml.FullLoader)
    effective_keys = list(output_shapes.keys()) + list(input_shapes.keys()) + ["episode_index", "frame_indx", "index", "next.done",  "timestamp"]
    effective_key_set = set(effective_keys)
    for key, value in stats.items():
        if key not in effective_key_set:
            continue
        inner_dict = {}
        for key_inner, value_inner in value.items():
            inner_dict[key_inner] = torch.tensor(value_inner)
        stats[key] = inner_dict

    # create policy
    conf = DiffusionConfig(input_shapes=input_shapes, output_shapes=output_shapes, input_normalization_modes=normalization_mode, crop_shape=None, num_inference_steps=5)
    if rgb_encoder_per_camera:
        conf.rgb_encoder_per_camera = True
    policy = DiffusionPolicy(conf, dataset_stats=stats)

    # inference
    observation = {"observation.state": torch.rand(1, 6)}
    for name in camera_names:
        observation[f"observation.image.{name}"] = torch.rand(1, 3, resol, resol)
                   

    action = policy.select_action(observation)

    # compute hash of action
    hash_value = sha256(action.numpy().tobytes()).hexdigest()
    print("hash value of output: ", hash_value)


if __name__ == "__main__":
    # case 1
    print(f"test with only gripper camera")
    camera_names = ["gripper"]
    run(camera_names, False)

    # case 2
    print(f"test with gripper and webcam cameras where rgb_encoder_per_camera is not set")
    camera_names = ["gripper", "webcam"]
    run(camera_names, False)

    # case 3
    print(f"test with gripper and webcam cameras where rgb_encoder_per_camera is set")
    has_rgb_encoder_per_camera = "rgb_encoder_per_camera" in DiffusionConfig.__annotations__
    if not has_rgb_encoder_per_camera:
        print("DiffusionConfig does not have attribute rgb_encoder_per_camera")
    else:
        camera_names = ["gripper", "webcam"]
        run(camera_names, True)

Before this PR

integral@umejuice:~/python/snippets/python/ext_examples/lerobot$ python3 diffusion_policy_multiple_cameras.py 
test with only gripper camera
hash value of output:  b3f55809cad72b41e484ec589d9ace5acf1f16439c4b0d71817dc6cbb41d0f4f
test with gripper and webcam cameras where rgb_encoder_per_camera is not set
hash value of output:  d08244f48c83964d90a3224790c9d1f9fc20d58c870420c028b3be46a0ff3b22
test with gripper and webcam cameras where rgb_encoder_per_camera is set
DiffusionConfig does not have attribute rgb_encoder_per_camera

After this PR

integral@umejuice:~/python/snippets/python/ext_examples/lerobot$ python3 diffusion_policy_multiple_cameras.py 
test with only gripper camera
hash value of output:  b3f55809cad72b41e484ec589d9ace5acf1f16439c4b0d71817dc6cbb41d0f4f
test with gripper and webcam cameras where rgb_encoder_per_camera is not set
hash value of output:  d08244f48c83964d90a3224790c9d1f9fc20d58c870420c028b3be46a0ff3b22
test with gripper and webcam cameras where rgb_encoder_per_camera is set
hash value of output:  a636c3ad1313eda2504b008d92eb823d58acc6344582bb4922d73892371e5da0

You can see the match of hash values.

b) validity check

The above test include the case (see case3 ), which is run only when the DiffusionConfig has rgb_encoder_per_camera attribute, so activate only after this PR. And as you can see, there is no error occured and output the action.

c) tested on real robot

I trained the diffusion policy with the rgb_encoder_per_camera=True , and checked that policy worked well. I cannot say concrete stuff but the performance is slightly better than the original.

How to checkout & try? (for the reviewer)

Try the above script and please check the hash value before and after this PR. Before the run, you need to save the following yaml file as 'stats-diffusion.yaml.

action:
  max:
  - 119.3543701171875
  - 49.64094543457031
  - 111.9273910522461
  - 7.118511199951172
  - 106.76649475097656
  - 26.715518951416016
  mean:
  - 94.45906829833984
  - 18.427291870117188
  - 73.95457458496094
  - 1.212478518486023
  - 79.41802978515625
  - 6.242947578430176
  min:
  - 77.6657943725586
  - -29.830978393554688
  - 39.58110809326172
  - -8.624532699584961
  - 44.424076080322266
  - -18.17777442932129
  std:
  - 8.80908489227295
  - 16.74974822998047
  - 14.223931312561035
  - 1.9911779165267944
  - 10.933554649353027
  - 9.21682357788086
episode_index:
  max:
  - 69.0
  mean:
  - 34.674591064453125
  min:
  - 0.0
  std:
  - 20.254430770874023
frame_index:
  max:
  - 176.0
  mean:
  - 61.95341873168945
  min:
  - 0.0
  std:
  - 37.45309829711914
index:
  max:
  - 8585.0
  mean:
  - 4292.5
  min:
  - 0.0
  std:
  - 2478.564453125
next.done:
  max:
  - 1.0
  mean:
  - 0.008152804337441921
  min:
  - 0.0
  std:
  - 0.08992405980825424
observation.image.gripper:
  max:
  - - - 1.0
  - - - 1.0
  - - - 1.0
  mean:
  - - - 0.3928315341472626
  - - - 0.39230185747146606
  - - - 0.360833078622818
  min:
  - - - 0.0
  - - - 0.0
  - - - 0.0
  std:
  - - - 0.2355380803346634
  - - - 0.23801472783088684
  - - - 0.2544608414173126
observation.image.webcam:
  max:
  - - - 1.0
  - - - 1.0
  - - - 1.0
  mean:
  - - - 0.405765175819397
  - - - 0.6512684226036072
  - - - 0.6204251646995544
  min:
  - - - 0.0
  - - - 0.0
  - - - 0.0
  std:
  - - - 0.1711459755897522
  - - - 0.1499525010585785
  - - - 0.1772834062576294
observation.state:
  max:
  - 113.90892791748047
  - 49.61915588378906
  - 111.92845916748047
  - 7.113752841949463
  - 106.78263092041016
  - 26.70062255859375
  mean:
  - 95.00767517089844
  - 15.08882999420166
  - 76.28932189941406
  - 1.3102922439575195
  - 80.53984832763672
  - 6.705284595489502
  min:
  - 77.66748809814453
  - -29.83199119567871
  - 39.72526550292969
  - -5.572042942047119
  - 44.40793991088867
  - -18.174049377441406
  std:
  - 8.437381744384766
  - 18.46141242980957
  - 14.492023468017578
  - 1.9003233909606934
  - 10.978218078613281
  - 8.922645568847656
timestamp:
  max:
  - 17.600000381469727
  mean:
  - 6.195342540740967
  min:
  - 0.0
  std:
  - 3.745309591293335

@HiroIshida
HiroIshida force-pushed the diffusion_policy_with_multi_rgb_encoders branch from 38c883b to 9633d87 Compare October 24, 2024 13:41
@HiroIshida
HiroIshida force-pushed the diffusion_policy_with_multi_rgb_encoders branch from 9633d87 to ac1cd33 Compare October 24, 2024 13:58
@HiroIshida HiroIshida changed the title feat: enable to use multiple rgb encoders per camera feat: enable to use multiple rgb encoders per camera in diffusion policy Oct 24, 2024
@HiroIshida
HiroIshida marked this pull request as ready for review October 24, 2024 20:22
@HiroIshida

Copy link
Copy Markdown
Contributor Author

@alexander-soare
Could you review this PR? :)

@alexander-soare alexander-soare left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for this PR! I'm a bag fan of the attention to detail you've put into testing your changes and communicating that in the main PR message.

I've replied some nits around naming and commenting.

HiroIshida and others added 2 commits October 29, 2024 00:17
Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>
@HiroIshida

Copy link
Copy Markdown
Contributor Author

@alexander-soare
Thank you for your review! I fixed the name and applied your suggestions.
also, modify the test code and checked that it works https://gist.github.com/HiroIshida/5d0abbec0fdd0d140c5262eb1301c98e

@alexander-soare alexander-soare left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved! Waiting for another HF team member to do a quick pass then we'll merge.

@danaaubakirova

danaaubakirova commented Oct 28, 2024 •

Copy link
Copy Markdown
Contributor

@HiroIshida Thanks a lot for this PR! The quality check Is not passing. Otherwise, LGTM. I will approve after the issue is fixed:)

@HiroIshida

Copy link
Copy Markdown
Contributor Author

@danaaubakirova
Thanks. I applied the formatter.

@danaaubakirova
danaaubakirova merged commit 538455a into huggingface:main Oct 30, 2024
DomThePorcupine pushed a commit to DomThePorcupine/lerobot that referenced this pull request Dec 2, 2024
…icy (huggingface#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>
Cadene pushed a commit that referenced this pull request Dec 28, 2024
…icy (#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>
villekuosmanen added a commit to villekuosmanen/lerobot that referenced this pull request Dec 30, 2024
* feat: enable to use multiple rgb encoders per camera in diffusion policy (huggingface#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>

* Fix config file (huggingface#495)

* fix: broken images and a few minor typos in README (huggingface#499)

Signed-off-by: ivelin <ivelin117@gmail.com>

* Add support for Windows (huggingface#494)

* bug causes error uploading to huggingface, unicode issue on windows. (huggingface#450)

* Add distinction between two unallowed cases in name check "eval_" (huggingface#489)

* Rename deprecated argument (temporal_ensemble_momentum) (huggingface#490)

* Dataset v2.0 (huggingface#461)

Co-authored-by: Remi <remi.cadene@huggingface.co>

* Refactor OpenX (huggingface#505)

* Fix missing local_files_only in record/replay (huggingface#540)

Co-authored-by: Simon Alibert <alibert.sim@gmail.com>

* Control simulated robot with real leader (huggingface#514)

Co-authored-by: Remi <remi.cadene@huggingface.co>

* Update 7_get_started_with_real_robot.md (huggingface#559)

* LerobotDataset pushable to HF from any folder (huggingface#563)

* Fix example 6 (huggingface#572)

* fixing typo from 'teloperation' to 'teleoperation' (huggingface#566)

* [vizualizer] for LeRobodDataset V2 (huggingface#576)

* Fix broken `create_lerobot_dataset_card`  (huggingface#590)

* feat(act): support training end of episode token to ACT model

* changes

* feat(arx): add arx arm (#2)

* feat(arx): support arx arm

* changes

* changes

* changes

* changes

* pass pipes explicitly

* changes

* us ndarray over a pipe

* changes

* changes

* replay basically works

* patch arx sdk

* changes

* support cameras in arx5

* rename to arx5

* kind of works

* changes

* changes

* changes

* various changes

* changes

* revert a few changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* remove TODO

* allow multiple tasks

---------

Signed-off-by: ivelin <ivelin117@gmail.com>
Co-authored-by: Hirokazu Ishida <38597814+HiroIshida@users.noreply.github.com>
Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>
Co-authored-by: Arsen Ohanyan <arsenohanyan@gmail.com>
Co-authored-by: Ivelin Ivanov <ivelin117@gmail.com>
Co-authored-by: Daniel Ritchie <daniel@brainwavecollective.ai>
Co-authored-by: resolver101757 <kelster101757@hotmail.com>
Co-authored-by: Jannik Grothusen <56967823+J4nn1K@users.noreply.github.com>
Co-authored-by: KasparSLT <133706781+KasparSLT@users.noreply.github.com>
Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>
Co-authored-by: Remi <remi.cadene@huggingface.co>
Co-authored-by: Michel Aractingi <michel.aractingi@huggingface.co>
Co-authored-by: Simon Alibert <alibert.sim@gmail.com>
Co-authored-by: berjaoui <berjaoui@gmail.com>
Co-authored-by: Claudio Coppola <Claudiocoppola90@gmail.com>
Co-authored-by: s1lent4gnt <kmeftah.khalil@gmail.com>
Co-authored-by: Mishig <dmishig@gmail.com>
Co-authored-by: Eugene Mironov <helper2424@gmail.com>
villekuosmanen added a commit to villekuosmanen/lerobot that referenced this pull request Jan 10, 2025
* feat: enable to use multiple rgb encoders per camera in diffusion policy (huggingface#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>

* Fix config file (huggingface#495)

* fix: broken images and a few minor typos in README (huggingface#499)

Signed-off-by: ivelin <ivelin117@gmail.com>

* Add support for Windows (huggingface#494)

* bug causes error uploading to huggingface, unicode issue on windows. (huggingface#450)

* Add distinction between two unallowed cases in name check "eval_" (huggingface#489)

* Rename deprecated argument (temporal_ensemble_momentum) (huggingface#490)

* Dataset v2.0 (huggingface#461)

Co-authored-by: Remi <remi.cadene@huggingface.co>

* Refactor OpenX (huggingface#505)

* Fix missing local_files_only in record/replay (huggingface#540)

Co-authored-by: Simon Alibert <alibert.sim@gmail.com>

* Control simulated robot with real leader (huggingface#514)

Co-authored-by: Remi <remi.cadene@huggingface.co>

* Update 7_get_started_with_real_robot.md (huggingface#559)

* LerobotDataset pushable to HF from any folder (huggingface#563)

* Fix example 6 (huggingface#572)

* fixing typo from 'teloperation' to 'teleoperation' (huggingface#566)

* [vizualizer] for LeRobodDataset V2 (huggingface#576)

* Fix broken `create_lerobot_dataset_card`  (huggingface#590)

* Update README.md (huggingface#612)

* Fix Quality workflow (huggingface#622)

* fix(docs): typos in benchmark readme.md (huggingface#614)

Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>

* fix(visualise): use correct language description for each episode id (huggingface#604)

Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>

* typo fix: batch_convert_dataset_v1_to_v2.py (huggingface#615)

Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>

* [viz] Fixes & updates to html visualizer (huggingface#617)

* fixes to SO-100 readme (huggingface#600)

Co-authored-by: Philip Fung <no@one>
Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>

---------

Signed-off-by: ivelin <ivelin117@gmail.com>
Co-authored-by: Hirokazu Ishida <38597814+HiroIshida@users.noreply.github.com>
Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>
Co-authored-by: Arsen Ohanyan <arsenohanyan@gmail.com>
Co-authored-by: Ivelin Ivanov <ivelin117@gmail.com>
Co-authored-by: Daniel Ritchie <daniel@brainwavecollective.ai>
Co-authored-by: resolver101757 <kelster101757@hotmail.com>
Co-authored-by: Jannik Grothusen <56967823+J4nn1K@users.noreply.github.com>
Co-authored-by: KasparSLT <133706781+KasparSLT@users.noreply.github.com>
Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>
Co-authored-by: Remi <remi.cadene@huggingface.co>
Co-authored-by: Michel Aractingi <michel.aractingi@huggingface.co>
Co-authored-by: Simon Alibert <alibert.sim@gmail.com>
Co-authored-by: berjaoui <berjaoui@gmail.com>
Co-authored-by: Claudio Coppola <Claudiocoppola90@gmail.com>
Co-authored-by: s1lent4gnt <kmeftah.khalil@gmail.com>
Co-authored-by: Mishig <dmishig@gmail.com>
Co-authored-by: Eugene Mironov <helper2424@gmail.com>
Co-authored-by: CharlesCNorton <135471798+CharlesCNorton@users.noreply.github.com>
Co-authored-by: Philip Fung <1054593+philfung@users.noreply.github.com>
Co-authored-by: Philip Fung <no@one>
menhguin pushed a commit to menhguin/lerobot that referenced this pull request Feb 9, 2025
…icy (huggingface#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>
aliberts pushed a commit that referenced this pull request Feb 9, 2025
[Fix] Move back to manual calibration (#488)

feat: enable to use multiple rgb encoders per camera in diffusion policy (#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>

Fix config file (#495)

fix: broken images and a few minor typos in README (#499)

Signed-off-by: ivelin <ivelin117@gmail.com>

Add support for Windows (#494)

bug causes error uploading to huggingface, unicode issue on windows. (#450)

Add distinction between two unallowed cases in name check "eval_" (#489)

WIP

Fix autocalib moss (#486)

[Fix] Move back to manual calibration (#488)

feat: enable to use multiple rgb encoders per camera in diffusion policy (#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>

Fix config file (#495)

fix: broken images and a few minor typos in README (#499)

Signed-off-by: ivelin <ivelin117@gmail.com>

Add support for Windows (#494)

bug causes error uploading to huggingface, unicode issue on windows. (#450)

Add distinction between two unallowed cases in name check "eval_" (#489)

Rename deprecated argument (temporal_ensemble_momentum) (#490)

Dataset v2.0 (#461)

Co-authored-by: Remi <remi.cadene@huggingface.co>

Refactor OpenX (#505)

Fix missing local_files_only in record/replay (#540)

Co-authored-by: Simon Alibert <alibert.sim@gmail.com>

Control simulated robot with real leader (#514)

Co-authored-by: Remi <remi.cadene@huggingface.co>

Update 7_get_started_with_real_robot.md (#559)

LerobotDataset pushable to HF from any folder (#563)

Fix example 6 (#572)

fixing typo from 'teloperation' to 'teleoperation' (#566)

[vizualizer] for LeRobodDataset V2 (#576)

Fix broken `create_lerobot_dataset_card`  (#590)

Update README.md (#612)

Add draccus, create MainConfig

WIP refactor train.py and ACT

Add policies training presets

Update diffusion policy

Add pusht and xarm env configs

Update tdmpc

Update vqbet

Fix poetry relax

Add feature types to envs

Add EvalPipelineConfig, parse features from envs

Add custom parser

Update pretrained loading mechanisms

Add dependency fixes & lock update

Fix pretrained_path

Refactor envs, remove RealEnv

Fix typo

Enable end-to-end tests

Fix Makefile

Log eval config

Fix end-to-end tests

Fix Quality workflow (#622)

Remove amp & add resume test

Speed-up tests

Fix poetry relax

Remove config yaml for robot devices (#594)

Co-authored-by: Simon Alibert <simon.alibert@huggingface.co>

fix(docs): typos in benchmark readme.md (#614)

Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>

fix(visualise): use correct language description for each episode id (#604)

Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>

typo fix: batch_convert_dataset_v1_to_v2.py (#615)

Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>

[viz] Fixes & updates to html visualizer (#617)

Fix logger

Remove hydra-core

Add aggregate_stats

Add estimate_num_samples for images, Add test image

Remove NoneSchedulerConfig

Add push_pretrained

Remove eval.episode_length

Fix wandb_video

Fix typo

Add features back into policy configs (#643)

fixes to SO-100 readme (#600)

Co-authored-by: Philip Fung <no@one>
Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>

Fix for the issue #638 (#639)

Fix env_to_policy_features call

Fix wandb init

remove omegaconf

Add branch arg

Move deprecated

Move training config

Remove pathable_args

Implement custom HubMixin

Fixes

Implement PreTrainedPolicy base class

Add HubMixin to TrainPipelineConfig

Udpate example 2 & 3

Update push_pretrained

Bump`rerun-sdk` dependency to `0.21.0` (#618)

Co-authored-by: Simon Alibert <75076266+aliberts@users.noreply.github.com>

Fix config_class

Fix from_pretrained kwargs

Remove policy_protocol

Camelize PretrainedConfig

Additional fix while retraining policies (#629)

Co-authored-by: Simon Alibert <simon.alibert@huggingface.co>

Actually reactivate tdmpc online test

Update example 4

Remove advanced example 1

Remove example 5

Move example 6 to advanced

Use HubMixin.save_pretrained

Enable config_path to be a repo_id

Dry has_method

Update example 4

Update README

Cleanup pyproject.toml

Update eval docstring

Update README

Clean example 4

Update README

Make 'last' checkpoint symlink relative

Fix cluster image (#653)

Simplify example 4

fix stats per episodes and aggregate stats and casting to tensor
Kalcy-U referenced this pull request in Kalcy-U/lerobot May 13, 2025
…icy (#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>
ZoreAnuj pushed a commit to luckyrobots/lerobot that referenced this pull request Jul 29, 2025
…icy (huggingface#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>
Minko82 pushed a commit to Minko82/xlerobot-pro that referenced this pull request Sep 2, 2026
…icy (huggingface#484)

Co-authored-by: Alexander Soare <alexander.soare159@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Diffusion policy's RGB encoder shared by all cameras. Is this intended?

3 participants