Skip to content

Qwen3-TTS 语音定制

网关地址: https://ai.ospreyai.cn(公网) 模型: Qwen3-TTS 1.7B 无需后端 Bearer Token

概述

使用 Qwen3-TTS 1.7B 模型做语音定制合成,支持两种模式:

模式用途输入是否需参考音频
VoiceDesign文字描述音色直接生成并朗读文本 + 音色描述
VoiceClone参考音频克隆音色朗读新文本目标文本 + 参考音频 + 参考文字

任务异步执行:提交工作流 → 轮询状态 → 下载结果。任务状态查询、结果下载等通用接口见 任务管理

前置条件: VoiceClone 模式需先通过 /api/v1/upload 上传参考音频。

bash
export GW="https://ai.ospreyai.cn"
export API_KEY="sk-your-api-key"

接口清单

用途方法路径
上传参考音频POST/api/v1/upload
提交任务POST/api/v1/ai/audio/generate
查询任务状态GET/api/v1/ai/tasks/{prompt_id}
下载结果文件GET/api/v1/ai/image/view/
查询队列GET/api/v1/ai/queue

音频提交端点 /ai/audio/generate,与 image/video/generate 一样转发到 ComfyUI 工作流引擎,区别在于工作流含音频节点,结果在 outputs[].audio 字段(不是 images/gifs)。

VoiceDesign 模式

用文字描述音色直接生成并朗读,无需参考音频。

POST /api/v1/ai/audio/generate
Content-Type: application/json
Authorization: Bearer sk-xxx
bash
curl -H "Authorization: Bearer $API_KEY" -X POST "$GW/api/v1/ai/audio/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": {
      "1": {"inputs": {"text": ["6", 0], "instruct": "成熟性感的御姐音色,磁性且慵懒", "model_choice": "1.7B", "device": "auto", "precision": "bf16", "language": "Auto", "seed": 12345, "max_new_tokens": 2048, "top_p": 0.8, "top_k": 20, "temperature": 1, "repetition_penalty": 1.05, "attention": "auto", "unload_model_after_generate": false}, "class_type": "FB_Qwen3TTSVoiceDesign"},
      "2": {"inputs": {"audioUI": "", "audio": ["1", 0]}, "class_type": "PreviewAudio"},
      "6": {"inputs": {"string": "今晚,和一个危险又迷人的姐姐喝了一杯。", "strip_newlines": true}, "class_type": "StringConstantMultiline"}
    },
    "extra_data": {}
  }'

响应:

json
{"prompt_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "number": 1, "node_errors": {}}

关键节点参数

节点字段说明推荐值
6string要朗读的文本
1instruct音色描述
1seed随机种子(避免缓存命中)任意整数

VoiceClone 模式

提供参考音频 + 参考文字,克隆音色朗读新文本。

原工作流 ref_audio 连 VoiceDesign 输出(界面用),API 调用需改用 LoadAudio 节点接已上传的参考音频。

1. 上传参考音频

bash
curl -H "Authorization: Bearer $API_KEY" -X POST "$GW/api/v1/upload" \
  -F "image=@/path/to/ref.wav" \
  -F "type=input"
# 返回: {"name": "ref.wav", "subfolder": "", "type": "input"}

2. 提交工作流

bash
curl -H "Authorization: Bearer $API_KEY" -X POST "$GW/api/v1/ai/audio/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": {
      "5": {"inputs": {"target_text": "紧张什么?你连坐姿都在发抖……", "model_choice": "1.7B", "device": "auto", "precision": "bf16", "language": "Auto", "ref_text": ["6", 0], "seed": 12345, "max_new_tokens": 2048, "top_p": 0.8, "top_k": 20, "temperature": 1, "repetition_penalty": 1.05, "x_vector_only": false, "attention": "auto", "unload_model_after_generate": false, "custom_model_path": "", "ref_audio": ["100", 0]}, "class_type": "FB_Qwen3TTSVoiceClone"},
      "6": {"inputs": {"string": "参考音频里说的那句话", "strip_newlines": true}, "class_type": "StringConstantMultiline"},
      "7": {"inputs": {"audioUI": "", "audio": ["5", 0]}, "class_type": "PreviewAudio"},
      "100": {"inputs": {"audio": "ref.wav", "audioUI": ""}, "class_type": "LoadAudio"}
    },
    "extra_data": {}
  }'

响应:

json
{"prompt_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "number": 1, "node_errors": {}}

关键节点参数

节点字段说明推荐值
6string参考音频对应的文字(ref_text)
5target_text要用克隆音色朗读的目标文本
100audio参考音频文件名(需先上传)上传返回的 name
5ref_audio连接 LoadAudio 节点 ["100", 0]
5seed随机种子任意整数

ref_text 必须与参考音频里真实说的话匹配,否则克隆效果差或报错。

下载结果

音频在 outputs[].audio 字段。Qwen3-TTS 输出在 temp 目录type=tempsubfolder=""),文件名带随机串如 ComfyUI_temp_xxx_00001.flac

bash
curl -H "Authorization: Bearer $API_KEY" \
  "$GW/api/v1/ai/image/view/?filename=ComfyUI_temp_xxx_00001.flac&type=temp&subfolder=" \
  -o result.flac

输出: FLAC 音频。

temp 是临时目录,ComfyUI 会定期清理,需及时下载。

缓存坑:若提交的工作流与历史完全相同(尤其 seed 相同),ComfyUI 会命中 execution_cached 直接返回,outputs 可能为空。提交时换个 seed 可避免。

Python 调用示例

python
import json, time, urllib.request

GW = "https://ai.ospreyai.cn"
API_KEY = "sk-your-api-key"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

# 1. 上传参考音频(VoiceClone 模式,参考「任务管理」页上传示例)

# 2. 提交工作流(以 VoiceDesign 为例)
nodes = {
    "1": {"inputs": {"text": ["6", 0], "instruct": "成熟性感的御姐音色,磁性且慵懒", "model_choice": "1.7B", "device": "auto", "precision": "bf16", "language": "Auto", "seed": 12345, "max_new_tokens": 2048, "top_p": 0.8, "top_k": 20, "temperature": 1, "repetition_penalty": 1.05, "attention": "auto", "unload_model_after_generate": false}, "class_type": "FB_Qwen3TTSVoiceDesign"},
    # ...其余节点同上 curl 示例...
}
nodes["6"]["inputs"]["string"] = "今晚,和一个危险又迷人的姐姐喝了一杯。"
nodes["1"]["inputs"]["instruct"] = "成熟性感的御姐音色,磁性且慵懒"
nodes["1"]["inputs"]["seed"] = 12345  # 避免缓存

req = urllib.request.Request(
    f"{GW}/api/v1/ai/audio/generate",
    data=json.dumps({"prompt": nodes, "extra_data": {}}).encode(),
    headers=HEADERS, method="POST",
)
prompt_id = json.loads(urllib.request.urlopen(req, timeout=30).read())["prompt_id"]

# 3. 轮询
while True:
    r = urllib.request.Request(f"{GW}/api/v1/ai/tasks/{prompt_id}", headers=HEADERS)
    task = json.loads(urllib.request.urlopen(r, timeout=15).read())[prompt_id]
    if task["status"].get("completed"):
        break
    time.sleep(4)

# 4. 下载(Qwen-TTS 音频在 temp 目录)
for out in task["outputs"].values():
    for a in out.get("audio", []):
        url = f"{GW}/api/v1/ai/image/view/?filename={a['filename']}&type={a['type']}&subfolder={a.get('subfolder','')}"
        req = urllib.request.Request(url, headers=HEADERS)
        open(a["filename"], "wb").write(urllib.request.urlopen(req, timeout=120).read())

常见问题

问题现象可能原因解决方案
401 UnauthorizedAPI Key 错误/未传检查 Authorization: Bearer sk-xxx
node_errors 非空参考音频未上传/文件名错POST /api/v1/upload(字段名 imagetype=input),文件名一致
任务 success 但 outputs 为空命中 ComfyUI 缓存换文本/seed/参考音频重提
下载 404type 错Qwen-TTS 用 type=temp(不是 output)
clone 报 ref_audio 错ref_text 与参考音频不匹配ref_text 应是参考音频里真实说的话
文件下载后失效temp 目录被清理temp 是临时目录,生成后及时下载

AI API Gateway Documentation