fix(diar): sherpa abschnittsweise laufen lassen (OOM bei langen Aufnahmen)

Der sherpa-Diarisierungslauf brauchte RAM quadratisch zur Gesprächslänge
(gemessen 349 MB bei 10 min, 1389 MB bei 20 min, 2643 MB bei 30 min). Die
54-min-Aufnahme #99 riss 5,4 GB, wurde OOM-getötet und nahm wegen
OOMPolicy=stop die ganze App mit — in der GUI "Transkription fehlgeschlagen"
und "failed to fetch".

Die v2-Pipeline verwirft sherpas Labels und nutzt nur die Turn-Grenzen, also
laeuft der Pass jetzt in 600-s-Abschnitten (je +-5 s Kontext) und die Grenzen
werden mit Zeit-Offset zusammengesetzt. Zusätzlich OOMPolicy=continue, damit
ein OOM-getöteter Helfer die App nicht mehr stoppt.

Verifiziert an #99: sherpa-Spitze 363 MB, 726 Turns, 8 Sprecher, Analyse
vollstaendig (done/done).
This commit is contained in:
2026-08-07 13:50:01 +02:00
parent 0aa6a37325
commit c5daee25af
4 changed files with 161 additions and 12 deletions
+37
View File
@@ -3,6 +3,43 @@
Chronik der Entwicklungsschritte. **Regel: jede zukünftige Änderung bekommt hier einen Eintrag** (Datum,
Was, Warum, betroffene Dateien/Backups).
## 2026-08-07 — Lange Aufnahmen scheiterten: sherpa-Diarisierung lief in den OOM-Killer
**Symptom:** Aufnahme #99 (53:56) endete mit „Transkription fehlgeschlagen“ (Badge „KI-Fehler“), beim
Abruf der Analyse zeigte die GUI „failed to fetch“. Verdacht lag auf dem eMMC-Umzug vom 2026-08-03 —
**war es nicht**: Speicher-Setup (zram 3,9 GB, kein Swapfile), RAM (7,83 GB) und `armbian-zram-config`
sind vor und nach dem Umzug identisch (alte SD-Root gegengeprüft).
**Tatsächliche Ursache** (aus `dmesg`): die Transkription war längst fertig (8666 Wörter, RTF 0,394),
gestorben ist der sherpa-Lauf danach —
`Out of memory: Killed process (sherpa-onnx-off) … anon-rss:5463416kB`. Und weil systemd eine Unit per
Default komplett stoppt, sobald ein Kindprozess OOM-getötet wird (`OOMPolicy=stop`), riss das die ganze
App mit: `callrec.service: Failed with result 'oom-kill'` → abgebrochene Analyse, leerer Fetch im
Browser. Warum es früher ging: der RAM-Bedarf wächst **quadratisch** mit der Gesprächslänge — gemessen
349 MB (10 min), 1389 MB (20 min), 2643 MB (30 min), 5,4 GB (54 min). Bis ~45 min passt es, danach nicht.
**Fix 1 (Ursache):** sherpa läuft jetzt in Abschnitten von 600 s (`DIAR_CHUNK_SEC`, `0` = aus), je mit
±5 s Kontext; die Turn-Grenzen werden mit Zeit-Offset zusammengesetzt. Zulässig, weil die v2-Pipeline
sherpas Labels ohnehin verwirft und nur die Grenzen nutzt. Speicher bleibt damit dauerhaft auf
Abschnitts-Niveau und der Lauf ist zusätzlich schneller (quadratische Kosten).
**Fix 2 (Schadensbegrenzung):** `OOMPolicy=continue` — ein OOM-getöteter Helfer (sherpa/whisper/rkllm)
darf die App nicht mehr mitreißen; Diarisierung und Analyse sind im Code bereits nicht-fatal.
**Verifiziert an #99** (Re-Transkription + Re-Diarisierung, 2026-08-07): sherpa-Spitze **363 MB** statt
5,4 GB, 6 Abschnitte (131/103/119/160/158/55 Turns) → 726 Turns → 1932 Fenster → **8 Sprecher**, alle
6 Live-Marker verankert und alle 8 Sprecher benannt (Fabio Haase, Merle, Dennis, Nico, Lisa, Kai, Kim,
Artur), Transkript 51.406 Zeichen, Zusammenfassung 15.930 Zeichen, 20 LLM-Abschnitte, Analyse 5073 s,
189 Passagen indexiert, `status=done` / `analysis_status=done`, kein Neustart, kein OOM, 64,7 °C.
Dateien: `app/diar.js` (Board-Backup `diar.js.bak-chunk`),
`system/etc/systemd/system/callrec.service.d/oom.conf` (neu), Kapitel
[04 – Sprechertrennung](04-diarization.md).
**Nebenbefund (offen):** während der Analyse belegt `rkllm_server` 6,5 GB RSS (NPU-Modell, shared) und
das System hat nur noch ~100 MB frei — funktioniert, aber ohne Reserve. Wenn wieder etwas OOM-nah
wird, ist das der Kandidat.
## 2026-08-03 — System von der SD-Karte auf die eMMC umgezogen
**Warum:** alles lag auf der SD-Karte (System, Datenbank, Aufnahmen, Modelle), die verlötete eMMC lag