# Anleitung zur Feinabstimmung von Text-to-Speech (TTS)

Das Feinabstimmen von TTS-Modellen ermöglicht es ihnen, sich an Ihren spezifischen Datensatz, Anwendungsfall oder gewünschten Stil und Ton anzupassen. Ziel ist es, diese Modelle zu individualisieren, Stimmen zu klonen, Sprechstile und -töne anzupassen, neue Sprachen zu unterstützen, spezifische Aufgaben zu bewältigen und mehr. Wir unterstützen auch **Speech-to-Text (STT)** Modelle wie OpenAIs Whisper.

Mit [Unsloth](https://github.com/unslothai/unsloth)können Sie feinabstimmen **jedes** TTS-Modell (`transformers` kompatibel) 1,5x schneller mit 50 % weniger Speicher als andere Implementierungen mit Flash Attention 2.

⭐ **Unsloth unterstützt jedes `transformers` kompatible TTS-Modell.** Selbst wenn wir noch kein Notebook oder Upload dafür haben, wird es trotzdem unterstützt, z. B. versuchen Sie, Dia-TTS oder Moshi feinzuabstimmen.

{% hint style="info" %}
Zero-Shot-Klonen erfasst den Ton, verfehlt aber oft das Tempo und den Ausdruck und klingt häufig robotisch und unnatürlich. Feinabstimmung liefert deutlich genauere und realistischere Stimmreplikationen. [Lesen Sie hier mehr](#fine-tuning-voice-models-vs.-zero-shot-voice-cloning).
{% endhint %}

### Notebooks zur Feinabstimmung:

Wir haben auch TTS-Modelle (original und quantisiert) auf unsere [Hugging Face-Seite](https://huggingface.co/collections/unsloth/text-to-speech-tts-models-68007ab12522e96be1e02155).

| [Sesame-CSM (1B)](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Sesame_CSM_\(1B\)-TTS.ipynb) | [Orpheus-TTS (3B)](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Orpheus_\(3B\)-TTS.ipynb) | [Whisper Large V3](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Whisper.ipynb) (STT) |
| ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| [Spark-TTS (0.5B)](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Spark_TTS_\(0_5B\).ipynb)   | [Llasa-TTS (1B)](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llasa_TTS_\(1B\).ipynb)     | [Oute-TTS (1B)](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Oute_TTS_\(1B\).ipynb)  |

{% hint style="success" %}
Wenn Sie feststellen, dass die Ausgabedauer ein Maximum von 10 Sekunden erreicht, erhöhen Sie`max_new_tokens = 125` von seinem Standardwert 125. Da 125 Tokens ungefähr 10 Sekunden Audio entsprechen, müssen Sie einen höheren Wert einstellen, um längere Ausgaben zu erhalten.
{% endhint %}

### Auswahl und Laden eines TTS-Modells

Für TTS werden oft kleinere Modelle bevorzugt, da sie geringere Latenz und schnellere Inferenz für Endnutzer bieten. Das Feinabstimmen eines Modells mit unter 3B Parametern ist oft ideal, und unsere Hauptbeispiele verwenden Sesame-CSM (1B) und Orpheus-TTS (3B), ein auf Llama basierendes Sprachmodell.

#### Details zu Sesame-CSM (1B)

**CSM-1B** ist ein Basismodell, während **Orpheus-ft** auf 8 professionellen Synchronsprechern feinabgestimmt ist, wodurch die Stimmkonsistenz der zentrale Unterschied ist. CSM benötigt Audiokontext für jeden Sprecher, um gut zu funktionieren, während Orpheus-ft diese Konsistenz eingebaut hat.

Feinabstimmung von einem Basismodell wie CSM erfordert im Allgemeinen mehr Rechenressourcen, während der Start von einem feinabgestimmten Modell wie Orpheus-ft bessere Ergebnisse sofort bietet.

Um CSM zu unterstützen, haben wir neue Sampling-Optionen und ein Beispiel hinzugefügt, das zeigt, wie man Audiokontext für verbesserte Stimmkonsistenz verwendet.

#### Details zu Orpheus-TTS (3B)

Orpheus ist auf einem großen Sprachkorpus vortrainiert und eignet sich hervorragend zur Erzeugung realistischer Sprache mit integriertem Support für emotionale Hinweise wie Lachen und Seufzer. Seine Architektur macht es zu einem der einfachsten TTS-Modelle in Nutzung und Training, da es über llama.cpp exportiert werden kann und somit eine hervorragende Kompatibilität über alle Inferenz-Engines bietet. Für nicht unterstützte Modelle können Sie nur den LoRA-Adapter als safetensors speichern.

#### Laden der Modelle

Da Stimmmodelle in der Regel klein sind, können Sie die Modelle mit LoRA 16-Bit oder vollständiger Feinabstimmung (FFT) trainieren, was möglicherweise qualitativ höhere Ergebnisse liefert. Um es in LoRA 16-Bit zu laden:

```python
from unsloth import FastModel

model_name = "unsloth/orpheus-3b-0.1-pretrained"
model, tokenizer = FastModel.from_pretrained(
    model_name,
    load_in_4bit=False  # use 4-bit precision (QLoRA)
)
```

Wenn dies ausgeführt wird, lädt Unsloth die Modellgewichte herunter. Wenn Sie 8-Bit bevorzugen, könnten Sie `load_in_8bit = True`verwenden, oder für vollständige Feinabstimmung setzen Sie `full_finetuning = True` (stellen Sie sicher, dass Sie genug VRAM haben). Sie können den Modellnamen auch durch andere TTS-Modelle ersetzen.

{% hint style="info" %}
**Hinweis:** Orpheus’ Tokenizer enthält bereits spezielle Tokens für Audioausgabe (mehr dazu später). Sie *brauchen* keinen separaten Vocoder – Orpheus wird Audio-Tokens direkt ausgeben, die zu einer Wellenform dekodiert werden können.
{% endhint %}

### Vorbereitung Ihres Datensatzes

Mindestens besteht ein TTS-Feinabstimmungsdatensatz aus **Audioclips und deren entsprechenden Transkripten** (Text). Verwenden wir den [*Elise* Datensatz](https://huggingface.co/datasets/MrDragonFox/Elise) bei dem es sich um ein etwa 3-stündiges Monosprecher-englisches Sprachkorpus handelt. Es gibt zwei Varianten:

* [`MrDragonFox/Elise`](https://huggingface.co/datasets/MrDragonFox/Elise) – eine augmentierte Version mit **Emotionstags** (z. B. \<sigh>, \<laughs>) eingebettet in den Transkripten. Diese Tags in spitzen Klammern markieren Ausdrücke (Lachen, Seufzer usw.) und werden vom Tokenizer von Orpheus als spezielle Tokens behandelt
* [`Jinsaryko/Elise`](https://huggingface.co/datasets/Jinsaryko/Elise) – Basisversion mit Transkripten ohne spezielle Tags.

Der Datensatz ist so organisiert, dass pro Eintrag ein Audio und ein Transkript vorhanden sind. Auf Hugging Face haben diese Datensätze Felder wie `audio` (die Wellenform), `text` (die Transkription) und einige Metadaten (Sprechername, Pitch-Statistiken usw.). Wir müssen Unsloth einen Datensatz aus Audio-Text-Paaren bereitstellen.

{% hint style="success" %}
Anstatt sich ausschließlich auf Ton, Kadenz und Pitch zu konzentrieren, sollte die Priorität darin liegen, sicherzustellen, dass Ihr Datensatz vollständig annotiert und ordnungsgemäß normalisiert ist.
{% endhint %}

{% hint style="info" %}
Bei einigen Modellen wie **Sesame-CSM-1B**können Sie eine Stimmvariation über Generierungen hinweg bemerken, wenn Sie speaker ID 0 verwenden, weil es ein **Basismodell**ist — es hat keine festen Stimmidentitäten. Speaker-ID-Tokens helfen hauptsächlich dabei, **Konsistenz innerhalb einer Unterhaltung**aufrechtzuerhalten, nicht über separate Generierungen hinweg.

Um eine konsistente Stimme zu erhalten, liefern Sie **kontextuelle Beispiele**, wie ein paar Referenz-Audioclips oder vorherige Äußerungen. Dies hilft dem Modell, die gewünschte Stimme zuverlässiger zu imitieren. Ohne dies ist Variation zu erwarten, selbst bei derselben Speaker-ID.
{% endhint %}

**Option 1: Verwendung der Hugging Face Datasets-Bibliothek** – Wir können den Elise-Datensatz mit Hugging Face’s `datasets` Bibliothek laden:

```python
from datasets import load_dataset, Audio

# Laden des Elise-Datensatzes (z. B. die Version mit Emotionstags)
dataset = load_dataset("MrDragonFox/Elise", split="train")
print(len(dataset), "samples")  # ~1200 Samples in Elise

# Stellen Sie sicher, dass alle Audios eine Abtastrate von 24 kHz haben (Orpheus’ erwartete Rate)
dataset = dataset.cast_column("audio", Audio(sampling_rate=24000))
```

Dies wird den Datensatz herunterladen (\~328 MB für \~1,2k Samples). Jeder Eintrag in `Datensatz` ist ein Wörterbuch mit mindestens:

* `"audio"`: dem Audioclip (Wellenform-Array und Metadaten wie Abtastrate), und
* `"text"`: der Transkript-String

Orpheus unterstützt Tags wie `<laugh>`, `<chuckle>`, `<sigh>`, `<cough>`, `<sniffle>`, `<groan>`, `<yawn>`, `<gasp>`, usw. Zum Beispiel: `"I missed you <laugh> so much!"`. Diese Tags sind in spitze Klammern eingeschlossen und werden vom Modell als spezielle Tokens behandelt (sie entsprechen [Orpheus’ erwarteten Tags](https://github.com/canopyai/Orpheus-TTS) wie `<laugh>` und `<sigh>`. Während des Trainings wird das Modell lernen, diese Tags mit den entsprechenden Audiomustern zu assoziieren. Der Elise-Datensatz mit Tags enthält bereits viele davon (z. B. 336 Vorkommen von „laughs“, 156 von „sighs“ usw., wie in seiner Card aufgeführt). Wenn Ihr Datensatz solche Tags nicht enthält, Sie sie aber einbeziehen möchten, können Sie die Transkripte manuell annotieren, wo das Audio diese Ausdrücke enthält.

**Option 2: Vorbereitung eines eigenen Datensatzes** – Wenn Sie eigene Audiodateien und Transkripte haben:

* Organisieren Sie Audioclips (WAV/FLAC-Dateien) in einem Ordner.
* Erstellen Sie eine CSV- oder TSV-Datei mit Spalten für Dateipfad und Transkript. Zum Beispiel:

  ```
  filename,text
  0001.wav,Hello there!
  0002.wav,<sigh> I am very tired.
  ```
* Verwenden Sie `load_dataset("csv", data_files="mydata.csv", split="train")` um sie zu laden. Möglicherweise müssen Sie dem Dataset-Loader mitteilen, wie Audio-Pfade zu behandeln sind. Eine Alternative ist die Verwendung des `datasets.Audio` Features, um Audiodaten bei Bedarf zu laden:

  ```python
  from datasets import Audio
  dataset = load_dataset("csv", data_files="mydata.csv", split="train")
  dataset = dataset.cast_column("filename", Audio(sampling_rate=24000))
  ```

  Dann `dataset[i]["audio"]` wird das Audio-Array enthalten.
* **Stellen Sie sicher, dass Transkripte normalisiert sind** (keine ungewöhnlichen Zeichen, die der Tokenizer möglicherweise nicht kennt, außer den Emotionstags, falls verwendet). Stellen Sie außerdem sicher, dass alle Audios eine konsistente Abtastrate haben (resampeln Sie sie bei Bedarf auf die Zielrate, die das Modell erwartet, z. B. 24 kHz für Orpheus).

Zusammenfassend, für die **Datensatzvorbereitung**:

* benötigen Sie eine **Liste von (Audio, Text)** Paaren.
* Verwenden Sie die HF `datasets` Bibliothek, um das Laden und optionale Preprocessing (wie Resampling) zu handhaben.
* Fügen Sie alle **spezial Tags** in den Text ein, die das Modell lernen soll (stellen Sie sicher, dass sie im `<angle_brackets>` Format sind, damit das Modell sie als eigene Tokens behandelt).
* (Optional) Wenn Multi-Sprecher, könnten Sie ein Speaker-ID-Token in den Text einfügen oder einen separaten Speaker-Embedding-Ansatz verwenden, aber das geht über diese grundlegende Anleitung hinaus (Elise ist Ein-Sprecher).

### Feinabstimmung von TTS mit Unsloth

Nun beginnen wir mit der Feinabstimmung! Wir illustrieren dies mit Python-Code (den Sie in einem Jupyter-Notebook, Colab usw. ausführen können).

**Schritt 1: Modell und Datensatz laden**

In allen unseren TTS-Notebooks aktivieren wir LoRA (16-Bit) Training und deaktivieren QLoRA (4-Bit) Training mit: `load_in_4bit = False`. Dies ermöglicht es dem Modell in der Regel, Ihren Datensatz besser zu lernen und eine höhere Genauigkeit zu erzielen.

```python
from unsloth import FastLanguageModel
import torch
dtype = None # None zur automatischen Erkennung. Float16 für Tesla T4, V100, Bfloat16 für Ampere+
load_in_4bit = False # Verwenden Sie 4-Bit-Quantisierung zur Reduzierung des Speicherbedarfs. Kann False sein.

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/orpheus-3b-0.1-ft",
    max_seq_length= 2048, # Wählen Sie beliebig für langen Kontext!
    dtype = dtype,
    load_in_4bit = load_in_4bit,
    #token = "hf_...", # verwenden Sie einen, wenn Sie gesperrte Modelle wie meta-llama/Llama-2-7b-hf nutzen
)

from datasets import load_dataset
dataset = load_dataset("MrDragonFox/Elise", split = "train")
```

{% hint style="info" %}
Wenn der Speicher sehr begrenzt ist oder der Datensatz groß ist, können Sie streamen oder in Teilen laden. Hier passen 3 Stunden Audio leicht in den RAM. Wenn Sie Ihre eigene Datensatz-CSV verwenden, laden Sie sie ähnlich.
{% endhint %}

**Schritt 2: Fortgeschritten – Daten für das Training vorverarbeiten (Optional)**

Wir müssen Eingaben für den Trainer vorbereiten. Für Text-to-Speech ist ein Ansatz, das Modell kausal zu trainieren: Text- und Audio-Token-IDs als Zielsequenz zu verketten. Da Orpheus jedoch ein Decoder-only-LLM ist, das Audio ausgibt, können wir den Text als Eingabe (Kontext) zuführen und die Audio-Token-IDs als Labels verwenden. In der Praxis könnte Unsloths Integration dies automatisch tun, wenn die Modellkonfiguration es als Text-to-Speech identifiziert. Falls nicht, können wir so etwas tun wie:

```python
# Tokenize the text transcripts
def preprocess_function(example):
    # Tokenize the text (keep the special tokens like <laugh> intact)
    tokens = tokenizer(example["text"], return_tensors="pt")
    # Flatten to list of token IDs
    input_ids = tokens["input_ids"].squeeze(0)
    # The model will generate audio tokens after these text tokens.
    # For training, we can set labels equal to input_ids (so it learns to predict next token).
    # But that only covers text tokens predicting the next text token (which might be an audio token or end).
    # A more sophisticated approach: append a special token indicating start of audio, and let the model generate the rest.
    # For simplicity, use the same input as labels (the model will learn to output the sequence given itself).
    return {"input_ids": input_ids, "labels": input_ids}

train_data = dataset.map(preprocess_function, remove_columns=dataset.column_names)
```

{% hint style="info" %}
Das Obige ist eine Vereinfachung. In Wirklichkeit müssten Sie, um Orpheus richtig feinabzustimmen, die *Audio-Tokens als Teil der Trainingslabels*haben. Orpheus’ Vortraining beinhaltete wahrscheinlich die Umwandlung von Audio in diskrete Tokens (über einen Audiocodec) und das Training des Modells, diese vorherzusagen, gegebenem vorausgehenden Text. Für die Feinabstimmung auf neue Sprachdaten müssten Sie ähnlich die Audio-Tokens für jeden Clip erhalten (mithilfe von Orpheus’ Audiocodec). Das Orpheus-GitHub stellt ein Skript zur Datenverarbeitung bereit – es kodiert Audio in Sequenzen von `<custom_token_x>` Tokens.
{% endhint %}

Allerdings **kann Unsloth dies abstrahieren**: Wenn das Modell ein FastModel mit einem zugehörigen Processor ist, der weiß, wie mit Audio umzugehen ist, könnte es die Audiokodierung im Datensatz automatisch vornehmen. Falls nicht, müssten Sie jeden Audioclip manuell in Token-IDs kodieren (mithilfe von Orpheus’ Codebook). Dies ist ein fortgeschrittener Schritt, der über diese Anleitung hinausgeht, aber bedenken Sie, dass das bloße Verwenden von Text-Tokens das Modell nicht das tatsächliche Audio lehren wird – es muss die Audiomuster abgleichen.

Gehen wir davon aus, dass Unsloth eine Möglichkeit bietet, Audio direkt zuzufüttern (zum Beispiel durch Setzen von `processor` und Übergabe des Audio-Arrays). Wenn Unsloth automatische Audiotokenisierung noch nicht unterstützt, müssen Sie möglicherweise die Orpheus-Repository- `encode_audio` Funktion verwenden, um Token-Sequenzen für das Audio zu erhalten und diese dann als Labels zu verwenden. (Die Datensatz-Einträge haben tatsächlich `Phoneme` und einige akustische Merkmale, was auf eine Pipeline hindeutet.)

**Schritt 3: Trainingsargumente und Trainer einrichten**

```python
from transformers import TrainingArguments,Trainer,DataCollatorForSeq2Seq
from unsloth import is_bfloat16_supported

trainer = Trainer(
    model = model,
    train_dataset = dataset,
    args = TrainingArguments(
        per_device_train_batch_size = 1,
        gradient_accumulation_steps = 4,
        warmup_steps = 5,
        # num_train_epochs = 1, # Set this for 1 full training run.
        max_steps = 60,
        learning_rate = 2e-4,
        fp16 = not is_bfloat16_supported(),
        bf16 = is_bfloat16_supported(),
        logging_steps = 1,
        optim = "adamw_8bit",
        weight_decay = 0.01,
        lr_scheduler_type = "linear",
        seed = 3407,
        output_dir = "outputs",
        report_to = "none", # Use this for WandB etc
    ),
)
```

Wir machen 60 Schritte, um die Dinge zu beschleunigen, aber Sie können `num_train_epochs=1` für einen vollständigen Lauf setzen und `max_steps=None`deaktivieren. Bei Verwendung eines per\_device\_train\_batch\_size >1 kann es zu Fehlern kommen, wenn ein Multi-GPU-Setup verwendet wird; um Probleme zu vermeiden, stellen Sie sicher, dass CUDA\_VISIBLE\_DEVICES auf eine einzelne GPU gesetzt ist (z. B. CUDA\_VISIBLE\_DEVICES=0). Passen Sie es bei Bedarf an.

**Schritt 4: Feinabstimmung beginnen**

Dies startet die Trainingsschleife. Sie sollten alle 50 Schritte Loss-Logs sehen (wie durch `logging_steps`gesetzt). Das Training kann je nach GPU einige Zeit dauern – zum Beispiel können auf einer Colab T4 GPU einige Epochen auf 3 Stunden Daten 1–2 Stunden dauern. Unsloths Optimierungen machen es schneller als das Standard-HF-Training.

**Schritt 5: Das feinabgestimmte Modell speichern**

Nachdem das Training abgeschlossen ist (oder wenn Sie es unterwegs stoppen, wenn Sie es für ausreichend halten), speichern Sie das Modell. Dies speichert NUR die LoRA-Adapter und nicht das vollständige Modell. Um in 16-Bit oder GGUF zu speichern, scrollen Sie nach unten!

```python
model.save_pretrained("lora_model")  # Lokal speichern
tokenizer.save_pretrained("lora_model")
# model.push_to_hub("your_name/lora_model", token = "...") # Online speichern
# tokenizer.push_to_hub("your_name/lora_model", token = "...") # Online speichern
```

Dies speichert die Modellgewichte (für LoRA könnte es nur Adaptergewichte speichern, wenn die Basis nicht vollständig feinabgestimmt wurde). Wenn Sie `--push_model` im CLI oder `trainer.push_to_hub()`verwendet haben, könnten Sie es direkt zum Hugging Face Hub hochladen.

Nun sollten Sie ein feinabgestimmtes TTS-Modell im Verzeichnis haben. Der nächste Schritt ist, es zu testen und, falls unterstützt, können Sie llama.cpp verwenden, um es in eine GGUF-Datei zu konvertieren.

### Feinabstimmung von Stimmmodellen vs. Zero-Shot-Stimmenklonen

Man sagt, man könne eine Stimme mit nur 30 Sekunden Audio mit Modellen wie XTTS klonen – kein Training erforderlich. Das ist technisch richtig, aber es verfehlt den Punkt.

Zero-Shot-Stimmenklonen, das auch in Modellen wie Orpheus und CSM verfügbar ist, ist eine Annäherung. Es erfasst das allgemeine **Ton und Timbre** der Stimme eines Sprechers, reproduziert jedoch nicht den vollen expressiven Bereich. Sie verlieren Details wie Sprechgeschwindigkeit, Phrasierung, vokale Eigenheiten und die Feinheiten der Prosodie – Dinge, die einer Stimme ihre **Persönlichkeit und Einzigartigkeit**.

geben. Wenn Sie nur eine andere Stimme möchten und mit den gleichen Vortragsmustern zufrieden sind, ist Zero-Shot in der Regel ausreichend. Die Sprache wird jedoch weiterhin dem **Stil des Modells**folgen, nicht dem des Sprechers.

Für alles, was persönlicher oder ausdrucksstärker sein soll, benötigen Sie Training mit Methoden wie LoRA, um wirklich einzufangen, wie jemand spricht.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unsloth.ai/docs/de/grundlagen/text-to-speech-tts-fine-tuning.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
