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:
@@ -3,12 +3,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from gpu_rent.config import Config
|
||||
from gpu_rent.inventory import FlavorInfo, looks_like_gpu, rank_flavors, resolve_flavor
|
||||
|
||||
Log = Callable[[str], None]
|
||||
Ask = Callable[[str, str], str]
|
||||
Confirm = Callable[[str], bool]
|
||||
|
||||
|
||||
def list_ranked_flavors(flavors: list[Any], cfg: Config) -> list[FlavorInfo]:
|
||||
@@ -61,6 +64,93 @@ def print_up_preview(
|
||||
log(f"! {line}")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ServerPlan:
|
||||
flavor: FlavorInfo
|
||||
data_gb: int
|
||||
spot: bool
|
||||
|
||||
|
||||
def prompt_server_plan(
|
||||
cfg: Config,
|
||||
flavors: list[Any],
|
||||
*,
|
||||
picked: FlavorInfo,
|
||||
spot: bool,
|
||||
ask: Ask,
|
||||
confirm: Confirm | None = None,
|
||||
) -> ServerPlan:
|
||||
"""Interactive Selectel VM knobs before create (flavor / disk / spot)."""
|
||||
ranked = list_ranked_flavors(flavors, cfg)
|
||||
if not ranked:
|
||||
return ServerPlan(flavor=picked, data_gb=cfg.data_volume_size_gb, spot=spot)
|
||||
|
||||
default_idx = 1
|
||||
for i, info in enumerate(ranked, 1):
|
||||
if info.id == picked.id:
|
||||
default_idx = i
|
||||
break
|
||||
|
||||
raw_idx = ask(
|
||||
f"Flavor Selectel [1-{len(ranked)}] (Enter = рекомендация)",
|
||||
str(default_idx),
|
||||
).strip()
|
||||
try:
|
||||
idx = int(raw_idx)
|
||||
except ValueError as exc:
|
||||
raise ValueError(f"номер flavor: жду 1…{len(ranked)}, получили {raw_idx!r}") from exc
|
||||
if idx < 1 or idx > len(ranked):
|
||||
raise ValueError(f"номер flavor: жду 1…{len(ranked)}, получили {idx}")
|
||||
chosen = ranked[idx - 1]
|
||||
|
||||
raw_gb = ask(
|
||||
"Data disk GB (тариф 24/7; рост только вверх)",
|
||||
str(cfg.data_volume_size_gb),
|
||||
).strip()
|
||||
try:
|
||||
data_gb = int(raw_gb)
|
||||
except ValueError as exc:
|
||||
raise ValueError(f"Data disk GB: жду число, получили {raw_gb!r}") from exc
|
||||
if data_gb < 20:
|
||||
raise ValueError("Data disk GB: минимум 20")
|
||||
|
||||
spot_default = "Y" if spot else "n"
|
||||
raw_spot = (
|
||||
ask(
|
||||
"Preemptible GPU (дешевле, могут усыпить ~24ч)? [Y/n]",
|
||||
spot_default,
|
||||
)
|
||||
.strip()
|
||||
.lower()
|
||||
)
|
||||
if raw_spot in {"", "y", "yes", "1", "true", "on"}:
|
||||
use_spot = True
|
||||
elif raw_spot in {"n", "no", "0", "false", "off"}:
|
||||
use_spot = False
|
||||
else:
|
||||
raise ValueError(f"preemptible: жду Y/n, получили {raw_spot!r}")
|
||||
|
||||
changed = (
|
||||
chosen.id != picked.id
|
||||
or data_gb != cfg.data_volume_size_gb
|
||||
or use_spot != spot
|
||||
)
|
||||
if confirm and changed and confirm("Запомнить flavor/disk/spot в gpu-rent.vars?"):
|
||||
from gpu_rent.paths import vars_path
|
||||
from gpu_rent.varsfile import upsert_vars
|
||||
|
||||
upsert_vars(
|
||||
vars_path(),
|
||||
{
|
||||
"DEFAULT_FLAVOR_ID": chosen.id,
|
||||
"DATA_VOLUME_SIZE_GB": str(data_gb),
|
||||
"DEFAULT_SPOT": "true" if use_spot else "false",
|
||||
},
|
||||
)
|
||||
|
||||
return ServerPlan(flavor=chosen, data_gb=data_gb, spot=use_spot)
|
||||
|
||||
|
||||
def resolve_and_preview(
|
||||
cfg: Config,
|
||||
flavors: list[Any],
|
||||
|
||||
Reference in New Issue
Block a user