API locale de synthèse vocale basée sur Qwen3-TTS (Alibaba), optimisée pour Mac Studio / Apple Silicon. Voice Design, Voice Clone, 9 voix préréglées, batch processing, détection auto de langue. FastAPI + PyTorch MPS. Génération audio haute qualité 100% local, sans cloud.
| Route | Fonction | Modèle |
|---|---|---|
GET / |
Health check | - |
GET /languages |
Liste des 10 langues supportées | - |
GET /voices |
Liste des voix (natives + personnalisées) | - |
POST /voices/custom |
Créer une voix personnalisée persistante | 1.7B-Base / 0.6B-Base |
GET /voices/custom/{name} |
Détails d'une voix personnalisée | - |
DELETE /voices/custom/{name} |
Supprimer une voix personnalisée | - |
POST /preset |
Voix préréglées (rapide) | 0.6B-CustomVoice |
POST /preset/instruct |
Voix préréglées + contrôle émotions/styles | 1.7B-CustomVoice |
POST /design |
Voice Design (création de voix par description) | 1.7B-VoiceDesign |
POST /clone |
Voice Clone (clonage depuis audio ou prompt) | 1.7B-Base / 0.6B-Base |
POST /clone/prompt |
Créer un prompt réutilisable pour clonage | 1.7B-Base / 0.6B-Base |
GET /clone/prompts |
Lister les prompts en cache | - |
DELETE /clone/prompts/{id} |
Supprimer un prompt | - |
POST /batch/preset |
Batch preset voice (retourne ZIP) | Variable |
POST /batch/design |
Batch voice design (retourne ZIP) | 1.7B-VoiceDesign |
POST /batch/clone |
Batch voice clone (retourne ZIP) | 1.7B-Base / 0.6B-Base |
POST /tokenizer/encode |
Encoder texte en tokens | - |
POST /tokenizer/decode |
Décoder tokens en texte | - |
GET /models/status |
Statut des modèles chargés | - |
POST /models/preload |
Pré-charger les modèles | - |
GET /generation/status |
Génération active, stats, elapsed | - |
GET /mcp/docs |
Documentation MCP interactive | - |
git clone https://github.com/Alexmacapple/VoxQwen.git
cd VoxQwen
python3.12 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install langdetect # Optionnel: détection auto de languesource venv/bin/activate
python models/download_models.py # Tous les modèles (~18GB)
python models/download_models.py --list # Voir les modèles disponibles
python models/download_models.py --model 1.7B-VoiceDesign # Un modèle spécifiquesource venv/bin/activate
python main.py
# API disponible sur http://localhost:8060
# Documentation Swagger: http://localhost:8060/docscurl -X POST http://localhost:8060/preset \
-F "text=Bonjour, je suis Serena!" \
-F "voice=Serena" \
-F "language=fr" \
--output preset.wavVoix disponibles: Vivian, Serena, Uncle_Fu, Dylan, Eric, Ryan, Aiden, Ono_Anna, Sohee
curl -X POST http://localhost:8060/preset/instruct \
-F "text=Je viens d'apprendre la nouvelle!" \
-F "voice=Serena" \
-F "instruct=Ton très joyeux et excité" \
-F "language=fr" \
--output preset_joyeux.wavcurl -X POST http://localhost:8060/design \
-H "Content-Type: application/json" \
-d '{
"text": "Bonjour, je suis une voix générée par IA.",
"voice_instruct": "Voix masculine grave, style narrateur documentaire",
"language": "fr"
}' \
--output speech.wav# Clonage direct
curl -X POST http://localhost:8060/clone \
-F "text=Bonjour, je suis un clone de votre voix." \
-F "reference_audio=@ma_voix.wav" \
-F "reference_text=Transcription exacte de l'audio" \
-F "language=fr" \
-F "model=1.7B" \
--output clone.wav# 1. Créer une voix personnalisée (persiste après redémarrage)
curl -X POST http://localhost:8060/voices/custom \
-F "name=ma-voix" \
-F "source=clone" \
-F "reference_audio=@ma_voix.wav" \
-F "reference_text=Transcription exacte"
# 2. Utiliser la voix par son nom
curl -X POST http://localhost:8060/preset \
-F "text=Bonjour avec ma voix personnalisée" \
-F "voice=ma-voix" \
-F "language=fr" \
--output custom.wav# Générer plusieurs audios en une requête (retourne ZIP)
curl -X POST http://localhost:8060/batch/preset \
-H "Content-Type: application/json" \
-d '{"texts": ["Phrase 1", "Phrase 2", "Phrase 3"], "voice": "Serena"}' \
-o batch.zip# language=auto détecte automatiquement la langue
curl -X POST http://localhost:8060/preset \
-F "text=Hello, how are you today?" \
-F "voice=Serena" \
-F "language=auto" \
--output auto_detect.wav# Encoder du texte en tokens
curl -X POST http://localhost:8060/tokenizer/encode \
-H "Content-Type: application/json" \
-d '{"text": "Bonjour"}'
# Décoder des tokens en texte
curl -X POST http://localhost:8060/tokenizer/decode \
-H "Content-Type: application/json" \
-d '{"tokens": [81581]}'| Modèle | Taille | Utilisation |
|---|---|---|
0.6B-CustomVoice |
2.3 GB | Voix préréglées rapides |
0.6B-Base |
2.3 GB | Clonage vocal rapide |
1.7B-VoiceDesign |
4.2 GB | Création de voix par description |
1.7B-CustomVoice |
4.2 GB | Voix préréglées + émotions |
1.7B-Base |
4.2 GB | Clonage vocal haute qualité |
Tokenizer |
651 MB | Speech tokenizer (requis) |
Total : ~18 GB
Français, Anglais, Chinois, Japonais, Coréen, Allemand, Russe, Portugais, Espagnol, Italien
+ Détection automatique : language=auto (nécessite pip install langdetect)
| URL | Description |
|---|---|
| http://localhost:8060/docs | Swagger UI - Interface interactive |
| http://localhost:8060/redoc | ReDoc - Documentation lisible |
| http://localhost:8060/openapi.json | Schéma OpenAPI 3.1 |
| http://localhost:8060/mcp/docs | Documentation MCP pour Claude Code |
VoxQwen est une API FastAPI monolithique (main.py, ~2900 lignes) qui charge les modeles Qwen3-TTS en memoire GPU et expose des routes de synthese vocale.
Client (VoxStudio ou curl)
│
▼
FastAPI (:8060)
│
├── Semaphore GPU (1 generation a la fois)
│ ├── Timeout queue : 5s → 503 si GPU occupe
│ └── Timeout execution : 120s → 504 si generation trop longue
│
├── Modeles Qwen3-TTS (chargement lazy, ~18 Go)
│ ├── 0.6B-CustomVoice → /preset (rapide)
│ ├── 1.7B-CustomVoice → /preset/instruct (emotionnel)
│ ├── 1.7B-VoiceDesign → /design (creation voix)
│ └── 1.7B-Base / 0.6B-Base → /clone (clonage)
│
└── Voix custom persistantes (voices/custom/)
├── meta.json (metadonnees)
└── prompt.pt (embedding PyTorch ~1.4 Ko)
Un seul appel TTS a la fois (semaphore asyncio.Semaphore(1)). Les requetes en attente recoivent une reponse 503 apres 5 secondes. Les generations qui depassent 120 secondes sont interrompues avec un 504.
Le monitoring est accessible via :
GET /models/status— modeles charges, voix custom, prompts en cacheGET /generation/status— generation active, stats (total, completed, timeouts, rejected)
Les modeles sont charges en memoire GPU au premier appel (lazy loading). Chaque modele occupe 2-4 Go de VRAM. Le pre-chargement est possible via POST /models/preload.
Les voix creees via /voices/custom sont persistees sur disque (voices/custom/{name}/). Au demarrage, toutes les voix sont rechargees automatiquement. L'embedding vocal (prompt.pt) est charge en memoire a la premiere utilisation.
- Python : 3.12
- Device : MPS (Apple Silicon) / CUDA / CPU
- PyTorch : 2.1+
- Port API : 8060
- Modeles : ~18 Go sur disque, 2-4 Go VRAM par modele
MIT