TTS-Slots (Piper CPU, Qwen3-TTS auf Ada), M4000 außer Betrieb, Engine-Grenzen im Placement (ADR-0006)
ci / test (push) Successful in 24s
ci / test (push) Successful in 24s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,8 @@ Vorgehen pro Baustein: **Spec → Implementierung → Tests → Commit**. Bis zu
|
||||
| 8 | API | SPEC-core §8 | FastAPI-App, Auth, Metriken | ✅ |
|
||||
| 9 | Deployment-Artefakte | PLAN §1, §3 | Compose pro Rolle, LiteLLM, Prometheus-Regeln, Alertmanager, n8n-Workflows | ✅ |
|
||||
| 10 | Plattform | ADR-0001/0002 | OpenTofu (bpg/proxmox), Ansible-Rollen (IOMMU/VFIO, ZFS-Replikation, Treiber-Pinning, Xid-Exporter) | ✅ geschrieben, **nicht** gegen echten Cluster/`tofu validate` geprüft |
|
||||
| 11 | CI | – | Gitea Actions: Tests, Lint, Konfig-Validierung, Compose-Prüfung | ✅ |
|
||||
| 11 | CI | – | Gitea Actions: Tests, Lint, Konfig-Validierung (Runner `gitrunner-knaster`) | ✅ |
|
||||
| 12 | TTS + Legacy-GPUs | ADR-0006 | Engine-Grenzen im Katalog, deaktivierte GPUs, geteilte GPU-Rollen, TTS-Slots, Piper-Dienst, TTS-Canary, `knaster bench tts` | ✅ |
|
||||
|
||||
## Teststrategie
|
||||
|
||||
@@ -29,7 +30,7 @@ Vorgehen pro Baustein: **Spec → Implementierung → Tests → Commit**. Bis zu
|
||||
|
||||
| Was | Wie geprüft |
|
||||
|---|---|
|
||||
| Kernlogik (Router, Eskalation, Verifier, Pflege-Agent, Healer, Lifecycle, Placement) | 127 Unit- und Integrationstests (`make test`) |
|
||||
| Kernlogik (Router, Eskalation, Verifier, Pflege-Agent, Healer, Lifecycle, Placement) | 136 Unit- und Integrationstests (`make test`) |
|
||||
| Konfiguration (Registry ↔ Skills ↔ LiteLLM ↔ Healer ↔ Policy ↔ Katalog) | `knaster validate` |
|
||||
| Compose-Dateien | `docker compose config` (`make compose-check`) |
|
||||
| Prometheus/Alertmanager/n8n-JSON | Strukturtests (`core/tests/test_artifacts.py`) |
|
||||
@@ -43,6 +44,8 @@ Vorgehen pro Baustein: **Spec → Implementierung → Tests → Commit**. Bis zu
|
||||
- Den n8n Chat-Trigger nach dem Import prüfen (Parameter der Knotenversion).
|
||||
- `sites/knaster/*`: Hosts, VM-IDs, IPs und PCI-Adressen sind Annahmen und werden durch den Inventarlauf ersetzt.
|
||||
- Classifier `ticket-kategorie.json` entsteht erst aus gelabelten Fällen (Warnung von `knaster validate`).
|
||||
- Qwen3-TTS-Server für `tts-de-hq` auswählen (OpenAI-kompatibler Wrapper um faster-qwen3-tts) und Image setzen.
|
||||
- Benchmark-Tag: `llama-bench` auf P2000 (und M4000), `knaster bench tts` für beide TTS-Slots, dazu Strom messen. Ergebnisse in Katalog und Registry übernehmen.
|
||||
|
||||
## Gemeinsames Deployment (später)
|
||||
|
||||
|
||||
+8
-4
@@ -51,12 +51,15 @@ Ziel: Ein starkes LLM (OpenRouter) erarbeitet neue Aufgaben einmalig und bricht
|
||||
|---|---|---|---|
|
||||
| `gpu-main` | RTX 4000 Ada #1 (20 GB) | vLLM, Multi-LoRA | Slot `tier1-general` plus Skill-Adapter |
|
||||
| `gpu-flex` | RTX 4000 Ada #2 (20 GB) | vLLM / Unsloth | tagsüber zweiter Slot oder Reserve, nachts LoRA-Training |
|
||||
| `gpu-embed` | 3× Quadro P2000 (5 GB) | llama.cpp (Embedding/Rerank) | `embed-default`, `rerank-default`, redundant |
|
||||
| `gpu-small` | 4× Quadro M4000 (8 GB) | llama.cpp | `verifier-small`, `signature-extractor` (3–4B) – **auf Nutzen prüfen** |
|
||||
| `gpu-embed` | 2× Quadro P2000 (5 GB) | llama.cpp (Embedding/Rerank) | `embed-default`, `rerank-default`, redundant auf zwei Hosts |
|
||||
| `gpu-small` | Quadro P2000 (5 GB) | llama.cpp | `verifier-small`, `signature-extractor` (3–4B) |
|
||||
| – | 4× Quadro M4000 (8 GB) | – | **vorerst außer Betrieb** (ADR-0006), nur nach Benchmark für llama.cpp-Rollen |
|
||||
| `tts-hq` | teilt RTX 4000 Ada #2 | PyTorch | `tts-de-hq`: Qwen3-TTS 1.7B (ADR-0006) |
|
||||
| `tts-cpu` | Infra-LXC (CPU) | Piper (ONNX) | `tts-de`: schnelle Sprachausgabe, Fallback |
|
||||
| `infra` | i7 6./7. Gen, 32 GB | Docker | n8n, LiteLLM, Postgres+pgvector, Redis, Router, Healer, Langfuse, Prometheus/Grafana |
|
||||
| `strong` | extern | OpenRouter | `tier0-strong`, Skill-Autor (Hermes) |
|
||||
|
||||
Wichtig: Auf Maxwell und Pascal läuft kein vLLM (das braucht Compute Capability ≥ 7.0), und CUDA 13 unterstützt sie nicht mehr. Daher auf diesen Nodes Treiber und Images pinnen.
|
||||
Wichtig: Auf Maxwell und Pascal läuft kein vLLM (das braucht Compute Capability ≥ 7.0), und CUDA 13 unterstützt sie nicht mehr. Daher auf diesen Nodes Treiber und Images pinnen. Auch PyTorch hat dort keine Zukunft mehr (2.14 ist die letzte Version mit CUDA-12-Wheels). Deshalb laufen auf alten Karten nur llama.cpp-Workloads (ADR-0006).
|
||||
|
||||
### 1.4 Netzwerk und Storage (entschieden, siehe ADR-0002)
|
||||
|
||||
@@ -296,10 +299,11 @@ Die Portabilität beruht also auf den **Daten und der Pipeline**, nicht auf Gewi
|
||||
- Slots statt Modellnamen, eine Lifecycle-Pipeline für alle Wechsel (ADR-0003)
|
||||
- Halbautomatische Pflege über einen Pflege-Agenten mit Freigabe per Prompt (ADR-0004)
|
||||
- Infrastruktur heilt deterministisch, ohne LLM-Entscheidungen (ADR-0005)
|
||||
- Alte GPUs nur llama.cpp, M4000 vorerst aus, TTS mit Piper (CPU) und Qwen3-TTS (Ada) (ADR-0006)
|
||||
|
||||
### Offen
|
||||
1. Erstes Basismodell für `tier1-general` (8–14B, gut quantisierbar, LoRA-freundlich, gutes Deutsch). Entscheidung per Kalibrierungslauf.
|
||||
2. Bleiben die M4000 im Einsatz? Benchmark gegen P2000 bzw. CPU und Stromverbrauch
|
||||
2. Kommen die M4000 zurück? `llama-bench` plus Strommessung am Deployment-Tag (bis dahin außer Betrieb, ADR-0006)
|
||||
3. Verifier-Strategie pro Aufgabentyp: Code-Checks, Schema, kleines Judge-Modell, Stichproben durch das starke Modell
|
||||
4. Schwellwerte: Graduierung (Start 90 %), Fallzahl fürs LoRA-Training (Start 300), Canary-Anteil (Start 10 %)
|
||||
5. Kanal für den Pflege-Agenten: n8n Chat, Telegram oder Matrix
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# ADR-0006: Alte GPUs nur für llama.cpp, M4000 vorerst außer Betrieb, TTS auf Ada und CPU
|
||||
|
||||
- Status: angenommen
|
||||
- Datum: 2026-10-12
|
||||
|
||||
## Kontext
|
||||
- PyTorch unterstützt Maxwell und Pascal seit 2.8 nur noch in den cu126-Builds. **PyTorch 2.14 ist die letzte Version mit CUDA-12.x-Wheels** (Ankündigung vom 04.09.2026), danach geht es nur noch über einen eigenen Build.
|
||||
- Pascal hat weder bf16 noch schnelles FP16, und FlashAttention fehlt. Qwen3-TTS 1.7B erreicht auf einer Tesla P40 nur **RTF ~7,3** (Referenz-Implementierung, gemessen von tinycomputers.io). P2000 und M4000 sind schwächer.
|
||||
- llama.cpp unterstützt Maxwell und Pascal mit CUDA 12 weiterhin. FlashAttention läuft dort auch auf Maxwell.
|
||||
- Für die M4000 gibt es keine direkten Messungen. Geschätzt liegt sie bei 7B Q4 auf 12–25 Token/s, bei 120 W pro Karte. Die P2000 decken Embedding, Rerank und Verifier bereits ab.
|
||||
|
||||
## Entscheidung
|
||||
1. **Engine-Grenzen im Katalog** (`catalog/models.yaml → engines`): `pytorch` ab Compute Capability 7.5, `vllm` ab 7.0, `llamacpp` ab 5.0. Das Placement setzt PyTorch-Workloads damit nie auf Maxwell/Pascal.
|
||||
2. **M4000 vorerst außer Betrieb** (`disabled: true` im Inventar). Wieder aufgenommen werden sie nur nach `llama-bench` plus Strommessung am Deployment-Tag, und dann nur für llama.cpp-Rollen.
|
||||
3. **TTS:**
|
||||
- `tts-de`: Piper auf der CPU im Infra-LXC. Schnell, robust, ohne GPU, zugleich Fallback.
|
||||
- `tts-de-hq`: Qwen3-TTS 1.7B (Apache 2.0, Deutsch, Stimmenklonen) in bf16 auf `gpu-flex`, im Wechsel mit Training und `tier1-flex`. Wenn TTS aktiv ist, sinkt der vLLM-Anteil am VRAM auf ~55 %.
|
||||
- Kein TTS auf P2000 oder M4000.
|
||||
|
||||
## Folgen
|
||||
- Bei `gpu-flex` muss sich der Lifecycle die Karte mit TTS teilen. Während des Trainings gehen sowohl `tier1-flex` als auch `tts-de-hq` auf `unavailable`, und LiteLLM fällt auf `tts-de` zurück.
|
||||
- Die tatsächlichen RTF-Werte misst `knaster bench tts` beim Deployment. Sie ersetzen die Schätzungen im Katalog.
|
||||
@@ -17,7 +17,8 @@ Datenquellen: `nvidia-smi --query-gpu=index,name,memory.total,compute_cap,driver
|
||||
|
||||
## 2. Katalog (`catalog/models.yaml`, `catalog/roles.yaml`)
|
||||
|
||||
Ein Modell hat `kind` (llm, embedding, reranker), `vram_gb` (Gewichte plus Mindest-KV-Cache), `min_cc`, `engines`, `context`, `lora`.
|
||||
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`)
|
||||
@@ -27,8 +28,9 @@ Deterministisch:
|
||||
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 `gpu: false` bzw. `cpu_fallback: true` werden ohne passende GPU den CPU-Nodes zugewiesen, sortiert nach RAM.
|
||||
4. Pro zugewiesener Rolle werden die Katalogmodelle gelistet, die passen (Engine, VRAM, CC).
|
||||
5. Ergebnis: `assignments[{role, node, gpu_index?, models_fitting[]}]` und `unplaced[{role, reason}]`.
|
||||
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.
|
||||
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).
|
||||
|
||||
Reference in New Issue
Block a user