语音合成(TTS)正在成为 AI 应用的标配:播客转写、有声书、智能客服、导航播报都离不开它。把语音合成放在本地部署,既能守住用户隐私,又能把每千字成本压到接近零。本文以阿里开源的 CosyVoice 为例,手把手带你在显卡服务器上搭建一套高自然度、可批量调用的本地 TTS 服务。
一、为什么要把语音合成搬回本地
调用云厂商的语音合成 API 确实省事,但长期运行会暴露三个痛点:按字符计费、音频与文本离开内网、高峰期限流。本地部署则把控制权交回自己手里。
| 维度 | 云 API | 本地 CosyVoice |
|---|---|---|
| 成本 | 按字符持续付费 | 一次性显卡投入,边际成本≈电费 |
| 隐私 | 文本上传第三方 | 数据不出机 |
| 并发 | 受配额与限流约束 | 取决于本地显存与队列 |
| 音色 | 固定可选音色 | 零样本克隆任意参考音色 |
如果你的业务是客服录音、内部培训音频或批量有声内容,本地语音合成的投资回报会非常明显。关于本地推理服务的整体思路,也可以参考我们此前介绍的 Xinference 多模型统一推理服务。
二、CosyVoice 是什么
CosyVoice 是阿里巴巴开源的语音生成大模型(FunAudioLLM 项目),目前主推 CosyVoice2-0.5B。它有三个让开发者眼前一亮的能力:零样本音色克隆(给 3–10 秒参考音频即可复刻音色)、多语言多情感(中/英/日/韩等,并支持情绪指令)、以及自然语言指令控制(例如“用开心的语气说”)。相比传统拼接式 TTS,它生成的语音停顿更自然、韵律更连贯。
三、环境准备
本地语音合成对算力有一定要求,但并非必须顶级显卡。下面是推荐基线:
- Python 3.10 或 3.11(CosyVoice 对 3.12 兼容性一般,建议锁 3.10)。
- CUDA 11.8 及以上;驱动版本与 PyTorch 匹配。
- 显存:CosyVoice-300M 约 6GB 可跑,CosyVoice2-0.5B 建议 8GB 以上,批量并发建议 16GB+。
- 系统:Ubuntu 20.04/22.04 最佳,Windows 需 WSL2。
用 conda 隔离依赖是稳妥做法,避免污染系统 Python。日常开发与调试推荐配合 VS Code 远程开发 直连服务器。
四、安装与下载模型
先从官方仓库拉取代码并安装依赖,再从 ModelScope(魔搭)下载预训练权重。注意 CosyVoice 包含子模块,必须递归拉取。
# 1. 拉取代码(含子模块)
git clone --recursive https://github.com/FunAudioLLM/CosyVoice.git
cd CosyVoice
git submodule update --init --recursive
# 2. 创建环境并安装依赖
conda create -n cosyvoice python=3.10 -y
conda activate cosyvoice
pip install -r requirements.txt
# 3. 下载模型权重(需先 pip install modelscope)
from modelscope import snapshot_download
snapshot_download('iic/CosyVoice2-0.5B', local_dir='pretrained_models/CosyVoice2-0.5B')
若网络对 GitHub 不友好,可改用国内镜像或先下载离线包再拷贝进 pretrained_models/ 目录。模型约 1–2GB,首次部署请预留空间。
五、快速推理:几行代码出声
安装完成后,最直接的验证方式是调用 Python API。下面用默认音色合成一段中文语音。
from cosyvoice.cli.model import CosyVoice
import torchaudio
cosyvoice = CosyVoice('pretrained_models/CosyVoice2-0.5B')
# 使用内置音色(s1~s4)做基础合成
for i, sample in enumerate(cosyvoice.inference_synthesize(
'欢迎使用本地语音合成服务,这是一段测试音频。',
stream=False, speed=1.0)):
torchaudio.save(f'output_{i}.wav', sample['tts_speech'], 24000)
运行后会在当前目录生成 24kHz 的 WAV 文件。speed 参数可微调语速,取值 0.5–2.0。
六、零样本音色克隆
这是 CosyVoice 最有用的能力:不需要训练,仅凭一段参考音频就能复刻音色。参考音频建议 3–10 秒、清晰无噪声,且必须提供其对应的原文文本(prompt_text),否则克隆效果会明显下降。
from cosyvoice.cli.model import CosyVoice
from cosyvoice.utils.file_utils import load_wav
import torchaudio
cosyvoice = CosyVoice('pretrained_models/CosyVoice2-0.5B')
# 参考音频与原文(务必准确,否则音色漂移)
prompt_wav = load_wav('prompt.wav', 16000)
prompt_text = '今天天气真好,我们出去走走吧。'
for i, sample in enumerate(cosyvoice.inference_zero_shot(
'这是用克隆音色合成的一句话,听起来像真人吗?',
prompt_text,
prompt_wav,
stream=False)):
torchaudio.save(f'clone_{i}.wav', sample['tts_speech'], 24000)
七、用指令控制情绪与语种
除了克隆音色,CosyVoice 还支持用自然语言指令切换情绪和语种,适合批量生成不同风格的内容。
# 指令模式:在指令中描述情绪 / 语种 / 角色
instruction = '用四川话悲伤地说'
for i, sample in enumerate(cosyvoice.inference_instruct(
'那年的樱花,开得比哪一年都热闹。',
instruction,
stream=False)):
torchaudio.save(f'instruct_{i}.wav', sample['tts_speech'], 24000)
指令模式对提示词较敏感,建议先用少量样本测试出稳定的描述词,再固化到生产流程里。
八、服务化:用 FastAPI 封装 TTS 接口
单机脚本无法支撑业务调用,把模型包成一个 HTTP 服务才是正道。下面是一份精简的 FastAPI 封装,支持文本合成与参考音频克隆两种模式。
from fastapi import FastAPI, UploadFile, File
from fastapi.responses import StreamingResponse
from cosyvoice.cli.model import CosyVoice
from cosyvoice.utils.file_utils import load_wav
import io, torchaudio, tempfile
app = FastAPI()
cosyvoice = CosyVoice('pretrained_models/CosyVoice2-0.5B')
@app.post('/tts')
async def tts(text: str, voice: str = 's1'):
out = next(cosyvoice.inference_synthesize(text, stream=False))
buf = io.BytesIO()
torchaudio.save(buf, out['tts_speech'], 24000, format='wav')
buf.seek(0)
return StreamingResponse(buf, media_type='audio/wav')
@app.post('/clone')
async def clone(text: str, prompt_text: str, audio: UploadFile = File(...)):
with tempfile.NamedTemporaryFile(suffix='.wav') as f:
f.write(await audio.read())
prompt_wav = load_wav(f.name, 16000)
out = next(cosyvoice.inference_zero_shot(text, prompt_text, prompt_wav, stream=False))
buf = io.BytesIO()
torchaudio.save(buf, out['tts_speech'], 24000, format='wav')
buf.seek(0)
return StreamingResponse(buf, media_type='audio/wav')
部署时务必加并发控制(如信号量或队列),避免多个请求同时抢显存导致 OOM。如需把服务纳入 CI 自动回归,可参考 GitHub Actions 实战 搭建测试流水线。
九、主流语音合成方案对比
| 方案 | 音色克隆 | 部署难度 | 实时率 | 适用场景 |
|---|---|---|---|---|
| CosyVoice2 | 零样本强 | 中 | 高 | 高质量、可克隆音色 |
| ChatTTS | 无(固定) | 低 | 很高 | 口语化对话 |
| Fish Speech | 需少量微调 | 中 | 高 | 多语种克隆 |
| Edge TTS | 无 | 极低 | 云端 | 轻量预览 |
| 云 API | 受限 | 最低 | 云端 | 快速接入 |
十、显存与性能优化
本地语音合成的瓶颈通常是显存与实时率(RTF,越小越快)。实测参考如下,具体取决于显卡与批大小。
| 模型 | 显存占用 | RTF(单句) | 建议显卡 |
|---|---|---|---|
| CosyVoice-300M | ~6GB | 0.1–0.2 | RTX 3060 12G |
| CosyVoice2-0.5B | ~8GB | 0.15–0.3 | RTX 4060 Ti 16G |
| + 并发批处理 | ~10GB | 0.3–0.5 | RTX 4070 及以上 |
优化手段包括:用 FP16 推理、开启 torch.compile、将短文本做动态 batch、用独立 worker 进程而非多线程(Python GIL 下多线程无效)。
十一、Docker 部署
生产环境建议用容器固化环境,避免“我机器上能跑”。下面是一份最小可运行的 Dockerfile 思路(基于 CUDA 基础镜像)。
FROM nvidia/cuda:12.1.1-runtime-ubuntu22.04
RUN apt-get update && apt-get install -y python3.10 python3-pip git && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
完整容器化编排与端口暴露可参考我们的 Docker 编排实战,重点是把 GPU 透传(--gpus all)和模型卷挂载好,避免每次启动重新下载权重。
十二、常见问题排查
| 现象 | 可能原因 | 对策 |
|---|---|---|
| 克隆音色不像 | 参考文本不准 / 音频有噪 | 逐字核对 prompt_text,重录干净参考音 |
| 显存 OOM | 并发过高 / 模型过大 | 降并发、换 300M、加 swap 无效需加显存 |
| 中文吞字 | 标点切分异常 | 规范化文本,长句按标点分片 |
| 推理极慢 | 走了 CPU | 确认 CUDA 可用,torch.cuda.is_available() |
如果想把语音合成嵌进更大的 AI 工作流(例如先由大模型生成文案再自动配音),可以把它接到 Dify + Ollama 这样的低代码平台上,用自定义工具节点调用上面的 TTS 接口即可。




