tts-dgx-spark-faster-qwen3-tts/config/generate_voices.py
mARTin 60db1b181f Initial release: Faster-Qwen3-TTS for DGX Spark GB10
Run Qwen3-TTS with CUDA graph acceleration on NVIDIA DGX Spark
(ARM64 / SM 121 / CUDA 13) as an OpenAI-compatible TTS API server.

- Dockerfile targeting nvidia/cuda:13.0.2-base-ubuntu24.04 with ARM64 cu130 PyTorch wheels
- Patch for max-seq-len support to handle long reference audio without crashes
- OpenWebUI + SillyTavern compatible API endpoints (/v1/models, /v1/audio/voices, /speakers)
- Voice management: auto-generate voices.json from speaker reference audio files
- Auto-transcription helper script for generating reference text from audio

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 00:06:05 +02:00

63 lines
2.2 KiB
Python

"""
Scan the speakers directory for reference audio files and generate voices.json.
Runs inside the container at startup to map all available voice reference
audio files into a format the OpenAI-compatible TTS server understands.
"""
import os
import json
# Internal container paths
speaker_dir = "/config/speakers"
output_file = "/config/voices.json"
voices = {}
if os.path.exists(speaker_dir):
for filename in os.listdir(speaker_dir):
if filename.endswith((".wav", ".mp3")):
base_name = os.path.splitext(filename)[0]
# Determine language based on file prefixes
lang = "Auto"
if base_name.startswith("EN_") or base_name.startswith("basic_ref_en"):
lang = "English"
elif base_name.startswith("DE_"):
lang = "German"
elif base_name.startswith("basic_ref_zh"):
lang = "Chinese"
# Create a clean voice ID
voice_id = base_name.lower()
prefixes_to_strip = ["en_m_", "en_f_", "de_m_", "de_f_"]
for prefix in prefixes_to_strip:
if voice_id.startswith(prefix):
voice_id = voice_id.replace(prefix, "", 1)
break
entry = {
"ref_audio": f"/config/speakers/{filename}",
"language": lang
}
# Look for matching reference text files
ref_txt_path = os.path.join(speaker_dir, f"{base_name}.reference.txt")
txt_path = os.path.join(speaker_dir, f"{base_name}.txt")
if os.path.exists(ref_txt_path):
with open(ref_txt_path, 'r', encoding='utf-8') as f:
entry["ref_text"] = f.read().strip()
elif os.path.exists(txt_path):
with open(txt_path, 'r', encoding='utf-8') as f:
entry["ref_text"] = f.read().strip()
voices[voice_id] = entry
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(voices, f, indent=2, ensure_ascii=False)
print(f"Success! Generated voices.json with {len(voices)} mapped voices.")
else:
print(f"Warning: Directory {speaker_dir} not found. Skipping voice generation.")