Qwen3-TTS VoiceDesign
Text → Speech with natural language voice descriptions + seed-based timbre fixation.
Quick Start
CODEBLOCK0
Environment Variables
All config via env vars — text is the only required argument:
| Variable | Default | Description |
|---|
| INLINECODE0 | INLINECODE1 | Server base URL (client side) |
| INLINECODE2 |
4096 | Random seed → controls timbre |
|
TTS_INSTRUCT | (generic female voice) | Voice description prompt |
|
TTS_MODEL_PATH |
Qwen/Qwen3-TTS-12Hz-1.7B-VoiceDesign | Model weights path |
|
TTS_PORT |
8881 | Server listen port |
|
TTS_HOST |
0.0.0.0 | Server bind address |
|
TTS_FORMAT |
mp3 | Output format:
mp3 /
wav |
Server reads from .env file in its directory. Client scripts read from shell env.
Voice Description Example
CODEBLOCK1
Tip: Once you've found your perfect voice (description + seed), set them as server defaults in .env. Then client calls only need to pass text.
API
OpenAI-Compatible
CODEBLOCK2
Custom (seed + instruct override)
CODEBLOCK3
GET (quick test)
CODEBLOCK4
Seed Mechanics
Same (description + seed) → same timbre. Different seeds → completely different voices.
⚠️ Seeds are purely random — seed 42 and 43 can sound completely different. Finding a voice = opening blind boxes.
Workflow: fix description → batch 30-40 seeds → listen → shortlist 2-3 → compare across scenarios → pick.
Deploy Your Own
CODEBLOCK5
Setup installs: qwen-tts, soundfile, pydub, uvicorn, fastapi, torch (CUDA).
Downloads VoiceDesign model (~3.5GB) via ModelScope (China) or HuggingFace.
Requirements: CUDA GPU with 4GB+ VRAM, Python 3.10+, ~4GB disk.
Scripts
| Script | Purpose |
|---|
| INLINECODE25 | Generate speech — INLINECODE26 |
| INLINECODE27 |
Compare seeds —
batch_seeds.sh "text" seed1 seed2 ... |
|
scripts/tts_server.py | FastAPI server (fully env-configurable) |
|
scripts/setup.sh | One-click deploy (venv + deps + model download) |
OpenClaw Integration
In openclaw.json:
CODEBLOCK6
Server Management
CODEBLOCK7
Troubleshooting
- - Connection refused → Server not running; start it
- 30s+ first request → Cold start (model loading ~60s); subsequent requests 10-15s
- Behind proxy → Set
NO_PROXY=<server_ip> on client side - Windows firewall → INLINECODE33
- No flash-attn on Windows → Expected; falls back to PyTorch SDPA (slower but works)
- PowerShell corrupts Chinese → Edit
.env/config via Python or SCP, not PowerShell INLINECODE35 - Process dies on SSH disconnect → Use scheduled task (Windows) or systemd (Linux) instead of foreground
Voice Design Tips
Describe like casting a voice actor:
- - Age/gender: "18岁女大学生" / "30岁男性播音员"
- Texture: "柔和温暖" / "清脆明亮" / "低沉磁性"
- Emotion: "轻柔细腻" / "活泼开朗"
- Accent: "南方口音软糯" / "台湾腔" / "东北大碴子味"
- Metaphor: "像棉花糖" / "像播音主持" (helps the model capture feeling)
⚠️ Timbre ≠ description. Description controls style/emotion; seed controls timbre. Don't put personality traits ("灵动俏皮") in description — that's the seed's job.
Qwen3-TTS 语音设计
文本 → 语音,支持自然语言语音描述 + 基于种子的音色固定。
快速开始
bash
生成语音(使用服务器默认设置)
TTS_URL=http://your-server:8881 scripts/say.sh 你好世界!
保存到文件
scripts/say.sh 保存这段 output.mp3
批量对比种子(语音探索)
scripts/batch_seeds.sh 你好世界! 42 123 201 456 789 /tmp/seeds
环境变量
所有配置通过环境变量设置——文本是唯一必需的参数:
| 变量 | 默认值 | 描述 |
|---|
| TTSURL | http://localhost:8881 | 服务器基础URL(客户端侧) |
| TTSSEED |
4096 | 随机种子 → 控制音色 |
| TTS_INSTRUCT | (通用女声) | 语音描述提示词 |
| TTS
MODELPATH | Qwen/Qwen3-TTS-12Hz-1.7B-VoiceDesign | 模型权重路径 |
| TTS_PORT | 8881 | 服务器监听端口 |
| TTS_HOST | 0.0.0.0 | 服务器绑定地址 |
| TTS_FORMAT | mp3 | 输出格式:mp3 / wav |
服务器从其目录下的 .env 文件读取配置。客户端脚本从shell环境变量读取。
语音描述示例
30岁男性播音员,声音低沉磁性,
语速稳重从容,咬字清晰标准,
像新闻联播主播的专业感,又带一点温暖。
提示: 一旦找到完美的语音(描述+种子),将其设置为 .env 中的服务器默认值。之后客户端调用只需传递 text。
API
OpenAI兼容
bash
curl -X POST $TTS_URL/v1/audio/speech \
-H Content-Type: application/json \
-d {input: 你好!} -o speech.mp3
自定义(种子+指令覆盖)
bash
curl -X POST $TTS_URL/tts \
-H Content-Type: application/json \
-d {text: 你好!, seed: 201, instruct: 温柔女生} -o speech.mp3
GET(快速测试)
bash
curl $TTS_URL/tts?text=你好&seed=201 -o test.mp3
种子机制
相同的 (描述 + 种子) → 相同的音色。不同的种子 → 完全不同的声音。
⚠️ 种子完全是随机的——种子42和43可能听起来完全不同。寻找语音就像开盲盒。
工作流程: 固定描述 → 批量测试30-40个种子 → 试听 → 筛选2-3个 → 跨场景对比 → 选定。
自行部署
bash
一键安装(需要Python 3.10+和CUDA GPU)
bash scripts/setup.sh ./my-tts
在.env中配置语音
echo TTS_SEED=201 >> ./my-tts/.env
echo TTS_INSTRUCT=在此输入您的语音描述 >> ./my-tts/.env
启动服务器
bash scripts/setup.sh start ./my-tts
安装程序会安装:qwen-tts、soundfile、pydub、uvicorn、fastapi、torch(CUDA版本)。
通过ModelScope(中国)或HuggingFace下载VoiceDesign模型(约3.5GB)。
系统要求: CUDA GPU(4GB+显存)、Python 3.10+、约4GB磁盘空间。
脚本
| 脚本 | 用途 |
|---|
| scripts/say.sh | 生成语音 — say.sh 文本 [output.mp3] |
| scripts/batchseeds.sh |
对比种子 — batchseeds.sh 文本 seed1 seed2 ... |
| scripts/tts_server.py | FastAPI服务器(完全环境变量可配置) |
| scripts/setup.sh | 一键部署(虚拟环境+依赖+模型下载) |
OpenClaw集成
在 openclaw.json 中:
json
{
env: { OPENAITTSBASE_URL: http://:8881/v1 },
messages: {
tts: {
provider: openai,
openai: { apiKey: dummy, model: qwen3-tts, voice: default },
timeoutMs: 120000
}
}
}
服务器管理
bash
健康检查
curl -s $TTS_URL/health
启动(前台)
python tts_server.py
启动(后台,Linux/macOS)
nohup python tts_server.py > server.log 2>&1 &
自动重启(Windows — 计划任务+守护脚本)
创建 tts_guard.bat:
@echo off
:loop
python tts_server.py
timeout /t 10
goto loop
注册:schtasks /create /tn TTS-Guard /tr tts_guard.bat /sc onlogon /rl highest
自动重启(Linux — systemd)
详见 setup.sh 输出的 systemd 单元模板
停止
Linux/macOS:kill $(lsof -ti:8881)
Windows:for /f tokens=5 %a in (netstat -aon ^| findstr :8881) do taskkill /PID %a /F
故障排除
- - 连接被拒绝 → 服务器未运行;启动它
- 首次请求30秒以上 → 冷启动(模型加载约60秒);后续请求10-15秒
- 位于代理后面 → 在客户端设置 NO_PROXY=<服务器IP>
- Windows防火墙 → netsh advfirewall firewall add rule name=TTS dir=in action=allow protocol=TCP localport=8881
- Windows上无flash-attn → 正常;回退到PyTorch SDPA(较慢但可用)
- PowerShell损坏中文 → 通过Python或SCP编辑 .env/配置,不要使用PowerShell的 Set-Content
- SSH断开时进程终止 → 使用计划任务(Windows)或systemd(Linux)代替前台运行
语音设计技巧
像为角色配音一样描述:
- - 年龄/性别:18岁女大学生 / 30岁男性播音员
- 质感:柔和温暖 / 清脆明亮 / 低沉磁性
- 情感:轻柔细腻 / 活泼开朗
- 口音:南方口音软糯 / 台湾腔 / 东北大碴子味
- 比喻:像棉花糖 / 像播音主持(帮助模型捕捉感觉)
⚠️ 音色 ≠ 描述。 描述控制风格/情感;种子控制音色。不要在描述中加入个性特征(灵动俏皮)——那是种子的工作。