pepijn223 HF Staff commited on
Commit
76e2cc2
·
verified ·
1 Parent(s): 1564378

Use embedded public hand assets and allow model estimates without login

Browse files
README.md CHANGED
@@ -51,7 +51,10 @@ not apply. Aria Gen1 image rotation is explicit. The annotated copy retains ever
51
  source frame, writes 156D actions and native SOMA parameters, and masks frames
52
  outside directly observed bimanual spans of at least 30 frames. This recipe has
53
  no motion infiller and needs no MANO files. Model assets come from a pinned,
54
- checksummed private runtime release using the signed-in user's read access.
 
 
 
55
  The worker image and asset identities are verified before native inference.
56
 
57
  The measured development reference is 39.41–41.04 input FPS on RTX 5090 over ten
 
51
  source frame, writes 156D actions and native SOMA parameters, and masks frames
52
  outside directly observed bimanual spans of at least 30 frames. This recipe has
53
  no motion infiller and needs no MANO files. Model assets come from a pinned,
54
+ checksummed package embedded in the public worker image. The Space build fetches
55
+ the large weights from public upstream sources; Jobs need no model-repository access.
56
+ Browsing and estimating public datasets need no login. Sign in to launch HF Jobs
57
+ or access private datasets.
58
  The worker image and asset identities are verified before native inference.
59
 
60
  The measured development reference is 39.41–41.04 input FPS on RTX 5090 over ten
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": "c42cab00f33cbe53582b0ad56f384d453cbb747eef6db7ec1ba91803bc469681",
35
  "flora_vision.py": "a5a4231abf7b615164c40986df5f87047f745a23c55d86385d88f2a09e70f1e8"
36
  },
37
  "acceptance": {
@@ -99,6 +99,7 @@
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
  }
 
31
  "flora_batcher.py": "38e03e2032af8d5f3ed34980cc4d89927fe70c9742aa2ce13f4d0ccdd6fba727",
32
  "flora_speed_entry.py": "192b18d75b9d876c2a65d88de340c8cea7c8da90543d0510b5ee6865d123d524",
33
  "studio_runtime.py": "2b393bf7fafcdead638ad1cea35e49df8c6edce725f5545b76fd68e0a8fedd80",
34
+ "pipeline-version.json": "fa74c6924bcb98c81dd90cfd05ad78209b6ca89bbb0b92e1e451ca14549b6f23",
35
  "flora_vision.py": "a5a4231abf7b615164c40986df5f87047f745a23c55d86385d88f2a09e70f1e8"
36
  },
37
  "acceptance": {
 
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": "33c4ca366114b8717bb5df6ed4f412387af12dfe",
103
+ "public_asset_distribution": "Only the hand asset provisioning helper changed; all Flora and execution-engine source bytes remain identical to the accepted release."
104
  }
105
  }
hand-pipeline-catalog.json CHANGED
@@ -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": "850bb584c545ebe9bfcefdcd9b02391cba1c4638"
48
  }
 
44
  "soma": "https://huggingface.co/nvidia/SOMA-X",
45
  "runtime": "https://github.com/NVlabs/GEM-X/blob/20555befe2fbbe5b2015e1fff7ff214dc18ea9d6/ATTRIBUTIONS.md"
46
  },
47
+ "lerobot_revision": "33c4ca366114b8717bb5df6ed4f412387af12dfe"
48
  }
hand-worker-image.json CHANGED
@@ -2,13 +2,15 @@
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",
11
- "manifest_sha256": "f6fb26f2f1c2d26a4622a67c5e775701564e22fe869180df6c2803de00580c91"
 
 
12
  },
13
  "backend": {
14
  "root": "/opt/camera-adapter",
@@ -50,5 +52,13 @@
50
  "calibration_mode": "estimate-moge",
51
  "metric_accuracy_validated": false,
52
  "compute_flavor": "h200"
 
 
 
 
 
 
 
 
53
  }
54
  }
 
2
  "recipe": "egohand-soma-v3-checkpoint-overlap-v4",
3
  "build_verified": true,
4
  "image_repo": "finerobotics/annotation-hands-worker",
5
+ "image_revision": "a42cb4f1194cf843c14ad3a8b4689b7303ffc36e",
6
  "image": "hf.co/spaces/finerobotics/annotation-hands-worker",
7
+ "image_version_sha256": "f151a235a263afe5c3e3c5e7ab16ab7d15f16927edb9fb0a1666f81d9eb537d3",
8
  "assets": {
9
+ "repo": "finerobotics/annotation-hands-worker",
10
+ "repo_type": "space",
11
+ "revision": "a42cb4f1194cf843c14ad3a8b4689b7303ffc36e",
12
+ "manifest_sha256": "f6fb26f2f1c2d26a4622a67c5e775701564e22fe869180df6c2803de00580c91",
13
+ "embedded": true
14
  },
15
  "backend": {
16
  "root": "/opt/camera-adapter",
 
52
  "calibration_mode": "estimate-moge",
53
  "metric_accuracy_validated": false,
54
  "compute_flavor": "h200"
55
+ },
56
+ "distribution_validation": {
57
+ "previous_gpu_accepted_image_revision": "775ee404b1c327b6f952561f761c5be27d455122",
58
+ "model_manifest_unchanged": true,
59
+ "native_runtime_unchanged": true,
60
+ "public_source_downloads": true,
61
+ "all_model_files_verified_at_build": true,
62
+ "new_gpu_inference_run": false
63
  }
64
  }
hand_actions.py CHANGED
@@ -95,15 +95,11 @@ def catalog():
95
 
96
 
97
  def prepare_hands(selection, camera, options, token):
98
- """Validate calibration, orientation, compute and asset access before quoting."""
99
- from huggingface_hub import HfApi
100
-
101
  options = options or {}
102
  compute = options.get("compute", "h200")
103
  if compute not in COMPUTE:
104
  raise ValueError("Choose a supported HF Jobs GPU")
105
- if not token:
106
- raise ValueError("Sign in with Hugging Face to use the hand runtime assets")
107
  feature = selection["info"]["features"][camera]
108
  names = feature.get("names") or ["height", "width", "channel"]
109
  shape = dict(zip(names, feature["shape"], strict=True))
@@ -130,12 +126,6 @@ def prepare_hands(selection, camera, options, token):
130
  "Choose a source dataset whose actions have not already been replaced by hand annotations"
131
  )
132
  profile = runtime_configuration()
133
- try:
134
- HfApi(token=token).model_info(profile["assets"]["repo"], revision=profile["assets"]["revision"])
135
- except Exception as exc:
136
- raise ValueError(
137
- "Your Hugging Face login needs read access to the private EgoHand/SOMA runtime assets"
138
- ) from exc
139
  return {
140
  "compute": compute,
141
  "calibration": calibration,
 
95
 
96
 
97
  def prepare_hands(selection, camera, options, token):
98
+ """Validate calibration, orientation and compute without a model-access login."""
 
 
99
  options = options or {}
100
  compute = options.get("compute", "h200")
101
  if compute not in COMPUTE:
102
  raise ValueError("Choose a supported HF Jobs GPU")
 
 
103
  feature = selection["info"]["features"][camera]
104
  names = feature.get("names") or ["height", "width", "channel"]
105
  shape = dict(zip(names, feature["shape"], strict=True))
 
126
  "Choose a source dataset whose actions have not already been replaced by hand annotations"
127
  )
128
  profile = runtime_configuration()
 
 
 
 
 
 
129
  return {
130
  "compute": compute,
131
  "calibration": calibration,
pipeline-source.tar.gz CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:ba5218df544d3a6491b97a10cb36506bec38ffddff40ce51a8947560ff52eee4
3
- size 1869569
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:41ba290372651fd9d16c9403ec36d8adc1c90313ae89ec9cd623319340ba9663
3
+ size 1869708
pipeline-version.json CHANGED
@@ -1,6 +1,6 @@
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",
 
1
  {
2
+ "git_commit": "33c4ca366114b8717bb5df6ed4f412387af12dfe",
3
+ "sha256": "41ba290372651fd9d16c9403ec36d8adc1c90313ae89ec9cd623319340ba9663",
4
  "preset": "abc_phases_schema_with_original_window_recovery",
5
  "preset_date": "2026-09-25",
6
  "engine": "lerobot.annotations.runtime",
test_hand_actions.py CHANGED
@@ -217,13 +217,21 @@ def test_launch_uses_only_hf_gpu_image_and_private_dataset(monkeypatch):
217
  assert api.run_job.call_count == 1
218
 
219
 
220
- def test_hand_quote_requires_measured_metadata_and_access_before_dispatch(monkeypatch):
 
221
  import hand_actions
222
 
223
  camera = "observation.images.ego"
224
- calibration = dict(
225
- model="pinhole", width=64, height=48, fx=50.0, fy=51.0, cx=32.0, cy=24.0, distortion=[]
226
- )
 
 
 
 
 
 
 
227
  selection = {
228
  "episodes": [{"length": 90}],
229
  "info": {
@@ -239,20 +247,20 @@ def test_hand_quote_requires_measured_metadata_and_access_before_dispatch(monkey
239
  }
240
  },
241
  }
242
- profile = {"assets": {"repo": "private/hand-runtime", "revision": "a" * 40}}
243
  monkeypatch.setattr(hand_actions, "runtime_configuration", lambda: profile)
244
  api = Mock()
245
  monkeypatch.setattr("huggingface_hub.HfApi", lambda **kwargs: api)
246
  quote = hand_actions.prepare_hands(
247
- selection, camera, {"compute": "h200", "orientation": "dataset"}, "user-token"
248
  )
249
  assert quote["calibration"] == calibration and quote["orientation"] == "aria-gen1-cw90"
250
  assert quote["timing"]["seconds"] is None
251
- api.model_info.assert_called_once_with("private/hand-runtime", revision="a" * 40)
252
  selection["info"]["features"][camera]["info"].pop("camera.intrinsics")
253
  with pytest.raises(ValueError, match="measured"):
254
  hand_actions.prepare_hands(selection, camera, {}, "user-token")
255
- assert api.model_info.call_count == 1
256
  quote = hand_actions.prepare_hands(selection, camera, {"calibration_mode": "estimate-moge"}, "user-token")
257
  assert quote["calibration"]["method"] == "moge-v2-fov-median-v1"
258
  assert "fx" not in quote["calibration"]
 
217
  assert api.run_job.call_count == 1
218
 
219
 
220
+ @pytest.mark.parametrize("token", [None, "user-token"])
221
+ def test_hand_quote_validates_metadata_without_model_access_login(monkeypatch, token):
222
  import hand_actions
223
 
224
  camera = "observation.images.ego"
225
+ calibration = {
226
+ "model": "pinhole",
227
+ "width": 64,
228
+ "height": 48,
229
+ "fx": 50.0,
230
+ "fy": 51.0,
231
+ "cx": 32.0,
232
+ "cy": 24.0,
233
+ "distortion": [],
234
+ }
235
  selection = {
236
  "episodes": [{"length": 90}],
237
  "info": {
 
247
  }
248
  },
249
  }
250
+ profile = {"assets": {"repo": "public/hand-runtime", "repo_type": "space", "revision": "a" * 40}}
251
  monkeypatch.setattr(hand_actions, "runtime_configuration", lambda: profile)
252
  api = Mock()
253
  monkeypatch.setattr("huggingface_hub.HfApi", lambda **kwargs: api)
254
  quote = hand_actions.prepare_hands(
255
+ selection, camera, {"compute": "h200", "orientation": "dataset"}, token
256
  )
257
  assert quote["calibration"] == calibration and quote["orientation"] == "aria-gen1-cw90"
258
  assert quote["timing"]["seconds"] is None
259
+ api.model_info.assert_not_called()
260
  selection["info"]["features"][camera]["info"].pop("camera.intrinsics")
261
  with pytest.raises(ValueError, match="measured"):
262
  hand_actions.prepare_hands(selection, camera, {}, "user-token")
263
+ api.model_info.assert_not_called()
264
  quote = hand_actions.prepare_hands(selection, camera, {"calibration_mode": "estimate-moge"}, "user-token")
265
  assert quote["calibration"]["method"] == "moge-v2-fov-median-v1"
266
  assert "fx" not in quote["calibration"]