Aller au contenu principal

Voix des personnages et seed

Avec eleven_v3, synthétiser la même phrase avec la même voix renvoie un audio différent à chaque fois. Le timbre comme l'énergie changent de façon perceptible.

Pour une piste de narration unique, cela n'a guère d'importance. Mais si l'audio doit être la voix de ce personnage, utilisée encore et encore, une personne différente à chaque appel ne convient pas.

Cette page explique comment l'éviter.

En bref
  • Les voix enregistrées d'AICU (elena et les autres) ont déjà une seed fixe. Passez simplement le slug dans voice
  • Pour la fixer vous-même, définissez seed explicitement. Même seed + même texte = même audio
  • Si vous avez changé la seed et que l'audio n'a pas changé, soupçonnez le cache (force: true)
  • Sur eleven_v4 et eleven_v4_turbo, il n'y a pas de seed à fixer — et vous n'en avez pas besoin. Voir ci-dessous

eleven_v4 n'accepte pas de seed (et n'en a pas besoin)​

Tout ce qui figure sur cette page concerne eleven_v3 et eleven_multilingual_v2. Les modèles v4 ignorent complètement seed, nous n'en envoyons donc pas.

La preuve : synthétisez la même réplique trois fois avec seed: 55 et une fois avec seed: 999. Sur eleven_v3, la seed différente change la longueur de l'audio (41,794 → 40,541 octets). Sur eleven_v4, la longueur ne bouge pas du tout (44,720 octets pour toutes les seeds). Le fournisseur le confirme : GET /v1/models indique can_use_style: false pour les modèles v4.

Cela ressemble à une perte, puisque tout l'intérêt d'une seed fixe est qu'un personnage garde sa voix. Mesures à l'appui, ce n'en est pas une.

Nous avons réauditionné les sept voix AiCuty le 2026-10-01 : trois prises d'une même réplique par voix et par modèle, en comparant la distance MFCC entre les prises, et en exprimant cette distance comme une fraction de la distance entre deux personnages différents.

eleven_v3 (seed fixée)eleven_v4 (sans seed)
Écart d'une prise à l'autre, pire voix7 % de « une autre personne »6 %
Écart d'une prise à l'autre, cas typique1–3 %1–2 %

v4 sans seed est aussi stable que v3 avec une seed fixée. Deux voix (Mei, Nao) étaient nettement plus stables sur v4.

Deux choses ont bien changé, et elles comptent si vous utilisez plusieurs personnages ensemble :

  • Les personnages sont plus proches les uns des autres sur v4. La distance médiane entre deux voix différentes passe de 0.114 (v3) à 0.089 — environ 22 % de marge en moins pour les distinguer
  • Les débits de parole convergent. Le même script durait de 6.84 à 8.44 s selon les sept voix sur v3, et de 7.34 à 7.86 s sur v4. Bien pour les chœurs et les dialogues minutés ; moins bien pour « celui qui parle vite et celui qui parle lentement »

Faire passer une voix de v3 à v4 la déplace aussi. Six des sept se sont déplacées de 7 à 34 % de la distance vers un autre personnage — l'écart qu'on attendrait de la même personne un autre jour. Nao Verde s'est déplacé de 106 %, c'est-à-dire aussi loin qu'un autre personnage.

Nous avons essayé de remplacer la voix sous-jacente de Nao — sept voix masculines, générées sur v4 et mesurées par rapport au Nao actuel. Le candidat le plus proche se situait encore à 60 % de la distance vers un autre personnage, et la voix actuelle à 86 %. Il n'y a pas de retour possible.

Ce constat établi, nous avons choisi le nouveau Nao plutôt que de traîner l'ancien : nao utilise désormais eleven_v4 par défaut.

curl -sD- -o nao.mp3 -X POST https://api.aicu.ai/v1/audio/speech \
-H "Authorization: Bearer $AICU_API_KEY" -H "Content-Type: application/json" \
-d '{"input": "やあ、ナオ・ヴェルデだよ。", "voice": "nao"}' | grep -i x-aicu-model
# → x-aicu-model: eleven_v4

Si vous dépendez de l'ancien Nao, demandez eleven_v3 explicitement — nous ne le retirons pas, et nous ne remplaçons jamais en silence ce que vous avez demandé. Toutes les autres voix utilisent toujours eleven_multilingual_v2 par défaut.

Le modèle actuel d'une voix se lit dans le registre des personnages : GET /v1/char/nao renvoie voice.model (et voice.seed, qui vaut null sur v4 — ces modèles n'acceptent pas de seed, nous ne faisons donc pas semblant qu'il y en ait une).

Le nom du paramètre change selon l'endpoint

Le champ qui porte la voix dépend de l'endpoint que vous appelez.

EndpointChamp de la voixChamp du texte
/v1/audio/speech, /v1/tts/speech (compatible OpenAI)voiceinput
/v1/tts/generate (propre à AICU)slugtext

Envoyer voice à /v1/tts/generate ne provoque pas d'erreur. Le champ est ignoré en silence et vous obtenez la voix par défaut — 200, un audio valide, aucun avertissement. C'est difficile à remarquer.

Mesuré le 2026-09-22, avec seed fixée pour que la sortie soit déterministe :

RequêteTaille de la réponse (deux exécutions)
pas de champ de voix22,196 / 22,196 octets
"voice": "mei"22,196 / 22,196 octets — identique à l'absence de voix
"slug": "mei"26,794 / 26,794 octets

Si vous lancez un long script par lots avant de vous en apercevoir, vous payez la totalité avec la mauvaise voix. Générez d'abord une seule réplique et vérifiez que l'audio a bien changé avant de lancer le volume.

Une mauvaise valeur, elle, échoue correctement — {"slug": "no_such_character"} renvoie 400 {"error":"Unknown character: no_such_character. GET /v1/tts/voices を参照"} (« を参照 » = « voir »). Seul un mauvais nom de champ passe en silence.

Ce qui se passe​

Envoyez trois fois la même requête et comparez les empreintes (hash) des MP3 renvoyés.

for i in 1 2 3; do
curl -s -X POST https://api.aicu.ai/v1/audio/speech \
-H "Authorization: Bearer $AICU_API_KEY" -H "Content-Type: application/json" \
-d '{"voice": "mina", "model": "eleven_v3", "input": "こんにちは", "seed": '"$RANDOM"'}' \
| md5sum
done

Avec une seed aléatoire, les trois empreintes diffèrent — et on croirait entendre trois personnes différentes. Fixez seed et les trois empreintes sont identiques.

Seeds par défaut des voix AiCuty​

Les voix enregistrées d'AICU sont livrées avec une seed que nous avons déjà choisie. Si vous omettez seed, c'est celle-ci qui est utilisée.

from openai import OpenAI

client = OpenAI(base_url="https://api.aicu.ai/v1", api_key="aicu_live_…")

# Inutile d'écrire une seed. Même voix, quel que soit le nombre d'appels
client.audio.speech.create(
model="eleven_v3", voice="mina", input="こんにちは"
).stream_to_file("mina.mp3")
slugNomCaractère de la voixv3v2
elenaElena Bloom (エレナ・ブルーム)Calme et facile à suivre ; narration féminine en japonais standard330330
meiMei Soleil (メイ・ソレイユ)Voix de jeune fille lumineuse, pleine d'énergie et facile à suivre, même pour les enfants721721
minaMina Azure (ミナ・アズール)Narration calme et intelligente ; aucune fatigue d'écoute sur la durée101105
naoNao Verde (ナオ・ヴェルデ)Voix douce d'un jeune homme bienveillant, passionné de sciences5555
sakiSaki Noire (サキ・ノワール)Voix chuchotée, douce avec une pointe de mystère10331035
marshaMarsha Arancia (マーシャ・アランチャ)Voix féminine fraîche, énergique et agréable à écouter418414
luc4LuC4 (ルカ/全力肯定彼氏くん)Agréable voix masculine grave11041104

Vous pouvez écouter les vraies voix sur les voix officielles AiCuty (japonais, anglais et français ; Marsha existe aussi en espagnol et en italien).

Pourquoi v2 et v3 utilisent des valeurs différentes​

La même seed donne une voix différente sur un modèle différent. Une prise réussie sur v3 ne l'est pas forcément sur v2 ; nous avons donc refait le choix pour chacun.

Mina est à 101 sur v3 et à 105 sur v2. Saki est à 1033 sur v3 et à 1035 sur v2.

Comment les valeurs sont choisies​

Nous partons de la date d'anniversaire du personnage, mois et jour accolés, puis nous auditionnons les valeurs voisines. Mina est née le 1er octobre : 101 est donc le point de départ, et nous écoutons ensuite 102, 103, 104, 105.

Les valeurs dérivées d'un anniversaire sont faciles à retenir, faciles à expliquer, et n'entrent pas en collision d'un personnage à l'autre.

Fixer votre propre voix​

Quand vous passez un voice_id ElevenLabs brut, il n'y a pas de seed par défaut. Choisissez-en une vous-même et indiquez-la explicitement.

curl -X POST https://api.aicu.ai/v1/audio/speech \
-H "Authorization: Bearer $AICU_API_KEY" -H "Content-Type: application/json" \
-d '{"voice": "pqHfZKP75CvOlQylNhV4", "model": "eleven_v3", "input": "…", "seed": 42}' \
--output out.mp3

Il n'y a pas de bonne façon unique de choisir, mais s'engager sur une valeur et la noter compte plus que la valeur elle-même. Le pire, c'est de ne plus pouvoir expliquer pourquoi la voix sonne comme elle sonne.

Auditionnez quelques candidates avant de décider. Même des seeds voisines peuvent donner une impression très différente.

Quand vous changez la seed et que l'audio ne change pas​

Soupçonnez le cache.

api.aicu.ai met en cache sur une clé unique « même voix × même modèle × même texte × même seed ». Les réponses en cache ne sont pas facturées (x-aicu-ap-cost: 0).

curl -sS -D - -o /dev/null -X POST https://api.aicu.ai/v1/audio/speech \
-H "Authorization: Bearer $AICU_API_KEY" -H "Content-Type: application/json" \
-d '{"voice": "mina", "model": "eleven_v3", "input": "こんにちは"}' \
| grep -i 'x-aicu-ap-cost\|x-cache-hit'

Si x-aicu-ap-cost: 0 revient, l'audio a été servi depuis le cache. Quand vous avez vraiment besoin de le régénérer, utilisez force: true sur /v1/tts/generate.

Il fut un temps où l'audio renvoyé n'était pas celui demandé

L'ancienne passerelle ne transmettait pas seed au fournisseur et ne l'incluait pas non plus dans la clé de cache. Résultat : changer la seed renvoyait quand même l'audio précédent — et comme la réponse était un 200, impossible de s'en apercevoir. La transmission comme la clé de cache sont désormais corrigées.

Aligner plusieurs voix ensemble​

Si vous assemblez l'audio de plusieurs personnages, normalisez le volume sonore clip par clip avant le mixage. Les niveaux diffèrent d'une voix à l'autre, et une concaténation telle quelle ne laisse ressortir que la plus forte.

ffmpeg -i in.mp3 -af "loudnorm=I=-18:TP=-2:LRA=9" -ac 1 -ar 44100 out.mp3

Un fondu enchaîné d'environ 0,1 seconde aux jonctions sonne naturel. Une simple concaténation coupe la fin de chaque respiration.

ffmpeg -i a.mp3 -i b.mp3 -filter_complex "[0][1]acrossfade=d=0.1:c1=tri:c2=tri" out.mp3
N'utilisez pas -c copy pour concaténer des mp3

Avec le démultiplexeur concat et -c copy, le délai de l'encodeur mp3 fait reculer les horodatages (non monotonically increasing dts) et les jonctions se dégradent. Reconstruisez-les plutôt avec le filtre concat.

Voir aussi​