Fix adapter loading: use set_peft_model_state_dict (plain load_state_dict silently no-opped the LoRA)
Browse files
app.py
CHANGED
|
@@ -12,7 +12,7 @@ import gradio as gr
|
|
| 12 |
import safetensors.torch
|
| 13 |
from huggingface_hub import hf_hub_download
|
| 14 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 15 |
-
from peft import PeftModel, LoraConfig
|
| 16 |
|
| 17 |
# ZeroGPU decorator if available; no-op fallback so the app also runs locally
|
| 18 |
try:
|
|
@@ -58,11 +58,20 @@ _model = PeftModel(_base, _peft_config)
|
|
| 58 |
|
| 59 |
_weights_path = hf_hub_download(ADAPTER, "adapter_model.safetensors")
|
| 60 |
_adapter_weights = safetensors.torch.load_file(_weights_path, device="cpu")
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
_model.eval()
|
| 63 |
|
| 64 |
|
| 65 |
-
@GPU(duration=
|
| 66 |
def translate(text: str) -> str:
|
| 67 |
"""Tokenize, generate, decode — the GPU-heavy work lives here."""
|
| 68 |
if not text.strip():
|
|
|
|
| 12 |
import safetensors.torch
|
| 13 |
from huggingface_hub import hf_hub_download
|
| 14 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 15 |
+
from peft import PeftModel, LoraConfig, set_peft_model_state_dict
|
| 16 |
|
| 17 |
# ZeroGPU decorator if available; no-op fallback so the app also runs locally
|
| 18 |
try:
|
|
|
|
| 58 |
|
| 59 |
_weights_path = hf_hub_download(ADAPTER, "adapter_model.safetensors")
|
| 60 |
_adapter_weights = safetensors.torch.load_file(_weights_path, device="cpu")
|
| 61 |
+
|
| 62 |
+
# Use PEFT's own loader, NOT _model.load_state_dict(). The safetensors keys are
|
| 63 |
+
# named `....lora_A.weight`, but the PeftModel expects the adapter name baked in
|
| 64 |
+
# (`....lora_A.default.weight`). A plain load_state_dict(strict=False) matches
|
| 65 |
+
# none of them and silently leaves lora_B at its zero-init — i.e. the adapter
|
| 66 |
+
# has zero effect. set_peft_model_state_dict performs the key remapping.
|
| 67 |
+
_load_result = set_peft_model_state_dict(_model, _adapter_weights)
|
| 68 |
+
assert not _load_result.unexpected_keys, (
|
| 69 |
+
f"Adapter weights did not load: {_load_result.unexpected_keys[:5]}"
|
| 70 |
+
)
|
| 71 |
_model.eval()
|
| 72 |
|
| 73 |
|
| 74 |
+
@GPU(duration=20)
|
| 75 |
def translate(text: str) -> str:
|
| 76 |
"""Tokenize, generate, decode — the GPU-heavy work lives here."""
|
| 77 |
if not text.strip():
|