From c55d22752a8cc4a22c3cac4b710a8ff87f90014b Mon Sep 17 00:00:00 2001 From: digital-garbage <133010426+digital-garbage@users.noreply.github.com> Date: Sat, 22 Aug 2026 23:27:48 +0300 Subject: [PATCH] feat(loaders): make gguf a FunPack requirement A fresh install now reads .gguf with nothing extra. The no-backend message points at re-running requirements rather than naming a lone package. --- gguf_support.py | 9 ++++++--- requirements.txt | 3 +++ tests/test_gguf_support.py | 15 +++++++++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/gguf_support.py b/gguf_support.py index 9f0181c5..30aee2af 100644 --- a/gguf_support.py +++ b/gguf_support.py @@ -190,9 +190,12 @@ def backend() -> Optional[str]: UNAVAILABLE = ( - "No GGUF backend is available. Either install ComfyUI-GGUF (custom node pack — keeps the " - "weights quantized in VRAM, which is the point of GGUF), or `pip install gguf` into " - "ComfyUI's environment for a load-time dequantize that works but gives back no memory." + "No GGUF backend is available. The `gguf` package is one of FunPack's requirements, so an " + "install that predates .gguf support just needs them re-run:\n" + " pip install -r custom_nodes/ComfyUI-FunPack/requirements.txt\n" + "That gives a load-time dequantize: the file loads, but at its full size. To keep the " + "weights quantized in VRAM — which is the point of GGUF — install the ComfyUI-GGUF node " + "pack as well; FunPack uses it as the runtime and stays the only loader you wire." ) diff --git a/requirements.txt b/requirements.txt index 4b472b8b..e6861fbf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,9 @@ transformers>=5.0.0 huggingface_hub safetensors numpy +# Reads .gguf containers in the FunPack loaders. Pure python + numpy; it does not +# pull CUDA or any model. Without it a .gguf needs the ComfyUI-GGUF node pack instead. +gguf Pillow insightface opencv-python-headless diff --git a/tests/test_gguf_support.py b/tests/test_gguf_support.py index c80e683c..8d74b174 100644 --- a/tests/test_gguf_support.py +++ b/tests/test_gguf_support.py @@ -74,9 +74,11 @@ def test_no_backend_refuses_with_both_remedies(monkeypatch): with pytest.raises(RuntimeError) as e: gguf_support.load_state_dict("/nope.gguf") msg = str(e.value) - # Both ways out must be named: they have different consequences for VRAM. + # Both ways out must be named: they have different consequences for VRAM. `gguf` is a + # FunPack requirement now, so the first is a re-run of them rather than a lone package. assert "ComfyUI-GGUF" in msg - assert "pip install gguf" in msg + assert "requirements.txt" in msg + assert "quantized in VRAM" in msg def test_the_pack_wins_when_both_are_available(monkeypatch): @@ -229,3 +231,12 @@ def test_a_pack_refusal_without_the_library_still_raises(tmp_path, monkeypatch): monkeypatch.setattr(gguf_support.importlib.util, "find_spec", lambda name: None) with pytest.raises(ValueError, match="nope"): gguf_support.load_state_dict("/h3.gguf") + + +def test_gguf_is_a_declared_requirement(): + """The advice in UNAVAILABLE is "re-run FunPack's requirements", which is only true + while gguf is actually in them.""" + import pathlib + reqs = pathlib.Path("requirements.txt").read_text(encoding="utf-8") + lines = [ln.strip() for ln in reqs.splitlines() if ln.strip() and not ln.startswith("#")] + assert any(ln == "gguf" or ln.startswith("gguf") for ln in lines)