Dans l’article précédent j’ai présenté Fish Audio en tant qu’entreprise et expliqué pourquoi trois de ses modèles sont ouverts alors que le modèle phare reste derrière une API payante. Celui-ci en constitue la suite pratique : comment intégrer concrètement le service. Authentification, point de terminaison, SDK Python, les deux méthodes de clonage vocal, le streaming qui commence à parler avant que votre modèle de langage ait fini de réfléchir, et le calcul des coûts qui détermine si l’ensemble reste abordable à votre volume. Tout ce qui suit provient de la documentation actuelle, pas de souvenirs.
En résumé
- Un POST vers https://api.fish.audio/v1/tts avec un jeton bearer vous renvoie de l’audio ; le modèle se choisit via un en-tête, pas dans le corps de la requête.
- Le modèle s2.1-pro-free est identique à s2.1-pro mais sans frais, destiné aux tests et au prototypage, ce qui rend l’évaluation véritablement gratuite.
- La facturation est de 15 dollars par million d’octets UTF-8, soit environ 180 000 mots anglais ou près de 12 heures de parole.
- Le clonage vocal existe sous deux formes : un modèle vocal persistant et réutilisable, ou des références zero shot passées en ligne avec une seule requête.
- Le mode websocket accepte un générateur de tokens textuels, ce qui permet de prononcer une réponse de LLM au fur et à mesure de sa production au lieu d’attendre la fin.
- Votre limite de débit est basée sur la concurrence et augmente avec les dépenses cumulées, en commençant à 5 requêtes simultanées.
Le minimum fonctionnel
Avant toute installation, vérifiez que votre clé fonctionne avec une seule requête. Le point de terminaison est POST https://api.fish.audio/v1/tts, l’authentification utilise un jeton bearer standard, et la réponse est un flux audio fragmenté plutôt qu’une enveloppe JSON contenant une URL.
# The model is selected with a header, which is unusual enough to trip people up.
# s2.1-pro-free costs nothing, so use it while you are still experimenting.
curl --request POST \
--url https://api.fish.audio/v1/tts \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header 'model: s2.1-pro-free' \
--data '{"text": "Hello! Welcome to Fish Audio."}' \
--output hello.mp3
Deux détails de cette requête ont plus d’importance qu’il n’y paraît. L’ model en-tête sert à choisir le moteur, donc une requête qui semble ignorer votre choix de modèle est généralement due au fait que la valeur a été placée dans le corps JSON. Et la réponse arrive directement sous forme d’octets audio, si bien qu’en déboguant par affichage du corps vous obtiendrez du bruit binaire plutôt qu’un message d’erreur.
Le SDK Python
Pour tout ce qui dépasse un simple test de fonctionnement, le SDK simplifie le travail. Un point à noter avant de commencer : le nom du paquet à installer et celui du module à importer ne s’écrivent pas de la même façon, ce qui fait perdre quelques minutes de confusion à beaucoup.
pip install fish-audio-sdk # note the hyphens
export FISH_API_KEY=your_api_key_here
from fishaudio import FishAudio # but the module has no hyphens
from fishaudio.utils import save
client = FishAudio() # reads FISH_API_KEY from the environment
# or be explicit: FishAudio(api_key="...")
# AsyncFishAudio is the asyncio variant
audio = client.tts.convert(text="Hello from Fish Audio!")
save(audio, "out.mp3")
Le format de sortie, la fréquence d’échantillonnage et le débit de parole sont tous réglables. Le format par défaut est le mp3, adapté à la diffusion dans un navigateur mais inapproprié pour tout traitement ultérieur, car il faut des trames non compressées dans ce cas.
from fishaudio.types import TTSConfig
# wav or pcm when the audio feeds another system, mp3 or opus when it feeds a person
audio = client.tts.convert(
text="High quality narration for the archive.",
config=TTSConfig(format="wav", sample_rate=44100),
)
# Speed accepts 0.5 to 2.0. Small adjustments read as natural, large ones do not.
brisk = client.tts.convert(text="Speaking a little faster.", speed=1.2)
# Pick a specific voice by id
branded = client.tts.convert(
text="This uses a specific voice.",
reference_id="9a9cf47702da476aa4629e2506d4a857",
)
Pour les longs documents, utilisez stream plutôt que convert. Cela produit des segments au lieu de construire l’intégralité du clip en mémoire, ce qui devient important dès que vous narrez un contenu de la longueur d’un livre.
with open("chapter.mp3", "wb") as f:
for chunk in client.tts.stream(text=very_long_passage):
f.write(chunk)
Quel modèle utiliser, et le niveau gratuit qui n’est pas une version dégradée
Cette partie mérite une lecture attentive, car la nomenclature cache quelque chose de vraiment utile. La documentation décrit s2.1-pro comme le modèle de production recommandé, avec une qualité, une latence et un débit améliorés par rapport au précédent S2-Pro. Elle décrit s2.1-pro-free comme le même modèle sans frais, destiné aux tests, au prototypage et au développement.
| Modèle | Prix | Utilisation |
|---|---|---|
| s2.1-pro | 15,00 dollars par million d’octets UTF-8 | Production, le choix par défaut recommandé |
| s2.1-pro-free | 0,00 dollar | Évaluation, prototypage, développement |
| s2-pro | 15,00 dollars par million d’octets UTF-8 | Génération précédente, remplacée |
| s1 | 15,00 dollars par million d’octets UTF-8 | Ancien modèle, uniquement pour les intégrations existantes |
| transcribe-1 | 0,36 dollar par heure audio | Reconnaissance vocale, facturée à la seconde |
| voice-design-1 | 0,01 dollar par requête réussie | Génération d’une voix à partir d’une description |
La conséquence pratique est que vous pouvez évaluer le véritable modèle de production avec votre contenu réel, dans vos langues réelles, sans aucun frais, avant d’engager le moindre centime. Cela supprime l’excuse habituelle qui consiste à faire des benchmarks sur un niveau inférieur pour ensuite être surpris en production. Faites vos tests de qualité sur le modèle gratuit, et changez une seule valeur d’en-tête lors du passage en production.
Conseil
Évaluez sur le modèle que vous allez déployer
Puisque s2.1-pro-free est documenté comme étant le même modèle sans frais, il n’y a aucune raison d’évaluer la qualité sur autre chose. Passez-lui vos pires textes, les noms de produits, les nombres, les abréviations, et décidez seulement ensuite si le niveau payant mérite sa place.
Le clonage vocal, des deux manières
Il existe deux approches, adaptées à des produits différents. Créez un modèle vocal persistant lorsque la même voix sera réutilisée, car vous clonez une fois puis référencez un identifiant pour toujours. Utilisez les références zero shot lorsque la voix est fournie à chaque requête et qu’il n’y a rien à conserver.
# Route 1: a reusable voice model. Clone once, reference the id afterwards.
with open("sample.wav", "rb") as f:
voice = client.voices.create(
title="Narrator",
voices=[f.read()],
description="Cloned from a studio sample",
visibility="private", # private is the default; unlist and public also exist
)
print(voice.id, voice.state)
audio = client.tts.convert(
text="Now I speak in the cloned voice.",
reference_id=voice.id,
)
# Route 2: zero shot. Nothing is stored, the reference travels with the request.
from fishaudio.types import ReferenceAudio
with open("reference.wav", "rb") as f:
audio = client.tts.convert(
text="This will sound like the reference voice.",
references=[ReferenceAudio(
audio=f.read(),
text="The exact words spoken in the reference clip.",
)],
)
Notez la transcription dans le chemin zero shot. Vous fournissez à la fois l’audio et les mots effectivement prononcés, et la précision à ce niveau affecte le résultat de manière mesurable. Une transcription qui ne correspond pas à l’audio produit un clone moins bon que si vous n’aviez rien tenté du tout.
La documentation est précise sur le matériel source : WAV, MP3, M4A ou Opus, un minimum de dix secondes par extrait, et l'idéal se situe entre une et deux minutes de parole claire d'un seul locuteur. Ce dernier chiffre mérite d'être respecté. Dix secondes fonctionnent, mais la différence entre le minimum et une bonne minute d'audio propre est audible, et c'est l'amélioration qualitative la moins coûteuse qui soit. L'amélioration audio pour les enregistrements bruités est activée par défaut.
Avertissement
Le parcours de consentement relève de votre responsabilité
Dix secondes d'audio suffisent pour usurper l'identité de quelqu'un. Si les utilisateurs peuvent téléverser un audio de référence, vous avez déployé un outil de clonage vocal. Vérifiez que la personne qui téléverse dispose des droits sur la voix, journalisez quel compte a généré quel extrait, et signalez aux auditeurs qu'il s'agit d'un audio de synthèse. Rien de tout cela n'est fourni par l'API.
Streaming, et parler pendant que le modèle réfléchit encore
Pour les agents vocaux et les assistants, le chemin de streaming HTTP reste trop lent, car il ne peut démarrer qu'une fois que votre modèle de langage a produit le texte complet. Le mode WebSocket supprime totalement cette attente. Il accepte un générateur de tokens de texte et commence à émettre l'audio au fur et à mesure que les mots arrivent.
from fishaudio import FishAudio
from fishaudio.utils import play
client = FishAudio()
def llm_tokens():
# In production this yields tokens from your LLM stream, not a fixed list
for token in ["The ", "first ", "move ", "sets ", "everything ", "in ", "motion."]:
yield token
for chunk in client.tts.stream_websocket(llm_tokens(), reference_id="YOUR_VOICE_ID"):
play(chunk)
C'est le schéma le plus important de toute l'intégration pour tout ce qui est conversationnel. Sans lui, la latence perçue est le temps de génération du modèle de langage plus le temps de synthèse. Avec lui, les deux se chevauchent, et l'utilisateur entend les premiers mots pendant que le modèle compose encore la suite. Cette différence est généralement ce qui sépare un assistant qui semble réactif d'un assistant qui semble cassé.
Il existe un latency paramètre avec deux réglages, et la documentation leur associe des chiffres concrets. normal est décrit comme la meilleure qualité avec environ 500 millisecondes, et balanced comme une bonne qualité avec environ 300 millisecondes. Pour tout usage conversationnel, cette différence de 200 millisecondes vaut plus que le gain de qualité, et la documentation elle-même recommande le mode équilibré lorsque l'audio met trop de temps à démarrer. Réservez normal pour l'audio pré-rendu où personne n'attend. Un client asynchrone, AsyncFishAudio, accepte des générateurs asynchrones sous la même forme.
| Mode | Qualité annoncée | Latence annoncée | Utilisation |
|---|---|---|---|
| équilibré | Bonne qualité | environ 300 ms | Agents vocaux, assistants, tout usage interactif |
| normal | Meilleure qualité | environ 500 ms | Narration et audio pré-rendu |
Conseil de pro
Mesurez le délai avant le premier octet audio côté client plutôt que côté serveur. Les mesures côté serveur omettent régulièrement 100 à 300 millisecondes de mise en mémoire tampon et de démarrage de la lecture, ce qui correspond précisément à la plage où une interface cesse de paraître immédiate.
Ce que cela coûte, en chiffres sur lesquels vous pouvez vous baser
La facturation se fait par million d'octets UTF-8 plutôt que par caractère ou par seconde, ce qui est difficile à appréhender tant qu'on ne l'a pas converti. La documentation indique qu'un million d'octets UTF-8 équivaut à environ 180 000 mots anglais, soit environ 12 heures de parole. À 15 dollars le million, cela donne quelques points de repère utiles.
| Charge de travail | Taille approximative | Coût approximatif |
|---|---|---|
| Un article de 1 500 mots lu à voix haute | environ 8 300 octets | environ 0,13 dollar |
| 100 articles de ce type | environ 830 000 octets | environ 12,50 dollars |
| 12 heures de parole continue | environ 1 000 000 octets | environ 15 dollars |
| Une notification de 30 mots, 10 000 fois | environ 1 700 000 octets | environ 25 dollars |
Soyez attentif au détail UTF-8 si vous travaillez avec des écritures non latines. La facturation compte les octets, pas les caractères, et le cinghalais, le tamoul, le chinois, le japonais, l'arabe et les écritures similaires utilisent plusieurs octets par caractère. Un texte qui semble avoir la même longueur qu'une phrase en anglais peut coûter deux à trois fois plus cher, ce qu'il vaut mieux modéliser avant de lancer un produit localisé plutôt que de le découvrir sur une facture.
L'autre limite à anticiper est la concurrence plutôt que le volume. Les limites de débit sont exprimées en requêtes simultanées et augmentent avec les dépenses cumulées.
| Palier | Seuil | Requêtes simultanées |
|---|---|---|
| Débutant | Moins de 100 dollars payés | 5 |
| Élevé | 100 dollars ou plus payés | 15 |
| Volume élevé | 1 000 dollars ou plus payés | 50 |
| Entreprise | Personnalisé | Personnalisé |
Cinq requêtes simultanées, c'est confortable pour un pipeline de contenu, mais c'est juste pour tout ce qui est destiné aux utilisateurs à grande échelle. Mettez donc votre travail en file d'attente plutôt que de lancer les requêtes au fur et à mesure. Un simple pool de workers dimensionné selon votre palier, avec des tentatives de reprise en cas de rejet, évite le mode de défaillance où un pic de trafic se transforme en un mur d'erreurs.
La liste de contrôle pour la production
Quatre choses séparent un prototype fonctionnel de quelque chose que vous pouvez laisser tourner.
1. Cache on a hash of text + voice + parameters.
Applications repeat far more utterances than anyone expects,
and cached audio costs nothing to serve.
2. Normalise text before synthesis.
Expand currency, dates, units and known acronyms into the words
you want spoken. This removes most reported quality complaints.
3. Queue to your concurrency tier.
Five simultaneous requests on the starter tier. Size a worker pool
to match and retry on rejection instead of failing the user.
4. Log voice provenance.
Which voice, which account, which authorisation, retained.
You cannot answer the only question that matters after an incident
without it.
! Erreurs courantes à éviter
-
✕Mettre le nom du modèle dans le corps JSON.
✓Le modèle est sélectionné avec un en-tête de requête. Un champ dans le corps est ignoré silencieusement, vous obtenez donc le modèle par défaut et vous concluez que votre choix de modèle ne fonctionne pas.
-
✕Évaluer la qualité sur un palier inférieur et déployer sur le produit phare.
✓Le modèle gratuit est documenté comme étant le même modèle que s2.1-pro, sans frais. Testez dessus et changez un en-tête lorsque vous passez en production.
-
✕Fournir une transcription qui ne correspond pas à l'audio de référence.
✓Le clonage zero shot utilise la transcription comme conditionnement. Une transcription incorrecte donne un résultat moins bon qu’une transcription soignée et fidèle de ce qui a été dit.
-
✕Attendre la réponse complète du LLM avant d’appeler la synthèse.
✓Utilisez le mode websocket avec un générateur de tokens. La génération et la synthèse se chevauchent, ce qui élimine complètement le temps de réflexion du modèle de la latence perçue.
-
✕Budgétiser par caractère quand votre contenu n’est pas en écriture latine.
✓La facturation compte les octets UTF-8. De nombreuses écritures utilisent deux à quatre octets par caractère, modélisez donc vos langues réelles avant de vous engager sur un prix par article.
-
✕Envoyer les requêtes dès leur arrivée en ignorant les limites de concurrence.
✓Les limites portent sur les requêtes simultanées, à partir de cinq. Mettez en file d’attente via un pool de workers dimensionné à votre palier pour que les pics de charge se dégradent progressivement au lieu de générer des erreurs.
? Foire aux questions
Quel est le point de terminaison de l’API Fish Audio ? +
La synthèse vocale se fait par POST https://api.fish.audio/v1/tts avec un en-tête d’autorisation Bearer. Le modèle est choisi via un en-tête distinct, et la réponse est un flux audio fragmenté plutôt que du JSON.
Existe-t-il un moyen vraiment gratuit de le tester ? +
Oui. Le modèle s2.1-pro-free est documenté comme étant le même modèle que s2.1-pro, mais facturé zéro, destiné aux tests, au prototypage et au développement, ce qui vous permet d’évaluer la qualité de production avant de payer.
Combien coûte Fish Audio ? +
Les modèles vocaux payants sont à 15 dollars par million d’octets UTF-8, ce que la documentation estime à environ 180 000 mots anglais ou environ 12 heures de parole. La transcription est à 0,36 dollar par heure audio.
De combien d’audio de référence ai-je besoin pour cloner une voix ? +
Un minimum de dix secondes par extrait, avec une à deux minutes d’audio clair d’un seul locuteur décrit comme optimal. Les formats acceptés sont WAV, MP3, M4A et Opus, et l’amélioration audio est activée par défaut.
Quelle est la différence entre reference_id et references ? +
reference_id pointe vers un modèle vocal stocké que vous avez créé précédemment et que vous souhaitez réutiliser. references transporte l’audio de référence en ligne avec une seule requête pour le clonage zero shot, sans rien conserver.
Puis-je diffuser l’audio d’un LLM au fur et à mesure qu’il génère ? +
Oui, c’est à cela que sert le mode websocket. Il accepte un générateur produisant des tokens de texte et renvoie des fragments audio au fur et à mesure de leur production, de sorte que la synthèse chevauche la génération au lieu de la suivre.
Quel est le nom du paquet pip ? +
Installez fish-audio-sdk avec des tirets, puis importez fishaudio sans tirets. La différence entre le nom du paquet et le nom du module est une source de confusion fréquente de quelques minutes au début.
Quel mode de latence dois-je utiliser ? +
Balanced pour tout ce qui est interactif, documenté comme offrant une bonne qualité et environ 300 millisecondes, contre normal pour la meilleure qualité et environ 500 millisecondes. La documentation recommande balanced lorsque l’audio tarde à démarrer.
Quelles sont les limites de débit ? +
Elles sont basées sur la concurrence et évoluent avec les dépenses cumulées : 5 requêtes simultanées en dessous de 100 dollars, 15 à partir de 100 dollars, 50 à partir de 1 000 dollars, et des limites personnalisées pour les entreprises.
Pour conclure
L’intégration elle-même est vraiment réduite. Un jeton Bearer, un point de terminaison, un en-tête pour choisir le modèle et une poignée de paramètres. Le travail qui détermine si le résultat est bon se situe de part et d’autre de cet appel : normaliser votre texte pour que les nombres et les acronymes soient prononcés correctement, mettre en cache pour ne pas payer deux fois la même phrase, mettre en file d’attente selon votre palier de concurrence, diffuser depuis votre modèle de langage pour que les deux étapes se chevauchent, et garder une trace honnête de la voix que vous utilisez et pourquoi. Commencez par le modèle gratuit avec votre contenu le plus difficile, et ne passez au palier payant qu’une fois que vous savez exactement ce que vous achetez.
Remarque
Spécifications dans cet article
Les chemins des points de terminaison, les noms des paramètres, les valeurs par défaut, les prix et les limites de débit proviennent de la documentation officielle au moment de la rédaction et peuvent changer sans préavis. Vérifiez la documentation actuelle avant de vous fier à un chiffre ici en production.
Commentaires
0Aucun commentaire pour l’instant. Soyez la première personne à donner votre avis.