> 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)

L’affinage des modèles TTS leur permet de s’adapter à votre jeu de données spécifique, à votre cas d’usage, 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 plus encore. Nous prenons également en charge **Speech-to-Text (STT)** des modèles comme Whisper d’OpenAI.

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

⭐ **Unsloth prend en charge n’importe quel `transformers` modèle TTS compatible.** Même si nous n’avons pas encore de notebook ou de téléversement pour celui-ci, il est tout de même pris en charge, par exemple essayez d’affiner Dia-TTS ou Moshi.

{% hint style="info" %}
Le clonage zero-shot capture le ton mais rate le rythme et l’expression, donnant souvent un rendu robotique et artificiel. L’affinage fournit une reproduction vocale bien plus précise et réaliste. [En savoir plus ici](#fine-tuning-voice-models-vs.-zero-shot-voice-cloning).
{% endhint %}

### Notebooks d’affinage :

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. Comme 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, les modèles plus petits sont souvent préférés 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 3 milliards 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 professionnels, ce qui fait de la cohérence vocale la principale différence. CSM nécessite un contexte audio pour chaque locuteur afin d’obtenir de bonnes performances, tandis qu’Orpheus-ft intègre cette cohérence nativement.

L’affinage à partir d’un modèle de base comme CSM nécessite 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 le contexte audio pour améliorer la cohérence vocale.

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

Orpheus est préentraîné sur un vaste corpus vocal et excelle dans la génération d’une parole réaliste avec une prise en charge intégrée d’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 safetensors de l’adaptateur LoRA.

#### Chargement des modèles

Comme les modèles vocaux sont généralement de petite taille, vous pouvez les entraîner en utilisant LoRA 16 bits ou un affinage complet FFT, ce qui peut fournir 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 une 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 (plus d’informations à ce sujet plus tard). Vous n’avez *pas* besoin d’un vocodeur séparé – Orpheus produira directement des jetons audio, qui pourront être décodés en forme d’onde.
{% endhint %}

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

Au minimum, un jeu de données pour l’affinage TTS se compose de **clips audio et de leurs transcriptions correspondantes** (texte). Utilisons le [*Elise* jeu de données](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 des **étiquettes d’émotion** (par ex. \<sigh>, \<laughs>) intégrées dans les transcriptions. Ces étiquettes 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 étiquettes 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), ainsi que કેટલીક métadonnées (nom du locuteur, statistiques de hauteur, etc.). Nous devons fournir à Unsloth un jeu de données de paires audio-texte.

{% hint style="success" %}
Plutôt que de se concentrer uniquement sur le ton, la cadence 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 entre les générations en utilisant l’ID de locuteur 0 parce que c’est un **modèle de base**— il n’a pas d’identités vocales fixes. Les jetons d’ID 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 répliques précédentes. Cela aide le modèle à imiter la voix souhaitée de manière plus fiable. Sans cela, une variation est normale, même avec le même ID 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 datasets` de Hugging Face :

```python
from datasets import load_dataset, Audio

# Charger le jeu de données Elise (par exemple, la version avec étiquettes d’émotion)
dataset = load_dataset("MrDragonFox/Elise", split="train")
print(len(dataset), "exemples")  # ~1200 exemples dans Elise

# S’assurer que tout l’audio est à un taux d’échantillonnage de 24 kHz (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,2k exemples). Chaque élément de `jeu de données` est un dictionnaire contenant au moins :

* `"audio"`: le clip audio (tableau de forme d’onde et métadonnées comme le taux d’échantillonnage), et
* `"text"`: la chaîne de transcription

Orpheus prend en charge des étiquettes comme `<laugh>`, `<chuckle>`, `<sigh>`, `<cough>`, `<sniffle>`, `<groan>`, `<yawn>`, `<gasp>`, etc. Par exemple : `"I missed you <laugh> so much!"`. Ces étiquettes sont entre chevrons et seront traitées comme des jetons spéciaux par le modèle (elles correspondent aux [étiquettes attendues par Orpheus](https://github.com/canopyai/Orpheus-TTS) comme `<laugh>` et `<sigh>`. Pendant l’entraînement, le modèle apprendra à associer ces étiquettes aux motifs audio correspondants. Le jeu de données Elise avec étiquettes contient déjà beaucoup d’entre elles (par exemple, 336 occurrences de « laughs », 156 de « sighs », etc., comme indiqué dans sa fiche). Si votre jeu de données n’a pas de telles étiquettes 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 clips 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 autre option 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** (pas de caractères inhabituels que le tokenizer pourrait ne pas connaître, sauf les étiquettes d’émotion si elles sont utilisées). Assurez-vous également que tout l’audio a un taux d’échantillonnage cohérent (rééchantillonnez-le si nécessaire au taux cible attendu 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 datasets` bibliothèque HF
* pour gérer le chargement et le prétraitement optionnel (comme le rééchantillonnage). **Incluez toutes les** étiquettes spéciales `dans le texte que vous souhaitez faire apprendre au modèle (assurez-vous qu’elles sont au format` \<angle\_brackets>
* afin que le modèle les traite comme des jetons distincts).

### (Facultatif) Si vous avez plusieurs locuteurs, vous pourriez inclure un jeton d’ID de locuteur dans le texte ou utiliser une approche séparée d’empreinte vocale, mais cela dépasse ce guide de base (Elise est monolocuteur).

Affinage de TTS avec Unsloth

**Commençons maintenant l’affinage ! Nous allons illustrer cela en utilisant du 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

```python
. Cela permet généralement au modèle d’apprendre mieux votre jeu de données et d’obtenir une plus grande précision.
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_...", # utilisez-en un si vous utilisez des modèles soumis à restriction comme meta-llama/Llama-2-7b-hf
from datasets import load_dataset
```

{% hint style="info" %}
dataset = load\_dataset("MrDragonFox/Elise", split = "train")
{% endhint %}

**Si la mémoire est très limitée ou si le jeu de données est volumineux, vous pouvez diffuser 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 manière.**

Étape 2 : avancé - prétraiter les données pour l’entraînement (facultatif)

```python
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 le texte et les IDs des jetons audio comme séquence cible. Cependant, comme Orpheus est un LLM décodeur uniquement qui produit de l’audio, nous pouvons fournir le texte en entrée (contexte) et utiliser les IDs 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 un modèle de text-to-speech. Si ce n’est pas le cas, nous pouvons faire quelque chose comme :
# Tokeniser les transcriptions textuelles
    def preprocess_function(example):
    # Tokeniser le texte (conserver intacts les jetons spéciaux comme <laugh>)
    tokens = tokenizer(example["text"], return_tensors="pt")
    # Aplatir en liste d’IDs de jetons
    input_ids = tokens["input_ids"].squeeze(0)
    # Le modèle générera des jetons audio après ces jetons texte.
    # Pour l’entraînement, nous pouvons définir labels égaux à input_ids (afin qu’il apprenne à prédire le jeton suivant).
    # Mais cela ne couvre que les jetons texte prédisant le jeton texte suivant (qui peut être un jeton audio ou une 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, utilisez la même entrée que les labels (le modèle apprendra à produire la séquence en se basant sur elle-même).

return {"input_ids": input_ids, "labels": input_ids}
```

{% hint style="info" %}
train\_data = dataset.map(preprocess\_function, remove\_columns=dataset.column\_names) *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 `. Le préentraînement d’Orpheus impliquait probablement la conversion de l’audio en jetons discrets (via un codec audio) et l’entraînement du modèle à les prédire à partir du texte précédent. Pour un affinage sur de nouvelles données vocales, vous devriez de la même manière obtenir les jetons audio pour chaque clip (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>
{% endhint %}

jetons. **Cependant,**&#x55;nsloth 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 devrez encoder manuellement chaque clip audio en IDs 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 texte n’enseignera pas au modèle l’audio réel – il doit correspondre aux motifs audio. `processor` et en passant le tableau audio). Si Unsloth ne prend pas encore en charge la tokenisation audio automatique, vous devrez peut-être utiliser la fonction `encode_audio` du dépôt Orpheus pour obtenir les séquences de jetons de 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 une exécution d’entraînement complète.
        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", # Utilisez ceci 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`. Utiliser per\_device\_train\_batch\_size >1 peut entraîner des erreurs si une configuration multi-GPU est utilisée ; 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 l’affinage**

Cela lancera la boucle d’entraînement. Vous devriez voir les 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 : enregistrer le modèle affiné**

Une fois l’entraînement terminé (ou si vous l’arrêtez en cours de route lorsque vous estimez que c’est suffisant), enregistrez le modèle. Cela enregistre UNIQUEMENT les adaptateurs LoRA, et non le modèle complet. Pour enregistrer en 16 bits ou en GGUF, faites défiler vers le bas !

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

Cela enregistre les poids du modèle (pour LoRA, il 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 la 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 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 nécessaire. 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 ne reproduit pas toute la gamme expressive. Vous perdez des détails comme la vitesse de parole, la formulation, les particularités vocales et les subtilités de la prosodie — des éléments qui donnent à une voix sa **personnalité et son unicité**.

Si vous voulez juste une voix différente et que le même mode d’élocution vous convient, le zero-shot est généralement suffisant. Mais la parole suivra toujours le **style du modèle**, et non celui du locuteur.

Pour quelque chose de plus personnalisé ou expressif, vous avez besoin d’un entraînement avec des méthodes comme LoRA pour vraiment capturer la manière dont quelqu’un parle.


---

# 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 dynamically by asking a question.

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

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
