Series · Aliyun Bailian · Chapter 5

阿里云百炼实战(五):Qwen-TTS 多语言语音合成

Qwen-TTS-Flash 实战:原生 only API、40+ 音色目录(含粤语 / 川语)、流式合成、文档一笔带过的 SSML 行为细节。

我做的每个中文产品最终都调 Qwen-TTS-Flash,原因不是便宜——便宜的 TTS 多得是。是它是唯一一个能在同一个 SDK 里同时讲清楚中国大陆方言(粤语、川语、吴语)和英文、且音色不像 2019 年海关广播的 TTS。在某营销视频配音流水线里跑了大约六个月,下面是我希望第一天就有人告诉我的事。

音色目录

按模型卡,Qwen-TTS-Flash 有 40+ 音色。我用得最多的:

Qwen-TTS 音色目录

普通话产品旁白我默认 Cherry(温暖,30 多女声)做营销内容,Ethan(沉稳,40 多男声)做教程。粤语广告位 Sunny 是稳妥选择。音色名稳定但新音色会陆续加——上线前到模型卡确认你要的还在。

只走原生 API

Qwen-TTS 不走 OpenAI 兼容层。用 DashScope 原生 SDK:

Qwen-TTS 原生调用结构

最小请求:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import os, dashscope, requests
from dashscope.audio.qwen_tts import SpeechSynthesizer

dashscope.api_key = os.environ["DASHSCOPE_API_KEY"]

resp = SpeechSynthesizer.call(
    model="qwen3-tts-flash",
    text="欢迎来到杭州,全城最安静的咖啡馆就在西湖边上。",
    voice="Cherry",
    format="mp3",
)

audio_url = resp.output.audio["url"]
with open("/tmp/out.mp3", "wb") as f:
    f.write(requests.get(audio_url, timeout=30).content)

两点强调:

  • 输出默认是 URL,不是字节。和万相一样,24 小时内下载(我的做法是立刻下、立刻 re-upload 到自己 OSS)。
  • format 默认 mp3,也支持 WAV。下游要做拼接 WAV 更方便,每段不带 MP3 头开销。

流式 TTS——延迟敏感时

语音机器人之类实时对话场景要流式。返回的就是音频字节,可以直接写到播放器或文件:

流式 TTS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from dashscope.audio.qwen_tts import SpeechSynthesizer

with open("/tmp/streamed.mp3", "wb") as f:
    for resp in SpeechSynthesizer.call(
        model="qwen3-tts-flash",
        text="这段语音是从模型那边一段一段流式返回的。",
        voice="Cherry",
        stream=True,
    ):
        if resp.output and resp.output.audio:
            f.write(resp.output.audio["data"])

上海区流式首字节通常 < 400ms,用户感知是即时的。非流式 30 秒话术大约 4-6 秒墙钟时间——批量旁白可以,对话场景偏慢。

多语言和方言细节

Qwen-TTS 会从文本检测语种,但混排时建议显式设 language。我的生产规则:

  • 纯普通话 → language="zh"(默认)。
  • 纯英文 → language="en"Eric 这类音色出彩。
  • 粤语繁体 → language="zh-yue",音色 SunnyLily
  • CJK + 英文混排(科技旁白常见)→ 不设语种,模型自然处理 code-switch。

经验: 方言上线前务必找母语者 A/B 一遍。Qwen-TTS 粤语好但音调不完美——粤语单字音调错了,意思会变。

SSML——什么管用、什么不

文档列了 SSML 支持但对哪些标签真生效不明。经验:

  • <break time="500ms"/> — 管用。营销文案句间停顿用。
  • <emphasis level="strong"> — 管用。
  • <prosody rate="slow"> — 管用。slow / medium / fast 或百分比。
  • <prosody pitch="..."> — 相对调整管用(+10%)。
  • <say-as interpret-as="digits"> — 电话、code、日期管用。
  • <phoneme> — 部分管用。中文上带声调拼音比 IPA 稳。
  • <voice>管用。一句话中间不能换音色。分次合成再拼接。

长旁白拼接

营销脚本通常很长。60 秒旁白模式:

1
2
3
4
5
6
7
8
def synthesize_long(script: str, voice: str = "Cherry") -> str:
    sentences = split_sentences(script)  # 自家分句器,简单 regex 也行
    parts = []
    for s in sentences:
        resp = SpeechSynthesizer.call(model="qwen3-tts-flash", text=s,
                                       voice=voice, format="wav")
        parts.append(download(resp.output.audio["url"]))
    return concat_wavs(parts, output="/tmp/full.wav")  # ffmpeg concat

为啥分句?两个理由:(1) 单句调用延迟低很多,并发合成更快;(2) 单句出问题只重做那一句不用整段重录。我们广告位这么干——句间用 <break> 处理停顿,并发后 60 秒片子大约 4 秒能出。

成本

按输出音频秒数计费。流式和非流式一个价。60 秒广告位几块钱——比配音演员小时费便宜得多,也快得让营销团队下午能试几十个版本。

系列收尾

到这里五篇结束。回顾:

  • 第一篇 — 百炼 / DashScope 入门。
  • 第二篇 — Qwen LLM 家族和细节(function calling、JSON mode、enable_thinking)。
  • 第三篇 — Qwen-Omni 多模态理解。
  • 第四篇 — 万相视频生成。
  • 第五篇 — Qwen-TTS 语音(本文)。

姐妹系列阿里云 PAI 讲 DSW / DLC / EAS——你自己跑 GPU 训练和推理的层。我合作过的多数团队两个都用:要别人的预训模型时用百炼,要控制权重时用 PAI。按你需要控什么选,不是按哪个写在简历上更显眼。

Liked this piece?

Follow on GitHub for the next one — usually one a week.

GitHub