ci / test (push) Successful in 25s
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>
37 lines
2.5 KiB
Markdown
37 lines
2.5 KiB
Markdown
# SPEC-inventory: Inventar, Modell-Katalog, Placement
|
|
|
|
Paket: `knaster.inventory`. CLI: `knaster inventory collect`, `knaster placement plan`.
|
|
|
|
## 1. Node-Profil
|
|
|
|
```yaml
|
|
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).
|