feat(docker): support a multimodal projector via --mmproj
Vision-capable GGUFs need a separate projector (mmproj) that maps image embeddings into the text model's space. Add `mmproj` and `mmproj_offload` as config keys and CLI overrides, and pass them through to llama-server. The projector path resolves under hf_home exactly like model_path, so it is covered by the existing read-only mount. validate_model_path() now also checks the projector, which means --change rejects a missing one *before* it removes the running container. --no-mmproj-offload is suppressed when no projector is configured, since llama.cpp rejects the flag on its own. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
489af21fd2
commit
218c3fc791
9 changed files with 199 additions and 9 deletions
|
|
@ -213,3 +213,34 @@ def test_container_lock_force_bypasses_busy(tmp_path, capsys):
|
|||
entered = True
|
||||
assert entered is True
|
||||
assert "busy lock" in capsys.readouterr().err
|
||||
|
||||
|
||||
# --- model / mmproj path validation ---------------------------------------
|
||||
|
||||
|
||||
def test_validate_model_path_accepts_existing_model(tmp_path):
|
||||
(tmp_path / "m.gguf").write_bytes(b"x")
|
||||
cfg = make_cfg(hf_home=tmp_path, model_path="m.gguf")
|
||||
actions.validate_model_path(cfg) # must not raise
|
||||
|
||||
|
||||
def test_validate_model_path_rejects_missing_model(tmp_path):
|
||||
cfg = make_cfg(hf_home=tmp_path, model_path="absent.gguf")
|
||||
with pytest.raises(FileNotFoundError, match="model file not found"):
|
||||
actions.validate_model_path(cfg)
|
||||
|
||||
|
||||
def test_validate_model_path_rejects_missing_mmproj(tmp_path):
|
||||
# The model exists but the configured projector does not: --change must fail
|
||||
# here, before the running container is removed.
|
||||
(tmp_path / "m.gguf").write_bytes(b"x")
|
||||
cfg = make_cfg(hf_home=tmp_path, model_path="m.gguf", mmproj="absent-proj.gguf")
|
||||
with pytest.raises(FileNotFoundError, match="mmproj file not found"):
|
||||
actions.validate_model_path(cfg)
|
||||
|
||||
|
||||
def test_validate_model_path_accepts_existing_mmproj(tmp_path):
|
||||
(tmp_path / "m.gguf").write_bytes(b"x")
|
||||
(tmp_path / "proj.gguf").write_bytes(b"x")
|
||||
cfg = make_cfg(hf_home=tmp_path, model_path="m.gguf", mmproj="proj.gguf")
|
||||
actions.validate_model_path(cfg) # must not raise
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue