goumsss Claude Sonnet 4.6 commited on
Commit
291f11c
·
1 Parent(s): 1f6e488

Fix HF Spaces startup: restore spaces import + clear stale cache placeholders

Browse files

- import spaces at top level (was missing, caused NameError on @spaces.GPU)
- restore sys.unraisablehook for asyncio GC bug suppression
- remove stale placeholder files before snapshot_download to prevent
[Errno 20] Not a directory errors on re-deploy

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

Files changed (1) hide show
  1. image_generator.py +22 -11
image_generator.py CHANGED
@@ -20,39 +20,50 @@ if not hasattr(torch, "xpu"):
20
 
21
  IS_HF_SPACE = os.environ.get("SPACE_ID") is not None
22
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  # ---------------------------------------------------------------------------
24
  # Persistent storage cache — survives sleep/restart on HF Spaces
25
  # ---------------------------------------------------------------------------
26
- # Enable in Space Settings → Storage (mount at /data).
27
- # HF_HOME env var can also be set manually in Space Settings → Variables,
28
- # but this block handles it automatically when /data is present.
29
  if IS_HF_SPACE and os.path.isdir("/data"):
30
  _cache_dir = "/data/hf_cache"
31
  os.makedirs(_cache_dir, exist_ok=True)
32
  os.environ.setdefault("HF_HOME", _cache_dir)
33
  print(f"Persistent cache active → {_cache_dir}")
34
 
35
- # Pre-download model at startup so the first @spaces.GPU call is fast.
36
- # /data survives sleep/restart download only happens once.
37
- import threading, asyncio
38
- from huggingface_hub import snapshot_download
39
-
40
- _hf_token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN")
41
- _model_id = "black-forest-labs/FLUX.2-klein-4B"
42
  _model_cache = os.path.join(_cache_dir, "models--black-forest-labs--FLUX.2-klein-4B")
 
 
 
 
 
43
 
44
  if os.path.isdir(_model_cache):
45
  print(f"✅ FLUX.2-klein-4B already cached — skipping download")
46
  else:
47
  print(f"Downloading FLUX.2-klein-4B to persistent cache…")
48
  try:
 
 
49
  _result = {}
50
  def _download():
51
  loop = asyncio.new_event_loop()
52
  asyncio.set_event_loop(loop)
53
  try:
54
  snapshot_download(
55
- _model_id,
56
  cache_dir=_cache_dir,
57
  token=_hf_token,
58
  ignore_patterns=["*.msgpack", "*.h5", "flax_model*"],
 
20
 
21
  IS_HF_SPACE = os.environ.get("SPACE_ID") is not None
22
 
23
+ if IS_HF_SPACE:
24
+ import spaces
25
+ import sys, threading, asyncio
26
+
27
+ # Suppress Python 3.10 asyncio GC bug (Invalid file descriptor: -1)
28
+ _orig_unraisable = sys.unraisablehook
29
+ def _unraisable_hook(args):
30
+ if args.exc_type is ValueError and "Invalid file descriptor" in str(args.exc_value):
31
+ return
32
+ _orig_unraisable(args)
33
+ sys.unraisablehook = _unraisable_hook
34
+
35
  # ---------------------------------------------------------------------------
36
  # Persistent storage cache — survives sleep/restart on HF Spaces
37
  # ---------------------------------------------------------------------------
 
 
 
38
  if IS_HF_SPACE and os.path.isdir("/data"):
39
  _cache_dir = "/data/hf_cache"
40
  os.makedirs(_cache_dir, exist_ok=True)
41
  os.environ.setdefault("HF_HOME", _cache_dir)
42
  print(f"Persistent cache active → {_cache_dir}")
43
 
44
+ # Clean up any stale placeholder files left by a previous failed download
45
+ # (huggingface_hub creates placeholder files that block re-download)
 
 
 
 
 
46
  _model_cache = os.path.join(_cache_dir, "models--black-forest-labs--FLUX.2-klein-4B")
47
+ for _placeholder in [_model_cache, f"{_model_cache}/blobs", f"{_model_cache}/refs",
48
+ f"{_model_cache}/snapshots"]:
49
+ if os.path.isfile(_placeholder):
50
+ os.remove(_placeholder)
51
+ print(f"Removed stale placeholder: {_placeholder}")
52
 
53
  if os.path.isdir(_model_cache):
54
  print(f"✅ FLUX.2-klein-4B already cached — skipping download")
55
  else:
56
  print(f"Downloading FLUX.2-klein-4B to persistent cache…")
57
  try:
58
+ from huggingface_hub import snapshot_download
59
+ _hf_token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN")
60
  _result = {}
61
  def _download():
62
  loop = asyncio.new_event_loop()
63
  asyncio.set_event_loop(loop)
64
  try:
65
  snapshot_download(
66
+ "black-forest-labs/FLUX.2-klein-4B",
67
  cache_dir=_cache_dir,
68
  token=_hf_token,
69
  ignore_patterns=["*.msgpack", "*.h5", "flax_model*"],