invarlock 0.3.6__py3-none-any.whl → 0.3.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- invarlock/__init__.py +4 -4
- invarlock/adapters/__init__.py +10 -14
- invarlock/adapters/auto.py +37 -50
- invarlock/adapters/capabilities.py +2 -2
- invarlock/adapters/hf_causal.py +418 -0
- invarlock/adapters/{hf_onnx.py → hf_causal_onnx.py} +3 -3
- invarlock/adapters/hf_loading.py +7 -7
- invarlock/adapters/hf_mixin.py +53 -9
- invarlock/adapters/{hf_bert.py → hf_mlm.py} +4 -11
- invarlock/adapters/{hf_t5.py → hf_seq2seq.py} +9 -9
- invarlock/assurance/__init__.py +15 -23
- invarlock/cli/adapter_auto.py +32 -26
- invarlock/cli/app.py +128 -27
- invarlock/cli/commands/__init__.py +2 -2
- invarlock/cli/commands/calibrate.py +48 -4
- invarlock/cli/commands/doctor.py +8 -10
- invarlock/cli/commands/evaluate.py +986 -0
- invarlock/cli/commands/explain_gates.py +25 -17
- invarlock/cli/commands/export_html.py +11 -9
- invarlock/cli/commands/plugins.py +13 -9
- invarlock/cli/commands/report.py +326 -92
- invarlock/cli/commands/run.py +1160 -228
- invarlock/cli/commands/verify.py +157 -97
- invarlock/cli/config.py +1 -1
- invarlock/cli/determinism.py +1 -1
- invarlock/cli/doctor_helpers.py +4 -5
- invarlock/cli/output.py +193 -0
- invarlock/cli/provenance.py +4 -4
- invarlock/core/bootstrap.py +1 -1
- invarlock/core/registry.py +9 -11
- invarlock/core/retry.py +14 -14
- invarlock/core/runner.py +112 -26
- invarlock/edits/noop.py +2 -2
- invarlock/edits/quant_rtn.py +67 -39
- invarlock/eval/__init__.py +1 -1
- invarlock/eval/bench.py +14 -10
- invarlock/eval/data.py +68 -23
- invarlock/eval/metrics.py +59 -1
- invarlock/eval/primary_metric.py +1 -1
- invarlock/eval/tasks/__init__.py +12 -0
- invarlock/eval/tasks/classification.py +48 -0
- invarlock/eval/tasks/qa.py +36 -0
- invarlock/eval/tasks/text_generation.py +102 -0
- invarlock/guards/invariants.py +19 -10
- invarlock/guards/rmt.py +2 -2
- invarlock/guards/spectral.py +1 -1
- invarlock/guards/variance.py +2 -2
- invarlock/model_profile.py +64 -62
- invarlock/observability/health.py +6 -6
- invarlock/observability/metrics.py +108 -0
- invarlock/plugins/hf_bnb_adapter.py +32 -21
- invarlock/reporting/__init__.py +18 -4
- invarlock/reporting/guards_analysis.py +154 -4
- invarlock/reporting/html.py +61 -11
- invarlock/reporting/normalizer.py +9 -2
- invarlock/reporting/policy_utils.py +1 -1
- invarlock/reporting/primary_metric_utils.py +11 -11
- invarlock/reporting/render.py +876 -510
- invarlock/reporting/report.py +72 -30
- invarlock/reporting/{certificate.py → report_builder.py} +252 -99
- invarlock/reporting/{certificate_schema.py → report_schema.py} +22 -22
- invarlock/reporting/report_types.py +6 -1
- invarlock/reporting/telemetry.py +86 -0
- invarlock-0.3.8.dist-info/METADATA +283 -0
- {invarlock-0.3.6.dist-info → invarlock-0.3.8.dist-info}/RECORD +69 -64
- {invarlock-0.3.6.dist-info → invarlock-0.3.8.dist-info}/WHEEL +1 -1
- {invarlock-0.3.6.dist-info → invarlock-0.3.8.dist-info}/entry_points.txt +5 -3
- invarlock/adapters/hf_gpt2.py +0 -404
- invarlock/adapters/hf_llama.py +0 -487
- invarlock/cli/commands/certify.py +0 -422
- invarlock-0.3.6.dist-info/METADATA +0 -588
- {invarlock-0.3.6.dist-info → invarlock-0.3.8.dist-info}/licenses/LICENSE +0 -0
- {invarlock-0.3.6.dist-info → invarlock-0.3.8.dist-info}/top_level.txt +0 -0
invarlock/adapters/hf_loading.py
CHANGED
|
@@ -50,7 +50,7 @@ def resolve_trust_remote_code(
|
|
|
50
50
|
return default
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
def
|
|
53
|
+
def default_dtype() -> torch.dtype:
|
|
54
54
|
"""Pick a safe default dtype for HF loads based on hardware."""
|
|
55
55
|
if torch.cuda.is_available():
|
|
56
56
|
try:
|
|
@@ -69,10 +69,10 @@ def default_torch_dtype() -> torch.dtype:
|
|
|
69
69
|
return torch.float32
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
def
|
|
73
|
-
"""Resolve
|
|
74
|
-
if kwargs and "
|
|
75
|
-
val = kwargs.get("
|
|
72
|
+
def resolve_dtype(kwargs: dict[str, Any] | None = None) -> torch.dtype | str:
|
|
73
|
+
"""Resolve dtype from kwargs or choose a hardware-aware default."""
|
|
74
|
+
if kwargs and "dtype" in kwargs:
|
|
75
|
+
val = kwargs.get("dtype")
|
|
76
76
|
if isinstance(val, torch.dtype):
|
|
77
77
|
return val
|
|
78
78
|
if isinstance(val, str):
|
|
@@ -91,7 +91,7 @@ def resolve_torch_dtype(kwargs: dict[str, Any] | None = None) -> torch.dtype | s
|
|
|
91
91
|
if s in mapping:
|
|
92
92
|
return mapping[s]
|
|
93
93
|
|
|
94
|
-
return
|
|
94
|
+
return default_dtype()
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
__all__ = ["resolve_trust_remote_code", "
|
|
97
|
+
__all__ = ["resolve_trust_remote_code", "default_dtype", "resolve_dtype"]
|
invarlock/adapters/hf_mixin.py
CHANGED
|
@@ -490,18 +490,39 @@ class HFAdapterMixin:
|
|
|
490
490
|
"""Return mapping of tied parameter names to source parameter names."""
|
|
491
491
|
|
|
492
492
|
tying: dict[str, str] = {}
|
|
493
|
-
|
|
493
|
+
try:
|
|
494
|
+
named = model.named_parameters(remove_duplicate=False) # type: ignore[call-arg]
|
|
495
|
+
except TypeError: # pragma: no cover - torch version dependent
|
|
496
|
+
named = model.named_parameters()
|
|
497
|
+
params = dict(named)
|
|
498
|
+
|
|
499
|
+
def _is_tied(name_a: str, name_b: str) -> bool:
|
|
500
|
+
a = params.get(name_a)
|
|
501
|
+
b = params.get(name_b)
|
|
502
|
+
if a is None or b is None:
|
|
503
|
+
return False
|
|
504
|
+
try:
|
|
505
|
+
if a is b:
|
|
506
|
+
return True
|
|
507
|
+
if hasattr(a, "data_ptr") and hasattr(b, "data_ptr"):
|
|
508
|
+
return int(a.data_ptr()) == int(b.data_ptr())
|
|
509
|
+
except Exception:
|
|
510
|
+
return False
|
|
511
|
+
return False
|
|
494
512
|
|
|
495
|
-
if "lm_head.weight"
|
|
513
|
+
if _is_tied("lm_head.weight", "transformer.wte.weight"):
|
|
496
514
|
tying["lm_head.weight"] = "transformer.wte.weight"
|
|
497
515
|
|
|
516
|
+
if _is_tied("lm_head.weight", "model.embed_tokens.weight"):
|
|
517
|
+
tying["lm_head.weight"] = "model.embed_tokens.weight"
|
|
518
|
+
|
|
498
519
|
decoder_name = "cls.predictions.decoder.weight"
|
|
499
|
-
if decoder_name in
|
|
520
|
+
if decoder_name in params:
|
|
500
521
|
for candidate in (
|
|
501
522
|
"bert.embeddings.word_embeddings.weight",
|
|
502
523
|
"embeddings.word_embeddings.weight",
|
|
503
524
|
):
|
|
504
|
-
if candidate
|
|
525
|
+
if _is_tied(decoder_name, candidate):
|
|
505
526
|
tying[decoder_name] = candidate
|
|
506
527
|
break
|
|
507
528
|
|
|
@@ -562,22 +583,45 @@ class HFAdapterMixin:
|
|
|
562
583
|
def _serialize_config(self, config: Any) -> dict[str, Any]:
|
|
563
584
|
"""Serialize HuggingFace config fields into simple Python types."""
|
|
564
585
|
|
|
586
|
+
def _collect(data: dict[str, Any]) -> dict[str, Any]:
|
|
587
|
+
out: dict[str, Any] = {}
|
|
588
|
+
for key, value in data.items():
|
|
589
|
+
if key.startswith("_") or key in {"method_calls"}:
|
|
590
|
+
continue
|
|
591
|
+
if value is None or isinstance(value, SCALAR_TYPES):
|
|
592
|
+
out[key] = value
|
|
593
|
+
elif isinstance(value, list | dict):
|
|
594
|
+
out[key] = value
|
|
595
|
+
return out
|
|
596
|
+
|
|
597
|
+
to_dict = getattr(config, "to_dict", None)
|
|
598
|
+
if callable(to_dict):
|
|
599
|
+
try:
|
|
600
|
+
data = to_dict()
|
|
601
|
+
except Exception:
|
|
602
|
+
data = None
|
|
603
|
+
if isinstance(data, dict):
|
|
604
|
+
return _collect(data)
|
|
605
|
+
|
|
606
|
+
try:
|
|
607
|
+
data = vars(config)
|
|
608
|
+
except TypeError:
|
|
609
|
+
data = None
|
|
610
|
+
if isinstance(data, dict):
|
|
611
|
+
return _collect(data)
|
|
612
|
+
|
|
565
613
|
result: dict[str, Any] = {}
|
|
566
614
|
for key in dir(config):
|
|
567
|
-
if key.startswith("_"):
|
|
615
|
+
if key.startswith("_") or key in {"torch_dtype"}:
|
|
568
616
|
continue
|
|
569
|
-
|
|
570
617
|
try:
|
|
571
618
|
value = getattr(config, key)
|
|
572
619
|
except AttributeError:
|
|
573
620
|
continue
|
|
574
|
-
|
|
575
621
|
if callable(value):
|
|
576
622
|
continue
|
|
577
|
-
|
|
578
623
|
if value is None or isinstance(value, SCALAR_TYPES):
|
|
579
624
|
result[key] = value
|
|
580
625
|
elif isinstance(value, list | dict):
|
|
581
626
|
result[key] = value
|
|
582
|
-
|
|
583
627
|
return result
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
"""
|
|
2
|
-
HuggingFace
|
|
2
|
+
HuggingFace masked LM adapter.
|
|
3
3
|
==============================
|
|
4
4
|
|
|
5
|
-
ModelAdapter implementation for HuggingFace
|
|
6
|
-
|
|
7
|
-
This adapter provides BERT-specific integration including:
|
|
8
|
-
- Support for BERT, RoBERTa, DistilBERT, and other BERT variants
|
|
9
|
-
- Proper handling of bidirectional attention layers
|
|
10
|
-
- Support for classification heads and pooling layers
|
|
11
|
-
- Token type embeddings and position embeddings handling
|
|
12
|
-
- Proper device-aware state serialization
|
|
5
|
+
ModelAdapter implementation for HuggingFace masked language models.
|
|
13
6
|
"""
|
|
14
7
|
|
|
15
8
|
from typing import Any
|
|
@@ -27,7 +20,7 @@ TensorType = torch.Tensor
|
|
|
27
20
|
ModuleType = nn.Module
|
|
28
21
|
|
|
29
22
|
|
|
30
|
-
class
|
|
23
|
+
class HF_MLM_Adapter(HFAdapterMixin, ModelAdapter):
|
|
31
24
|
"""
|
|
32
25
|
HuggingFace-specific ModelAdapter implementation for BERT models.
|
|
33
26
|
|
|
@@ -39,7 +32,7 @@ class HF_BERT_Adapter(HFAdapterMixin, ModelAdapter):
|
|
|
39
32
|
- Device-aware state serialization
|
|
40
33
|
"""
|
|
41
34
|
|
|
42
|
-
name = "
|
|
35
|
+
name = "hf_mlm"
|
|
43
36
|
|
|
44
37
|
def load_model(
|
|
45
38
|
self, model_id: str, device: str = "auto", **kwargs: Any
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"""
|
|
2
|
-
HuggingFace
|
|
3
|
-
|
|
2
|
+
HuggingFace encoder-decoder adapter.
|
|
3
|
+
===================================
|
|
4
4
|
|
|
5
|
-
ModelAdapter implementation for HuggingFace
|
|
5
|
+
ModelAdapter implementation for HuggingFace encoder-decoder (seq2seq) models.
|
|
6
6
|
|
|
7
|
-
Loads AutoModelForSeq2SeqLM
|
|
8
|
-
|
|
7
|
+
Loads AutoModelForSeq2SeqLM and exposes a minimal describe() sufficient for
|
|
8
|
+
guard policies and reporting.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
@@ -25,10 +25,10 @@ TensorType = torch.Tensor
|
|
|
25
25
|
ModuleType = nn.Module
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
class
|
|
29
|
-
"""HuggingFace
|
|
28
|
+
class HF_Seq2Seq_Adapter(HFAdapterMixin, ModelAdapter):
|
|
29
|
+
"""HuggingFace encoder-decoder adapter using AutoModelForSeq2SeqLM."""
|
|
30
30
|
|
|
31
|
-
name = "
|
|
31
|
+
name = "hf_seq2seq"
|
|
32
32
|
|
|
33
33
|
def load_model( # type: ignore[override]
|
|
34
34
|
self, model_id: str, device: str = "auto", **kwargs: Any
|
|
@@ -136,4 +136,4 @@ class HF_T5_Adapter(HFAdapterMixin, ModelAdapter):
|
|
|
136
136
|
return super().restore(model, blob)
|
|
137
137
|
|
|
138
138
|
|
|
139
|
-
__all__ = ["
|
|
139
|
+
__all__ = ["HF_Seq2Seq_Adapter"]
|
invarlock/assurance/__init__.py
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
"""Assurance namespace (`invarlock.assurance`).
|
|
2
|
-
|
|
3
|
-
This namespace groups safety-certificate related surfaces. For now it forwards
|
|
4
|
-
to `invarlock.eval` and guard modules; future work may move implementations here.
|
|
5
|
-
"""
|
|
1
|
+
"""Assurance namespace (`invarlock.assurance`)."""
|
|
6
2
|
|
|
7
3
|
from __future__ import annotations
|
|
8
4
|
|
|
@@ -11,33 +7,29 @@ from typing import Any
|
|
|
11
7
|
from invarlock.reporting.report_types import RunReport
|
|
12
8
|
|
|
13
9
|
try: # pragma: no cover - shim to reporting modules
|
|
14
|
-
from invarlock.reporting.certificate import (
|
|
15
|
-
CERTIFICATE_SCHEMA_VERSION,
|
|
16
|
-
make_certificate,
|
|
17
|
-
validate_certificate,
|
|
18
|
-
)
|
|
19
|
-
|
|
20
10
|
# Prefer direct import from render for rendering APIs
|
|
21
|
-
from invarlock.reporting.render import
|
|
11
|
+
from invarlock.reporting.render import render_report_markdown
|
|
12
|
+
from invarlock.reporting.report_builder import make_report
|
|
13
|
+
from invarlock.reporting.report_schema import REPORT_SCHEMA_VERSION, validate_report
|
|
22
14
|
except Exception: # pragma: no cover - provide soft stubs
|
|
23
|
-
|
|
15
|
+
REPORT_SCHEMA_VERSION = "v1"
|
|
24
16
|
|
|
25
|
-
def
|
|
17
|
+
def make_report(
|
|
26
18
|
report: RunReport,
|
|
27
19
|
baseline: RunReport | dict[str, Any],
|
|
28
20
|
) -> dict[str, Any]:
|
|
29
|
-
raise ImportError("invarlock.reporting.
|
|
21
|
+
raise ImportError("invarlock.reporting.report_builder not available")
|
|
30
22
|
|
|
31
|
-
def
|
|
32
|
-
raise ImportError("invarlock.reporting.
|
|
23
|
+
def render_report_markdown(evaluation_report: dict[str, Any]) -> str:
|
|
24
|
+
raise ImportError("invarlock.reporting.report_builder not available")
|
|
33
25
|
|
|
34
|
-
def
|
|
35
|
-
raise ImportError("invarlock.reporting.
|
|
26
|
+
def validate_report(report: dict[str, Any]) -> bool:
|
|
27
|
+
raise ImportError("invarlock.reporting.report_schema not available")
|
|
36
28
|
|
|
37
29
|
|
|
38
30
|
__all__ = [
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
31
|
+
"REPORT_SCHEMA_VERSION",
|
|
32
|
+
"make_report",
|
|
33
|
+
"render_report_markdown",
|
|
34
|
+
"validate_report",
|
|
43
35
|
]
|
invarlock/cli/adapter_auto.py
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
Auto adapter resolution utilities.
|
|
3
3
|
|
|
4
4
|
These helpers map a model identifier (HF directory or Hub ID) to a
|
|
5
|
-
concrete built-in adapter name (
|
|
5
|
+
concrete built-in adapter name (hf_causal, hf_mlm, hf_seq2seq, hf_causal_onnx)
|
|
6
|
+
without
|
|
6
7
|
adding a hard dependency on Transformers.
|
|
7
8
|
"""
|
|
8
9
|
|
|
@@ -46,11 +47,7 @@ def _detect_quant_family_from_cfg(cfg: dict[str, Any]) -> str | None:
|
|
|
46
47
|
return "hf_gptq"
|
|
47
48
|
if any(tok in method for tok in ("awq",)):
|
|
48
49
|
return "hf_awq"
|
|
49
|
-
|
|
50
|
-
if any(
|
|
51
|
-
str(q.get(k, "")).lower() in {"true", "1"}
|
|
52
|
-
for k in ("load_in_4bit", "load_in_8bit")
|
|
53
|
-
) or any("bitsandbytes" in str(v).lower() for v in q.values()):
|
|
50
|
+
if "bitsandbytes" in method or "bnb" in method:
|
|
54
51
|
return "hf_bnb"
|
|
55
52
|
except Exception:
|
|
56
53
|
return None
|
|
@@ -58,15 +55,15 @@ def _detect_quant_family_from_cfg(cfg: dict[str, Any]) -> str | None:
|
|
|
58
55
|
|
|
59
56
|
|
|
60
57
|
def resolve_auto_adapter(
|
|
61
|
-
model_id: str | os.PathLike[str], default: str = "
|
|
58
|
+
model_id: str | os.PathLike[str], default: str = "hf_causal"
|
|
62
59
|
) -> str:
|
|
63
60
|
"""Resolve an appropriate built-in adapter name for a model.
|
|
64
61
|
|
|
65
62
|
Heuristics:
|
|
66
63
|
- Prefer local config.json (no network). Inspect `model_type` and
|
|
67
|
-
`architectures` to classify
|
|
64
|
+
`architectures` to classify causal vs masked-LM vs seq2seq.
|
|
68
65
|
- Fallback to simple name heuristics on the model_id string.
|
|
69
|
-
- Default to `
|
|
66
|
+
- Default to `hf_causal` when unsure.
|
|
70
67
|
"""
|
|
71
68
|
cfg = _read_local_hf_config(model_id)
|
|
72
69
|
model_id_str = str(model_id)
|
|
@@ -77,32 +74,41 @@ def resolve_auto_adapter(
|
|
|
77
74
|
if fam:
|
|
78
75
|
return fam
|
|
79
76
|
mt = str(c.get("model_type", "")).lower()
|
|
77
|
+
if bool(c.get("is_encoder_decoder", False)):
|
|
78
|
+
return "hf_seq2seq"
|
|
80
79
|
archs = [str(a) for a in c.get("architectures", []) if isinstance(a, str)]
|
|
81
80
|
arch_blob = " ".join(archs)
|
|
82
|
-
if
|
|
83
|
-
|
|
84
|
-
or "Llama" in arch_blob
|
|
85
|
-
or "Mistral" in arch_blob
|
|
86
|
-
):
|
|
87
|
-
return "hf_llama"
|
|
81
|
+
if "ConditionalGeneration" in arch_blob or "Seq2SeqLM" in arch_blob:
|
|
82
|
+
return "hf_seq2seq"
|
|
88
83
|
# Treat masked-LM families as BERT-like
|
|
89
84
|
if (
|
|
90
85
|
mt in {"bert", "roberta", "distilbert", "albert", "deberta", "deberta-v2"}
|
|
91
86
|
or "MaskedLM" in arch_blob
|
|
92
87
|
):
|
|
93
|
-
return "
|
|
94
|
-
#
|
|
95
|
-
if "CausalLM" in arch_blob or
|
|
88
|
+
return "hf_mlm"
|
|
89
|
+
# Causal LM families (best-effort; structural validation happens in the adapter).
|
|
90
|
+
if "CausalLM" in arch_blob or "ForCausalLM" in arch_blob:
|
|
91
|
+
return "hf_causal"
|
|
92
|
+
if mt in {
|
|
93
|
+
"mistral",
|
|
94
|
+
"mixtral",
|
|
95
|
+
"qwen",
|
|
96
|
+
"qwen2",
|
|
97
|
+
"qwen2_moe",
|
|
98
|
+
"yi",
|
|
96
99
|
"gpt2",
|
|
97
100
|
"gpt_neox",
|
|
98
101
|
"opt",
|
|
99
102
|
"gptj",
|
|
100
|
-
"
|
|
103
|
+
"phi",
|
|
104
|
+
"falcon",
|
|
105
|
+
"glm",
|
|
106
|
+
"deepseek",
|
|
101
107
|
}:
|
|
102
|
-
return "
|
|
108
|
+
return "hf_causal"
|
|
103
109
|
return None
|
|
104
110
|
|
|
105
|
-
# If local directory contains ONNX model files, prefer
|
|
111
|
+
# If local directory contains ONNX model files, prefer the ONNX causal adapter.
|
|
106
112
|
try:
|
|
107
113
|
p = Path(model_id)
|
|
108
114
|
if p.exists() and p.is_dir():
|
|
@@ -114,7 +120,7 @@ def resolve_auto_adapter(
|
|
|
114
120
|
"encoder_model.onnx",
|
|
115
121
|
]
|
|
116
122
|
if any((p / fname).exists() for fname in onnx_files):
|
|
117
|
-
return "
|
|
123
|
+
return "hf_causal_onnx"
|
|
118
124
|
except Exception:
|
|
119
125
|
pass
|
|
120
126
|
|
|
@@ -134,10 +140,10 @@ def resolve_auto_adapter(
|
|
|
134
140
|
k in lower_id for k in ["bnb", "bitsandbytes", "-4bit", "-8bit", "4bit", "8bit"]
|
|
135
141
|
):
|
|
136
142
|
return "hf_bnb"
|
|
137
|
-
if any(k in lower_id for k in ["
|
|
138
|
-
return "
|
|
143
|
+
if any(k in lower_id for k in ["t5", "bart"]):
|
|
144
|
+
return "hf_seq2seq"
|
|
139
145
|
if any(k in lower_id for k in ["bert", "roberta", "albert", "deberta"]):
|
|
140
|
-
return "
|
|
146
|
+
return "hf_mlm"
|
|
141
147
|
return default
|
|
142
148
|
|
|
143
149
|
|
|
@@ -148,7 +154,7 @@ def apply_auto_adapter_if_needed(cfg: Any) -> Any:
|
|
|
148
154
|
"""
|
|
149
155
|
try:
|
|
150
156
|
adapter = str(getattr(cfg.model, "adapter", ""))
|
|
151
|
-
if adapter.strip().lower() not in {"auto", "
|
|
157
|
+
if adapter.strip().lower() not in {"auto", "auto_hf"}:
|
|
152
158
|
return cfg
|
|
153
159
|
model_id = str(getattr(cfg.model, "id", ""))
|
|
154
160
|
resolved = resolve_auto_adapter(model_id)
|