qqyule commited on
Commit
535bb9d
·
verified ·
1 Parent(s): e20e3d9

Add explicit ZeroGPU spaces dependency

Browse files
docs/03-dev-schedule.md CHANGED
@@ -52,12 +52,13 @@
52
  - [x] 做 JSON repair
53
  - [x] 加 example gallery
54
  - [x] 新增 Space VLM 验证脚本
 
55
  - [ ] 缓存示例输出
56
- - [ ] Space 1x L4 真实图片验证(2026-06-06 已尝试,因 HF `402 Payment Required` 阻塞,已回滚 mock-safe)
57
 
58
  验收:上传杯子/键盘/鞋子,模型能识别物品并提取外观特征。
59
 
60
- 完成记录:MiniCPM-V 2.6 已作为可配置 vision backend 接入,默认仍是 mock vision;`scripts/check_space_vlm.py` 已可用三张临时公开图片验证 Space 端 mug/keyboard/shoe。2026-06-06 已尝试切到 L4,但 Hugging Face 返回 `402 Payment Required`,需要组织 billing/pre-paid credits;随后已执行 mock-safe rollback。文本生成已接入可选 llama.cpp runtime wiring,但最终 GGUF 模型仍未选择/下载。
61
 
62
  ---
63
 
 
52
  - [x] 做 JSON repair
53
  - [x] 加 example gallery
54
  - [x] 新增 Space VLM 验证脚本
55
+ - [x] 新增 ZeroGPU 兼容装饰器
56
  - [ ] 缓存示例输出
57
+ - [ ] Space 真实图片验证(L4 因 HF `402 Payment Required` 阻塞;ZeroGPU 已到 `RUNNING` 但验证请求长时间无返回,已回滚 mock-safe)
58
 
59
  验收:上传杯子/键盘/鞋子,模型能识别物品并提取外观特征。
60
 
61
+ 完成记录:MiniCPM-V 2.6 已作为可配置 vision backend 接入,默认仍是 mock vision;`scripts/check_space_vlm.py` 已可用三张临时公开图片验证 Space 端 mug/keyboard/shoe。2026-06-06 已尝试切到 L4,但 Hugging Face 返回 `402 Payment Required`,需要组织 billing/pre-paid credits;随后尝试 ZeroGPU,Space 可到 `RUNNING`,但验证请求长时间无返回。两次尝试后均已执行 mock-safe rollback。文本生成已接入可选 llama.cpp runtime wiring,但最终 GGUF 模型仍未选择/下载。
62
 
63
  ---
64
 
docs/DEVELOPMENT_STATUS.md CHANGED
@@ -18,11 +18,14 @@ Last updated: 2026-06-06
18
  - Space VLM validation tooling:
19
  - `scripts/check_space_vlm.py`
20
  - failed L4 validation report at `docs/SPACE_VLM_REPORT.md`
 
 
 
21
  - Local tests and initial acceptance currently pass.
22
 
23
  ## Not Completed
24
 
25
- - Hosted Space 1x L4 MiniCPM-V validation with real public mug/keyboard/shoe images. Attempted on 2026-06-06 and blocked by Hugging Face `402 Payment Required` for paid hardware; mock-safe rollback was applied.
26
  - Stable example output caching for real VLM demos.
27
  - Real GGUF model selection, download/configuration outside Git, and `TEXT_MODEL_PATH` smoke test.
28
  - Final text model parameter count documentation.
@@ -41,7 +44,7 @@ Last updated: 2026-06-06
41
 
42
  ## Next Recommended Gate
43
 
44
- Unblock Hugging Face paid hardware access or choose another available GPU option, then rerun the hosted Space VLM validation:
45
 
46
  ```bash
47
  .venv/bin/python -B scripts/check_space_vlm.py \
 
18
  - Space VLM validation tooling:
19
  - `scripts/check_space_vlm.py`
20
  - failed L4 validation report at `docs/SPACE_VLM_REPORT.md`
21
+ - ZeroGPU compatibility:
22
+ - optional `src/utils/zero_gpu.py`
23
+ - Gradio generation callback wrapped with `@zero_gpu(duration=180)`
24
  - Local tests and initial acceptance currently pass.
25
 
26
  ## Not Completed
27
 
28
+ - Hosted Space MiniCPM-V validation with real public mug/keyboard/shoe images. Paid L4 was blocked by Hugging Face `402 Payment Required`; ZeroGPU reached `RUNNING` but the validation request did not return within the practical waiting window; mock-safe rollback was applied.
29
  - Stable example output caching for real VLM demos.
30
  - Real GGUF model selection, download/configuration outside Git, and `TEXT_MODEL_PATH` smoke test.
31
  - Final text model parameter count documentation.
 
44
 
45
  ## Next Recommended Gate
46
 
47
+ Unblock Hugging Face paid hardware access, or debug the ZeroGPU queue/request path with a smaller probe model, then rerun the hosted Space VLM validation:
48
 
49
  ```bash
50
  .venv/bin/python -B scripts/check_space_vlm.py \
docs/EXTERNAL_SETUP.md CHANGED
@@ -98,7 +98,10 @@ The validation script must not print Hugging Face tokens. It uses three temporar
98
  - `--configure-space` was run for `l4x1`.
99
  - Hugging Face returned `402 Payment Required` for paid hardware on the `build-small-hackathon` organization.
100
  - Mock-safe rollback was run afterward.
101
- - Next unblock step: enable billing/pre-paid credits or choose an available free GPU option before rerunning validation.
 
 
 
102
 
103
  ## Safety Notes
104
 
 
98
  - `--configure-space` was run for `l4x1`.
99
  - Hugging Face returned `402 Payment Required` for paid hardware on the `build-small-hackathon` organization.
100
  - Mock-safe rollback was run afterward.
101
+ - ZeroGPU compatibility was added and uploaded to the Space.
102
+ - `--configure-space --hardware zero-a10g` reached `RUNNING`, and `/config` was reachable, but the validation request did not return within the practical waiting window.
103
+ - Mock-safe rollback was run afterward and confirmed at `cpu-basic`.
104
+ - Next unblock step: enable billing/pre-paid credits, or debug ZeroGPU with a smaller probe before retrying full MiniCPM-V validation.
105
 
106
  ## Safety Notes
107
 
docs/SPACE_VLM_REPORT.md CHANGED
@@ -1,42 +1,50 @@
1
  # Space VLM Validation Report
2
 
3
- - Generated at: 2026-06-06 04:25 UTC
4
  - Space URL: https://huggingface.co/spaces/build-small-hackathon/ObjectverseDiary
5
  - Space repo: `build-small-hackathon/ObjectverseDiary`
6
  - Overall status: FAIL
7
  - Vision backend expected: `minicpm-v`
8
  - Text backend expected: `mock`
9
 
10
- ## Space Configuration
11
 
12
  - Requested configuration:
13
  - `hardware`: `l4x1`
14
  - `OBJECTVERSE_VISION_BACKEND`: `minicpm-v`
15
  - `VISION_MODEL_ID`: `openbmb/MiniCPM-V-2_6`
16
  - `OBJECTVERSE_TEXT_BACKEND`: `mock`
 
 
 
 
17
 
18
- - Rollback configuration applied:
19
- - `hardware`: `cpu-basic`
20
- - `OBJECTVERSE_VISION_BACKEND`: `mock`
21
- - `OBJECTVERSE_TEXT_BACKEND`: `mock`
22
-
23
- ## Configuration Error
24
 
25
- - Error: `HfHubHTTPError: 402 Payment Required`
26
- - Meaning: Hugging Face requires pre-paid credits or billing access for the `build-small-hackathon` organization before the Space can use paid `l4x1` hardware.
27
- - Impact: Remote MiniCPM-V validation did not run. No mug / keyboard / shoe image inference results were produced.
28
- - Safety outcome: Mock-safe rollback was run after the failed hardware request.
 
 
 
 
 
 
 
 
29
  - Post-rollback runtime check: Space is `RUNNING` with `hardware=cpu-basic` and `requested_hardware=cpu-basic`.
30
 
31
  ## Results
32
 
33
- - Coffee mug: NOT RUN
34
- - Computer keyboard: NOT RUN
35
- - Running shoe: NOT RUN
36
 
37
  ## Notes
38
 
39
  - Test images are temporary public Wikimedia Commons assets and are not committed.
40
  - Text generation remains mock during this validation plan.
41
  - No tokens, secrets, or private file paths are recorded in this report.
42
- - Next unblock step: enable billing/pre-paid credits for the Hugging Face organization or choose an available free GPU option, then rerun `scripts/check_space_vlm.py`.
 
 
1
  # Space VLM Validation Report
2
 
3
+ - Generated at: 2026-06-06 04:55 UTC
4
  - Space URL: https://huggingface.co/spaces/build-small-hackathon/ObjectverseDiary
5
  - Space repo: `build-small-hackathon/ObjectverseDiary`
6
  - Overall status: FAIL
7
  - Vision backend expected: `minicpm-v`
8
  - Text backend expected: `mock`
9
 
10
+ ## Attempt 1: Paid L4
11
 
12
  - Requested configuration:
13
  - `hardware`: `l4x1`
14
  - `OBJECTVERSE_VISION_BACKEND`: `minicpm-v`
15
  - `VISION_MODEL_ID`: `openbmb/MiniCPM-V-2_6`
16
  - `OBJECTVERSE_TEXT_BACKEND`: `mock`
17
+ - Result: failed before validation.
18
+ - Error: `HfHubHTTPError: 402 Payment Required`
19
+ - Meaning: Hugging Face requires billing or pre-paid credits for the `build-small-hackathon` organization before it can use paid `l4x1` hardware.
20
+ - Safety outcome: mock-safe rollback was run after the failed hardware request.
21
 
22
+ ## Attempt 2: ZeroGPU
 
 
 
 
 
23
 
24
+ - Local compatibility update:
25
+ - Added optional `@spaces.GPU` support through `src/utils/zero_gpu.py`.
26
+ - Wrapped the Gradio generation callback with `@zero_gpu(duration=180)`.
27
+ - Uploaded the ZeroGPU-compatible app code to the Space.
28
+ - Requested configuration:
29
+ - `hardware`: `zero-a10g`
30
+ - `OBJECTVERSE_VISION_BACKEND`: `minicpm-v`
31
+ - `VISION_MODEL_ID`: `openbmb/MiniCPM-V-2_6`
32
+ - `OBJECTVERSE_TEXT_BACKEND`: `mock`
33
+ - Result: Space reached `RUNNING` on `zero-a10g`, and `/config` was reachable, but the validation request did not return within the practical waiting window.
34
+ - Observed logs: app startup only; no model load or inference error was shown in the fetched Space logs.
35
+ - Safety outcome: the stuck local validation process was terminated, then mock-safe rollback was run.
36
  - Post-rollback runtime check: Space is `RUNNING` with `hardware=cpu-basic` and `requested_hardware=cpu-basic`.
37
 
38
  ## Results
39
 
40
+ - Coffee mug: NOT RUN to completion
41
+ - Computer keyboard: NOT RUN to completion
42
+ - Running shoe: NOT RUN to completion
43
 
44
  ## Notes
45
 
46
  - Test images are temporary public Wikimedia Commons assets and are not committed.
47
  - Text generation remains mock during this validation plan.
48
  - No tokens, secrets, or private file paths are recorded in this report.
49
+ - The validation script now has configuration-failure reporting, Gradio config retry, rollback-on-validation-failure, and per-prediction timeout protection.
50
+ - Next unblock step: enable billing/pre-paid credits for the Hugging Face organization, or debug the ZeroGPU queue/request path with a smaller VLM or a minimal ZeroGPU probe before retrying full MiniCPM-V validation.
docs/SUBMISSION_GUIDE.md CHANGED
@@ -18,7 +18,7 @@
18
  - Runtime boundary: `docs/RUNTIME.md`
19
  - Dataset plan and preview workflow: `docs/DATASET.md`
20
  - External setup checklist: `docs/EXTERNAL_SETUP.md`
21
- - Space VLM validation report: `docs/SPACE_VLM_REPORT.md` currently failed because `l4x1` hardware returned `402 Payment Required`.
22
  - Public mock traces: `data/traces/samples/`
23
  - Optional llama.cpp runtime wiring: `src/models/llama_cpp_runner.py`
24
 
@@ -31,7 +31,7 @@
31
 
32
  ## Not Completed Yet
33
 
34
- - Hosted Space L4 MiniCPM-V validation for mug, keyboard, and shoe; attempted and blocked by Hugging Face paid hardware billing.
35
  - Real GGUF `TEXT_MODEL_PATH` smoke test and final text model parameter count.
36
  - Real model traces, curated dataset, LoRA training, model/dataset publishing.
37
  - Field Notes article, demo video, social post, final submission package.
@@ -39,7 +39,7 @@
39
  ## Final Checks
40
 
41
  - [ ] Space is under the official organization.
42
- - [ ] Space MiniCPM-V validation passes for mug, keyboard, and shoe. Current status: blocked by paid hardware billing.
43
  - [ ] Demo video is under 2 minutes.
44
  - [ ] README includes model parameter counts.
45
  - [ ] No commercial cloud AI APIs are used.
 
18
  - Runtime boundary: `docs/RUNTIME.md`
19
  - Dataset plan and preview workflow: `docs/DATASET.md`
20
  - External setup checklist: `docs/EXTERNAL_SETUP.md`
21
+ - Space VLM validation report: `docs/SPACE_VLM_REPORT.md` currently failed because `l4x1` hardware returned `402 Payment Required`; ZeroGPU reached `RUNNING` but the validation request did not return.
22
  - Public mock traces: `data/traces/samples/`
23
  - Optional llama.cpp runtime wiring: `src/models/llama_cpp_runner.py`
24
 
 
31
 
32
  ## Not Completed Yet
33
 
34
+ - Hosted Space MiniCPM-V validation for mug, keyboard, and shoe; L4 is blocked by Hugging Face paid hardware billing, and ZeroGPU needs further debugging.
35
  - Real GGUF `TEXT_MODEL_PATH` smoke test and final text model parameter count.
36
  - Real model traces, curated dataset, LoRA training, model/dataset publishing.
37
  - Field Notes article, demo video, social post, final submission package.
 
39
  ## Final Checks
40
 
41
  - [ ] Space is under the official organization.
42
+ - [ ] Space MiniCPM-V validation passes for mug, keyboard, and shoe. Current status: L4 blocked by paid hardware billing; ZeroGPU request path unresolved.
43
  - [ ] Demo video is under 2 minutes.
44
  - [ ] README includes model parameter counts.
45
  - [ ] No commercial cloud AI APIs are used.
pyproject.toml CHANGED
@@ -12,6 +12,7 @@ dependencies = [
12
  "Pillow",
13
  "sentencepiece",
14
  "accelerate",
 
15
  ]
16
 
17
  [tool.objectverse-diary]
 
12
  "Pillow",
13
  "sentencepiece",
14
  "accelerate",
15
+ "spaces>=0.30",
16
  ]
17
 
18
  [tool.objectverse-diary]
requirements.txt CHANGED
@@ -6,3 +6,4 @@ transformers>=4.40,<5
6
  Pillow
7
  sentencepiece
8
  accelerate
 
 
6
  Pillow
7
  sentencepiece
8
  accelerate
9
+ spaces>=0.30
scripts/check_space_vlm.py CHANGED
@@ -4,6 +4,7 @@ from __future__ import annotations
4
 
5
  import argparse
6
  import json
 
7
  import sys
8
  import time
9
  import urllib.request
@@ -28,6 +29,7 @@ DEFAULT_HARDWARE = "l4x1"
28
  MOCK_SAFE_HARDWARE = "cpu-basic"
29
  GENERATE_API_NAME = "/generate_object_file"
30
  REQUEST_TIMEOUT_SECONDS = 45
 
31
 
32
  SPACE_VARIABLES = {
33
  "OBJECTVERSE_VISION_BACKEND": "minicpm-v",
@@ -181,11 +183,11 @@ def run_space_validation(
181
  timeout_seconds: int = 900,
182
  assets: list[ValidationAsset] | None = None,
183
  ) -> list[ValidationResult]:
184
- from gradio_client import Client, handle_file
185
 
186
  selected_assets = assets or TEST_ASSETS
187
  paths = download_validation_assets(asset_dir, selected_assets)
188
- client = Client(space_url, verbose=False)
189
  results: list[ValidationResult] = []
190
  started = time.monotonic()
191
  for asset in selected_assets:
@@ -193,11 +195,12 @@ def run_space_validation(
193
  if remaining <= 0:
194
  raise TimeoutError(f"Validation exceeded timeout of {timeout_seconds}s")
195
  try:
196
- response = client.predict(
 
197
  handle_file(str(paths[asset.key])),
198
  asset.description,
199
  asset.mode,
200
- api_name=GENERATE_API_NAME,
201
  )
202
  results.append(validate_prediction(asset, paths[asset.key], response))
203
  except Exception as exc:
@@ -221,6 +224,47 @@ def run_space_validation(
221
  return results
222
 
223
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  def validate_prediction(
225
  asset: ValidationAsset,
226
  image_path: Path,
@@ -450,11 +494,22 @@ def main() -> None:
450
 
451
  results: list[ValidationResult] = []
452
  if not args.skip_validation and not configuration_error:
453
- results = run_space_validation(
454
- space_url=args.space_url,
455
- asset_dir=args.asset_dir,
456
- timeout_seconds=args.timeout_seconds,
457
- )
 
 
 
 
 
 
 
 
 
 
 
458
 
459
  if args.rollback_to_mock and rollback is None:
460
  rollback = rollback_space_to_mock(repo_id)
 
4
 
5
  import argparse
6
  import json
7
+ import signal
8
  import sys
9
  import time
10
  import urllib.request
 
29
  MOCK_SAFE_HARDWARE = "cpu-basic"
30
  GENERATE_API_NAME = "/generate_object_file"
31
  REQUEST_TIMEOUT_SECONDS = 45
32
+ PREDICTION_TIMEOUT_SECONDS = 360
33
 
34
  SPACE_VARIABLES = {
35
  "OBJECTVERSE_VISION_BACKEND": "minicpm-v",
 
183
  timeout_seconds: int = 900,
184
  assets: list[ValidationAsset] | None = None,
185
  ) -> list[ValidationResult]:
186
+ from gradio_client import handle_file
187
 
188
  selected_assets = assets or TEST_ASSETS
189
  paths = download_validation_assets(asset_dir, selected_assets)
190
+ client = _build_gradio_client(space_url, timeout_seconds=timeout_seconds)
191
  results: list[ValidationResult] = []
192
  started = time.monotonic()
193
  for asset in selected_assets:
 
195
  if remaining <= 0:
196
  raise TimeoutError(f"Validation exceeded timeout of {timeout_seconds}s")
197
  try:
198
+ response = _predict_with_timeout(
199
+ client,
200
  handle_file(str(paths[asset.key])),
201
  asset.description,
202
  asset.mode,
203
+ timeout_seconds=min(PREDICTION_TIMEOUT_SECONDS, remaining),
204
  )
205
  results.append(validate_prediction(asset, paths[asset.key], response))
206
  except Exception as exc:
 
224
  return results
225
 
226
 
227
+ def _predict_with_timeout(
228
+ client: Any,
229
+ image: Any,
230
+ description: str,
231
+ mode: str,
232
+ *,
233
+ timeout_seconds: int,
234
+ ) -> Any:
235
+ def _raise_timeout(_signum: int, _frame: Any) -> None:
236
+ raise TimeoutError(f"Gradio prediction did not finish within {timeout_seconds}s")
237
+
238
+ previous_handler = signal.signal(signal.SIGALRM, _raise_timeout)
239
+ signal.alarm(max(1, timeout_seconds))
240
+ try:
241
+ return client.predict(
242
+ image,
243
+ description,
244
+ mode,
245
+ api_name=GENERATE_API_NAME,
246
+ )
247
+ finally:
248
+ signal.alarm(0)
249
+ signal.signal(signal.SIGALRM, previous_handler)
250
+
251
+
252
+ def _build_gradio_client(space_url: str, *, timeout_seconds: int) -> Any:
253
+ from gradio_client import Client
254
+
255
+ deadline = time.monotonic() + timeout_seconds
256
+ last_error: Exception | None = None
257
+ while time.monotonic() < deadline:
258
+ try:
259
+ return Client(space_url, verbose=False)
260
+ except Exception as exc:
261
+ last_error = exc
262
+ time.sleep(10)
263
+ if last_error is None:
264
+ raise TimeoutError(f"Could not create Gradio client for {space_url}")
265
+ raise TimeoutError(f"Could not fetch Gradio config for {space_url}: {type(last_error).__name__}: {last_error}")
266
+
267
+
268
  def validate_prediction(
269
  asset: ValidationAsset,
270
  image_path: Path,
 
494
 
495
  results: list[ValidationResult] = []
496
  if not args.skip_validation and not configuration_error:
497
+ try:
498
+ results = run_space_validation(
499
+ space_url=args.space_url,
500
+ asset_dir=args.asset_dir,
501
+ timeout_seconds=args.timeout_seconds,
502
+ )
503
+ except Exception as exc:
504
+ configuration_error = f"{type(exc).__name__}: {exc}"
505
+ if args.rollback_to_mock and rollback is None:
506
+ try:
507
+ rollback = rollback_space_to_mock(repo_id)
508
+ except Exception as rollback_exc:
509
+ configuration_error = (
510
+ f"{configuration_error}; rollback failed with "
511
+ f"{type(rollback_exc).__name__}: {rollback_exc}"
512
+ )
513
 
514
  if args.rollback_to_mock and rollback is None:
515
  rollback = rollback_space_to_mock(repo_id)