From eb456b37ea9ea7f33781c2311cbaea445f869580 Mon Sep 17 00:00:00 2001 From: Johannes Rest Date: Mon, 12 Oct 2026 12:36:11 +0200 Subject: [PATCH] Preserve desktop VRAM reserve and portable CPU compression setup --- CHANGELOG.md | 10 +++ README.md | 21 +++-- config/compression.env.example | 20 +++++ config/llama-local.env.example | 2 +- config/llama.env.example | 6 +- docs/MIGRATION.md | 13 ++- docs/RTX3080.md | 105 +++++++++++++++++++++++-- docs/VALIDATION.md | 13 +++ docs/WORKSTATION.md | 25 +++++- install.sh | 2 + libexec/hermes-stack-llama-profile | 4 +- libexec/hermes-stack-llama-run | 5 +- systemd/user/llama-compression.service | 20 +++++ tests/test_llama.py | 30 ++++++- uninstall.sh | 4 +- 15 files changed, 255 insertions(+), 25 deletions(-) create mode 100644 config/compression.env.example create mode 100644 systemd/user/llama-compression.service diff --git a/CHANGELOG.md b/CHANGELOG.md index 0026861..9ea8316 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# 2026-10-12 — VRAM-Reserve und portable CPU-Kompression + +- `desktop-64k` mit 4096 MiB Fit-Zielmarge und 64K Kontext als Standard neuer + Konfigurationen ergänzt; frühere Profile bleiben verfügbar. +- Separaten CPU-Kompressionsdienst mit eigener portabler Konfiguration, + Geräte-/Op-/KV-Offload-Ausschluss und Installation ohne Aktivierung ergänzt. +- Migrationsschritte, tatsächliche Workstation-Abnahme und Prüfgrenzen dokumentiert. +- Bestehende lokale Konfigurationen und laufende Dienste bleiben beim Deployment + erhalten; Optionen werden vor dem Modellstart auf Unterstützung geprüft. + # 2026-09-10 — Cleanup-Reparatur und dauerhafte Modelle - Korrigierte Cleanup-Skripte unter maintenance/ aufgenommen: kein globales diff --git a/README.md b/README.md index fc3f8ad..79ecdc8 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Reproduzierbares Benutzer-Deployment für Hermes Agent auf Arch Linux mit: - offizieller Hermes-Git-Installation unter `~/.hermes/hermes-agent` - von Hermes erzeugtem systemd-User-Service für den Messaging Gateway - optionalem lokalen llama.cpp/OpenAI-kompatiblen Modellendpunkt +- optionalem CPU-Kompressionsserver für Hermes - optionalem signal-cli HTTP-Daemon - robustem Hermes-Update mit Vorprüfung, Retry, Backup und Rollback - regelmäßigen Healthchecks und Selbstheilungsversuchen @@ -13,7 +14,7 @@ Reproduzierbares Benutzer-Deployment für Hermes Agent auf Arch Linux mit: - optionalem CUDA-Build von llama-server, llama-cli und llama-bench - Qwen-/RTX-3080-Profilen mit prüfbarem Wechsel und Rückweg -Stand: 2026-09-05. Für deine **bestehende Workstation** zuerst +Stand: 2026-10-12. Für deine **bestehende Workstation** zuerst [`docs/WORKSTATION.md`](docs/WORKSTATION.md) lesen. Der Schnellstart unten ist für eine neue Maschine. Hardware-Leistungsgewinne sind noch nicht auf deiner GPU gemessen. Es wird kein Gitea-Server angelegt und nichts automatisch gepusht. @@ -43,6 +44,8 @@ Danach die beim ersten Lauf erzeugten lokalen Konfigurationen bearbeiten: ```bash $EDITOR ~/.config/hermes-stack-maintenance/config.env $EDITOR ~/.config/hermes-stack-maintenance/llama.env +# Bei Nutzung der lokalen Kompression: +$EDITOR ~/.config/hermes-stack-maintenance/compression.env $EDITOR ~/.config/hermes-stack-maintenance/signal-cli.env $EDITOR ~/.hermes/.env ``` @@ -123,11 +126,17 @@ Start des llama-Dienstes geladen, nicht bei der Konfigurationsprüfung. ~/.local/libexec/hermes-stack-llama-report ``` -`baseline` behält deine bisherigen 64K Kontext / 1536 MiB Fit-Zielmarge. -`balanced` reduziert nur den Kontext auf 48K; `vram-plus` danach optional die -Marge auf 1280 MiB. `compact` bietet 32K bei 1536 MiB. Das sind Vergleichsprofile, -keine Garantie gegen Desktop-Speicherdruck. Details, Messprotokoll und Rücknahme: -[`docs/RTX3080.md`](docs/RTX3080.md). +Für neue Konfigurationen ist `desktop-64k` der Standard: 64K Kontext, +4096 MiB Fit-Zielmarge, Reasoning-Budget 128 ohne Reasoning-Preserve. +Das priorisiert Spielraum für Browser und Desktop auf einer gemeinsam genutzten +GPU. Die früheren Profile bleiben für bewusste Vergleiche verfügbar. +Bestehende Konfigurationen werden nicht umgestellt. Bei expliziten `LLAMA_ARGS` +und leerem `LLAMA_PROFILE` wirken die Profile nicht. + +Der optionale Dienst `llama-compression.service` verwendet eine eigene +`compression.env`, Port 8081 und CPU-Ausführung einschließlich KV-/Op-Offload. +Für beide Server werden Modellgewichte separat bereitgestellt. Einrichtung, +Messgrenzen und Migration: [`docs/RTX3080.md`](docs/RTX3080.md). Profilwechsel ändern zunächst nur eine separate Auswahl-Datei. Ein Neustart benötigt `hermes-stack-llama-restart --jobs-finished`. Der Healthcheck teilt das diff --git a/config/compression.env.example b/config/compression.env.example new file mode 100644 index 0000000..4def57b --- /dev/null +++ b/config/compression.env.example @@ -0,0 +1,20 @@ +# Optionaler CPU-Kompressionsserver. Modellgewichte separat bereitstellen. +# Gleiche Binary-Auswahl wie beim Hauptmodell; bei Bedarf explizit setzen. +LLAMA_SERVER_BIN="" +LLAMA_MODEL="$HOME/.local/share/hermes-stack/models/qwen3-1.7b-compression/Qwen3-1.7B-Q4_K_M.gguf" +LLAMA_HF_REPO="" +LLAMA_MMPROJ="" +LLAMA_ALIAS="qwen3-1.7b-compression" +LLAMA_HOST="127.0.0.1" +LLAMA_PORT="8081" +LLAMA_PROFILE="" +LLAMA_ARGS=( + --ctx-size 65536 --rope-scaling yarn --rope-scale 2 --yarn-orig-ctx 32768 + --parallel 1 --jinja --reasoning-budget 0 --no-reasoning-preserve + --n-gpu-layers 0 --device none --no-op-offload --no-kv-offload + --threads 8 --threads-batch 8 --flash-attn auto + --cache-type-k q8_0 --cache-type-v q8_0 --no-ui +) +# 64K-Kontext ist die übernommene Workstation-Konfiguration mit YaRN. +# Die Binary meldet Kontext über dem Trainingslimit; Qualität bei langen +# Kompressionsaufgaben auf dem Zielmodell gesondert prüfen. diff --git a/config/llama-local.env.example b/config/llama-local.env.example index 98ba1e4..530f37c 100644 --- a/config/llama-local.env.example +++ b/config/llama-local.env.example @@ -9,5 +9,5 @@ LLAMA_HF_REPO="" LLAMA_ALIAS="qwen38-27b-local" LLAMA_HOST="127.0.0.1" LLAMA_PORT="8080" -LLAMA_PROFILE="baseline" +LLAMA_PROFILE="desktop-64k" LLAMA_ARGS=() diff --git a/config/llama.env.example b/config/llama.env.example index bbcd44f..4edff48 100644 --- a/config/llama.env.example +++ b/config/llama.env.example @@ -9,9 +9,9 @@ LLAMA_MMPROJ="" LLAMA_HOST="127.0.0.1" LLAMA_PORT="8080" -# Erster Start unverändert mit 64K / 1536 MiB Fit-Zielmarge. -# baseline bleibt Standard; vram-64k ist ein optionales Testprofil. -LLAMA_PROFILE="baseline" +# Standard für eine gemeinsam mit dem Desktop genutzte GPU: 64K / 4096 MiB. +# Fit ist ein Planungsziel; die freie Reserve auf der Zielmaschine messen. +LLAMA_PROFILE="desktop-64k" LLAMA_ARGS=() # HF lädt beim ersten echten Start herunter. Für offline/reproduzierbar: # LLAMA_MODEL und optional LLAMA_MMPROJ setzen; LLAMA_HF_REPO leeren. diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md index 5539fdb..b12cc64 100644 --- a/docs/MIGRATION.md +++ b/docs/MIGRATION.md @@ -56,7 +56,16 @@ betreiben. Für Parallelbetrieb die neue Maschine als separates Gerät verknüpf inklusive CLI und Benchmark) oder vorhandene Binary verwenden. Die GGUF-Datei und einen ggf. benötigten Vision-Projektor übertragen oder beim ersten Start über HF beziehen. Danach -`~/.config/hermes-stack-maintenance/llama.env` anpassen. Modellgewichte gehören +`~/.config/hermes-stack-maintenance/llama.env` anpassen. + +Für eine Workstation mit Desktop auf derselben GPU `desktop-64k` (64K, +4096 MiB Fit-Zielmarge) als Ausgangspunkt verwenden. Den optionalen lokalen +Kompressionsserver über `compression.env` auf CPU konfigurieren und seine +GGUF-Datei separat übertragen. Die vollständige Einrichtung und Abnahme steht +unter [Desktop-Reserve und CPU-Kompression](RTX3080.md#desktop-reserve-und-cpu-kompression-seit-12102026). +Auch die eigenen `~/.config/hermes-stack-maintenance/`-Dateien sichern und +gezielt übertragen; lokale Pfade, Binary-Auswahl und Profil-Override auf der +neuen Maschine prüfen. Keine vollständige systemd-Konfiguration blind kopieren. Modellgewichte gehören wegen Größe und Lizenz nicht in dieses Repository. Die RTX-3080-Profile sind für 10 GB VRAM und die bisherige CPU ausgelegt; auf @@ -70,6 +79,8 @@ NVIDIA-/Kernelpakete. Keine Binärkopie des alten CUDA-Builds erzwingen. hermes gateway install --force systemctl --user daemon-reload systemctl --user enable --now signal-cli.service llama-qwen.service +# Nur nach Einrichtung der optionalen Kompression: +systemctl --user enable --now llama-compression.service systemctl --user enable --now \ hermes-stack-hermes-update.timer \ hermes-stack-health.timer \ diff --git a/docs/RTX3080.md b/docs/RTX3080.md index 5ad1ee6..b071b92 100644 --- a/docs/RTX3080.md +++ b/docs/RTX3080.md @@ -9,17 +9,22 @@ helfen; weder Voll-Offload noch eine bestimmte Beschleunigung werden versprochen | Profil | Kontextlimit | Fit-Zielmarge | Einsatz | | --- | ---: | ---: | --- | -| `baseline` | 65536 | 1536 MiB | bisherige Startparameter, Referenz und Rückweg | +| `desktop-64k` | 65536 | 4096 MiB | Standard für Neuinstallationen mit Desktop auf derselben GPU | +| `baseline` | 65536 | 1536 MiB | historische Vergleichsparameter | | `vram-64k` | 65536 | 1280 MiB | optionaler Vergleich, kein Standard | | `balanced` | 49152 | 1536 MiB | erster Vergleich, nur Kontext reduzieren | | `vram-plus` | 49152 | 1280 MiB | zweiter Vergleich, kleinere Zielmarge | | `compact` | 32768 | 1536 MiB | Alternative für kürzere Sitzungen | -Alle Profile: ein Slot, K/V-Cache q8_0, Flash Attention auto, GPU-Layer auto, -Fit an, 6 Generierungs-/16 Batch-Threads, Jinja, Reasoning auto/512/preserve, +Gemeinsam: ein Slot, K/V-Cache q8_0, Flash Attention auto, GPU-Layer auto, +Fit an, 6 Generierungs-/16 Batch-Threads, Jinja, Reasoning auto, Image-Minimum 1024 Tokens und Idle-Sleep nach 300 Sekunden. Modellalias bleibt `qwen38-27b-local`. Es werden keine Sampling-Werte oder Hermes-Memories geändert. +`desktop-64k` verwendet Reasoning-Budget 128 ohne Preserve wie die am +12.10.2026 geprüfte Workstation. Die älteren Vergleichsprofile behalten 512 mit +Preserve; sie ändern neben der Speicherplanung auch diesen Parameter. + Die Definitionen stehen zentral in `libexec/hermes-stack-llama-run`. Die Konfiguration und Optionsnamen werden anhand der installierten Binary geprüft. Nicht unterstützte Optionen führen zum Abbruch, nicht zum stillen @@ -35,14 +40,15 @@ hier bewusst nicht als fertiges Profil vorgesehen. ## Messung statt Auslastungsziel -1. Zuerst `baseline` mit deiner normalen Browser-/Hyprland-Nutzung messen. +1. Zuerst `desktop-64k` mit deiner normalen Browser-/Hyprland-Nutzung messen. 2. Nur bei erneutem Tuning: Jobs beenden, ein Vergleichsprofil wählen und kontrolliert neu starten. Für 64K Kontext ist dies `vram-64k`. 3. Dieselben Aufgaben erneut ausführen: kurze Textantwort, längerer Agent-Task mit Tools und eine repräsentative Bildaufgabe. Qualität mitbewerten. 4. Kalten Start nach Idle-Sleep getrennt von warmem Prompt-Cache messen. 5. Erst bei genügend Spielraum `vram-plus` probieren. Bei Rucklern, OOM, - Grafikfehlern oder deutlich schlechterer Latenz zurück auf `baseline`. + Grafikfehlern wieder die größere Reserve von `desktop-64k` verwenden. + Latenz und Qualität gegen die eigenen Anforderungen prüfen. ```bash ~/.local/libexec/hermes-stack-llama-profile list @@ -98,3 +104,92 @@ für Fit-Marge, Kontext, Cache und Idle-Sleep; geprüft am 2026-09-05. Maßgebli für deinen Rechner bleibt `llama-server --help` seiner tatsächlich installierten Version. Die Profile übernehmen die von dir gezeigten Modellparameter; sie sind noch kein auf deiner GPU gemessener Optimalwert. + +## Desktop-Reserve und CPU-Kompression seit 12.10.2026 + +Auf der RTX 3080 mit NVIDIA Open 615.78.08 standen vor den GUI-Abstürzen +NVKMS-Allokationsfehler und `NV_ERR_NO_MEMORY` im Kerneljournal; danach folgten +anhaltende GSP-Zustandsfehler und Abstürze neuer GPU-Anwendungen. VRAM-Druck ist +belegt, die vollständige Kausalkette zum Treiberfehler nicht. Eine spätere +Momentaufnahme mit freiem Speicher schließt frühere Lastspitzen nicht aus. + +Die aktive Workstation-Konfiguration wurde auf 4096 MiB Fit-Zielmarge geändert. +Das Kompressionsmodell bekam zusätzlich zu `--n-gpu-layers 0` die Optionen +`--device none --no-op-offload --no-kv-offload`. Nur null GPU-Layer hatte zuvor +noch etwa 700 MiB VRAM belegt. `MemoryHigh`/`MemoryMax` begrenzen RAM, nicht VRAM. + +Kurze produktive Abnahme am 12.10.2026: CPU-Kompression antwortet, Hauptmodell +verarbeitet einen Text mit 984 Eingabetokens und erkennt ein synthetisches +96×96-Bild. Mindestens 4096 MiB VRAM frei während dieser Tests; keine neuen +NVIDIA-/CUDA-OOM-Fehler im Prüfzeitraum. Kein Nachweis langfristiger +Treiberstabilität, maximaler Kontext-/Bildlast oder einer bestimmten Leistung. +Das Hauptmodell behält 64K Kontext und GPU-Visionprojektor. Bei weiterem +Speicherdruck zuerst Reserve messen; optional `--no-mmproj-offload` prüfen, +Kontextkürzungen mit Hermes abstimmen. Mehr CPU-Offload kann langsamer sein. + +### Auf einer neuen Workstation einrichten + +Nach `./install.sh` und Bereitstellung der Modellgewichte: + +1. In `llama.env` Binary/Modell/Projektor setzen; `LLAMA_PROFILE="desktop-64k"` + und `LLAMA_ARGS=()` verwenden. Ein eventuell aus dem alten Rechner kopiertes + `llama-profile.env` kann die Profilwahl überschreiben. Über den Profilhelfer + bewusst `desktop-64k` wählen. Die lokale Modellvorlage verwendet `$HOME`. +2. In `compression.env` CPU-Binary bzw. die gemeinsame CUDA-Binary, Modellpfad + und Port prüfen. Die CUDA-Binary kann mit `--device none` auf CPU rechnen. +3. Beide Konfigurationen ohne Modellstart prüfen: + + ```bash + ~/.local/libexec/hermes-stack-llama-run --check + HERMES_LLAMA_CONFIG="$HOME/.config/hermes-stack-maintenance/compression.env" \ + ~/.local/libexec/hermes-stack-llama-run --check + ``` + +4. Hermes' Hauptmodell auf `http://127.0.0.1:8080/v1`, Alias + `qwen38-27b-local`, und den separaten Kompressionsanbieter auf + `http://127.0.0.1:8081/v1`, Alias `qwen3-1.7b-compression`, konfigurieren. + Bestehende `config.yaml` übernehmen und mit der installierten Hermes-Version + abgleichen; keine Zugangsdaten oder allgemeine Modellantworten überschreiben. +5. Erst ohne laufende Backend-Aufträge aktivieren: + + ```bash + systemctl --user daemon-reload + systemctl --user enable --now llama-compression.service llama-qwen.service + ``` + + Bei bereits laufenden Diensten aktiviert `enable --now` keine neuen + Einstellungen: nach Abschluss aller Anfragen gezielt neu starten. + +6. Mit normalem Browser-/Desktopbetrieb Text- und Bildanfragen prüfen und + `nvidia-smi` im Sekundentakt beobachten. Für diese 10-GB-Klasse mindestens + etwa 3 GiB tatsächlich freie Reserve unter den eigenen Aufgaben anstreben; + 4096 MiB Fit-Zielmarge ist nur der Ausgangspunkt. CPU-Kompression sollte + nicht als NVIDIA-Verbraucher erscheinen. Journal auf neue CUDA-OOM-, NVKMS- + und GSP-Fehler prüfen. Aufwachen nach Idle-Sleep separat testen. + +Die Unit-Vorlage verwendet den üblichen Konfigurationspfad unter `~/.config`. +Bei abweichendem `XDG_CONFIG_HOME` den Environment-Pfad in der Unit ebenfalls +anpassen. Auch vorhandene `ExecStart`-Drop-ins vor der Übernahme prüfen. + +Der Installer installiert den Kompressionsdienst, aktiviert ihn aber nicht und +lädt keine Kompressionsgewichte herunter. Fehlende `compression.env` wird +angelegt, eine bestehende Datei bleibt erhalten. Die alte Workstation nutzt +aktuell explizite Argumente im Hauptmodell und eine direkte Kompressions-Unit; +diese portable Repo-Variante bildet die wirksamen Optionen ab. Ein erneuter +Installerlauf ersetzt Units/Wrapper nach Sicherung, startet aber keine laufenden +Modellserver neu. Für bestehende Setups deshalb zuerst sichern und den geplanten +Dienstwechsel ohne laufende Anfragen durchführen. + +### Rücknahme auf einer Zielmaschine + +Vor Änderungen `llama.env`, `llama-profile.env` (falls vorhanden), +`compression.env` und bestehende Units/Drop-ins sichern. Die Installer-Sicherung +enthält ersetzte Units/Wrapper; unveränderte Konfigurationen separat sichern. +Bei Rücknahme die betroffenen Dateien gezielt wiederherstellen, `daemon-reload` +ausführen und die beiden Server nach Abschluss der Anfragen neu starten. +Die früheren Profile sind Vergleichsmöglichkeiten, kein bewiesener stabiler +Rückfallweg bei Speicherdruck. + +Quellen: [llama.cpp: Serveroptionen](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md), +[ähnlicher NVIDIA-GSP-Bericht](https://github.com/NVIDIA/open-gpu-kernel-modules/issues/1408). +Der dort genannte Display-Wakeup-Auslöser ist lokal nicht bewiesen. diff --git a/docs/VALIDATION.md b/docs/VALIDATION.md index d45b3b7..cf376fc 100644 --- a/docs/VALIDATION.md +++ b/docs/VALIDATION.md @@ -1,3 +1,16 @@ +# Validierung vom 2026-10-12 + +- `make test`: Shell-Syntaxprüfung, Secret-Mustercheck und **26 isolierte + Funktionstests bestanden**, einschließlich separater CPU-Kompressionskonfiguration. +- `git diff --check`: erfolgreich. +- Neue Profil- und Kompressionsvorlagen mit der installierten llama.cpp-Binary + auf unterstützte Optionsnamen geprüft, ohne Modellstart. +- ShellCheck ist lokal nicht installiert; weiterhin über Gitea-CI vorgesehen. +- Die aktive Workstation-Konfiguration wurde vor der Repo-Änderung mit echten + Text-/Bildanfragen und mindestens 4096 MiB freiem VRAM geprüft. Die portablen + Installer-/Wrapperdateien wurden nicht erneut auf den laufenden Rechner + installiert. Keine neue Workstation eingerichtet und kein Langzeitnachweis. + # Validierung vom 2026-09-05 Ausgeführt in einer isolierten Arbeitsumgebung, nicht auf der Workstation: diff --git a/docs/WORKSTATION.md b/docs/WORKSTATION.md index d02a66b..beae4e1 100644 --- a/docs/WORKSTATION.md +++ b/docs/WORKSTATION.md @@ -90,7 +90,8 @@ der neue Standard: HTTP-Probleme werden gemeldet, nicht durch Neustarts behandel ## 3. Optimieren und zurücksetzen Nun gemäß [RTX3080.md](RTX3080.md) jeweils nur ein Profil vergleichen. Zurück: -Profil `baseline` wählen und kontrolliert neustarten. Für vollständige Rückkehr +Bei Speicherdruck die größere Reserve von `desktop-64k` verwenden. Die +früheren Vergleichsprofile bieten keine Stabilitätsgarantie. Für vollständige Rückkehr alte llama.env und ggf. alte Unit/Wrapper aus der Deployment-Sicherung einzeln wiederherstellen, `daemon-reload` und Neustart nach Jobende. Nicht pauschal ein Archiv über dein gesamtes Home extrahieren. Die Datei `llama-profile.env` hat nur @@ -98,7 +99,7 @@ bei aktivem Profilbetrieb Vorrang; ihre vorherigen Stände liegen daneben. ## Workstation-Abgleich vom 2026-09-09 -Alltagsprofil bleibt baseline: 65536 Kontext, Fit-Zielmarge 1536 MiB. +Historischer Stand (durch den Abgleich vom 12.10.2026 abgelöst): baseline, 65536 Kontext, Fit-Zielmarge 1536 MiB. Die zwei kurzen Texttests vom 5. September ergaben im Mittel rund 2,58 tok/s für baseline und 2,62 tok/s für vram-64k. Das belegt keinen belastbaren Geschwindigkeitsvorteil. Im fünfminütigen Desktop-/Bildtest mit vram-64k @@ -126,3 +127,23 @@ Ein echter Update-/Rollback-Lauf der neuen Fassung war damit noch nicht geprüft Modell und Projektor liegen jetzt außerhalb von ~/.cache. Die korrigierten Cleanup-Skripte sind unter ~/Scripts installiert. Details und Prüfgrenzen: [CLEANUP_RECOVERY.md](CLEANUP_RECOVERY.md). + + +## Workstation-Abgleich vom 2026-10-12 + +Nach NVIDIA-Speicherallokationsfehlern und GUI-Abstürzen wurde der aktive +Hauptserver auf 4096 MiB Fit-Zielmarge bei unverändert 65536 Kontext umgestellt. +Die aktive `llama.env` enthält dafür explizite `LLAMA_ARGS` bei leerem +`LLAMA_PROFILE`; Profilwechsel wirken dort erst nach bewusster Umstellung auf +Profilbetrieb. Reasoning: auto, Budget 128, kein Preserve. + +Die bestehende Kompressions-Unit wurde um `--device none --no-op-offload +--no-kv-offload` ergänzt. Der vorher mit null GPU-Layern weiterhin belegte +VRAM wurde freigegeben. Kurze Text-/Bildtests bestanden mit mindestens 4096 MiB +freiem VRAM und ohne neue NVIDIA-/CUDA-OOM-Fehler. Langzeitstabilität bleibt offen. + +Diese aktiven Änderungen wurden separat installiert. Die neuen portablen +Repo-Dateien wurden danach aufgenommen und getestet, aber nicht erneut über +`install.sh` auf die Workstation ausgerollt. Der aktuelle Betrieb bleibt bei den +bereits geprüften Einstellungen. Details zur Übertragung und zu bestehenden +Units/Drop-ins stehen in [RTX3080.md](RTX3080.md). diff --git a/install.sh b/install.sh index 68f0726..c891a22 100755 --- a/install.sh +++ b/install.sh @@ -105,6 +105,8 @@ install_config_if_missing \ "$ROOT_DIR/config/config.env.example" "$config_dir/config.env" install_config_if_missing \ "$ROOT_DIR/config/llama.env.example" "$config_dir/llama.env" +install_config_if_missing \ + "$ROOT_DIR/config/compression.env.example" "$config_dir/compression.env" install_config_if_missing \ "$ROOT_DIR/config/signal-cli.env.example" "$config_dir/signal-cli.env" diff --git a/libexec/hermes-stack-llama-profile b/libexec/hermes-stack-llama-profile index 31f4878..332d993 100755 --- a/libexec/hermes-stack-llama-profile +++ b/libexec/hermes-stack-llama-profile @@ -8,10 +8,10 @@ runner="$(dirname -- "${BASH_SOURCE[0]}")/hermes-stack-llama-run" case "${1:-list}" in list) printf '%-12s %8s %10s\n' Profil Kontext Fit-MiB \ - baseline 65536 1536 vram-64k 65536 1280 \ + desktop-64k 65536 4096 baseline 65536 1536 vram-64k 65536 1280 \ balanced 49152 1536 vram-plus 49152 1280 compact 32768 1536 exit 0 ;; - baseline|vram-64k|balanced|vram-plus|compact) selected="$1" ;; + desktop-64k|baseline|vram-64k|balanced|vram-plus|compact) selected="$1" ;; *) printf 'Unbekanntes Profil. Verfügbare Profile: %s list\n' "$0" >&2 exit 2 ;; diff --git a/libexec/hermes-stack-llama-run b/libexec/hermes-stack-llama-run index 36637a1..6caddde 100755 --- a/libexec/hermes-stack-llama-run +++ b/libexec/hermes-stack-llama-run @@ -72,7 +72,10 @@ fi profile_args=() if [[ -n "${LLAMA_PROFILE:-}" ]]; then + reasoning_budget=512 + reasoning_preserve=--reasoning-preserve case "$LLAMA_PROFILE" in + desktop-64k) ctx=65536; margin=4096; reasoning_budget=128; reasoning_preserve=--no-reasoning-preserve ;; baseline) ctx=65536; margin=1536 ;; vram-64k) ctx=65536; margin=1280 ;; balanced) ctx=49152; margin=1536 ;; @@ -86,7 +89,7 @@ if [[ -n "${LLAMA_PROFILE:-}" ]]; then profile_args=( --ctx-size "$ctx" --parallel 1 --jinja - --reasoning auto --reasoning-budget 512 --reasoning-preserve + --reasoning auto --reasoning-budget "$reasoning_budget" "$reasoning_preserve" --flash-attn auto --threads 6 --threads-batch 16 --n-gpu-layers auto --fit on --fit-target "$margin" --cache-type-k q8_0 --cache-type-v q8_0 diff --git a/systemd/user/llama-compression.service b/systemd/user/llama-compression.service new file mode 100644 index 0000000..debe8a3 --- /dev/null +++ b/systemd/user/llama-compression.service @@ -0,0 +1,20 @@ +[Unit] +Description=Hermes auxiliary compression LLM (CPU) +After=default.target +StartLimitIntervalSec=300 +StartLimitBurst=3 + +[Service] +Type=simple +Environment=HERMES_LLAMA_CONFIG=%h/.config/hermes-stack-maintenance/compression.env +ExecStart=%h/.local/libexec/hermes-stack-llama-run +Restart=on-failure +RestartSec=30 +Nice=10 +MemoryHigh=8G +MemoryMax=12G +OOMPolicy=stop +TimeoutStopSec=60 + +[Install] +WantedBy=default.target diff --git a/tests/test_llama.py b/tests/test_llama.py index 3c43975..64f90e2 100644 --- a/tests/test_llama.py +++ b/tests/test_llama.py @@ -13,9 +13,10 @@ RUNNER = ROOT / "libexec/hermes-stack-llama-run" PROFILE = ROOT / "libexec/hermes-stack-llama-profile" RESTART = ROOT / "libexec/hermes-stack-llama-restart" OPTIONS = """--model --hf-repo --mmproj --alias --host --port --ctx-size --parallel ---jinja --reasoning --reasoning-budget --reasoning-preserve --flash-attn --threads +--jinja --reasoning --reasoning-budget --reasoning-preserve --no-reasoning-preserve --flash-attn --threads --threads-batch --n-gpu-layers --fit --fit-target --cache-type-k --cache-type-v ---sleep-idle-seconds --image-min-tokens --cors-origins --no-ui""" +--sleep-idle-seconds --image-min-tokens --cors-origins --no-ui --rope-scaling --rope-scale --yarn-orig-ctx +--device --no-op-offload --no-kv-offload""" class LlamaTests(unittest.TestCase): @@ -72,7 +73,8 @@ class LlamaTests(unittest.TestCase): return result def test_profile_values(self): - for name, ctx, margin in [("baseline", "65536", "1536"), + for name, ctx, margin in [("desktop-64k", "65536", "4096"), + ("baseline", "65536", "1536"), ("vram-64k", "65536", "1280"), ("balanced", "49152", "1536"), ("vram-plus", "49152", "1280"), @@ -85,6 +87,28 @@ class LlamaTests(unittest.TestCase): self.assertEqual(args.count("--ctx-size"), 1) self.assertIn("qwen38-27b-local", args) + def test_cpu_compression_template_uses_separate_config(self): + model = self.root / "compression model.gguf" + model.touch() + template = (ROOT / "config/compression.env.example").read_text() + template = template.replace('LLAMA_SERVER_BIN=""', + f'LLAMA_SERVER_BIN={shlex.quote(str(self.server))}') + template = template.replace( + 'LLAMA_MODEL="$HOME/.local/share/hermes-stack/models/qwen3-1.7b-compression/Qwen3-1.7B-Q4_K_M.gguf"', + f'LLAMA_MODEL={shlex.quote(str(model))}') + config = self.config / "compression.env" + config.write_text(template) + self.env["HERMES_LLAMA_CONFIG"] = str(config) + self.run_tool(RUNNER) + args = self.record.read_text().splitlines() + self.assertEqual(args[args.index("--port") + 1], "8081") + self.assertEqual(args[args.index("--device") + 1], "none") + self.assertIn("--no-op-offload", args) + self.assertIn("--no-kv-offload", args) + self.assertIn(str(model), args) + self.assertNotIn("qwen38-27b-local", args) + self.assertNotIn("--fit-target", args) + def test_check_does_not_run_inference(self): self.run_tool(RUNNER, "--check") self.assertFalse(self.record.exists()) diff --git a/uninstall.sh b/uninstall.sh index 6147d9a..03b4251 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -8,9 +8,11 @@ units=( hermes-stack-health.service hermes-stack-health.timer hermes-stack-signal-health.service hermes-stack-signal-health.timer hermes-stack-signal-update-check.service hermes-stack-signal-update-check.timer - llama-qwen.service signal-cli.service + llama-qwen.service llama-compression.service signal-cli.service ) +systemctl --user disable --now llama-compression.service 2>/dev/null || true + systemctl --user disable --now \ hermes-stack-hermes-update.timer \ hermes-stack-health.timer \