Chinesische Sprachsynthese: Textnormalisierung und Ingenieurwesen
Dieses Skill stammt von einem KI-Schreibtischhaustier (siehe „Quelle und Wartung“ am Ende), das ständig spricht: Claude antwortet im Stream, jeder Satz wird an einen lokalen TTS-Engine übergeben und vorgelesen. Die folgenden Regeln sind alle getestet, die Zahlen sind gemessen.
Ein Grundsatz: Die Aussprache wird auf dieser Ebene korrigiert, der Engine obliegt nur die Aussprache. Wenn man es der Engine überlässt, ändert sich die Aussprache durch den Engine-Wechsel; wenn man ein fertiges TN-System einsetzt, gibt es auch ein paar Stellen, die schlechter werden. Fertige Systeme (wetext, PaddleSpeech) dienen zum Vergleich und zur Ergänzung der Regeln.
Ablauf
Streaming-Text des Modells
→ ① Filterung: Entfernen von Dekorationen, Emojis, Listensymbolen; Codeblöcke, Tabellen, Links durch einen Satz ersetzen (beim Streaming müssen aufgetrennte erkannt werden)
→ ② Aussprache-Transformation: Zahlen, Zeitangaben, Einheiten, Symbole, Aussprache-Ersetzungstabelle (beim Streaming Grenzen beachten)
→ ③ Satzsegmentierung: Erster Absatz bis zum ersten Komma, danach bei über 40 Zeichen am Komma trennen
→ ④ Synthese: Nur etwa 20 Sekunden vor dem vorgelesenen Teil vorausberechnen; beim Abbruch die Inferenz wirklich stoppen
Die Reihenfolge darf nicht geändert werden: Erst Aussprache-Transformation, dann Satzsegmentierung. Beim Testen mit falscher Reihenfolge drei Fehler aufgetreten:
| Original | Ergebnis (falsche Reihenfolge) | Problem |
|---|---|---|
下午14:30开会 | 下午14: / 30开会 | Doppelpunkt als Komma erkannt, Zeitangabe getrennt |
看这里:https://…/pull/7 就行 | https: / //…/pull/7 就行 | Link zerschnitten, Adresse buchstabiert |
大概3~5天 | 大概35天 | ~ als Dekoration entfernt, „fünfunddreißig Tage“ gelesen |
Der halbe Doppelpunkt : wird nur als Komma betrachtet, wenn ein Leerzeichen folgt.
Streaming-Grenzen beachten
Ein ganzer Satz kann richtig sein, aber im Stream nicht. Beim zeichenweisen Stream wird „工作了26年“ als „26 Jahre“ und „80年代“ als „80er Jahre“ gelesen, weil die nachfolgenden Zeichen noch nicht da sind; „-10°C“ wird als englischer Originaltext gelesen.
- Nach einer Zahl 2 Zeichen warten, bevor sie ausgegeben wird; Einheiten mit Leerzeichen müssen erkannt werden (
跑了 5erst halten, aufkmwarten). - Beim nächsten Absatz die letzten paar Zeichen des vorherigen Absatzes mitnehmen (um „了 26 年“ zu erkennen, muss man das vorherige „了“ sehen).
- Maximal 200 Zeichen halten, bei Codeblöcken und Tabellen maximal 4000 Zeichen, bei Erreichen der Grenze freigeben.
- Jeder Test wird sowohl „zeichenweise“ als auch „als ganzer Satz“ durchgeführt, die Ergebnisse müssen identisch sein.
Regelsuche (siehe references/rules.md für Details)
| Kategorie | Beispiele | Aussprache |
|---|---|---|
| Jahreszahlen | 2026年、2026届、26年见 | Stellenweise: zweinullzweiundsechzig Jahr, zweinullzweiundsechzig Jahrgang, zweisechzig Jahr sehen |
| Anzahlen | 工作了26年、80年代、26年前 | Als Zahl: sechsundzwanzig Jahre, achtziger Jahre, sechsundzwanzig Jahre vor |
| Nummern | Telefonnummer, Code, 编号27149, 房间1201 | Stellenweise, 1 als „yao“, Bindestrich und Leerzeichen Pause |
| Fünfstellige Zahlen | 95588 / 价格 12999 | Keine Mengenangabe, nicht mit 0 endend, nicht vor Geld → Nummer; sonst als Menge |
| Netzjargon | 666、2333、520 alleinstehend / 666个赞、花了888 | Stellenweise / als Menge (nur feste Liste) |
| 2 vor Einheiten | 2个、2L、2℃ | Zwei (liǎng) Stück, zwei (liǎng) Liter; außer Temperatur: zwei (èr) Grad Celsius |
| Einheiten | 60km/h、3kWh、5min、10mg | Sechzig Kilometer pro Stunde, drei Kilowattstunden, fünf Minuten, zehn Milligramm |
| Nicht umwandelbare Einheiten | 4g网络、5A景区、16GB | Original an Engine übergeben |
| Bereich, Prozent | 3~5%、3-5km、-1.5~2 | Drei bis fünf Prozent, drei bis fünf Kilometer, minus eins Komma fünf bis zwei |
| Uhrzeit | 14:30、13:00、9:05 | Vierzehn Uhr dreißig, dreizehn Uhr, neun Uhr null fünf (24-Stunden-Format) |
| Datum, Bruch | 10/26 交 / 有7/12的观众 | Zehnter Oktober / Fünf Siebtel der Zuschauer (nur als Bruch, wenn „von“ oder „ungefähr“ davor) |
| Symbole | #15、2x、x3、100w | Nummer 15, doppelt, mal drei, eine Million |
Prüfung mit goldenen Fällen
references/golden-cases.json enthält 115 ganze Fälle und 24 Streaming-Fälle, die alle vom Ursprungsprojekt validiert wurden. scripts/check-tn.mjs testet Ihre Implementierung damit:
node scripts/check-tn.mjs ./my-tn.mjs # Modul exportiert normalize(text) und (optional) createStream()
node scripts/check-tn.mjs ./my-tn.mjs --only 号码 # Nur eine Gruppe testen
- Beim Vergleich werden Leerzeichen und häufige Satzzeichen ignoriert, nur die Aussprache wird verglichen. Fälle mit
notesind „Referenz“, werden nur gemeldet, nicht als Fehler gezählt. - Verwenden Sie es als Akzeptanzlinie beim Schreiben neuer TN-Regeln; führen Sie es nach Regeländerungen aus, um zu verhindern, dass eine Korrektur eine andere Stelle beschädigt.
- Bei strittigen Aussprachen (z. B. „dieser Computer 12999“ wird als Nummer behandelt) hat das Ursprungsprojekt die Entscheidung akzeptiert. Wenn Ihr Produkt eine andere Aussprache wünscht, ändern Sie die Fälle und notieren Sie den Grund neben dem Fall.
Fehlerhafte Aussprache suchen
Vier Kategorien: Aussprache nicht vorher festgelegt; Homophone vom Modell falsch geraten; Referenzaufnahme fehlerhaft; zufällig (einfach erneut abspielen).
Verwenden Sie die aktuelle Stimme und zwei andere Stimmen für denselben Satz: wenn alle Stimmen am gleichen Zeichen falsch liegen, Aussprache-Ersetzungstabelle hinzufügen; wenn nur eine Stimme seltsam klingt, Stimme wechseln. Protokollieren Sie jedes Mal Originaltext und umgewandelte Aussprache in einer JSONL-Datei, um später nachschlagen zu können.
Ingenieurwesen (siehe references/engines.md)
- Latenz des ersten Satzes: Erster Absatz nur bis zum ersten Komma. Bei Matcha 0,65 Sekunden nach Erreichen des ersten Zeichens wird der erste Audioblock ausgegeben.
- Effizienteste Beschleunigung ist Caching: Bei nicht synthetisierten Sätzen braucht CosyVoice 2,6–3 Sekunden für den ersten Block, bei Cache-Treffer 6 Millisekunden. Sobald der Benutzer spricht, vorab synthetisierte Füllwörter („ähm“, „lass mich überlegen“) generieren.
- Abbruch muss die Inferenz wirklich stoppen: vLLM bei Verbindungsabbruch
abort_request, sonst wartet der nächste Satz 4,9 Sekunden (nach Optimierung 0,8–1,7 Sekunden). - Englisch wird still übersprungen: Manche Engines lesen
GitHub,PR,%nicht; nach Engine-Upgrades Englisch erneut validieren. - Fallback-Audioquelle: Wenn die Hauptquelle nicht bereit ist oder beim ersten Satz einen Fehler macht, auf Fallback umschalten; Fehler während des Vorlesens nicht wiederholen. Ein HTTP-Status „up“ bedeutet nicht, dass das Modell geladen ist; bei 503 wiederholen.
Quelle und Wartung
- Quelle: Cirra (KI-Schreibtischhaustier, RedCarpG/cirra-deskpet) und sein Sprachdienst cirra-voice, 2026-10 bis 2026-11.
- Code:
sidecar/src/tts/speech/(numbers.ts、units.ts、links.ts、filter.ts、overrides.ts、speech.test.ts)、sidecar/src/tts/splitter.ts、sidecar/src/tts/pronunciations.ts. - Dokumentation:
docs/speech.md、docs/speech-tn.md(119 Vergleichssätze)、docs/tts.md、docs/voices.md、docs/voice-chat.md、docs/voice-chat-2.md、docs/voice-install.md、docs/perf-checkup.md. - Erfahrungen:
lessons/chinese-tts.mdim privaten Repo (https://github.com/RedCarpG/redcarpg-skills-private/blob/main/lessons/chinese-tts.md).
- Code:
- Ursprung:
skills/chinese-tts/im RedCarpG/redcarpg-skills. Die Kopie in~/.claude/skills/ist eine Installationskopie, nicht direkt ändern.references/golden-cases.jsonwurde am 2026-11-10 aus Cirrasspeech.test.tsmit einem Skript extrahiert, die beiden synchronisieren sich nicht automatisch. - Änderungen:
- Im redcarpg-skills Repo ändern, per PR; Versionsnummer in
manifest.jsonerhöhen, nach Bestehen vonnode scripts/validate.mjsreleasen (Tagchinese-tts-v<Version>), dann lokale Kopie neu installieren. Vorherlessons/chinese-tts.mdauf neue Einträge prüfen, die aufgenommen werden können. - Bei Änderungen an Cirras TN-Regeln die goldenen Fälle neu extrahieren (Methode: aus
speech.test.tsdie[Original, Aussprache]Paare derreadNumbers-Gruppe und der „Streaming“-Gruppe lesen), und mit Cirras erstelltemsidecar/dist/tts/Adaptermodulcheck-tn.mjsausführen; sollten alle bestanden werden. - Die Messwerte der Engines (Latenz, Echtzeitfaktor, VRAM) wurden 2026-10 auf einem Rechner mit 8 GB VRAM und CPU ohne VNNI gemessen. Bei Hardwarewechsel neu messen.
- Im redcarpg-skills Repo ändern, per PR; Versionsnummer in
- Änderungsprotokoll:
- 2026-11-12 · 1.0.0, in redcarpg-skills öffentlich veröffentlicht. Absolute Pfade entfernt, Quellprojekt als Link geschrieben; Inhalt unverändert.
- 2026-11-10 · Cirra · Erste Version: Ablauf und Reihenfolge, Streaming-Grenzen, Regelsuche und Details, Fehlersuche, Engine-Ingenieurwesen; 139 goldene Testfälle und
check-tn.mjs(mit Cirras Implementierung getestet, alle bestanden); zwei Test-Prompts inevals/.