pepijn223 HF Staff commited on
Commit
fdadf53
·
verified ·
1 Parent(s): 5123dba

Deploy cleaned hand annotation PR and verified minimal worker image

Browse files
deploy.py CHANGED
@@ -63,10 +63,13 @@ def main():
63
  [
64
  sys.executable,
65
  "-c",
66
- "import json; from lerobot.annotations.hands.config import public_catalog; print(json.dumps(public_catalog()))",
67
  ],
68
  cwd=temporary,
69
- env={**os.environ, "PYTHONPATH": str(Path(temporary) / "src")},
 
 
 
70
  text=True,
71
  )
72
  )
 
63
  [
64
  sys.executable,
65
  "-c",
66
+ "import json; from hand_actions import public_catalog; print(json.dumps(public_catalog()))",
67
  ],
68
  cwd=temporary,
69
+ env={
70
+ **os.environ,
71
+ "PYTHONPATH": os.pathsep.join([str(Path(temporary) / "src"), str(folder)]),
72
+ },
73
  text=True,
74
  )
75
  )
flora-worker-image.json CHANGED
@@ -31,7 +31,7 @@
31
  "flora_batcher.py": "38e03e2032af8d5f3ed34980cc4d89927fe70c9742aa2ce13f4d0ccdd6fba727",
32
  "flora_speed_entry.py": "192b18d75b9d876c2a65d88de340c8cea7c8da90543d0510b5ee6865d123d524",
33
  "studio_runtime.py": "2b393bf7fafcdead638ad1cea35e49df8c6edce725f5545b76fd68e0a8fedd80",
34
- "pipeline-version.json": "b0c3e208fae3ebc0ee38cb9df8ea657aadeca6b70629697a197df1d30dbe17c1",
35
  "flora_vision.py": "a5a4231abf7b615164c40986df5f87047f745a23c55d86385d88f2a09e70f1e8"
36
  },
37
  "acceptance": {
@@ -98,6 +98,7 @@
98
  ]
99
  },
100
  "inference_or_benchmark_rerun": false,
101
- "core_change_scope": "Hand package only; other src files byte-identical to accepted pipeline bd4c312dac38068440edf59e764ba0c68ab7ce0b"
 
102
  }
103
  }
 
31
  "flora_batcher.py": "38e03e2032af8d5f3ed34980cc4d89927fe70c9742aa2ce13f4d0ccdd6fba727",
32
  "flora_speed_entry.py": "192b18d75b9d876c2a65d88de340c8cea7c8da90543d0510b5ee6865d123d524",
33
  "studio_runtime.py": "2b393bf7fafcdead638ad1cea35e49df8c6edce725f5545b76fd68e0a8fedd80",
34
+ "pipeline-version.json": "c42cab00f33cbe53582b0ad56f384d453cbb747eef6db7ec1ba91803bc469681",
35
  "flora_vision.py": "a5a4231abf7b615164c40986df5f87047f745a23c55d86385d88f2a09e70f1e8"
36
  },
37
  "acceptance": {
 
98
  ]
99
  },
100
  "inference_or_benchmark_rerun": false,
101
+ "core_change_scope": "Hand package only; other src files byte-identical to accepted pipeline bd4c312dac38068440edf59e764ba0c68ab7ce0b",
102
+ "pipeline_revision": "850bb584c545ebe9bfcefdcd9b02391cba1c4638"
103
  }
104
  }
hand-pipeline-catalog.json CHANGED
@@ -29,14 +29,14 @@
29
  "frames": 1500,
30
  "planning_fps": null,
31
  "seconds": null,
32
- "basis": "HF hardware has not been benchmarked",
33
  "reference_fps": [
34
  39.41450219151414,
35
  41.03790957211554
36
  ],
37
  "reference_compute": "RTX 5090",
38
  "reference_scope": "Two fresh ten-clip development samples, 1500 input frames and 1120 accepted frames each. Includes startup, decode, calibration, fresh DROID-W+MoGe, hands and native156D export. Excludes installation and model downloads; not a cold filesystem-cache benchmark.",
39
- "caveat": "Different HF GPUs have no measured FPS yet. Queue, installation, downloads and dataset copying are additional."
40
  },
41
  "licenses": {
42
  "egohand": "https://huggingface.co/nvidia/EgoHand-v1",
@@ -44,5 +44,5 @@
44
  "soma": "https://huggingface.co/nvidia/SOMA-X",
45
  "runtime": "https://github.com/NVlabs/GEM-X/blob/20555befe2fbbe5b2015e1fff7ff214dc18ea9d6/ATTRIBUTIONS.md"
46
  },
47
- "lerobot_revision": "6b25ea37e6e96122d4af1fa85f6f0d8659f274f4"
48
  }
 
29
  "frames": 1500,
30
  "planning_fps": null,
31
  "seconds": null,
32
+ "basis": "Runtime depends on video resolution and GPU",
33
  "reference_fps": [
34
  39.41450219151414,
35
  41.03790957211554
36
  ],
37
  "reference_compute": "RTX 5090",
38
  "reference_scope": "Two fresh ten-clip development samples, 1500 input frames and 1120 accepted frames each. Includes startup, decode, calibration, fresh DROID-W+MoGe, hands and native156D export. Excludes installation and model downloads; not a cold filesystem-cache benchmark.",
39
+ "caveat": "Queue, installation, downloads and dataset copying add time."
40
  },
41
  "licenses": {
42
  "egohand": "https://huggingface.co/nvidia/EgoHand-v1",
 
44
  "soma": "https://huggingface.co/nvidia/SOMA-X",
45
  "runtime": "https://github.com/NVlabs/GEM-X/blob/20555befe2fbbe5b2015e1fff7ff214dc18ea9d6/ATTRIBUTIONS.md"
46
  },
47
+ "lerobot_revision": "850bb584c545ebe9bfcefdcd9b02391cba1c4638"
48
  }
hand-worker-image.json CHANGED
@@ -1,10 +1,10 @@
1
  {
2
  "recipe": "egohand-soma-v3-checkpoint-overlap-v4",
3
  "build_verified": true,
4
- "image_repo": "finerobotics/egohand-soma-worker-v4",
5
- "image_revision": "06dcbf6fc970289d532eeebc86bedeef72b8c791",
6
- "image": "hf.co/spaces/finerobotics/egohand-soma-worker-v4",
7
- "image_version_sha256": "624de4590d55adfe656876c3ff6b00929519b5d960cc6c3d710b6a204bc034ac",
8
  "assets": {
9
  "repo": "finerobotics/egohand-soma-runtime",
10
  "revision": "cb082150aed8612fd50a6a78a0e37deebf24b6c3",
@@ -30,28 +30,25 @@
30
  "timeout_s": 7200
31
  },
32
  "gpu_acceptance": {
33
- "job": "pepijn223/6adad0bec191903149a796ea",
34
- "dataset": "pepijn223/egovista-kitchen-manipulation-v1-egohand-soma-test8",
35
- "dataset_revision": "c66be7c66d7da19496cf3120a6621ed275fa5bbc",
36
- "verified_at": "2026-10-23T03:27:35.320627+00:00",
37
- "retained_frames": 751,
38
- "valid_frames": 741,
39
- "invalid_masked_frames": 10,
40
  "native_parameters_finite": true,
41
- "ordinary_data_loader": true,
 
 
 
 
 
 
 
 
 
 
42
  "calibration_mode": "estimate-moge",
43
  "metric_accuracy_validated": false,
44
- "actual_video_review": false,
45
- "compute_flavor": "h200",
46
- "source_resolution": [
47
- 3840,
48
- 2160
49
- ],
50
- "source_fps": 10,
51
- "native_annotation_seconds": 82.9781820140197,
52
- "job_running_seconds": 557,
53
- "job_wall_seconds": 729,
54
- "compute_usd_estimated": 0.83333,
55
- "invoice_available": false
56
  }
57
  }
 
1
  {
2
  "recipe": "egohand-soma-v3-checkpoint-overlap-v4",
3
  "build_verified": true,
4
+ "image_repo": "finerobotics/annotation-hands-worker",
5
+ "image_revision": "775ee404b1c327b6f952561f761c5be27d455122",
6
+ "image": "hf.co/spaces/finerobotics/annotation-hands-worker",
7
+ "image_version_sha256": "96757674746f24b8e2031e6d0ca656b8d24681eb6493a2e826edbbd735dbaf6f",
8
  "assets": {
9
  "repo": "finerobotics/egohand-soma-runtime",
10
  "revision": "cb082150aed8612fd50a6a78a0e37deebf24b6c3",
 
30
  "timeout_s": 7200
31
  },
32
  "gpu_acceptance": {
33
+ "job": "pepijn223/6adb536b046eb82b1ecd4421",
34
+ "core_revision": "850bb584c545ebe9bfcefdcd9b02391cba1c4638",
35
+ "image_revision": "775ee404b1c327b6f952561f761c5be27d455122",
36
+ "retained_frames": 60,
37
+ "valid_frames": 60,
 
 
38
  "native_parameters_finite": true,
39
+ "camera_depth_prior": {
40
+ "mode": "on",
41
+ "counts": {
42
+ "depth_loads": 1,
43
+ "depth_predictions": 7,
44
+ "depth_bypasses": 0
45
+ },
46
+ "metric_depth_reg": true,
47
+ "source_sha256": "9bb2fe41b6c52cfe8d4d2f584e9ea4d230b83a27bd44afb43c401cd63d0f7f04",
48
+ "gt_scale_fit": false
49
+ },
50
  "calibration_mode": "estimate-moge",
51
  "metric_accuracy_validated": false,
52
+ "compute_flavor": "h200"
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
  }
hand_actions.py CHANGED
@@ -1,15 +1,70 @@
1
  """Native EgoHand/SOMA actions in the shared annotation wizard and HF Jobs lifecycle."""
2
 
3
  import json
 
4
  import re
5
  from dataclasses import asdict
6
  from pathlib import Path
7
 
8
- from lerobot.annotations.hands.config import COMPUTE, RECIPE, HandBackendConfig, estimate, public_catalog
 
 
 
 
 
 
9
  from lerobot.annotations.hands.intrinsics import METHOD
10
  from lerobot.annotations.hands.writer import validate_calibration
11
 
12
  HANDS = "Hand actions"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
 
15
  def runtime_configuration():
 
1
  """Native EgoHand/SOMA actions in the shared annotation wizard and HF Jobs lifecycle."""
2
 
3
  import json
4
+ import math
5
  import re
6
  from dataclasses import asdict
7
  from pathlib import Path
8
 
9
+ from lerobot.annotations.hands.config import (
10
+ ACTION_SCHEMA,
11
+ GEM_REVISION,
12
+ RECIPE,
13
+ RUNTIME_REVISION,
14
+ HandBackendConfig,
15
+ )
16
  from lerobot.annotations.hands.intrinsics import METHOD
17
  from lerobot.annotations.hands.writer import validate_calibration
18
 
19
  HANDS = "Hand actions"
20
+ COMPUTE = {
21
+ "a100-large": "A100 80 GB",
22
+ "rtx-pro-6000": "RTX PRO 6000 96 GB",
23
+ "h200": "H200 141 GB",
24
+ }
25
+
26
+
27
+ def estimate(frames, planning_fps=None):
28
+ """Separate a planning assumption from the qualified development reference."""
29
+ if planning_fps is not None and (not math.isfinite(planning_fps) or planning_fps <= 0):
30
+ raise ValueError("Planning FPS must be finite and positive")
31
+ return {
32
+ "frames": frames,
33
+ "planning_fps": planning_fps,
34
+ "seconds": frames / planning_fps if planning_fps else None,
35
+ "basis": "user planning assumption"
36
+ if planning_fps
37
+ else "Runtime depends on video resolution and GPU",
38
+ "reference_fps": [39.41450219151414, 41.03790957211554],
39
+ "reference_compute": "RTX 5090",
40
+ "reference_scope": "Two fresh ten-clip development samples, 1500 input frames and 1120 accepted "
41
+ "frames each. Includes startup, decode, calibration, fresh DROID-W+MoGe, hands and native156D "
42
+ "export. Excludes installation and model downloads; not a cold filesystem-cache benchmark.",
43
+ "caveat": "Queue, installation, downloads and dataset copying add time.",
44
+ }
45
+
46
+
47
+ def public_catalog():
48
+ """Expose Studio's compute choices and model terms alongside the core recipe."""
49
+ return {
50
+ "recipe": RECIPE,
51
+ "runtime_revision": RUNTIME_REVISION,
52
+ "gem_revision": GEM_REVISION,
53
+ "action_schema": ACTION_SCHEMA,
54
+ "action_dimension": 156,
55
+ "camera": "DROID-W + MoGe Small (required)",
56
+ "hand_model": "nvidia/EgoHand-v1",
57
+ "hand_representation": "SOMA/MHR",
58
+ "motion_infilling": False,
59
+ "profiles": [{"key": key, "name": value, "reference_fps": None} for key, value in COMPUTE.items()],
60
+ "reference": estimate(1500),
61
+ "licenses": {
62
+ "egohand": "https://huggingface.co/nvidia/EgoHand-v1",
63
+ "detector": "https://huggingface.co/nvidia/RT-DETR-Hand-Detector-v1",
64
+ "soma": "https://huggingface.co/nvidia/SOMA-X",
65
+ "runtime": f"https://github.com/NVlabs/GEM-X/blob/{GEM_REVISION}/ATTRIBUTIONS.md",
66
+ },
67
+ }
68
 
69
 
70
  def runtime_configuration():
pipeline-source.tar.gz CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:47f2782ac691b7664ae312310deac193cba0376c8404646b608da4607ae94a77
3
- size 1873266
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ba5218df544d3a6491b97a10cb36506bec38ffddff40ce51a8947560ff52eee4
3
+ size 1869569
pipeline-version.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
- "git_commit": "6b25ea37e6e96122d4af1fa85f6f0d8659f274f4",
3
- "sha256": "47f2782ac691b7664ae312310deac193cba0376c8404646b608da4607ae94a77",
4
  "preset": "abc_phases_schema_with_original_window_recovery",
5
  "preset_date": "2026-09-25",
6
  "engine": "lerobot.annotations.runtime",
 
1
  {
2
+ "git_commit": "850bb584c545ebe9bfcefdcd9b02391cba1c4638",
3
+ "sha256": "ba5218df544d3a6491b97a10cb36506bec38ffddff40ce51a8947560ff52eee4",
4
  "preset": "abc_phases_schema_with_original_window_recovery",
5
  "preset_date": "2026-09-25",
6
  "engine": "lerobot.annotations.runtime",
studio.py CHANGED
@@ -14,7 +14,7 @@ from pathlib import Path, PurePosixPath
14
  import pyarrow.parquet as pq
15
  from flora_captioner import FLORA
16
  from flora_image import validated_worker_image
17
- from hand_actions import HANDS, prepare_hands, runtime_configuration
18
  from huggingface_hub import HfApi, hf_hub_download
19
  from huggingface_hub.utils import validate_repo_id
20
  from model_catalog import (
@@ -28,8 +28,6 @@ from model_catalog import (
28
  )
29
  from prompt_config import TEMPLATES, validate_prompts
30
 
31
- from lerobot.annotations.hands.config import COMPUTE
32
-
33
  MODEL = model_profile()["route"]
34
  PROVIDER = model_profile()["provider"]
35
  FEATURES = {
 
14
  import pyarrow.parquet as pq
15
  from flora_captioner import FLORA
16
  from flora_image import validated_worker_image
17
+ from hand_actions import COMPUTE, HANDS, prepare_hands, runtime_configuration
18
  from huggingface_hub import HfApi, hf_hub_download
19
  from huggingface_hub.utils import validate_repo_id
20
  from model_catalog import (
 
28
  )
29
  from prompt_config import TEMPLATES, validate_prompts
30
 
 
 
31
  MODEL = model_profile()["route"]
32
  PROVIDER = model_profile()["provider"]
33
  FEATURES = {
test_hand_actions.py CHANGED
@@ -15,7 +15,7 @@ import pytest
15
  sys.path.insert(0, str(Path(__file__).parent))
16
  import studio
17
  import worker
18
- from hand_actions import HANDS, catalog
19
  from studio_runtime import run_episode
20
 
21
  from lerobot.annotations.hands.config import ACTION_SCHEMA
@@ -23,6 +23,12 @@ from lerobot.annotations.hands.writer import PARAMETERS
23
  from lerobot.annotations.steerable_pipeline.reader import EpisodeRecord
24
 
25
 
 
 
 
 
 
 
26
  def test_unconfigured_runtime_cannot_claim_ready(monkeypatch):
27
  monkeypatch.setattr(
28
  "hand_actions.runtime_configuration",
 
15
  sys.path.insert(0, str(Path(__file__).parent))
16
  import studio
17
  import worker
18
+ from hand_actions import COMPUTE, HANDS, catalog, estimate
19
  from studio_runtime import run_episode
20
 
21
  from lerobot.annotations.hands.config import ACTION_SCHEMA
 
23
  from lerobot.annotations.steerable_pipeline.reader import EpisodeRecord
24
 
25
 
26
+ def test_no_fabricated_hf_throughput():
27
+ assert set(COMPUTE) == {"h200", "a100-large", "rtx-pro-6000"}
28
+ assert estimate(3000)["seconds"] is None
29
+ assert estimate(3000)["reference_fps"] == [39.41450219151414, 41.03790957211554]
30
+
31
+
32
  def test_unconfigured_runtime_cannot_claim_ready(monkeypatch):
33
  monkeypatch.setattr(
34
  "hand_actions.runtime_configuration",