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:
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Pull Ollama models from a JSON list. Stdlib only. Runs on the VM."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
JOBS = Path("/tmp/gpu-rent-ollama-models.json")
|
||||
MARKER = Path("/mnt/swarm_data/.gpu-rent-ollama-pulling")
|
||||
|
||||
|
||||
def listed() -> set[str]:
|
||||
try:
|
||||
out = subprocess.check_output(["ollama", "list"], text=True, stderr=subprocess.DEVNULL)
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
return set()
|
||||
names: set[str] = set()
|
||||
for i, line in enumerate(out.splitlines()):
|
||||
if i == 0 and line.lower().startswith("name"):
|
||||
continue
|
||||
parts = line.split()
|
||||
if parts:
|
||||
names.add(parts[0])
|
||||
# also bare name without tag
|
||||
names.add(parts[0].split(":")[0])
|
||||
return names
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if not JOBS.is_file():
|
||||
print("no jobs file", file=sys.stderr)
|
||||
return 1
|
||||
models = json.loads(JOBS.read_text(encoding="utf-8"))
|
||||
if not isinstance(models, list) or not models:
|
||||
print("ollama pull: пустой список — skip")
|
||||
return 0
|
||||
have = listed()
|
||||
MARKER.parent.mkdir(parents=True, exist_ok=True)
|
||||
MARKER.write_text("1\n", encoding="utf-8")
|
||||
failed = 0
|
||||
try:
|
||||
for i, name in enumerate(models, 1):
|
||||
name = str(name).strip()
|
||||
if not name:
|
||||
continue
|
||||
bare = name.split(":")[0]
|
||||
if name in have or bare in have:
|
||||
# Prefer exact tag match when possible
|
||||
exact = any(h == name or h.startswith(name + ":") or name.startswith(h) for h in have)
|
||||
if name in have or exact:
|
||||
print(f"[{i}/{len(models)}] уже есть {name}")
|
||||
continue
|
||||
print(f"[{i}/{len(models)}] ollama pull {name}")
|
||||
try:
|
||||
subprocess.check_call(["ollama", "pull", name])
|
||||
except subprocess.CalledProcessError as exc:
|
||||
failed += 1
|
||||
print(f"FAIL pull {name}: {exc}", file=sys.stderr)
|
||||
finally:
|
||||
MARKER.unlink(missing_ok=True)
|
||||
if failed:
|
||||
return 1
|
||||
print("ollama pull ok")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user