jmullings commited on
Commit
254fd6c
·
1 Parent(s): 1cf1f1a

DeepSeek Update

Browse files
Files changed (1) hide show
  1. src/audit/engine.py +147 -136
src/audit/engine.py CHANGED
@@ -14,7 +14,150 @@ from typing import Any, Callable, Dict, List, Optional, Tuple
14
  import numpy as np
15
  import scipy.linalg as la
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  class SafeFallbackNode:
19
  """Universal null-safe node that never crashes on any attribute access,
20
  indexing, iteration, or function call."""
@@ -60,12 +203,11 @@ class SafeFallbackNode:
60
 
61
 
62
  def make_auto_healing_config(base_config):
63
- """Wraps and mutates any PretrainedConfig so that missing attributes or
64
  None sub-configs never raise AttributeError."""
65
  if base_config is None:
66
  return SafeFallbackNode()
67
 
68
- # 1. Pre-populate essential Transformer fields with sensible defaults
69
  defaults = {
70
  "pad_token_id": getattr(base_config, "eos_token_id", None) or 0,
71
  "eos_token_id": getattr(base_config, "pad_token_id", None) or 0,
@@ -93,7 +235,6 @@ def make_auto_healing_config(base_config):
93
  except Exception:
94
  pass
95
 
96
- # 2. Replace None sub-configs with SafeFallbackNode so config.quantization_config.anything never crashes
97
  for sub in [
98
  "quantization_config", "rope_scaling", "generation_config",
99
  "task_specific_params", "auto_map", "vision_config", "text_config", "language_config"
@@ -105,7 +246,6 @@ def make_auto_healing_config(base_config):
105
  except Exception:
106
  pass
107
 
108
- # 3. Patch __getattr__ on the config class to catch all remaining undefined attributes
109
  cls = base_config.__class__
110
  if not hasattr(cls, "_xray_universal_healed"):
111
  orig_getattr = getattr(cls, "__getattr__", None)
@@ -173,6 +313,9 @@ def silence_specific_warnings():
173
  tf_logger.setLevel(old_level)
174
 
175
 
 
 
 
176
  try:
177
  import torch
178
  from transformers import (
@@ -183,95 +326,6 @@ try:
183
  AutoModelForVision2Seq,
184
  AutoTokenizer,
185
  )
186
-
187
- def apply_transformers_backward_compatibility_patches():
188
- """Polyfills legacy transformers classes and utilities that custom modeling scripts on Hugging Face expect."""
189
- # 1. DynamicCache backwards compatibility
190
- try:
191
- from transformers.cache_utils import DynamicCache
192
- if not hasattr(DynamicCache, "from_legacy_cache"):
193
- @classmethod
194
- def _from_legacy_cache(cls, past_key_values=None):
195
- cache = cls()
196
- if past_key_values is not None:
197
- for layer_idx, (key, value) in enumerate(past_key_values):
198
- cache.update(key, value, layer_idx)
199
- return cache
200
- DynamicCache.from_legacy_cache = _from_legacy_cache
201
- except Exception:
202
- pass
203
-
204
- # 2. LLaMA legacy attention classes (LlamaFlashAttention2, LlamaSdpaAttention)
205
- try:
206
- import transformers.models.llama.modeling_llama as llama_mod
207
- llama_attn = getattr(llama_mod, "LlamaAttention", None)
208
- if llama_attn is not None:
209
- if not hasattr(llama_mod, "LlamaFlashAttention2"):
210
- setattr(llama_mod, "LlamaFlashAttention2", llama_attn)
211
- if not hasattr(llama_mod, "LlamaSdpaAttention"):
212
- setattr(llama_mod, "LlamaSdpaAttention", llama_attn)
213
- except Exception:
214
- pass
215
-
216
- # 3. Mistral legacy attention classes
217
- try:
218
- import transformers.models.mistral.modeling_mistral as mistral_mod
219
- mistral_attn = getattr(mistral_mod, "MistralAttention", None)
220
- if mistral_attn is not None:
221
- if not hasattr(mistral_mod, "MistralFlashAttention2"):
222
- setattr(mistral_mod, "MistralFlashAttention2", mistral_attn)
223
- if not hasattr(mistral_mod, "MistralSdpaAttention"):
224
- setattr(mistral_mod, "MistralSdpaAttention", mistral_attn)
225
- except Exception:
226
- pass
227
-
228
- # 4. Qwen2 legacy attention classes
229
- try:
230
- import transformers.models.qwen2.modeling_qwen2 as qwen2_mod
231
- qwen2_attn = getattr(qwen2_mod, "Qwen2Attention", None)
232
- if qwen2_attn is not None:
233
- if not hasattr(qwen2_mod, "Qwen2FlashAttention2"):
234
- setattr(qwen2_mod, "Qwen2FlashAttention2", qwen2_attn)
235
- if not hasattr(qwen2_mod, "Qwen2SdpaAttention"):
236
- setattr(qwen2_mod, "Qwen2SdpaAttention", qwen2_attn)
237
- except Exception:
238
- pass
239
-
240
- # 5. Gemma legacy attention classes
241
- try:
242
- import transformers.models.gemma.modeling_gemma as gemma_mod
243
- gemma_attn = getattr(gemma_mod, "GemmaAttention", None)
244
- if gemma_attn is not None:
245
- if not hasattr(gemma_mod, "GemmaFlashAttention2"):
246
- setattr(gemma_mod, "GemmaFlashAttention2", gemma_attn)
247
- if not hasattr(gemma_mod, "GemmaSdpaAttention"):
248
- setattr(gemma_mod, "GemmaSdpaAttention", gemma_attn)
249
- except Exception:
250
- pass
251
-
252
- # 6. Legacy import_utils functions (e.g., is_torch_fx_available)
253
- try:
254
- import transformers.utils.import_utils as import_utils
255
- if not hasattr(import_utils, "is_torch_fx_available"):
256
- setattr(import_utils, "is_torch_fx_available", lambda: True)
257
- if not hasattr(import_utils, "is_torch_fx_proxy_available"):
258
- setattr(import_utils, "is_torch_fx_proxy_available", lambda: True)
259
-
260
- import transformers.utils as utils
261
- if not hasattr(utils, "is_torch_fx_available"):
262
- setattr(utils, "is_torch_fx_available", lambda: True)
263
- if not hasattr(utils, "is_torch_fx_proxy_available"):
264
- setattr(utils, "is_torch_fx_proxy_available", lambda: True)
265
-
266
- import transformers
267
- if not hasattr(transformers, "is_torch_fx_available"):
268
- setattr(transformers, "is_torch_fx_available", lambda: True)
269
- if not hasattr(transformers, "is_torch_fx_proxy_available"):
270
- setattr(transformers, "is_torch_fx_proxy_available", lambda: True)
271
- except Exception:
272
- pass
273
-
274
- apply_transformers_backward_compatibility_patches()
275
  HAS_TRANSFORMERS = True
276
  except ImportError:
277
  HAS_TRANSFORMERS = False
@@ -281,49 +335,6 @@ class AuditError(Exception):
281
  """Raised whenever an audit cannot be completed."""
282
 
283
 
284
- def try_auto_install_packages(error_msg: str) -> bool:
285
- """Detects missing pip packages from Transformers/Python errors and installs them dynamically."""
286
- pkgs_to_install = []
287
-
288
- match_pip = re.search(r"pip install\s+([^`\n\r]+)", error_msg)
289
- if match_pip:
290
- raw = match_pip.group(1).strip()
291
- for p in re.split(r"[\s,]+", raw):
292
- p = p.strip().strip("'\"")
293
- if p and not p.startswith("-") and p not in pkgs_to_install:
294
- pkgs_to_install.append(p)
295
-
296
- match_mod = re.findall(r"No module named ['\"]([^'\"]+)['\"]", error_msg)
297
- for m in match_mod:
298
- top_pkg = m.split(".")[0].strip()
299
- if top_pkg and top_pkg not in pkgs_to_install:
300
- pkgs_to_install.append(top_pkg)
301
-
302
- if not pkgs_to_install:
303
- return False
304
-
305
- print(f"[LLM-X-RAY] 📦 Dynamically installing required package(s): {pkgs_to_install}...", flush=True)
306
- try:
307
- cmd = [sys.executable, "-m", "pip", "install", "--no-cache-dir"] + pkgs_to_install
308
- res = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
309
- if res.returncode == 0:
310
- print(f"[LLM-X-RAY] ✅ Successfully installed {pkgs_to_install}!", flush=True)
311
- importlib.invalidate_caches()
312
- for p in pkgs_to_install:
313
- try:
314
- importlib.import_module(p)
315
- except Exception:
316
- pass
317
- apply_transformers_backward_compatibility_patches()
318
- return True
319
- else:
320
- print(f"[LLM-X-RAY] ⚠️ Pip install failed: {res.stderr}", flush=True)
321
- return False
322
- except Exception as exc:
323
- print(f"[LLM-X-RAY] ⚠️ Error during auto-pip install: {exc}", flush=True)
324
- return False
325
-
326
-
327
  PROBE_CORPUS: List[Dict[str, Any]] = [
328
  {"id": "GEO01", "q": "What is the capital of Australia?", "paraphrases": ["Which city serves as Australia's capital?", "Name the federal capital of Australia."], "answers": ["Canberra"], "cat": "Geography", "is_adversarial": False},
329
  {"id": "GEO02", "q": "What is the longest river in South America?", "paraphrases": ["Which South American river is the longest?", "Name the longest river on the South American continent."], "answers": ["Amazon"], "cat": "Geography", "is_adversarial": False},
 
14
  import numpy as np
15
  import scipy.linalg as la
16
 
17
+ # -----------------------------------------------------------------------------
18
+ # 1. Transformers Backward Compatibility & Legacy Polyfills (Top-Level)
19
+ # -----------------------------------------------------------------------------
20
+ def apply_transformers_backward_compatibility_patches():
21
+ """Polyfills legacy transformers classes and utilities that custom modeling scripts on Hugging Face expect."""
22
+ # 1. DynamicCache backwards compatibility
23
+ try:
24
+ from transformers.cache_utils import DynamicCache
25
+ if not hasattr(DynamicCache, "from_legacy_cache"):
26
+ @classmethod
27
+ def _from_legacy_cache(cls, past_key_values=None):
28
+ cache = cls()
29
+ if past_key_values is not None:
30
+ for layer_idx, (key, value) in enumerate(past_key_values):
31
+ cache.update(key, value, layer_idx)
32
+ return cache
33
+ DynamicCache.from_legacy_cache = _from_legacy_cache
34
+ except Exception:
35
+ pass
36
+
37
+ # 2. LLaMA legacy attention classes (LlamaFlashAttention2, LlamaSdpaAttention)
38
+ try:
39
+ import transformers.models.llama.modeling_llama as llama_mod
40
+ llama_attn = getattr(llama_mod, "LlamaAttention", None)
41
+ if llama_attn is not None:
42
+ if not hasattr(llama_mod, "LlamaFlashAttention2"):
43
+ setattr(llama_mod, "LlamaFlashAttention2", llama_attn)
44
+ if not hasattr(llama_mod, "LlamaSdpaAttention"):
45
+ setattr(llama_mod, "LlamaSdpaAttention", llama_attn)
46
+ except Exception:
47
+ pass
48
+
49
+ # 3. Mistral legacy attention classes
50
+ try:
51
+ import transformers.models.mistral.modeling_mistral as mistral_mod
52
+ mistral_attn = getattr(mistral_mod, "MistralAttention", None)
53
+ if mistral_attn is not None:
54
+ if not hasattr(mistral_mod, "MistralFlashAttention2"):
55
+ setattr(mistral_mod, "MistralFlashAttention2", mistral_attn)
56
+ if not hasattr(mistral_mod, "MistralSdpaAttention"):
57
+ setattr(mistral_mod, "MistralSdpaAttention", mistral_attn)
58
+ except Exception:
59
+ pass
60
+
61
+ # 4. Qwen2 legacy attention classes
62
+ try:
63
+ import transformers.models.qwen2.modeling_qwen2 as qwen2_mod
64
+ qwen2_attn = getattr(qwen2_mod, "Qwen2Attention", None)
65
+ if qwen2_attn is not None:
66
+ if not hasattr(qwen2_mod, "Qwen2FlashAttention2"):
67
+ setattr(qwen2_mod, "Qwen2FlashAttention2", qwen2_attn)
68
+ if not hasattr(qwen2_mod, "Qwen2SdpaAttention"):
69
+ setattr(qwen2_mod, "Qwen2SdpaAttention", qwen2_attn)
70
+ except Exception:
71
+ pass
72
+
73
+ # 5. Gemma legacy attention classes
74
+ try:
75
+ import transformers.models.gemma.modeling_gemma as gemma_mod
76
+ gemma_attn = getattr(gemma_mod, "GemmaAttention", None)
77
+ if gemma_attn is not None:
78
+ if not hasattr(gemma_mod, "GemmaFlashAttention2"):
79
+ setattr(gemma_mod, "GemmaFlashAttention2", gemma_attn)
80
+ if not hasattr(gemma_mod, "GemmaSdpaAttention"):
81
+ setattr(gemma_mod, "GemmaSdpaAttention", gemma_attn)
82
+ except Exception:
83
+ pass
84
+
85
+ # 6. Legacy import_utils functions (e.g., is_torch_fx_available)
86
+ try:
87
+ import transformers.utils.import_utils as import_utils
88
+ if not hasattr(import_utils, "is_torch_fx_available"):
89
+ setattr(import_utils, "is_torch_fx_available", lambda: True)
90
+ if not hasattr(import_utils, "is_torch_fx_proxy_available"):
91
+ setattr(import_utils, "is_torch_fx_proxy_available", lambda: True)
92
+
93
+ import transformers.utils as utils
94
+ if not hasattr(utils, "is_torch_fx_available"):
95
+ setattr(utils, "is_torch_fx_available", lambda: True)
96
+ if not hasattr(utils, "is_torch_fx_proxy_available"):
97
+ setattr(utils, "is_torch_fx_proxy_available", lambda: True)
98
+
99
+ import transformers
100
+ if not hasattr(transformers, "is_torch_fx_available"):
101
+ setattr(transformers, "is_torch_fx_available", lambda: True)
102
+ if not hasattr(transformers, "is_torch_fx_proxy_available"):
103
+ setattr(transformers, "is_torch_fx_proxy_available", lambda: True)
104
+ except Exception:
105
+ pass
106
+
107
+
108
+ # Apply baseline patches on module load
109
+ apply_transformers_backward_compatibility_patches()
110
+
111
+
112
+ # -----------------------------------------------------------------------------
113
+ # 2. Dynamic Auto-Installer for Missing Packages
114
+ # -----------------------------------------------------------------------------
115
+ def try_auto_install_packages(error_msg: str) -> bool:
116
+ """Detects missing pip packages from Transformers/Python errors and installs them dynamically."""
117
+ pkgs_to_install = []
118
+
119
+ match_pip = re.search(r"pip install\s+([^`\n\r]+)", error_msg)
120
+ if match_pip:
121
+ raw = match_pip.group(1).strip()
122
+ for p in re.split(r"[\s,]+", raw):
123
+ p = p.strip().strip("'\"")
124
+ if p and not p.startswith("-") and p not in pkgs_to_install:
125
+ pkgs_to_install.append(p)
126
+
127
+ match_mod = re.findall(r"No module named ['\"]([^'\"]+)['\"]", error_msg)
128
+ for m in match_mod:
129
+ top_pkg = m.split(".")[0].strip()
130
+ if top_pkg and top_pkg not in pkgs_to_install:
131
+ pkgs_to_install.append(top_pkg)
132
 
133
+ if not pkgs_to_install:
134
+ return False
135
+
136
+ print(f"[LLM-X-RAY] 📦 Dynamically installing required package(s): {pkgs_to_install}...", flush=True)
137
+ try:
138
+ cmd = [sys.executable, "-m", "pip", "install", "--no-cache-dir"] + pkgs_to_install
139
+ res = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
140
+ if res.returncode == 0:
141
+ print(f"[LLM-X-RAY] ✅ Successfully installed {pkgs_to_install}!", flush=True)
142
+ importlib.invalidate_caches()
143
+ for p in pkgs_to_install:
144
+ try:
145
+ importlib.import_module(p)
146
+ except Exception:
147
+ pass
148
+ apply_transformers_backward_compatibility_patches()
149
+ return True
150
+ else:
151
+ print(f"[LLM-X-RAY] ⚠️ Pip install failed: {res.stderr}", flush=True)
152
+ return False
153
+ except Exception as exc:
154
+ print(f"[LLM-X-RAY] ⚠️ Error during auto-pip install: {exc}", flush=True)
155
+ return False
156
+
157
+
158
+ # -----------------------------------------------------------------------------
159
+ # 3. Universal Safe Config Proxy & Fallbacks
160
+ # -----------------------------------------------------------------------------
161
  class SafeFallbackNode:
162
  """Universal null-safe node that never crashes on any attribute access,
163
  indexing, iteration, or function call."""
 
203
 
204
 
205
  def make_auto_healing_config(base_config):
206
+ """Wraps and mutates any PretrainedConfig so missing attributes or
207
  None sub-configs never raise AttributeError."""
208
  if base_config is None:
209
  return SafeFallbackNode()
210
 
 
211
  defaults = {
212
  "pad_token_id": getattr(base_config, "eos_token_id", None) or 0,
213
  "eos_token_id": getattr(base_config, "pad_token_id", None) or 0,
 
235
  except Exception:
236
  pass
237
 
 
238
  for sub in [
239
  "quantization_config", "rope_scaling", "generation_config",
240
  "task_specific_params", "auto_map", "vision_config", "text_config", "language_config"
 
246
  except Exception:
247
  pass
248
 
 
249
  cls = base_config.__class__
250
  if not hasattr(cls, "_xray_universal_healed"):
251
  orig_getattr = getattr(cls, "__getattr__", None)
 
313
  tf_logger.setLevel(old_level)
314
 
315
 
316
+ # -----------------------------------------------------------------------------
317
+ # 4. Main Transformers and Auditor Classes
318
+ # -----------------------------------------------------------------------------
319
  try:
320
  import torch
321
  from transformers import (
 
326
  AutoModelForVision2Seq,
327
  AutoTokenizer,
328
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329
  HAS_TRANSFORMERS = True
330
  except ImportError:
331
  HAS_TRANSFORMERS = False
 
335
  """Raised whenever an audit cannot be completed."""
336
 
337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  PROBE_CORPUS: List[Dict[str, Any]] = [
339
  {"id": "GEO01", "q": "What is the capital of Australia?", "paraphrases": ["Which city serves as Australia's capital?", "Name the federal capital of Australia."], "answers": ["Canberra"], "cat": "Geography", "is_adversarial": False},
340
  {"id": "GEO02", "q": "What is the longest river in South America?", "paraphrases": ["Which South American river is the longest?", "Name the longest river on the South American continent."], "answers": ["Amazon"], "cat": "Geography", "is_adversarial": False},