> For the complete documentation index, see [llms.txt](https://unsloth.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unsloth.ai/docs/fr/notions-de-base/text-to-speech-tts-fine-tuning.md).

# Guide de fine-tuning Text-to-Speech (TTS)

Découvrez comment fine-tuner des modèles vocaux TTS et STT avec Unsloth.

Le réglage fin des modèles TTS leur permet de s'adapter à votre jeu de données spécifique, à votre cas d'utilisation ou au style et au ton souhaités. L'objectif est de personnaliser ces modèles pour cloner des voix, adapter des styles et des tons de parole, prendre en charge de nouvelles langues, gérer des tâches spécifiques et bien plus encore. Nous prenons également en charge **la reconnaissance vocale (STT)** des modèles comme Whisper d'OpenAI.

Avec [Unsloth](https://github.com/unslothai/unsloth), vous pouvez affiner **any** un modèle TTS (`transformers` compatible) 1,5× plus rapide avec 50 % de mémoire en moins que les autres implémentations avec Flash Attention 2.

⭐ **Unsloth prend en charge tout modèle TTS `transformers` compatible.** Même si nous n'avons pas encore de notebook ni de téléversement pour cela, c'est quand même pris en charge, par ex. essayez d'affiner Dia-TTS ou Moshi.

{% hint style="info" %}
Le clonage zero-shot capture le ton mais manque le rythme et l'expression, sonnant souvent robotique et artificiel. Le réglage fin offre une réplication vocale bien plus précise et réaliste. [En savoir plus ici](#fine-tuning-voice-models-vs.-zero-shot-voice-cloning).
{% endhint %}

### Notebooks de réglage fin :

Nous avons également téléversé des modèles TTS (originaux et quantifiés) sur notre [page Hugging Face](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" %}
Si vous remarquez que la durée de sortie atteint un maximum de 10 secondes, augmentez`max_new_tokens = 125` par rapport à sa valeur par défaut de 125. Puisque 125 jetons correspondent à 10 secondes d'audio, vous devrez définir une valeur plus élevée pour des sorties plus longues.
{% endhint %}

### Choisir et charger un modèle TTS

Pour le TTS, on préfère souvent les modèles plus petits en raison d'une latence plus faible et d'une inférence plus rapide pour les utilisateurs finaux. Affiner un modèle de moins de 3B de paramètres est souvent idéal, et nos principaux exemples utilisent Sesame-CSM (1B) et Orpheus-TTS (3B), un modèle vocal basé sur Llama.

#### Détails de Sesame-CSM (1B)

**CSM-1B** est un modèle de base, tandis que **Orpheus-ft** est affiné sur 8 comédiens vocaux professionnels, ce qui fait de la cohérence de la voix la principale différence. CSM nécessite un contexte audio pour chaque locuteur afin de bien fonctionner, tandis qu'Orpheus-ft intègre cette cohérence.

Affiner à partir d'un modèle de base comme CSM demande généralement plus de calcul, tandis que partir d'un modèle déjà affiné comme Orpheus-ft offre de meilleurs résultats dès le départ.

Pour aider avec CSM, nous avons ajouté de nouvelles options d'échantillonnage et un exemple montrant comment utiliser un contexte audio pour améliorer la cohérence vocale.

#### Détails d'Orpheus-TTS (3B)

Orpheus est pré-entraîné sur un grand corpus vocal et excelle dans la génération d'une parole réaliste avec un support intégré des indices émotionnels comme les rires et les soupirs. Son architecture en fait l'un des modèles TTS les plus faciles à utiliser et à entraîner, car il peut être exporté via llama.cpp, ce qui lui confère une excellente compatibilité avec tous les moteurs d'inférence. Pour les modèles non pris en charge, vous ne pourrez enregistrer que les poids safetensors de l'adaptateur LoRA.

#### Chargement des modèles

Comme les modèles vocaux sont généralement petits, vous pouvez entraîner les modèles en utilisant LoRA 16 bits ou un affinage complet FFT, ce qui peut donner des résultats de meilleure qualité. Pour le charger en LoRA 16 bits :

```python
from unsloth import FastModel

model_name = "unsloth/orpheus-3b-0.1-pretrained"
model, tokenizer = FastModel.from_pretrained(
    model_name,
    load_in_4bit=False  # utiliser la précision 4 bits (QLoRA)
)
```

Lorsque cela s'exécute, Unsloth téléchargera les poids du modèle ; si vous préférez 8 bits, vous pouvez utiliser `load_in_8bit = True`, ou pour un affinage complet définissez `full_finetuning = True` (assurez-vous d'avoir suffisamment de VRAM). Vous pouvez également remplacer le nom du modèle par d'autres modèles TTS.

{% hint style="info" %}
**Remarque :** Le tokenizer d'Orpheus inclut déjà des jetons spéciaux pour la sortie audio (nous y reviendrons plus tard). Vous n'avez *ne* pas besoin d'un vocodeur séparé – Orpheus produira directement des jetons audio, qui peuvent être décodés en forme d'onde.
{% endhint %}

### Préparation de votre jeu de données

Au minimum, un jeu de données de réglage fin TTS se compose de **extraits audio et de leurs transcriptions correspondantes** (texte). Utilisons [*Elise* dataset](https://huggingface.co/datasets/MrDragonFox/Elise) qui est un corpus de parole anglaise d'environ 3 heures, avec un seul locuteur. Il existe deux variantes :

* [`MrDragonFox/Elise`](https://huggingface.co/datasets/MrDragonFox/Elise) – une version augmentée avec **balises d'émotion** (par ex. \<sigh>, \<laughs>) intégrées dans les transcriptions. Ces balises entre chevrons indiquent des expressions (rire, soupirs, etc.) et sont traitées comme des jetons spéciaux par le tokenizer d'Orpheus
* [`Jinsaryko/Elise`](https://huggingface.co/datasets/Jinsaryko/Elise) – version de base avec des transcriptions sans balises spéciales.

Le jeu de données est organisé avec un audio et une transcription par entrée. Sur Hugging Face, ces jeux de données ont des champs tels que `audio` (la forme d'onde), `text` (la transcription), et quelques métadonnées (nom du locuteur, statistiques de hauteur tonale, etc.). Nous devons fournir à Unsloth un jeu de données de paires audio-texte.

{% hint style="success" %}
Au lieu de se concentrer uniquement sur le ton, le débit et la hauteur, la priorité devrait être de s'assurer que votre jeu de données est entièrement annoté et correctement normalisé.
{% endhint %}

{% hint style="info" %}
Avec certains modèles comme **Sesame-CSM-1B**, vous pourriez remarquer une variation de voix d'une génération à l'autre en utilisant l'identifiant de locuteur 0, car c'est un **modèle de base**— il n'a pas d'identités vocales fixes. Les jetons d'identifiant de locuteur aident principalement à maintenir **la cohérence au sein d'une conversation**, pas entre des générations séparées.

Pour obtenir une voix cohérente, fournissez **des exemples contextuels**, comme quelques extraits audio de référence ou des énoncés antérieurs. Cela aide le modèle à imiter la voix souhaitée de manière plus fiable. Sans cela, des variations sont à prévoir, même avec le même identifiant de locuteur.
{% endhint %}

**Option 1 : Utiliser la bibliothèque Hugging Face Datasets** – Nous pouvons charger le jeu de données Elise à l'aide de la `bibliothèque` :

```python
from datasets import load_dataset, Audio

# Charger le jeu de données Elise (par ex., la version avec balises d'émotion)
dataset = load_dataset("MrDragonFox/Elise", split="train")
print(len(dataset), "samples")  # ~1200 échantillons dans Elise

# S'assurer que tout l'audio est à une fréquence d'échantillonnage de 24 kHz (le taux attendu par Orpheus)
dataset = dataset.cast_column("audio", Audio(sampling_rate=24000))
```

Cela téléchargera le jeu de données (\~328 Mo pour \~1,2 k échantillons). Chaque élément dans `dataset` est un dictionnaire contenant au moins :

* `"audio"`: l'extrait audio (tableau de forme d'onde et métadonnées comme la fréquence d'échantillonnage), et
* `"text"`: la chaîne de transcription

Orpheus prend en charge des balises comme `<laugh>`, `<chuckle>`, `<sigh>`, `<cough>`, `<sniffle>`, `<groan>`, `<yawn>`, `<gasp>`, etc. Par exemple : `"I missed you <laugh> so much!"`. Ces balises sont encadrées de chevrons et seront traitées comme des jetons spéciaux par le modèle (elles correspondent [aux balises attendues par Orpheus](https://github.com/canopyai/Orpheus-TTS) comme `<laugh>` et `<sigh>`. Pendant l'entraînement, le modèle apprendra à associer ces balises aux motifs audio correspondants. Le jeu de données Elise avec balises contient déjà beaucoup de ces éléments (par ex., 336 occurrences de « laughs », 156 de « sighs », etc. comme indiqué dans sa fiche). Si votre jeu de données ne contient pas de telles balises mais que vous souhaitez les intégrer, vous pouvez annoter manuellement les transcriptions lorsque l'audio contient ces expressions.

**Option 2 : Préparer un jeu de données personnalisé** – Si vous avez vos propres fichiers audio et transcriptions :

* Organisez les extraits audio (fichiers WAV/FLAC) dans un dossier.
* Créez un fichier CSV ou TSV avec des colonnes pour le chemin du fichier et la transcription. Par exemple :

  ```
  filename,text
  0001.wav,Bonjour !
  0002.wav,<sigh> Je suis très fatigué.
  ```
* Utilisez `load_dataset("csv", data_files="mydata.csv", split="train")` pour le charger. Vous devrez peut-être indiquer au chargeur de jeu de données comment gérer les chemins audio. Une alternative consiste à utiliser la `fonctionnalité` datasets.Audio pour charger les données audio à la volée :

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

  Ensuite `dataset[i]["audio"]` contiendra le tableau audio.
* **Assurez-vous que les transcriptions sont normalisées** (aucun caractère inhabituel que le tokenizer pourrait ne pas connaître, sauf les balises d'émotion si elles sont utilisées). Assurez-vous également que tout l'audio a une fréquence d'échantillonnage cohérente (rééchantillonnez-le si nécessaire à la fréquence cible attendue par le modèle, par ex. 24 kHz pour Orpheus).

En résumé, pour **la préparation du jeu de données**:

* Vous avez besoin d'une **liste de paires (audio, texte)** .
* Utilisez la bibliothèque HF `bibliothèque` pour gérer le chargement et le prétraitement optionnel (comme le rééchantillonnage).
* Incluez toutes les **balises spéciales** dans le texte que vous voulez que le modèle apprenne (assurez-vous qu'elles sont en `<crochets_angulaires>` format afin que le modèle les traite comme des jetons distincts).
* (Facultatif) Si c'est multi-locuteur, vous pourriez inclure un jeton d'identifiant de locuteur dans le texte ou utiliser une approche distincte d'embedding de locuteur, mais cela dépasse ce guide de base (Elise est mono-locuteur).

### Affinage des modèles TTS avec Unsloth

Maintenant, commençons le réglage fin ! Nous allons illustrer cela à l'aide de code Python (que vous pouvez exécuter dans un notebook Jupyter, Colab, etc.).

**Étape 1 : Charger le modèle et le jeu de données**

Dans tous nos notebooks TTS, nous activons l'entraînement LoRA (16 bits) et désactivons l'entraînement QLoRA (4 bits) avec : `load_in_4bit = False`. Ainsi, le modèle peut généralement mieux apprendre votre jeu de données et obtenir une meilleure précision.

```python
from unsloth import FastLanguageModel
import torch
dtype = None # None pour la détection automatique. Float16 pour Tesla T4, V100, Bfloat16 pour Ampere+
load_in_4bit = False # Utiliser la quantification 4 bits pour réduire l'utilisation mémoire. Peut être False.

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/orpheus-3b-0.1-ft",
    max_seq_length= 2048, # Choisissez n'importe quelle valeur pour un long contexte !
    dtype = dtype,
    load_in_4bit = load_in_4bit,
    #token = "hf_...", # en utiliser un si vous utilisez des modèles verrouillés comme meta-llama/Llama-2-7b-hf
)

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

{% hint style="info" %}
Si la mémoire est très limitée ou si le jeu de données est volumineux, vous pouvez streamer ou charger par morceaux. Ici, 3 h d'audio tiennent facilement en RAM. Si vous utilisez votre propre CSV de jeu de données, chargez-le de la même façon.
{% endhint %}

**Étape 2 : Avancé - Prétraiter les données pour l'entraînement (facultatif)**

Nous devons préparer les entrées pour le Trainer. Pour la synthèse vocale, une approche consiste à entraîner le modèle de manière causale : concaténer les identifiants de texte et de jetons audio comme séquence cible. Cependant, comme Orpheus est un LLM décodeur seul qui produit de l'audio, nous pouvons fournir le texte comme entrée (contexte) et utiliser les identifiants des jetons audio comme étiquettes. En pratique, l'intégration d'Unsloth peut faire cela automatiquement si la configuration du modèle l'identifie comme texte-vers-parole. Sinon, nous pouvons faire quelque chose comme :

```python
# Tokeniser les transcriptions textuelles
def preprocess_function(example):
    # Tokeniser le texte (garder intacts les jetons spéciaux comme <laugh>)
    tokens = tokenizer(example["text"], return_tensors="pt")
    # Aplatir en liste d'identifiants de jetons
    input_ids = tokens["input_ids"].squeeze(0)
    # Le modèle générera des jetons audio après ces jetons de texte.
    # Pour l'entraînement, nous pouvons définir les labels égaux à input_ids (afin qu'il apprenne à prédire le jeton suivant).
    # Mais cela ne couvre que les jetons de texte qui prédisent le jeton de texte suivant (qui peut être un jeton audio ou la fin).
    # Une approche plus sophistiquée : ajouter un jeton spécial indiquant le début de l'audio, et laisser le modèle générer le reste.
    # Pour simplifier, utiliser la même entrée comme labels (le modèle apprendra à produire la séquence à partir d'elle-même).
    return {"input_ids": input_ids, "labels": input_ids}

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

{% hint style="info" %}
Ce qui précède est une simplification. En réalité, pour affiner Orpheus correctement, vous auriez besoin des *jetons audio comme partie des labels d'entraînement*. L'entraînement initial d'Orpheus a probablement consisté à convertir l'audio en jetons discrets (via un codec audio) et à entraîner le modèle à les prédire à partir du texte précédent. Pour un réglage fin sur de nouvelles données vocales, vous devriez de même obtenir les jetons audio pour chaque extrait (en utilisant le codec audio d'Orpheus). Le GitHub d'Orpheus fournit un script de traitement des données – il encode l'audio en séquences de `<custom_token_x>` jetons.
{% endhint %}

Cependant, **Unsloth peut abstraire cela**: si le modèle est un FastModel avec un processeur associé qui sait gérer l'audio, il pourrait encoder automatiquement l'audio du jeu de données en jetons. Sinon, vous devriez encoder manuellement chaque extrait audio en identifiants de jetons (en utilisant le codebook d'Orpheus). C'est une étape avancée au-delà de ce guide, mais gardez à l'esprit que le simple fait d'utiliser des jetons de texte n'apprendra pas au modèle l'audio réel – il doit correspondre aux motifs audio.

Supposons qu'Unsloth fournisse un moyen de fournir directement l'audio (par exemple, en définissant `processor` et en passant le tableau audio). Si Unsloth ne prend pas encore en charge la tokenisation audio automatique, vous devrez peut-être utiliser le dépôt Orpheus `encode_audio` la fonction pour obtenir des séquences de jetons pour l'audio, puis les utiliser comme labels. (Les entrées du jeu de données ont bien des `phonèmes` et certaines caractéristiques acoustiques, ce qui suggère un pipeline.)

**Étape 3 : Configurer les arguments d'entraînement et le Trainer**

```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, # Définissez ceci pour un entraînement complet en une seule exécution.
        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", # Utiliser cela pour WandB etc.
    ),
)
```

Nous faisons 60 étapes pour accélérer les choses, mais vous pouvez définir `num_train_epochs=1` pour une exécution complète, et désactiver `max_steps=None`. L'utilisation d'un per\_device\_train\_batch\_size > 1 peut entraîner des erreurs en configuration multi-GPU ; pour éviter les problèmes, assurez-vous que CUDA\_VISIBLE\_DEVICES est défini sur un seul GPU (par ex., CUDA\_VISIBLE\_DEVICES=0). Ajustez selon vos besoins.

**Étape 4 : Commencer le réglage fin**

Cela lancera la boucle d'entraînement. Vous devriez voir des journaux de perte toutes les 50 étapes (comme défini par `logging_steps`). L'entraînement peut prendre un certain temps selon le GPU – par exemple, sur un GPU Colab T4, quelques époques sur 3 h de données peuvent prendre 1 à 2 heures. Les optimisations d'Unsloth le rendront plus rapide que l'entraînement HF standard.

**Étape 5 : Sauvegarder le modèle affiné**

Après la fin de l'entraînement (ou si vous l'arrêtez à mi-parcours lorsque vous estimez que c'est suffisant), sauvegardez le modèle. Cela ne sauvegarde QUE les adaptateurs LoRA, et pas le modèle complet. Pour sauvegarder en 16 bits ou GGUF, faites défiler vers le bas !

```python
model.save_pretrained("lora_model")  # Sauvegarde locale
tokenizer.save_pretrained("lora_model")
# model.push_to_hub("your_name/lora_model", token = "...") # Sauvegarde en ligne
# tokenizer.push_to_hub("your_name/lora_model", token = "...") # Sauvegarde en ligne
```

Cela enregistre les poids du modèle (pour LoRA, cela peut n'enregistrer que les poids de l'adaptateur si la base n'est pas entièrement affinée). Si vous avez utilisé `--push_model` dans l'interface CLI ou `trainer.push_to_hub()`, vous pourriez le téléverser directement sur Hugging Face Hub.

Vous devriez maintenant avoir un modèle TTS affiné dans le répertoire. L'étape suivante consiste à le tester et, si cela est pris en charge, vous pouvez utiliser llama.cpp pour le convertir en fichier GGUF.

### Affinage des modèles vocaux vs clonage vocal zero-shot

On dit qu'on peut cloner une voix avec seulement 30 secondes d'audio en utilisant des modèles comme XTTS — sans entraînement requis. C'est techniquement vrai, mais cela passe à côté de l'essentiel.

Le clonage vocal zero-shot, également disponible dans des modèles comme Orpheus et CSM, est une approximation. Il capture le **ton et le timbre** généraux **de la voix d'un locuteur, mais il ne reproduit pas toute la plage expressive. Vous perdez des détails comme la vitesse de parole, le phrasé, les particularités vocales et les subtilités de la prosodie - des éléments qui donnent à une voix sa**.

personnalité et son caractère unique **Si vous voulez seulement une voix différente et que les mêmes schémas de rendu vous conviennent, le zero-shot est généralement suffisant. Mais la parole suivra toujours le**style du modèle

, et non celui du locuteur.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://unsloth.ai/docs/fr/notions-de-base/text-to-speech-tts-fine-tuning.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
