Files
perinco-CRM/docs/04-diktat.md
T
Sascha WolfandClaude Opus 5 59080019d2 docs: Umlaute auch im erklaerenden Text der Codebloecke
Der Dateibaum im README und in 05/08, die Kommentare hinter # in den
Beispielbefehlen und die Beschriftungen in Mermaid-Sequenzdiagrammen sind
Lesetext, stehen aber in Codeblöcken - die erste Runde hat sie deshalb
übersprungen.

Die Befehle selbst und alle Bezeichner bleiben unverändert: ersetzt wurde
nur hinter "# ", hinter den zwei Leerzeichen des Dateibaums und hinter
": " in Mermaid-Nachrichten. ER-Labels wie bewertet_fuer sind Bezeichner
und bleiben, "systemctl daemon-reload" ebenfalls.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 09:48:11 +02:00

86 lines
3.2 KiB
Markdown

# 04 Diktat (Whisper im Browser)
Überall, wo längerer Text entsteht - Projektbeschreibung, Interaktionsnotiz,
nächster Schritt, interne Notizen - sitzt ein Mikrofon-Button. Die Erkennung
läuft **vollständig im Browser des Benutzers**.
Das Backend ist daran nicht beteiligt und sieht keine Audiodaten: kein API-Key,
keine Kosten pro Minute, kein Datenabfluss. Aufnahmen werden nirgends gespeichert.
## Weg der Aufnahme
```mermaid
flowchart LR
MIC(("Mikrofon")) --> MR["MediaRecorder"]
MR --> AC["AudioContext<br/>16 kHz Mono PCM"]
AC --> W["Web Worker"]
W --> ONNX["Whisper als ONNX<br/>WebGPU, sonst WASM"]
ONNX --> T["Text"]
T --> F["Formularfeld"]
HF["Hugging-Face-CDN"] -.->|"einmalig 759 MB"| CACHE[("Cache-Speicher<br/>der Seite")]
CACHE --> ONNX
```
Die Erkennung liegt im Web Worker (`src/lib/whisper.worker.ts`), damit die
Oberfläche währenddessen nicht einfriert. Die ONNX-Laufzeit wird mit
ausgeliefert (Vite bundelt die `.wasm`), nur die Modelldateien kommen beim ersten
Laden vom CDN und bleiben danach im Cache-Speicher der Seite.
## Lebenszyklus des Modells
```mermaid
stateDiagram-v2
[*] --> idle : Anmeldung
idle --> loading : "Sprachmodell laden" oder<br/>automatisch, wenn schon im Cache
loading --> ready : im Worker initialisiert
loading --> error : Abbruch, Hänger, kein Speicher
error --> loading : erneut versuchen
ready --> idle : "Sprachmodell löschen"
ready --> ready : Diktat benutzen
note right of loading
Phase download: Dateien holen
Phase init: Modell im Worker aufbauen
end note
```
Beim Anmelden wird das Modell automatisch bereitgestellt, **wenn** es schon in
diesem Browser liegt. Ein Download von 759 MB startet nie von allein, und der
Automatismus greift bewusst nur einmal pro Seitenaufruf: wer das Modell löscht,
bekommt es nicht sofort wieder heruntergeladen.
## Wo es sitzt
Reiter **Whisper** in den Einstellungen - für **jede Rolle** sichtbar, denn jeder
richtet sein Diktat auf seinem eigenen Gerät ein. Genau deshalb sind die
Einstellungen überhaupt für alle Rollen zugänglich; welche Reiter erscheinen,
entscheidet die Rolle:
```mermaid
flowchart LR
E["Einstellungen"] --> A["Mein Konto<br/>(alle)"]
E --> W["Whisper<br/>(alle)"]
E --> N["Nutzerverwaltung<br/>(admin)"]
E --> S["Scanner<br/>(admin)"]
```
Ist das Modell noch nicht geladen, wird der Mikrofon-Button zu *Diktat
einrichten* und springt per `goTo('Einstellungen', { tab: 'whisper' })` direkt
dorthin - ein offener Dialog wird vorher geschlossen (`onBeforeNavigate`).
## Warum keine Auswahl
Modell, Genauigkeit, Rechenweg und Sprache stehen als Konstanten in
`src/lib/whisper.tsx`: `large-v3-turbo`, `q4`, Grafikkarte wenn vorhanden,
Deutsch. Jede andere Kombination war in den Messungen entweder schlechter oder
kaputt - bei `small` in fp16 auf WebGPU reagiert der ganze Browser-Tab nicht mehr,
und **kein Timeout in der Seite kann das abfangen**, weil das Skript selbst nicht
mehr läuft.
Eine Auswahl hätte also nur Gelegenheit geboten, etwas falsch zu machen. Die
Messwerte stehen im [README](../README.md#warum-small-und-q4---die-messungen).
Als Netz bleibt eine Frist pro Erkennung (15x Aufnahmedauer, mindestens 45 s,
höchstens 5 min) und eine Hänger-Erkennung beim Laden.