Files
cluster-knaster/docs/spec/SPEC-inventory.md
T
rorappandClaude Opus 5.5 c81e372c49
ci / test (push) Successful in 25s
sites: Inventar und Zielbild an echte Knoten (pve44–pve61) angepasst; ADR-0001/0002/0006 ergänzt
Aufbauplan Task 0.4:
- inventory.yaml: pve44/46/48/52/61 und GODE-PC-05/06 (Ada, Windows, cpu_roles: false)
- proxmox.yaml: eine GPU-VM pro Knoten mit allen Karten (D2), local-lvm/tank (D1 B),
  192.168.100.0/24 ohne VLAN, Gast-IPs .220–.239 (ANNAHME bis Task 0.2)
- registry.yaml/prometheus.yml: ops-Labels auf gpu-pve44/46/48, Ada ohne pve_node/vmid
- tofu: dynamische hostpci, Speicher je Gast; Ansible: pve_gpu_hosts/pve_kiosk,
  Replikation auf mehrere Ziele
- Placement: cpu_roles=false schließt Arbeitsplätze/Kiosk von CPU-Rollen aus
- PLAN §1.3/§1.4/§9 und ADR-Nachträge (D1 entschieden, D2/D3 Bestätigung offen)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 01:39:49 +02:00

2.5 KiB

SPEC-inventory: Inventar, Modell-Katalog, Placement

Paket: knaster.inventory. CLI: knaster inventory collect, knaster placement plan.

1. Node-Profil

name: pve-ada
cpu: {model: "...", cores: 8, threads: 16}
memory_gb: 64
disks: [{name: nvme0n1, size_gb: 256, rotational: false}]
gpus:
  - {index: 0, name: "NVIDIA RTX 4000 Ada Generation", memory_gb: 20, compute_cap: 8.9, driver: "..."}

Datenquellen: nvidia-smi --query-gpu=index,name,memory.total,compute_cap,driver_version --format=csv,noheader,nounits, /proc/meminfo, /proc/cpuinfo bzw. lscpu, lsblk -J -b -d -o NAME,SIZE,ROTA. Die Parser sind reine Funktionen auf dem jeweiligen Text und testbar. collect ruft die Befehle lokal auf.

2. Katalog (catalog/models.yaml, catalog/roles.yaml)

Engines (models.yaml → engines) setzen Untergrenzen für die Compute Capability, die für alle ihre Modelle gelten (z. B. pytorch ≥ 7.5). GPUs mit disabled: true im Inventar ignoriert das Placement und listet sie unter disabled_gpus. Ein Modell hat kind (llm, embedding, reranker, tts), vram_gb (Gewichte plus Mindest-KV-Cache), min_cc, engines, context, lora. Eine Rolle hat needs (engine, min_vram_gb, min_cc, max_cc?, gpu: true|false), prefer (z. B. smallest_fitting), count und slots.

3. Placement (plan(nodes, roles, models) -> PlacementPlan)

Deterministisch:

  1. Alle GPUs aller Nodes zu einer Liste (node, gpu) zusammenfassen.
  2. Rollen nach priority (aufsteigend) abarbeiten. Für jede Rolle werden count GPUs gesucht, die needs erfüllen und noch frei sind.
    • prefer: largest wählt die GPU mit dem meisten VRAM (für LLM-Rollen).
    • prefer: smallest_fitting wählt die kleinste passende GPU (für Embedding und Rerank). So bleiben große Karten frei.
  3. Rollen mit share_with: <rolle> teilen sich die GPU (bzw. bei gpu: false den Node) einer bereits platzierten Rolle. Ein Beispiel ist TTS auf gpu-flex.
  4. Rollen mit gpu: false bzw. cpu_fallback: true werden ohne passende GPU den CPU-Nodes zugewiesen, sortiert nach RAM. Nodes mit cpu_roles: false (Arbeitsplätze, Kiosk) sind davon ausgenommen. Dort wird nur die eigene GPU verplant.
  5. Pro zugewiesener Rolle werden die Katalogmodelle gelistet, die passen (Engine, VRAM, CC).
  6. Ergebnis: assignments[{role, node, gpu_index?, models_fitting[]}] und unplaced[{role, reason}].

Der Plan ist der Input für platform/proxmox (welche VM-Rolle auf welchem Host mit welchem Resource Mapping) und für die Registry (welche Slots existieren).