hamxaameer commited on
Commit
581b6a9
·
1 Parent(s): eb6ce9a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -22
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
- # Try to load using torch.load which supports map_location for CPU-only machines
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  try:
39
- if torch.cuda.is_available():
40
- model_package = torch.load(pickle_path)
41
- else:
 
 
 
42
  model_package = torch.load(pickle_path, map_location=torch.device('cpu'))
43
- except RuntimeError as rte:
44
- # Common error when a GPU-saved object is loaded on CPU-only machine
45
- if 'Attempting to deserialize object on a CUDA device' in str(rte):
46
- # Retry mapping to CPU
47
- model_package = torch.load(pickle_path, map_location=torch.device('cpu'))
48
- else:
49
- raise
 
 
 
 
 
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
- # Specific hint for CUDA->CPU deserialization issues
104
  err = str(e)
105
- if 'Attempting to deserialize object on a CUDA device' in err:
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"""