fix: a vision-projector .gguf is not accepted as a text encoder; a pack whose gguf library is missing says how to fix it (attacker round 8)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
f37a647d85
commit
dfa8f8edf2
@@ -256,6 +256,10 @@ def _load(path: str, clip: bool) -> tuple[dict, dict, str]:
|
||||
sd = read(path)
|
||||
if isinstance(sd, tuple): # newer ComfyUI-GGUF: (state dict, {arch_str, metadata})
|
||||
sd = sd[0]
|
||||
if clip and any(str(k).startswith(("blk.", "v.", "mm.", "token_embd")) for k in sd):
|
||||
# llama.cpp's own names came back unmapped: a vision projector (mmproj) or an architecture the pack
|
||||
# let through without a name map. Built as a text encoder it would be an empty shell that "loaded".
|
||||
raise ValueError("this .gguf is not a text encoder ComfyUI-GGUF can map (an mmproj / vision file, or an unsupported architecture)")
|
||||
options = {}
|
||||
ggml_ops = getattr(ops, "GGMLOps", None)
|
||||
if ggml_ops is not None:
|
||||
@@ -263,6 +267,8 @@ def _load(path: str, clip: bool) -> tuple[dict, dict, str]:
|
||||
return sd, options, f"gguf: quantized (ComfyUI-GGUF at {os.path.basename(d)})"
|
||||
except Exception as e: # noqa: BLE001 -- any refusal is a reason to fall back
|
||||
if importlib.util.find_spec("gguf") is None:
|
||||
if isinstance(e, ModuleNotFoundError) and "gguf" in str(e):
|
||||
raise RuntimeError(UNAVAILABLE) from e # the pack is here, the library it imports is not
|
||||
raise
|
||||
if clip:
|
||||
# The native reader keeps llama.cpp's tensor names; only the pack maps them back to a text encoder's.
|
||||
|
||||
@@ -286,3 +286,28 @@ def test_a_text_encoder_gguf_with_no_backend_says_the_pack_not_pip(monkeypatch):
|
||||
monkeypatch.setattr(gguf_support, "backend", lambda: None)
|
||||
with pytest.raises(RuntimeError, match="ComfyUI-GGUF"):
|
||||
gguf_support.load_clip_state_dict("/x.gguf")
|
||||
|
||||
|
||||
def _pack(tmp_path, body):
|
||||
d = tmp_path / "pack"
|
||||
d.mkdir()
|
||||
(d / "ops.py").write_text("class GGMLOps:\n pass\n")
|
||||
(d / "loader.py").write_text(body)
|
||||
return d
|
||||
|
||||
|
||||
def test_a_vision_projector_gguf_the_pack_lets_through_is_refused_as_a_text_encoder(tmp_path, monkeypatch):
|
||||
d = _pack(tmp_path, "def gguf_clip_loader(path):\n return {'v.blk.0.attn_q.weight': 1}\n")
|
||||
monkeypatch.setattr(gguf_support, "_pack_dir", lambda: str(d))
|
||||
monkeypatch.delitem(sys.modules, gguf_support._PKG_NAME, raising=False)
|
||||
with pytest.raises(RuntimeError, match="not supported"):
|
||||
gguf_support.load_clip_state_dict("/mmproj.gguf")
|
||||
|
||||
|
||||
def test_a_pack_whose_gguf_library_is_missing_says_how_to_fix_it_not_an_import_error(tmp_path, monkeypatch):
|
||||
d = _pack(tmp_path, "import gguf_missing_for_this_test\ndef gguf_sd_loader(path):\n return {}\n")
|
||||
monkeypatch.setattr(gguf_support, "_pack_dir", lambda: str(d))
|
||||
monkeypatch.delitem(sys.modules, gguf_support._PKG_NAME, raising=False)
|
||||
monkeypatch.setattr(gguf_support.importlib.util, "find_spec", lambda name: None)
|
||||
with pytest.raises(RuntimeError):
|
||||
gguf_support.load_state_dict("/x.gguf")
|
||||
|
||||
Reference in New Issue
Block a user