Audio (Sprache · TTS & STT)
OpenAI-kompatible Sprachsynthese (Text-to-Speech) und Transkription (Speech-to-Text), EU-souverän.
SovrGPT bietet Text-to-Speech (/v1/audio/speech) und Speech-to-Text
(/v1/audio/transcriptions) im OpenAI-kompatiblen Format. Bestehende
OpenAI-Audio-Clients funktionieren ohne Code-Änderung — nur baseURL umstellen.
Beide Endpunkte verlangen einen gültigen SovrGPT-API-Key mit dem passenden
Funktions-Scope — speech für TTS, transcribe für STT (siehe
Authentifizierung → Berechtigungen).
SovrGPT bietet drei TTS-Engines, alle EU-souverän — wählbar pro Request über
das OpenAI-übliche model-Feld (supertonic-3 / cosyvoice-3 /
voxtral-mini-tts) oder das explizite provider-Feld (aus der Stimme abgeleitet,
wenn keins gesetzt ist):
provider | Stärke | Stimmen | Emotion / Tags | Cloning | Format |
|---|---|---|---|---|---|
supertonic (Default) | schnell, kein Cold-Start | M1–M5 / F1–F5 | <breath>/<sigh> | – | wav/flac/ogg |
cosyvoice | Deutsch + Emotion + Cloning | de-thorsten oder eigene Stimme | volle Inline-Tags + natürlichsprachige Emotion | ✅ Zero-Shot | wav (24 kHz) |
mistral | SaaS-Fallback | default-de/default-en | – | – | mp3/wav/opus/flac |
- STT läuft auf Mistral Voxtral (Paris, DSGVO).
- Ohne
providerbleibt es beim Server-Default (Supertonic) — bestehende Aufrufe ändern sich nicht.
KI-Kennzeichnung: Synthetisch erzeugte Sprache ist als KI-Inhalt zu kennzeichnen (EU-AI-Act Art. 50). Supertonic-Gewichte stehen unter OpenRAIL-M; CosyVoice trägt kein eingebautes Wasserzeichen — die Kennzeichnung erfolgt auf Anwendungsebene.
POST /v1/audio/speech — Text-to-Speech
Erzeugt gesprochene Audio-Bytes aus Text. Antwort ist der rohe Audio-Body (kein JSON-Wrapper), wie bei OpenAI.
curl https://sovrgpt.com/api/v1/audio/speech \
-H "Authorization: Bearer $SOVR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "supertonic-3",
"input": "Guten Tag <breath> willkommen bei SovrGPT.",
"voice": "F3",
"response_format": "wav"
}' --output hallo.wavRequest-Body
| Feld | Typ | Gilt für | Beschreibung |
|---|---|---|---|
input | string | alle | Pflicht. Der zu sprechende Text, ≤ 4 000 Zeichen. Inline-Tags je nach Provider (s. u.). |
voice | string | alle | Supertonic: M1–M5/F1–F5. CosyVoice: de-thorsten. Mistral: default-de/default-en. |
provider | string | alle | supertonic | cosyvoice | mistral. Optional — sonst aus model/voice abgeleitet, sonst Server-Default (supertonic). |
response_format | string | Supertonic/Mistral | wav/flac/ogg (Supertonic), zusätzlich mp3/opus/aac (Mistral). CosyVoice liefert immer wav. |
language | string | Supertonic/CosyVoice | ISO-639-1 (de/en/…). |
emotion / instruction | string | CosyVoice | Natürlichsprachige Stil-/Emotions-Anweisung, z. B. "Sprich sehr traurig und langsam." |
reference_audio_b64 | string | CosyVoice | Base64 wav/flac (≤ 30 s) → klont diese Stimme (Zero-Shot). Überschreibt voice. |
prompt_text | string | CosyVoice | Transkript des Referenzclips (beste Qualität). Für eingebaute Stimmen automatisch. |
speed | number | CosyVoice | 0,5–2,0 (Default 1,0). Supertonic/Mistral: akzeptiert, aktuell ignoriert. |
model | string | alle | Wählt die Engine (OpenAI-idiomatisch): supertonic-3, cosyvoice-3 oder voxtral-mini-tts. provider hat Vorrang, falls beides gesetzt ist. |
Antwort
200 mit Audio-Bytes. Header:
Content-Type: audio/wav (bzw. audio/flac, audio/mpeg …)
X-Voice-Provider: supertonic (oder: cosyvoice / mistral)Fehler: 400 (kein/zu langer input, ungültige Stimme), 401/403
(Auth/Scope), 503 (TTS-Anbieter nicht konfiguriert oder CosyVoice-Worker im
Cold-Start → in ~1 Min erneut senden), 502 (Upstream-Fehler).
CosyVoice — Deutsch mit Emotion, Tags & eigener Stimme
Für expressives Deutsch, Betonung, Lachen/Atmen und Voice-Cloning den
Provider cosyvoice wählen. Vollständige Fähigkeiten:
Modelle → Voice.
Inline-Tags (direkt im input): [laughter], [breath],
<laughter>…</laughter> (lachend gesprochen), <strong>…</strong> (Betonung).
# Deutsch mit Tags + Betonung
curl https://sovrgpt.com/api/v1/audio/speech \
-H "Authorization: Bearer $SOVR_KEY" -H "Content-Type: application/json" \
-d '{
"provider": "cosyvoice",
"voice": "de-thorsten",
"input": "Und dann [breath] öffnete ich die Tür. [laughter] Das war <strong>unglaublich</strong>."
}' --output tags.wavEmotion — natürlichsprachig über emotion (bzw. instruction):
curl https://sovrgpt.com/api/v1/audio/speech \
-H "Authorization: Bearer $SOVR_KEY" -H "Content-Type: application/json" \
-d '{
"provider": "cosyvoice",
"voice": "de-thorsten",
"input": "Diese Zeiten sind für immer vorbei.",
"emotion": "Sprich sehr traurig, leise und langsam."
}' --output traurig.wavEigene Stimme (Zero-Shot-Cloning) — einen 10–20-s-Referenzclip als Base64
mitgeben, plus dessen Transkript als prompt_text (beste Qualität):
REF=$(base64 -w0 meine_stimme.wav)
curl https://sovrgpt.com/api/v1/audio/speech \
-H "Authorization: Bearer $SOVR_KEY" -H "Content-Type: application/json" \
-d "{
\"provider\": \"cosyvoice\",
\"input\": \"Ein neuer Satz, gesprochen in meiner geklonten Stimme.\",
\"reference_audio_b64\": \"$REF\",
\"prompt_text\": \"<wörtliches Transkript des Referenzclips>\"
}" --output geklont.wavEingebaute Stimmen: aktuell
de-thorsten(Deutsch, männlich, ruhig; CC0). Eigene Stimmen jederzeit überreference_audio_b64(Zero-Shot, kein Training). Eine persistente Stimm-Bibliothek mit Upload-UI ist in Vorbereitung.Cold-Start: Der CosyVoice-GPU-Worker skaliert auf null. Warm liefert er in ~6 s; ein kalt angelaufener Worker kann Minuten brauchen — dann kommt
503 „warming up", einfach in ~1 Min erneut senden. Supertonic (Default) hat keinen Cold-Start.
POST /v1/audio/transcriptions — Speech-to-Text
Transkribiert eine hochgeladene Audiodatei (multipart/form-data).
curl https://sovrgpt.com/api/v1/audio/transcriptions \
-H "Authorization: Bearer $SOVR_KEY" \
-F file=@aufnahme.webm \
-F language=de \
-F response_format=jsonForm-Felder
| Feld | Typ | Default | Beschreibung |
|---|---|---|---|
file | Datei | – | Pflicht. Audio (webm/ogg/mp3/wav/m4a …), ≤ 25 MiB. |
language | string | auto | ISO-639-1, z. B. de. Die Sprache wird auch ohne Angabe zuverlässig erkannt. |
response_format | string | json | json ({ "text": … }), text (Klartext), verbose_json ({ text, language, duration }). |
context_bias | string | – | Wiederholbar. Eigennamen und Fachbegriffe, auf die die Erkennung gezogen werden soll — z. B. Produkt- oder Kundennamen. Ein Begriff darf kein Leerzeichen enthalten (Bindestriche sind erlaubt); Begriffe mit Leerzeichen werden verworfen. Höchstens 100 Einträge. |
format_text | boolean | false | Formatiert das Transkript zusätzlich: Absätze, nummerierte Liste aus gesprochenem „erstens/zweitens/drittens", Leerzeile nach der Anrede, abgesetzte Grußformel. Siehe unten. |
model | string | – | Beratend (voxtral-mini-transcribe). |
context_bias nur für Eigennamen. Der Parameter zieht den Text zu den
gelisteten Begriffen hin. Bei Allgemeinwortschatz verbiegt er dadurch korrekt
erkannte Wörter — ein gelistetes „Refactoring" hat ein richtig transkribiertes
„refactoren" zu „refactoring" gemacht.
Antwort
{ "text": "Hallo, dies ist ein Test." }Fehler: 400 (kein file), 413 (> 25 MiB), 401/403 (Auth/Scope),
503 (MISTRAL_API_KEY nicht gesetzt), 502 (Upstream-Fehler).
format_text — Transkript mit Struktur
Ein Rohtranskript ist eine Textwand: keine Absätze, keine Aufzählungen, keine Leerzeile nach der Anrede. Das ist keine Eigenheit unseres Anbieters — kein Speech-to-Text-Dienst am Markt erzeugt so etwas; „smart formatting" heißt überall nur Interpunktion und Großschreibung. Struktur kann nur ein Modell liefern, das den Inhalt versteht.
Mit format_text=1 läuft deshalb zusätzlich ein zweiter Durchlauf über ein
Modell mit Audio-Verständnis. Beide Durchläufe starten gleichzeitig, die
Antwortzeit ist also die des langsameren, nicht die Summe.
curl https://sovrgpt.com/api/v1/audio/transcriptions \
-H "Authorization: Bearer $SOVR_KEY" \
-F file=@diktat.webm \
-F format_text=1 \
-F response_format=verbose_json{
"text": "Sehr geehrte Frau Dr. Schmitt,\n\nvielen Dank …\n\n1. Die Übertragung …\n2. Die Antwortzeiten …\n\nMit freundlichen Grüßen\nHans Elstner",
"text_raw": "Sehr geehrte Frau Dr. Schmitt, vielen Dank … Erstens die Übertragung …",
"language": null,
"duration": 101,
"formatting": { "applied": true, "verdict": "ok", "coverage": 0.996 }
}Der Wortlaut ist geschützt. Ein Modell, das formatieren soll, kann dabei umformulieren oder kürzen — und das Ergebnis sieht dann tadellos aus, obwohl Inhalt fehlt. Jede formatierte Fassung wird deshalb gegen das Rohtranskript geprüft, bevor sie ausgeliefert wird:
formatting.verdict | Bedeutung | Was Sie bekommen |
|---|---|---|
ok | Nur die Gliederung hat sich geändert. | die formatierte Fassung |
auffaellig | Einzelne Wörter weichen ab. | die formatierte Fassung — text_raw gegenlesen |
— (applied: false) | Der Wortlaut wurde verändert oder der Durchlauf schlug fehl. | das Rohtranskript, dazu formatting.reason |
text_raw ist bei format_text=1 immer dabei, auch wenn die Formatierung
angewendet wurde. Ein Client, der auf den wörtlichen Text angewiesen ist,
liest immer text_raw und ignoriert text.
format_text ist bewusst standardmäßig aus. Bestandsintegrationen
bekommen unverändert dieselben Bytes wie bisher. Wer Struktur will, schaltet
sie ein.
Grenzen des formatierten Pfads. Er nutzt ein anderes Modell als der
Rohpfad und kennt deshalb context_bias, Sprechertrennung und
Wort-Zeitstempel nicht — diese wirken nur auf text_raw. Außerdem
verarbeitet er höchstens ~20 Minuten Audio je Anfrage (der Rohpfad deutlich
mehr). Für Diktate ist das reichlich, für Mitschnitte langer Besprechungen
nicht.
SDK-Beispiel (OpenAI-Client)
from openai import OpenAI
client = OpenAI(base_url="https://sovrgpt.com/api/v1", api_key=SOVR_KEY)
# Text-to-Speech (Supertonic, schnell)
client.audio.speech.create(
model="supertonic-3", voice="F3", response_format="wav",
input="Hallo Welt <sigh> das war ein langer Tag.",
).stream_to_file("hallo.wav")
# Text-to-Speech (CosyVoice, deutsch + Emotion)
# model="cosyvoice-3" wählt die Engine; emotion (SovrGPT-Extension) via extra_body
client.audio.speech.create(
model="cosyvoice-3", voice="de-thorsten", response_format="wav",
input="Was für ein wunderbarer Tag!",
extra_body={"emotion": "Sprich fröhlich und aufgeregt."},
).stream_to_file("froehlich.wav")
# Speech-to-Text
with open("aufnahme.webm", "rb") as f:
tr = client.audio.transcriptions.create(
model="voxtral-mini-transcribe", file=f, language="de",
)
print(tr.text)Im Chat
Ohne API funktioniert Sprache direkt im Chat: das Mikrofon-Symbol im Composer diktiert (STT → Text im Eingabefeld), der Lautsprecher-Button an jeder Assistenten-Antwort liest sie vor (TTS). Siehe Modelle → Voice.