fport commited on
Commit
128a508
·
verified ·
1 Parent(s): 15c591f

Load the adapter on CPU, ZeroGPU has no GPU at import time

Browse files
Files changed (1) hide show
  1. app.py +15 -11
app.py CHANGED
@@ -46,25 +46,29 @@ TR_WORDS = (" bir ", " için ", " ve ", " bu ", " ile ", " var ", " yok ", " ama
46
 
47
  source = MODEL_ID or BASE_ID
48
  tokenizer = AutoTokenizer.from_pretrained(source)
49
- # device_map="cuda" streams the shards straight onto the device. Two things go
50
- # wrong without it on ZeroGPU: "auto" sees no reserved GPU at import time and
51
- # offloads to disk, and loading onto CPU first needs ~16 GB of RAM the Space does
52
- # not have, so the process is killed with no traceback.
 
53
  model = AutoModelForCausalLM.from_pretrained(
54
- source,
55
- dtype=torch.bfloat16,
56
- device_map="cuda" if torch.cuda.is_available() else None,
57
- attn_implementation="sdpa",
58
  )
59
  if ADAPTER_ID and not MODEL_ID:
60
  # peft's own API rather than transformers' model.load_adapter(): that bridge
61
  # imports private peft symbols and breaks whenever the two versions drift.
62
- # The wrapper is left in place — merge_and_unload() would run real matmuls at
63
- # import time, and no GPU is attached until a @spaces.GPU call.
 
 
 
64
  from peft import PeftModel
65
 
66
- model = PeftModel.from_pretrained(model, ADAPTER_ID)
 
67
  model.eval()
 
 
68
 
69
  LOADED = MODEL_ID or (f"{BASE_ID} + {ADAPTER_ID}" if ADAPTER_ID else BASE_ID)
70
 
 
46
 
47
  source = MODEL_ID or BASE_ID
48
  tokenizer = AutoTokenizer.from_pretrained(source)
49
+ # Everything below stays on CPU until the very last line. On ZeroGPU no real GPU
50
+ # exists at import time: device_map="auto" offloads to disk, and device_map="cuda"
51
+ # makes peft ask safetensors to read straight onto the device, which the spaces
52
+ # patching layer cannot fake ("No CUDA GPUs are available"). The final .to("cuda")
53
+ # is the one call spaces *does* intercept, so that is the only device move here.
54
  model = AutoModelForCausalLM.from_pretrained(
55
+ source, dtype=torch.bfloat16, attn_implementation="sdpa"
 
 
 
56
  )
57
  if ADAPTER_ID and not MODEL_ID:
58
  # peft's own API rather than transformers' model.load_adapter(): that bridge
59
  # imports private peft symbols and breaks whenever the two versions drift.
60
+ # torch_device is not optional here. peft defaults it to infer_device(), which
61
+ # answers "cuda" because the spaces layer reports a GPU that does not exist
62
+ # yet, and safetensors then fails reading the adapter straight onto it.
63
+ # Merging on CPU is plain matmul, no CUDA, and it drops the LoRA wrapper so
64
+ # generation runs at base speed.
65
  from peft import PeftModel
66
 
67
+ model = PeftModel.from_pretrained(model, ADAPTER_ID, torch_device="cpu")
68
+ model = model.merge_and_unload()
69
  model.eval()
70
+ if torch.cuda.is_available():
71
+ model = model.to("cuda")
72
 
73
  LOADED = MODEL_ID or (f"{BASE_ID} + {ADAPTER_ID}" if ADAPTER_ID else BASE_ID)
74