0merle0 Claude Sonnet 4.6 commited on
Commit
a2d7113
·
1 Parent(s): d1e3d49

Pre-download protenix weights from HF Hub; ByteDance CDN is geo-blocked

Browse files

protenix.tos-cn-beijing.volces.com returns 403 from HF Space IPs.
TMF001/protenix-v2-weights on HF Hub has the same checkpoint (1.77 GB).
Download via hf_hub_download before running inference, skip if already
present. PROTENIX_ROOT_DIR controls where protenix looks for checkpoints.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +33 -0
app.py CHANGED
@@ -398,6 +398,34 @@ def toggle_secondary_structure(choice):
398
  PROTENIX_MODEL = os.environ.get("PROTENIX_MODEL", "protenix-v2")
399
  PROTENIX_TIMEOUT = int(os.environ.get("PROTENIX_TIMEOUT", "1200")) # first run: JIT compile + weight download
400
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  # pLDDT confidence colour bands (AlphaFold convention, B-factor scale 0-100)
402
  _PLDDT_COLORS = [
403
  (90, "#0053D6"), # very high — dark blue
@@ -496,6 +524,11 @@ def fold_with_protenix(sequence, msa_file, model_name):
496
  output_dir = work_dir / "output"
497
  output_dir.mkdir()
498
 
 
 
 
 
 
499
  # Invoke protenix via Python directly — bypasses the entry-point binary
500
  # which is sometimes not created during startup installs.
501
  # Equivalent to: protenix pred -i <input> -o <output> -n <model>
 
398
  PROTENIX_MODEL = os.environ.get("PROTENIX_MODEL", "protenix-v2")
399
  PROTENIX_TIMEOUT = int(os.environ.get("PROTENIX_TIMEOUT", "1200")) # first run: JIT compile + weight download
400
 
401
+ # Checkpoint directory protenix uses: $PROTENIX_ROOT_DIR/checkpoint (default ~/checkpoint)
402
+ _PROTENIX_CKPT_DIR = Path(os.environ.get("PROTENIX_ROOT_DIR", Path.home())) / "checkpoint"
403
+
404
+ # Map of model_name → HF Hub repo/file that mirrors the ByteDance CDN
405
+ # (CDN protenix.tos-cn-beijing.volces.com is geo-blocked from HF Spaces)
406
+ _HF_WEIGHT_SOURCES = {
407
+ "protenix-v2": ("TMF001/protenix-v2-weights", "protenix-v2.pt"),
408
+ }
409
+
410
+ def _ensure_protenix_weights(model_name: str) -> str | None:
411
+ """Download model weights from HF Hub if not already present. Returns error str or None."""
412
+ ckpt_path = _PROTENIX_CKPT_DIR / f"{model_name}.pt"
413
+ if ckpt_path.exists():
414
+ return None
415
+ if model_name not in _HF_WEIGHT_SOURCES:
416
+ return f"No HF Hub mirror known for model '{model_name}'; ByteDance CDN is geo-blocked from HF Spaces"
417
+ repo_id, filename = _HF_WEIGHT_SOURCES[model_name]
418
+ print(f"[protenix-weights] Downloading {filename} from {repo_id} …")
419
+ try:
420
+ from huggingface_hub import hf_hub_download
421
+ _PROTENIX_CKPT_DIR.mkdir(parents=True, exist_ok=True)
422
+ tmp = hf_hub_download(repo_id=repo_id, filename=filename)
423
+ shutil.copy(tmp, ckpt_path)
424
+ print(f"[protenix-weights] Saved to {ckpt_path}")
425
+ return None
426
+ except Exception as e:
427
+ return f"Weight download failed: {e}"
428
+
429
  # pLDDT confidence colour bands (AlphaFold convention, B-factor scale 0-100)
430
  _PLDDT_COLORS = [
431
  (90, "#0053D6"), # very high — dark blue
 
524
  output_dir = work_dir / "output"
525
  output_dir.mkdir()
526
 
527
+ # Ensure model weights are present (ByteDance CDN is geo-blocked; use HF Hub mirror)
528
+ weight_err = _ensure_protenix_weights(model_name)
529
+ if weight_err:
530
+ return None, None, None, f"Weight download error: {weight_err}"
531
+
532
  # Invoke protenix via Python directly — bypasses the entry-point binary
533
  # which is sometimes not created during startup installs.
534
  # Equivalent to: protenix pred -i <input> -o <output> -n <model>