Spaces:
Sleeping
Sleeping
Commit
·
581b6a9
1
Parent(s):
eb6ce9a
Update app.py
Browse files
app.py
CHANGED
|
@@ -34,20 +34,50 @@ def load_model_from_pickle(pickle_path="best_model.pkl"):
|
|
| 34 |
# Check if file exists
|
| 35 |
if not os.path.exists(pickle_path):
|
| 36 |
return f"❌ Model file not found: {pickle_path}\n\nPlease ensure best_model.pkl is uploaded to the HuggingFace Space."
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
try:
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
| 42 |
model_package = torch.load(pickle_path, map_location=torch.device('cpu'))
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
|
|
|
| 51 |
# Handle a few common package shapes.
|
| 52 |
if isinstance(model_package, dict):
|
| 53 |
loaded_model = model_package.get('model', None)
|
|
@@ -100,18 +130,9 @@ def load_model_from_pickle(pickle_path="best_model.pkl"):
|
|
| 100 |
return config_info
|
| 101 |
|
| 102 |
except Exception as e:
|
| 103 |
-
#
|
| 104 |
err = str(e)
|
| 105 |
-
|
| 106 |
-
return ("❌ Error loading model: The file was saved for a GPU device but this runtime has no CUDA available. "
|
| 107 |
-
"The loader attempted to remap tensors to CPU, but loading still failed.\n\n"
|
| 108 |
-
"Try re-saving the model on a CPU by running:\n"
|
| 109 |
-
"```python\n"
|
| 110 |
-
"model.to('cpu')\n"
|
| 111 |
-
"torch.save({'model': model, 'tokenizer': tokenizer, 'config': config}, 'best_model.pkl')\n"
|
| 112 |
-
"```\n\n"
|
| 113 |
-
"Or upload a CPU-compatible `best_model.pkl` to the Space and retry.")
|
| 114 |
-
return f"❌ Error loading model: {err}\n\nPlease ensure best_model.pkl is properly uploaded to the Space and is CPU-compatible."
|
| 115 |
|
| 116 |
def calculate_bleu_score(reference, hypothesis):
|
| 117 |
"""Calculate BLEU score between reference and generated code"""
|
|
|
|
| 34 |
# Check if file exists
|
| 35 |
if not os.path.exists(pickle_path):
|
| 36 |
return f"❌ Model file not found: {pickle_path}\n\nPlease ensure best_model.pkl is uploaded to the HuggingFace Space."
|
| 37 |
+
|
| 38 |
+
# Strategy: Use a custom unpickler that forces all CUDA tensors to CPU during deserialization
|
| 39 |
+
# This prevents the "Attempting to deserialize object on a CUDA device" error entirely
|
| 40 |
+
class CPUUnpickler(pickle.Unpickler):
|
| 41 |
+
def find_class(self, module, name):
|
| 42 |
+
# Remap torch CUDA classes to CPU equivalents
|
| 43 |
+
if module == 'torch.storage' and name.endswith('Storage'):
|
| 44 |
+
# Force all storage types to CPU (e.g., cuda:0 -> cpu)
|
| 45 |
+
return super().find_class('torch', name.replace('Cuda', '').replace('cuda', ''))
|
| 46 |
+
return super().find_class(module, name)
|
| 47 |
+
|
| 48 |
+
def persistent_load(self, pid):
|
| 49 |
+
# Handle torch storage tuples: ('storage', storage_type, key, location, size)
|
| 50 |
+
if isinstance(pid, tuple) and len(pid) > 0 and pid[0] == 'storage':
|
| 51 |
+
storage_type, key, location, size = pid[1], pid[2], pid[3], pid[4]
|
| 52 |
+
# Force location to CPU regardless of original device
|
| 53 |
+
if 'cuda' in str(location).lower():
|
| 54 |
+
location = 'cpu'
|
| 55 |
+
# Rebuild the storage descriptor with CPU location
|
| 56 |
+
return ('storage', storage_type, key, location, size)
|
| 57 |
+
return pid
|
| 58 |
+
|
| 59 |
try:
|
| 60 |
+
# Attempt 1: Custom CPU unpickler (most robust for CUDA->CPU)
|
| 61 |
+
with open(pickle_path, 'rb') as f:
|
| 62 |
+
model_package = CPUUnpickler(f).load()
|
| 63 |
+
except Exception as e1:
|
| 64 |
+
try:
|
| 65 |
+
# Attempt 2: torch.load with map_location (standard approach)
|
| 66 |
model_package = torch.load(pickle_path, map_location=torch.device('cpu'))
|
| 67 |
+
except Exception as e2:
|
| 68 |
+
try:
|
| 69 |
+
# Attempt 3: torch.load with weights_only=False (for older torch versions)
|
| 70 |
+
model_package = torch.load(pickle_path, map_location='cpu', weights_only=False)
|
| 71 |
+
except Exception as e3:
|
| 72 |
+
# All strategies failed - return combined error info
|
| 73 |
+
return (f"❌ All loading strategies failed:\n\n"
|
| 74 |
+
f"1. Custom CPU unpickler: {str(e1)[:100]}\n"
|
| 75 |
+
f"2. torch.load(map_location): {str(e2)[:100]}\n"
|
| 76 |
+
f"3. torch.load(weights_only=False): {str(e3)[:100]}\n\n"
|
| 77 |
+
f"The pickle may be corrupted or incompatible with this PyTorch version.\n"
|
| 78 |
+
f"Try re-saving with: model.to('cpu'); torch.save({{'model': model, ...}}, 'file.pkl')")
|
| 79 |
|
| 80 |
+
# Success! Model loaded with one of the strategies above
|
| 81 |
# Handle a few common package shapes.
|
| 82 |
if isinstance(model_package, dict):
|
| 83 |
loaded_model = model_package.get('model', None)
|
|
|
|
| 130 |
return config_info
|
| 131 |
|
| 132 |
except Exception as e:
|
| 133 |
+
# Final catch-all for any unexpected errors
|
| 134 |
err = str(e)
|
| 135 |
+
return f"❌ Unexpected error loading model: {err}\n\nPlease ensure best_model.pkl is properly uploaded and compatible with this environment."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
|
| 137 |
def calculate_bleu_score(reference, hypothesis):
|
| 138 |
"""Calculate BLEU score between reference and generated code"""
|