Update configuration and documentation for LLM support and local watchdog

- Added `ollama-models.yaml` to .gitignore and implemented logic to copy it in gpu-rent.ps1 and gpu-rent.sh.
- Enhanced env.example to include new variables for LLM runtime options and local watchdog configuration.
- Updated CLI commands to support LLM options during setup and execution, including new flags for Ollama and llama.cpp.
- Improved documentation in cli.md and README.md to reflect changes in LLM integration and local watchdog functionality.
- Adjusted architecture and decisions documentation to clarify the role of LLMs and local watchdog in the system.
This commit is contained in:
Leonid Pershin
2026-08-21 05:29:23 +03:00
parent a9cf2e0f90
commit 2005b00175
43 changed files with 2258 additions and 197 deletions
+49 -35
View File
@@ -7,7 +7,13 @@ from pathlib import Path
from gpu_rent.config import Config
from gpu_rent.payload import has_payload, iter_payload_files, model_push_set, sha256_file
from gpu_rent.ssh_ops import get_file, put_file, remote_sha256, run_ssh
from gpu_rent.ssh_ops import (
get_file_on,
open_ssh,
put_file_on,
remote_sha256_on,
run_ssh_on,
)
Log = Callable[[str], None]
@@ -26,19 +32,22 @@ def push_tree(
return 0
files = model_push_set(local_root) if models else iter_payload_files(local_root)
sent = 0
for path in files:
rel = path.relative_to(local_root).as_posix()
remote = f"{remote_root.rstrip('/')}/{rel}"
local_hash = sha256_file(path)
remote_hash = remote_sha256(cfg, host, remote)
if remote_hash and remote_hash.lower() == local_hash.lower():
continue
if models and not _is_weight_name(path.name):
# sidecar: warn if we somehow got here without weight — still send
pass
log(f"push {rel}")
put_file(cfg, host, path, remote)
sent += 1
client = open_ssh(cfg, host)
try:
for path in files:
rel = path.relative_to(local_root).as_posix()
remote = f"{remote_root.rstrip('/')}/{rel}"
local_hash = sha256_file(path)
remote_hash = remote_sha256_on(client, remote)
if remote_hash and remote_hash.lower() == local_hash.lower():
continue
if models and not _is_weight_name(path.name):
pass
log(f"push {rel}")
put_file_on(client, path, remote)
sent += 1
finally:
client.close()
if sent == 0:
log(f"push {local_root.name}: всё уже на VM")
else:
@@ -48,29 +57,34 @@ def push_tree(
def _is_weight_name(name: str) -> bool:
lower = name.lower()
return lower.endswith((".safetensors", ".ckpt", ".pt", ".pth", ".bin", ".gguf", ".sft", ".onnx"))
return lower.endswith(
(".safetensors", ".ckpt", ".pt", ".pth", ".bin", ".gguf", ".sft", ".onnx")
)
def pull_tree(cfg: Config, host: str, remote_root: str, local_root: Path, log: Log) -> int:
listing = run_ssh(
cfg,
host,
f"find {remote_root} -type f 2>/dev/null | sed 's|^{remote_root}/||'",
check=False,
timeout=120,
)
names = [line.strip() for line in listing.splitlines() if line.strip()]
pulled = 0
for rel in names:
if rel.endswith("/.gitkeep") or rel.rsplit("/", 1)[-1] in {".gitkeep", "README.md"}:
continue
remote = f"{remote_root.rstrip('/')}/{rel}"
local = local_root / rel
remote_hash = remote_sha256(cfg, host, remote)
if local.is_file() and remote_hash and sha256_file(local).lower() == remote_hash.lower():
continue
log(f"pull {rel}")
get_file(cfg, host, remote, local)
pulled += 1
client = open_ssh(cfg, host)
try:
listing = run_ssh_on(
client,
f"find {remote_root} -type f 2>/dev/null | sed 's|^{remote_root}/||'",
check=False,
timeout=120,
)
names = [line.strip() for line in listing.splitlines() if line.strip()]
pulled = 0
for rel in names:
if rel.endswith("/.gitkeep") or rel.rsplit("/", 1)[-1] in {".gitkeep", "README.md"}:
continue
remote = f"{remote_root.rstrip('/')}/{rel}"
local = local_root / rel
remote_hash = remote_sha256_on(client, remote)
if local.is_file() and remote_hash and sha256_file(local).lower() == remote_hash.lower():
continue
log(f"pull {rel}")
get_file_on(client, remote, local)
pulled += 1
finally:
client.close()
log(f"pull Output: {pulled} файл(ов)" if pulled else "pull Output: нечего забирать")
return pulled