Update LLM support for llama.cpp and enhance configuration management

- Added support for `llamacpp-models.yaml` in `.gitignore` and implemented logic to copy it in `gpu-rent.ps1` and `gpu-rent.sh`.
- Enhanced CLI to prompt for llama.cpp model presets during setup and execution, improving user experience.
- Updated configuration handling to include `llamacpp_models_manifest` and related functions for managing llama.cpp models.
- Improved documentation in `cli.md` and `llm.md` to reflect changes in llama.cpp integration and model management.
- Refactored provisioning logic to handle llama.cpp model downloads and configurations effectively.
This commit is contained in:
Leonid Pershin
2026-08-21 06:25:12 +03:00
parent 2ccb03f7d2
commit 64f93b4bf6
18 changed files with 607 additions and 32 deletions
+31
View File
@@ -0,0 +1,31 @@
from pathlib import Path
from gpu_rent.llm_runtime import (
gguf_filename_from_url,
parse_llamacpp_models,
write_llamacpp_models_preset,
)
def test_gguf_filename_from_url():
url = (
"https://huggingface.co/org/repo/resolve/main/"
"Qwen2.5-3B-Instruct-Q4_K_M.gguf"
)
assert gguf_filename_from_url(url) == "Qwen2.5-3B-Instruct-Q4_K_M.gguf"
def test_write_and_parse_llamacpp_preset(tmp_path: Path):
path = tmp_path / "llamacpp-models.yaml"
write_llamacpp_models_preset(path, "light")
entries = parse_llamacpp_models(path)
assert len(entries) == 1
assert entries[0].default is True
assert "Qwen2.5-3B" in entries[0].url
assert entries[0].url.startswith("https://")
def test_parse_llamacpp_empty(tmp_path: Path):
path = tmp_path / "llamacpp-models.yaml"
write_llamacpp_models_preset(path, "empty")
assert parse_llamacpp_models(path) == []
+61
View File
@@ -0,0 +1,61 @@
from gpu_rent.inventory import FlavorInfo
from gpu_rent.ux import prompt_server_plan
from gpu_rent.varsfile import parse_vars_file, upsert_vars
def _cfg_stub(monkeypatch, data_gb: int = 100):
monkeypatch.setenv("OS_AUTH_URL", "https://example.invalid/identity/v3")
monkeypatch.setenv("OS_USER_DOMAIN_NAME", "999")
monkeypatch.setenv("OS_USERNAME", "svc")
monkeypatch.setenv("OS_PASSWORD", "secret")
monkeypatch.setenv("OS_PROJECT_ID", "proj")
monkeypatch.setenv("OS_REGION_NAME", "ru-7")
monkeypatch.setenv("GPU_RENT_AZ", "ru-7a")
monkeypatch.setenv("DATA_VOLUME_SIZE_GB", str(data_gb))
from gpu_rent.config import load_config
return load_config(require_auth=True)
def test_prompt_server_plan_with_ranked(monkeypatch, tmp_path):
cfg = _cfg_stub(monkeypatch)
monkeypatch.setattr("gpu_rent.paths.app_root", lambda: tmp_path)
f1 = FlavorInfo(
id="a", name="small", vcpus=4, ram_mb=16384, disabled=False, extra={}, label="4090-24"
)
f2 = FlavorInfo(
id="b", name="big", vcpus=12, ram_mb=65536, disabled=False, extra={}, label="4090-48"
)
monkeypatch.setattr(
"gpu_rent.ux.list_ranked_flavors",
lambda flavors, cfg: [f1, f2],
)
answers = iter(["2", "200", "n"])
def ask(msg: str, default: str = "") -> str:
return next(answers)
remembered: list[bool] = []
plan = prompt_server_plan(
cfg,
["x"],
picked=f1,
spot=True,
ask=ask,
confirm=lambda m: remembered.append(True) or False,
)
assert plan.flavor.id == "b"
assert plan.data_gb == 200
assert plan.spot is False
assert remembered
def test_upsert_vars(tmp_path):
path = tmp_path / "gpu-rent.vars"
path.write_text("# c\nLLM_RUNTIME=none\n", encoding="utf-8")
upsert_vars(path, {"LLM_RUNTIME": "llamacpp", "DATA_VOLUME_SIZE_GB": "200"})
data = parse_vars_file(path)
assert data["LLM_RUNTIME"] == "llamacpp"
assert data["DATA_VOLUME_SIZE_GB"] == "200"