Make Qwen3-TTS the default engine, add CPU-only docker support

- Switch default TTS engine from Piper to Qwen3-TTS (1.7B params)
- Upgrade to Python 3.12
- Add docker-compose.cpu.yml for CPU-only deployments
- Improve GPU configuration with NVIDIA environment variables
- Comment out optional engines (Piper, XTTS, Silero, Kokoro) in requirements
- Update Makefile with local/local-cpu targets and venv support
- Simplify voice_to_speaker.default.yaml for Qwen3-TTS voices
- Update docs/MODELS.md with Qwen3-TTS documentation
- Add git commit guidelines to CLAUDE.md
This commit is contained in:
russell@unturf.com 2026-01-26 10:40:29 -05:00
parent 4a019cf897
commit b315659be6
9 changed files with 572 additions and 951 deletions

View file

@ -1,892 +1,77 @@
tts-1:
# OpenAI-compatible voice aliases (backward compatibility)
alloy:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 79 # 64, 79, 80, 101, 130
echo:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 134 # 52, 102, 134
fable:
model: /app/voices/en/en_GB/northern_english_male/medium/en_GB-northern_english_male-medium.onnx
speaker: # default speaker
onyx:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 159 # 55, 90, 132, 136, 137, 159
nova:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 107 # 57, 61, 107, 150, 162
shimmer:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 163
# uncloseai-speech Voice Configuration
# Only tts-1-qwen is enabled by default
# English US voices - all available Piper models
# libritts_r has 904 speakers (multi-speaker model)
en_us_libritts_r_0:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 0
en_us_libritts_r_52:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 52
en_us_libritts_r_55:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 55
en_us_libritts_r_57:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 57
en_us_libritts_r_61:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 61
en_us_libritts_r_64:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 64
en_us_libritts_r_79:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 79
en_us_libritts_r_80:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 80
en_us_libritts_r_90:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 90
en_us_libritts_r_101:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 101
en_us_libritts_r_102:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 102
en_us_libritts_r_107:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 107
en_us_libritts_r_130:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 130
en_us_libritts_r_132:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 132
en_us_libritts_r_134:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 134
en_us_libritts_r_136:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 136
en_us_libritts_r_137:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 137
en_us_libritts_r_150:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 150
en_us_libritts_r_159:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 159
en_us_libritts_r_162:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 162
en_us_libritts_r_163:
model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
speaker: 163
tts-1-qwen:
# OpenAI-compatible voice aliases
# Each voice requires ref_audio (reference audio) and ref_text (transcript of the audio)
# Language: Chinese, English, Japanese, Korean, German, French, Russian, Portuguese, Spanish, Italian
# Single-speaker Piper voices (to be downloaded)
en_us_amy:
model: /app/voices/en/en_US/amy/medium/en_US-amy-medium.onnx
speaker: # default
en_us_arctic:
model: /app/voices/en/en_US/arctic/medium/en_US-arctic-medium.onnx
speaker: # default
en_us_bryce:
model: /app/voices/en/en_US/bryce/medium/en_US-bryce-medium.onnx
speaker: # default
en_us_danny:
model: /app/voices/en/en_US/danny/low/en_US-danny-low.onnx
speaker: # default
en_us_hfc_female:
model: /app/voices/en/en_US/hfc_female/medium/en_US-hfc_female-medium.onnx
speaker: # default
en_us_hfc_male:
model: /app/voices/en/en_US/hfc_male/medium/en_US-hfc_male-medium.onnx
speaker: # default
en_us_joe:
model: /app/voices/en/en_US/joe/medium/en_US-joe-medium.onnx
speaker: # default
en_us_john:
model: /app/voices/en/en_US/john/medium/en_US-john-medium.onnx
speaker: # default
en_us_kathleen:
model: /app/voices/en/en_US/kathleen/low/en_US-kathleen-low.onnx
speaker: # default
en_us_kristin:
model: /app/voices/en/en_US/kristin/medium/en_US-kristin-medium.onnx
speaker: # default
en_us_kusal:
model: /app/voices/en/en_US/kusal/medium/en_US-kusal-medium.onnx
speaker: # default
en_us_l2arctic:
model: /app/voices/en/en_US/l2arctic/medium/en_US-l2arctic-medium.onnx
speaker: # default (multi-speaker model)
en_us_lessac:
model: /app/voices/en/en_US/lessac/medium/en_US-lessac-medium.onnx
speaker: # default (multi-speaker model)
en_us_libritts:
model: /app/voices/en/en_US/libritts/high/en_US-libritts-high.onnx
speaker: # default (multi-speaker model)
en_us_ljspeech:
model: /app/voices/en/en_US/ljspeech/medium/en_US-ljspeech-medium.onnx
speaker: # default
en_us_norman:
model: /app/voices/en/en_US/norman/medium/en_US-norman-medium.onnx
speaker: # default
en_us_reza_ibrahim:
model: /app/voices/en/en_US/reza_ibrahim/medium/en_US-reza_ibrahim-medium.onnx
speaker: # default
en_us_ryan:
model: /app/voices/en/en_US/ryan/high/en_US-ryan-high.onnx
speaker: # default
en_us_sam:
model: /app/voices/en/en_US/sam/medium/en_US-sam-medium.onnx
speaker: # default
# Default voice - using Qwen's example clone audio
alloy:
ref_audio: https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen3-TTS-Repo/clone.wav
ref_text: "Okay. Yeah. I resent you. I love you. I respect you. But you know what? You blew it!"
language: English
# English GB voices
en_gb_alan:
model: /app/voices/en/en_GB/alan/medium/en_GB-alan-medium.onnx
speaker: # default
en_gb_alba:
model: /app/voices/en/en_GB/alba/medium/en_GB-alba-medium.onnx
speaker: # default
en_gb_aru:
model: /app/voices/en/en_GB/aru/medium/en_GB-aru-medium.onnx
speaker: # default (multi-speaker model)
en_gb_cori:
model: /app/voices/en/en_GB/cori/medium/en_GB-cori-medium.onnx
speaker: # default (multi-speaker model)
en_gb_jenny_dioco:
model: /app/voices/en/en_GB/jenny_dioco/medium/en_GB-jenny_dioco-medium.onnx
speaker: # default
en_gb_northern_english_male:
model: /app/voices/en/en_GB/northern_english_male/medium/en_GB-northern_english_male-medium.onnx
speaker: # default
en_gb_semaine:
model: /app/voices/en/en_GB/semaine/medium/en_GB-semaine-medium.onnx
speaker: # default
en_gb_southern_english_female:
model: /app/voices/en/en_GB/southern_english_female/low/en_GB-southern_english_female-low.onnx
speaker: # default
en_gb_vctk:
model: /app/voices/en/en_GB/vctk/medium/en_GB-vctk-medium.onnx
speaker: # default (multi-speaker model)
tts-1-hd:
alloy-alt:
model: xtts
speaker: voices/alloy-alt.wav
alloy:
model: xtts
speaker: voices/alloy.wav
# Echo - same sample, different name for compatibility
echo:
model: xtts
speaker: voices/echo.wav
ref_audio: https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen3-TTS-Repo/clone.wav
ref_text: "Okay. Yeah. I resent you. I love you. I respect you. But you know what? You blew it!"
language: English
# Fable - same sample
fable:
model: xtts
speaker: voices/fable.wav
ref_audio: https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen3-TTS-Repo/clone.wav
ref_text: "Okay. Yeah. I resent you. I love you. I respect you. But you know what? You blew it!"
language: English
# Onyx - same sample
onyx:
model: xtts
speaker: voices/onyx.wav
ref_audio: https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen3-TTS-Repo/clone.wav
ref_text: "Okay. Yeah. I resent you. I love you. I respect you. But you know what? You blew it!"
language: English
# Nova - same sample
nova:
model: xtts
speaker: voices/nova.wav
ref_audio: https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen3-TTS-Repo/clone.wav
ref_text: "Okay. Yeah. I resent you. I love you. I respect you. But you know what? You blew it!"
language: English
# Shimmer - same sample
shimmer:
model: xtts
speaker: voices/shimmer.wav
me:
model: xtts_v2.0.2 # you can specify an older xtts version
speaker: voices/me.wav # this could be you
language: auto
enable_text_splitting: True
length_penalty: 1.0
repetition_penalty: 10
speed: 1.0
temperature: 0.75
top_k: 50
top_p: 0.85
comment: You can add a comment here also, which will be persistent and otherwise ignored.
tts-1-silero:
# All 118 Silero v3_en voices with proper names
# NOTE: Use native Silero voice names (en_0, en_1, etc.) for Silero
# OpenAI voice names (alloy, echo, etc.) are reserved for tts-1 and tts-1-hd only
en_0:
language: en
speaker: en_0
silero_speaker: v3_en
en_1:
language: en
speaker: en_1
silero_speaker: v3_en
en_2:
language: en
speaker: en_2
silero_speaker: v3_en
en_3:
language: en
speaker: en_3
silero_speaker: v3_en
en_4:
language: en
speaker: en_4
silero_speaker: v3_en
en_5:
language: en
speaker: en_5
silero_speaker: v3_en
en_6:
language: en
speaker: en_6
silero_speaker: v3_en
en_7:
language: en
speaker: en_7
silero_speaker: v3_en
en_8:
language: en
speaker: en_8
silero_speaker: v3_en
en_9:
language: en
speaker: en_9
silero_speaker: v3_en
en_10:
language: en
speaker: en_10
silero_speaker: v3_en
en_11:
language: en
speaker: en_11
silero_speaker: v3_en
en_12:
language: en
speaker: en_12
silero_speaker: v3_en
en_13:
language: en
speaker: en_13
silero_speaker: v3_en
en_14:
language: en
speaker: en_14
silero_speaker: v3_en
en_15:
language: en
speaker: en_15
silero_speaker: v3_en
en_16:
language: en
speaker: en_16
silero_speaker: v3_en
en_17:
language: en
speaker: en_17
silero_speaker: v3_en
en_18:
language: en
speaker: en_18
silero_speaker: v3_en
en_19:
language: en
speaker: en_19
silero_speaker: v3_en
en_20:
language: en
speaker: en_20
silero_speaker: v3_en
en_21:
language: en
speaker: en_21
silero_speaker: v3_en
en_22:
language: en
speaker: en_22
silero_speaker: v3_en
en_23:
language: en
speaker: en_23
silero_speaker: v3_en
en_24:
language: en
speaker: en_24
silero_speaker: v3_en
en_25:
language: en
speaker: en_25
silero_speaker: v3_en
en_26:
language: en
speaker: en_26
silero_speaker: v3_en
en_27:
language: en
speaker: en_27
silero_speaker: v3_en
en_28:
language: en
speaker: en_28
silero_speaker: v3_en
en_29:
language: en
speaker: en_29
silero_speaker: v3_en
en_30:
language: en
speaker: en_30
silero_speaker: v3_en
en_31:
language: en
speaker: en_31
silero_speaker: v3_en
en_32:
language: en
speaker: en_32
silero_speaker: v3_en
en_33:
language: en
speaker: en_33
silero_speaker: v3_en
en_34:
language: en
speaker: en_34
silero_speaker: v3_en
en_35:
language: en
speaker: en_35
silero_speaker: v3_en
en_36:
language: en
speaker: en_36
silero_speaker: v3_en
en_37:
language: en
speaker: en_37
silero_speaker: v3_en
en_38:
language: en
speaker: en_38
silero_speaker: v3_en
en_39:
language: en
speaker: en_39
silero_speaker: v3_en
en_40:
language: en
speaker: en_40
silero_speaker: v3_en
en_41:
language: en
speaker: en_41
silero_speaker: v3_en
en_42:
language: en
speaker: en_42
silero_speaker: v3_en
en_43:
language: en
speaker: en_43
silero_speaker: v3_en
en_44:
language: en
speaker: en_44
silero_speaker: v3_en
en_45:
language: en
speaker: en_45
silero_speaker: v3_en
en_46:
language: en
speaker: en_46
silero_speaker: v3_en
en_47:
language: en
speaker: en_47
silero_speaker: v3_en
en_48:
language: en
speaker: en_48
silero_speaker: v3_en
en_49:
language: en
speaker: en_49
silero_speaker: v3_en
en_50:
language: en
speaker: en_50
silero_speaker: v3_en
en_51:
language: en
speaker: en_51
silero_speaker: v3_en
en_52:
language: en
speaker: en_52
silero_speaker: v3_en
en_53:
language: en
speaker: en_53
silero_speaker: v3_en
en_54:
language: en
speaker: en_54
silero_speaker: v3_en
en_55:
language: en
speaker: en_55
silero_speaker: v3_en
en_56:
language: en
speaker: en_56
silero_speaker: v3_en
en_57:
language: en
speaker: en_57
silero_speaker: v3_en
en_58:
language: en
speaker: en_58
silero_speaker: v3_en
en_59:
language: en
speaker: en_59
silero_speaker: v3_en
en_60:
language: en
speaker: en_60
silero_speaker: v3_en
en_61:
language: en
speaker: en_61
silero_speaker: v3_en
en_62:
language: en
speaker: en_62
silero_speaker: v3_en
en_63:
language: en
speaker: en_63
silero_speaker: v3_en
en_64:
language: en
speaker: en_64
silero_speaker: v3_en
en_65:
language: en
speaker: en_65
silero_speaker: v3_en
en_66:
language: en
speaker: en_66
silero_speaker: v3_en
en_67:
language: en
speaker: en_67
silero_speaker: v3_en
en_68:
language: en
speaker: en_68
silero_speaker: v3_en
en_69:
language: en
speaker: en_69
silero_speaker: v3_en
en_70:
language: en
speaker: en_70
silero_speaker: v3_en
en_71:
language: en
speaker: en_71
silero_speaker: v3_en
en_72:
language: en
speaker: en_72
silero_speaker: v3_en
en_73:
language: en
speaker: en_73
silero_speaker: v3_en
en_74:
language: en
speaker: en_74
silero_speaker: v3_en
en_75:
language: en
speaker: en_75
silero_speaker: v3_en
en_76:
language: en
speaker: en_76
silero_speaker: v3_en
en_77:
language: en
speaker: en_77
silero_speaker: v3_en
en_78:
language: en
speaker: en_78
silero_speaker: v3_en
en_79:
language: en
speaker: en_79
silero_speaker: v3_en
en_80:
language: en
speaker: en_80
silero_speaker: v3_en
en_81:
language: en
speaker: en_81
silero_speaker: v3_en
en_82:
language: en
speaker: en_82
silero_speaker: v3_en
en_83:
language: en
speaker: en_83
silero_speaker: v3_en
en_84:
language: en
speaker: en_84
silero_speaker: v3_en
en_85:
language: en
speaker: en_85
silero_speaker: v3_en
en_86:
language: en
speaker: en_86
silero_speaker: v3_en
en_87:
language: en
speaker: en_87
silero_speaker: v3_en
en_88:
language: en
speaker: en_88
silero_speaker: v3_en
en_89:
language: en
speaker: en_89
silero_speaker: v3_en
en_90:
language: en
speaker: en_90
silero_speaker: v3_en
en_91:
language: en
speaker: en_91
silero_speaker: v3_en
en_92:
language: en
speaker: en_92
silero_speaker: v3_en
en_93:
language: en
speaker: en_93
silero_speaker: v3_en
en_94:
language: en
speaker: en_94
silero_speaker: v3_en
en_95:
language: en
speaker: en_95
silero_speaker: v3_en
en_96:
language: en
speaker: en_96
silero_speaker: v3_en
en_97:
language: en
speaker: en_97
silero_speaker: v3_en
en_98:
language: en
speaker: en_98
silero_speaker: v3_en
en_99:
language: en
speaker: en_99
silero_speaker: v3_en
en_100:
language: en
speaker: en_100
silero_speaker: v3_en
en_101:
language: en
speaker: en_101
silero_speaker: v3_en
en_102:
language: en
speaker: en_102
silero_speaker: v3_en
en_103:
language: en
speaker: en_103
silero_speaker: v3_en
en_104:
language: en
speaker: en_104
silero_speaker: v3_en
en_105:
language: en
speaker: en_105
silero_speaker: v3_en
en_106:
language: en
speaker: en_106
silero_speaker: v3_en
en_107:
language: en
speaker: en_107
silero_speaker: v3_en
en_108:
language: en
speaker: en_108
silero_speaker: v3_en
en_109:
language: en
speaker: en_109
silero_speaker: v3_en
en_110:
language: en
speaker: en_110
silero_speaker: v3_en
en_111:
language: en
speaker: en_111
silero_speaker: v3_en
en_112:
language: en
speaker: en_112
silero_speaker: v3_en
en_113:
language: en
speaker: en_113
silero_speaker: v3_en
en_114:
language: en
speaker: en_114
silero_speaker: v3_en
en_115:
language: en
speaker: en_115
silero_speaker: v3_en
en_116:
language: en
speaker: en_116
silero_speaker: v3_en
en_117:
language: en
speaker: en_117
silero_speaker: v3_en
random:
language: en
speaker: random
silero_speaker: v3_en
# Russian voices (v3_ru/ru_v3 model) - use ru_v3 for better compatibility
ru_aidar:
language: ru
speaker: aidar
silero_speaker: ru_v3
ru_baya:
language: ru
speaker: baya
silero_speaker: ru_v3
ru_kseniya:
language: ru
speaker: kseniya
silero_speaker: ru_v3
ru_xenia:
language: ru
speaker: xenia
silero_speaker: ru_v3
ru_eugene:
language: ru
speaker: eugene
silero_speaker: ru_v3
ru_random:
language: ru
speaker: random
silero_speaker: ru_v3
# German voices (v3_de model)
de_bernd_ungerer:
language: de
speaker: bernd_ungerer
silero_speaker: v3_de
de_eva_k:
language: de
speaker: eva_k
silero_speaker: v3_de
de_friedrich:
language: de
speaker: friedrich
silero_speaker: v3_de
de_hokuspokus:
language: de
speaker: hokuspokus
silero_speaker: v3_de
de_karlsson:
language: de
speaker: karlsson
silero_speaker: v3_de
de_random:
language: de
speaker: random
silero_speaker: v3_de
# Spanish voices (v3_es model)
es_0:
language: es
speaker: es_0
silero_speaker: v3_es
es_1:
language: es
speaker: es_1
silero_speaker: v3_es
es_2:
language: es
speaker: es_2
silero_speaker: v3_es
es_random:
language: es
speaker: random
silero_speaker: v3_es
# French voices (v3_fr model)
fr_0:
language: fr
speaker: fr_0
silero_speaker: v3_fr
fr_1:
language: fr
speaker: fr_1
silero_speaker: v3_fr
fr_2:
language: fr
speaker: fr_2
silero_speaker: v3_fr
fr_3:
language: fr
speaker: fr_3
silero_speaker: v3_fr
fr_4:
language: fr
speaker: fr_4
silero_speaker: v3_fr
fr_5:
language: fr
speaker: fr_5
silero_speaker: v3_fr
fr_random:
language: fr
speaker: random
silero_speaker: v3_fr
tts-1-kokoro:
# OpenAI-compatible voice aliases (Kokoro's intentional OpenAI-themed voices)
alloy:
lang_code: a
kokoro_voice: af_alloy
echo:
lang_code: a
kokoro_voice: am_echo
fable:
lang_code: b
kokoro_voice: bm_fable
onyx:
lang_code: a
kokoro_voice: am_onyx
nova:
lang_code: a
kokoro_voice: af_nova
shimmer:
lang_code: a
kokoro_voice: af_sky
# Female American voices
af_heart:
lang_code: a
kokoro_voice: af_heart
af_bella:
lang_code: a
kokoro_voice: af_bella
af_nicole:
lang_code: a
kokoro_voice: af_nicole
af_aoede:
lang_code: a
kokoro_voice: af_aoede
af_kore:
lang_code: a
kokoro_voice: af_kore
af_sarah:
lang_code: a
kokoro_voice: af_sarah
af_nova:
lang_code: a
kokoro_voice: af_nova
af_sky:
lang_code: a
kokoro_voice: af_sky
af_alloy:
lang_code: a
kokoro_voice: af_alloy
af_jessica:
lang_code: a
kokoro_voice: af_jessica
af_river:
lang_code: a
kokoro_voice: af_river
# Male American voices
am_michael:
lang_code: a
kokoro_voice: am_michael
am_fenrir:
lang_code: a
kokoro_voice: am_fenrir
am_puck:
lang_code: a
kokoro_voice: am_puck
am_echo:
lang_code: a
kokoro_voice: am_echo
am_eric:
lang_code: a
kokoro_voice: am_eric
am_liam:
lang_code: a
kokoro_voice: am_liam
am_onyx:
lang_code: a
kokoro_voice: am_onyx
am_santa:
lang_code: a
kokoro_voice: am_santa
am_adam:
lang_code: a
kokoro_voice: am_adam
# Female British voices
bf_emma:
lang_code: b
kokoro_voice: bf_emma
bf_isabella:
lang_code: b
kokoro_voice: bf_isabella
bf_alice:
lang_code: b
kokoro_voice: bf_alice
bf_lily:
lang_code: b
kokoro_voice: bf_lily
# Male British voices
bm_george:
lang_code: b
kokoro_voice: bm_george
bm_fable:
lang_code: b
kokoro_voice: bm_fable
bm_lewis:
lang_code: b
kokoro_voice: bm_lewis
bm_daniel:
lang_code: b
kokoro_voice: bm_daniel
ref_audio: https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen3-TTS-Repo/clone.wav
ref_text: "Okay. Yeah. I resent you. I love you. I respect you. But you know what? You blew it!"
language: English
# Custom voice example - add your own reference audio
# my_voice:
# ref_audio: voices/my_voice_sample.wav
# ref_text: "The exact text spoken in the reference audio file"
# language: English
# Other models are disabled by default. Uncomment to enable.
# See the git history for full voice configurations.
# tts-1:
# # Piper TTS voices (fast CPU inference)
# alloy:
# model: /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx
# speaker: 79
# tts-1-hd:
# # XTTS voice cloning
# alloy:
# model: xtts
# speaker: voices/alloy.wav
# tts-1-silero:
# # Silero TTS (CPU-friendly)
# en_0:
# language: en
# speaker: en_0
# silero_speaker: v3_en
# tts-1-kokoro:
# # Kokoro TTS (lightweight 82M params)
# alloy:
# lang_code: a
# kokoro_voice: af_alloy