EmotiVoice 保姆级部署教程:网易有道开源多情感中英文 TTS 引擎从零到一完整搭建
EmotiVoice(易魔声)是网易有道开源的现代化语音合成(TTS)引擎,基于 Apache-2.0 协议发布,支持中英文双语、2000+ 种音色,并通过提示词(Prompt)控制情感——开心、兴奋、悲伤、愤怒等情绪都可以直接写进文本里让模型合成出来。与同类项目相比,它的定位很清晰:不是零样本声音克隆工具,而是一个"开箱即用、带情感控制、自带 WebUI 和 OpenAI 兼容 API"的完整 TTS 服务端。本文将按照官方 README 的步骤,从零开始把 EmotiVoice 跑起来,覆盖 Docker 一键部署、源码完整安装、模型文件下载、命令行推理、WebUI 与 OpenAI 兼容 API 全部环节。
一、项目介绍与适用场景
EmotiVoice 的核心特点在官方 README 里有明确描述:它是一个强大的、现代的开源 TTS 引擎,免费使用,支持中英文双语,内置超过 2000 种音色(完整列表见官方 Wiki 的 Voice Wiki 页面),最突出的能力是"情感合成"——可以通过文本控制合成语音的情感色彩(Happy、Sad、Angry 等)。项目由网易有道团队维护,底层基于 PromptTTS 论文思路,并整合了 HiFi-GAN、Transformers、SimBERT、cn2an 等组件。
适用场景包括:
- 个人创作者:给短视频、有声书、播客快速生成带情感的中文旁白,不用自己录音;
- 团队/小公司:搭建一个内部 TTS 服务,通过 OpenAI 兼容 API 给 App、客服机器人、阅读类产品接语音能力;
- 开发者:研究"提示词控制情感 TTS"这一方向,作为二次开发基座(官方提供了基于自有数据做声音克隆训练的 Recipe);
- 自托管价值:数据不出本机,音色和情感策略完全可控,不依赖任何商业 TTS 云服务的按量计费。
与站点此前写过的 TTS 项目(GPT-SoVITS、F5-TTS、CosyVoice 等)相比,EmotiVoice 的差异化在于:它不要求你准备参考音频去克隆音色,而是直接用官方预置的 2000+ 音色 ID 合成,情感靠文本里的风格提示词控制,部署门槛和使用成本都更低。
具体来说,使用 GPT-SoVITS 这类克隆工具,你需要先录制一段几分钟的目标人声,跑通数据标注、微调训练流程,才能得到一个专属音色;而 EmotiVoice 把"选音色"简化成了"填一个数字 ID",把"要情绪"简化成了"在文本里写 Happy/Sad"。对只是想给视频配个音、给阅读产品接个朗读接口的用户来说,这种"零样本训练、直接可用"的形态更省事。代价是:它不能像克隆工具那样完全复刻某个特定真人的声音,音色上限由官方音色库决定。
另外两个值得注意的工程细节:一是官方同时维护了 Docker 镜像与 conda 源码两条路线,新手走 Docker、开发者走源码;二是官方直接提供了 OpenAI 兼容 API,意味着你现有的、基于 OpenAI TTS SDK 写的业务代码,只改一下 base_url 就能切到自己的 EmotiVoice 服务,迁移成本极低。
二、核心功能逐条拆解
以下功能均来自官方 README 与 Wiki:
- 多情感合成:在待合成文本中加入情感提示词(如
Happy|...),模型即输出对应情绪的语音。对应入口:推理文本的第二列。 - 2000+ 预置音色:中英文音色库,音色 ID 形如
8051,完整列表见官方 Wiki "voice wiki page"。对应入口:--test_file文本文件中的 speaker 字段。 - 中英文双语:中文分词走 jieba/pypinyin,英文走 g2p_en。对应入口:
frontend.py文本预处理脚本。 - Streamlit WebUI:浏览器里点点鼠标就能合成音频。对应入口:
streamlit run demo_page.py。 - OpenAI 兼容 TTS API:暴露 8000 端口的 HTTP 接口,可以直接用 OpenAI SDK 的语音合成接口对接。对应入口:
uvicorn openaiapi:app --reload。 - Docker 镜像:官方发布
syq163/emoti-voice:latest镜像,一条命令拉起 WebUI。对应入口:Docker 部署小节。 - 批量脚本推理:通过命令行一次性处理整个文本文件。对应入口:
inference_am_vocoder_joint.py。 - 声音克隆训练 Recipe:官方提供 DataBaker、LJSpeech 数据集的训练 Recipe,支持用自有数据微调音色。对应入口:仓库
data/目录下的 Recipe 与 Wiki "Voice Cloning with your personal data"。
三、全套官方链接
| 类型 | 链接 |
|---|---|
| GitHub 仓库 | https://github.com/netease-youdao/EmotiVoice |
| 官方文档 | https://github.com/netease-youdao/EmotiVoice/wiki |
| 官方 Demo | https://replicate.com/bramhooimeijer/emotivoice |
| License | Apache-2.0(代码);交互页另附《易魔声用户协议》 |
四、硬件与环境前置要求
官方 README 明确说明:Docker 方式需要一台带 NVIDIA GPU 的机器,并安装 NVIDIA Container Toolkit(Linux)或在 Windows WSL2 中配置好 nvidia-docker。也就是说:
- 最低配置:一张 NVIDIA 显卡(官方未明确具体显存型号,按同类 PromptTTS 级模型的常规要求,建议 6GB 显存以上)、Linux 系统(或 WSL2)、安装好 Docker 与 NVIDIA Container Toolkit;
- 源码方式:官方要求 Python 3.8(conda 环境)、支持 CUDA 的 PyTorch;
- 磁盘:模型文件体积较大(SimBERT 中文模型 + 联合模型 outputs),预留至少 10GB 磁盘空间;
- 网络:模型可从 HuggingFace 或 ModelScope(魔搭)下载,国内用户走 ModelScope 更稳。
官方出处:README "EmotiVoice Docker image" 小节明确写了 "You need a machine with a NVidia GPU" 以及 NVIDIA Container Toolkit 的配置指引链接。
五、多平台部署步骤
官方提供三种使用方式:Docker 镜像(最快上手)、conda 源码完整安装(可二次开发)、以及基于前者的 WebUI/API 启动。官方未提供 Windows 原生安装包部署方式(仅提供过一个 Mac dmg 客户端,非服务端部署),本文不展开 Windows 原生。
5.1 Docker / Docker Compose 部署(官方推荐)
第 1 步:安装 NVIDIA Container Toolkit。按官方 README 给出的指引,Linux 用户参考 NVIDIA 官方文档配置好 nvidia-docker,确保 docker run --rm --gpus all nvidia/cuda:12.0.0-base-ubuntu22.04 nvidia-smi 能正常输出显卡信息。
第 2 步:拉取并运行官方镜像。官方原文命令:
docker run -dp 127.0.0.1:8501:8501 syq163/emoti-voice:latest
逐段解释:-d 表示后台运行;-p 127.0.0.1:8501:8501 把容器内 8501 端口(Streamlit WebUI)映射到本机回环地址;syq163/emoti-voice:latest 是官方发布的镜像名。
如果你的镜像是旧版本,官方 README 给出的更新命令为:
docker pull syq163/emoti-voice:latest
docker run -dp 127.0.0.1:8501:8501 -p 127.0.0.1:8000:8000 syq163/emoti-voice:latest
第二个 -p 127.0.0.1:8000:8000 用于暴露 OpenAI 兼容 TTS API(官方说明:从该版本起,OpenAI-compatible-TTS API 通过 http://localhost:8000/ 访问)。
第 3 步:验证。浏览器打开 http://localhost:8501,能看到 EmotiVoice 的交互式合成页面即部署成功。
出处:https://github.com/netease-youdao/EmotiVoice#emotivoice-docker-image
5.2 Linux 源码部署(官方 Full installation)
第 1 步:创建并激活 conda 环境(官方指定 Python 3.8):
conda create -n EmotiVoice python=3.8 -y
conda activate EmotiVoice
逐段解释:conda create -n EmotiVoice 创建名为 EmotiVoice 的隔离环境;python=3.8 是官方明确指定的版本;-y 自动确认。激活后终端提示符前出现 (EmotiVoice)。
第 2 步:安装 PyTorch 与依赖:
pip install torch torchaudio
pip install numpy numba scipy transformers soundfile yacs g2p_en jieba pypinyin pypinyin_dict
python -m nltk.downloader "averaged_perceptron_tagger_eng"
逐段解释:第一行装官方 PyTorch(建议按 CUDA 版本选择对应 wheel,参见 pytorch.org);第二行是官方列出的全部推理依赖(g2p_en 是英文音素转换、jieba/pypinyin 是中文处理、yacs 是配置库);第三行下载 NLTK 的词性标注模型(英文文本预处理依赖)。
第 3 步:拉取项目代码:
git clone https://github.com/netease-youdao/EmotiVoice.git
cd EmotiVoice
第 4 步:下载 SimBERT 中文模型(官方给出两种来源,二选一):
git lfs install
git lfs clone https://huggingface.co/WangZeJun/simbert-base-chinese WangZeJun/simbert-base-chinese
或者国内用户走 ModelScope:
git clone https://www.modelscope.cn/syq163/WangZeJun.git
逐段解释:git lfs install 初始化大文件支持;第一条命令从 HuggingFace 拉取 SimBERT 中文语义模型到本地 WangZeJun/simbert-base-chinese 目录;ModelScope 命令是官方提供的国内镜像替代。
第 5 步:下载预训练联合模型(官方原文):
git clone https://www.modelscope.cn/syq163/outputs.git
这个 outputs 目录即官方预训练模型,对应推理命令中的 --logdir prompt_tts_open_source_joint 与 --checkpoint g_00140000。官方提示:如果下载遇到问题,参考 Wiki 页面 "How to download the pretrained model files"。
出处:https://github.com/netease-youdao/EmotiVoice#full-installation
六、配置文件全部参数解释
EmotiVoice 源码方式没有独立的 .env 配置文件,"配置"主要体现在两个地方:推理脚本命令行参数,以及推理文本文件的格式。按官方 README 逐一说明:
| 参数/字段 | 作用 | 可选值 | 默认值 | 配置示例 | 改错后果 |
|---|---|---|---|---|---|
--logdir |
模型输出目录(即 outputs 里的联合模型目录名) | 官方为 prompt_tts_open_source_joint |
无(必填) | --logdir prompt_tts_open_source_joint |
指向错误目录会报模型文件找不到 |
--config_folder |
配置文件夹 | 官方为 config/joint |
无(必填) | --config_folder config/joint |
配置缺失导致模型结构加载失败 |
--checkpoint |
模型 checkpoint 文件名 | 官方为 g_00140000 |
无(必填) | --checkpoint g_00140000 |
checkpoint 不存在直接报错退出 |
--test_file |
待合成文本文件路径 | 官方示例为 data/inference/text |
无(必填) | TEXT=data/inference/text |
空文件或格式错误会无输出 |
| 推理文本第一列 | speaker 音色 ID | 2000+ 音色(见 Wiki) | 无 | 8051 |
音色 ID 不存在时使用默认音色 |
| 推理文本第二列 | 风格/情感提示词 | Happy、Sad、Angry 等 | 无 | Happy |
写法不当时情感效果不明显 |
| 推理文本第三列 | 音素(phoneme) | 由 frontend.py 生成 | 无 | <sos/eos> [IH0] [M] ... |
手动写错音素会发音异常 |
| 推理文本第四列 | 实际要朗读的内容 | 任意文本 | 无 | Emoti-Voice - a Multi-Voice... |
列缺失导致解析错位 |
官方说明:推理文本格式为 <speaker>|<style_prompt/emotion_prompt/content>|<phoneme>|<content>。官方给出的完整示例为:
8051|Happy|<sos/eos> [IH0] [M] [AA1] [T] engsp4 [V] [OY1] [S] engsp4 [AH0] engsp1 [M] [AH1] [L] [T] [IY0] engsp4 [V] [OY1] [S] engsp1 [AE1] [N] [D] engsp1 [P] [R] [AA1] [M] [P] [T] engsp4 [K] [AH0] [N] [T] [R] [OW1] [L] [D] engsp1 [T] [IY1] engsp4 [T] [IY1] engsp4 [EH1] [S] engsp1 [EH1] [N] [JH] [AH0] [N] . <sos/eos>|Emoti-Voice - a Multi-Voice and Prompt-Controlled T-T-S Engine
出处:https://github.com/netease-youdao/EmotiVoice#inference
七、启动、后台常驻与开机自启
7.1 命令行推理(前台)
官方原文命令:
TEXT=data/inference/text
python inference_am_vocoder_joint.py \
--logdir prompt_tts_open_source_joint \
--config_folder config/joint \
--checkpoint g_00140000 \
--test_file $TEXT
逐段解释:TEXT= 指定待合成文本文件;inference_am_vocoder_joint.py 是联合模型推理脚本;四个参数即上节配置表内容。合成完成后,音频文件输出到 outputs/prompt_tts_open_source_joint/test_audio 目录下。
先用官方文本预处理生成音素:
python frontend.py data/my_text.txt > data/my_text_for_tts.txt
7.2 WebUI 启动(Streamlit)
pip install streamlit
streamlit run demo_page.py
默认占用 8501 端口(Docker 镜像中已固化)。前台运行时终端会打印 Local URL: http://localhost:8501。
7.3 OpenAI 兼容 API 启动
pip install fastapi pydub uvicorn[standard] pyrubberband
uvicorn openaiapi:app --reload
默认监听 8000 端口。官方说明该接口兼容 OpenAI 的 TTS 调用方式(POST /v1/audio/speech 一类接口),可用官方 SDK 直接对接。
7.4 后台常驻与开机自启
官方 README 未提供 systemd 等常驻方案,以下为 Linux 通用做法(基于官方前台命令封装):
创建 /etc/systemd/system/emotivoice-webui.service:
[Unit]
Description=EmotiVoice Streamlit WebUI
After=network.target
[Service]
User=your_user
WorkingDirectory=/your/path/EmotiVoice
ExecStart=/bin/bash -c "source /opt/conda/etc/profile.d/conda.sh && conda activate EmotiVoice && streamlit run demo_page.py --server.port 8501"
Restart=always
[Install]
WantedBy=multi-user.target
然后:
sudo systemctl daemon-reload
sudo systemctl enable --now emotivoice-webui
7.5 修改端口
Docker 方式改端口只需修改 -p 映射,例如 127.0.0.1:9501:8501;源码方式给 streamlit run demo_page.py 加 --server.port=9501,或给 uvicorn 加 --port 8001。改完浏览器访问新端口验证。
八、功能实操教程
第 1 步:确认 Docker 容器在跑。docker ps 应看到 syq163/emoti-voice:latest,PORTS 列显示 127.0.0.1:8501->8501/tcp。
第 2 步:浏览器打开 http://localhost:8501,进入 EmotiVoice 交互式页面。
第 3 步:在输入框粘贴一段中文文本,选择一个音色 ID(可从官方 Wiki 的音色列表里挑一个,例如 8051),在情感栏写 Happy。
第 4 步:点击合成,页面播放生成的音频。听到中文、音色为所选 speaker、情绪偏欢快即成功。
第 5 步(命令行方式验证):在 data/inference/text 写入一行符合四列格式的文本,执行 python inference_am_vocoder_joint.py --logdir prompt_tts_open_source_joint --config_folder config/joint --checkpoint g_00140000 --test_file data/inference/text,等待命令结束,到 outputs/prompt_tts_open_source_joint/test_audio 目录下找到 wav 文件。
第 6 步(API 方式验证):启动 uvicorn openaiapi:app --reload,用 curl 调用:
curl http://localhost:8000/v1/audio/speech -H "Content-Type: application/json" -d '{"model":"emotivoice","input":"你好,这是一段测试","voice":"8051"}' --output test.wav
(具体请求字段以官方 Wiki "HTTP API" 页面为准。)
第 7 步(批量实战:给一整段中文旁白合成):新建 data/my_text.txt,写入一段旁白,例如"今天给大家介绍一款开源的语音合成引擎"。执行:
python frontend.py data/my_text.txt > data/my_text_for_tts.txt
cat data/my_text_for_tts.txt
确认输出已经是"音色|情感|音素|正文"四列格式后,把这一行追加到 data/inference/text,再跑一次联合推理命令,到 outputs/prompt_tts_open_source_joint/test_audio 里拿 wav 文件,用任意播放器试听。如果觉得情感不到位,把第二列从 Happy 改成 Excited 或 Sad 重新合成,对比听感差异——这就是 EmotiVoice 最核心的玩法:不改模型、不重训,只改提示词就能切换语音情绪。
九、全套报错故障排查
-
报错:docker 启动后访问 8501 无响应,或日志里出现
could not select device driver "" with capabilities: [[gpu]]。 原因分析:宿主机未安装 NVIDIA Container Toolkit,或 Docker 未配置 nvidia runtime。 分步解决方案:按官方 README 给出的 NVIDIA Container Toolkit 指引,在 Linux 上安装nvidia-container-toolkit,sudo systemctl restart docker,再重新docker run。 -
报错:
ModuleNotFoundError: No module named 'jieba'或No module named 'g2p_en'。 原因分析:conda 环境没激活,或依赖漏装。 分步解决方案:先conda activate EmotiVoice;再按官方 Full installation 小节重跑pip install numpy numba scipy transformers soundfile yacs g2p_en jieba pypinyin pypinyin_dict。 -
报错:
nltk相关的Resource averaged_perceptron_tagger_eng not found。 原因分析:NLTK 模型未下载。 分步解决方案:执行官方命令python -m nltk.downloader "averaged_perceptron_tagger_eng"。 -
报错:模型目录不存在,如
FileNotFoundError: prompt_tts_open_source_joint。 原因分析:outputs模型未下载或未放到仓库根目录。 分步解决方案:按官方命令git clone https://www.modelscope.cn/syq163/outputs.git,确认outputs/prompt_tts_open_source_joint路径存在后再运行推理。 -
报错:HuggingFace 拉 SimBERT 模型超时。 原因分析:国内网络访问 HF 不稳定。 分步解决方案:改用官方提供的 ModelScope 替代命令
git clone https://www.modelscope.cn/syq163/WangZeJun.git,或设置HF_ENDPOINT=https://hf-mirror.com后重试。 -
报错:合成出的音频是噪音或英文读中文。 原因分析:推理文本第三列音素格式不对,直接手写了中文导致解析错位。 分步解决方案:不要手写音素,先用
python frontend.py data/my_text.txt > data/my_text_for_tts.txt自动生成四列格式文本,再喂给推理脚本。
十、升级、回滚与卸载
升级:Docker 方式执行官方命令 docker pull syq163/emoti-voice:latest,然后删除旧容器重新 docker run(记得同时映射 8501 与 8000 两个端口)。源码方式 git pull 后按 README 重装依赖即可。
备份建议:模型目录(WangZeJun/、outputs/)体积大,建议单独备份到网盘或 ModelScope 私有库;自己写过的推理文本文件 data/my_text_for_tts.txt 记得备份。
回滚:Docker 方式用旧 tag(docker images 查看历史镜像)重新 run;源码方式 git checkout <旧commit>。
卸载:docker rm -f <容器> 并 docker rmi syq163/emoti-voice:latest;源码方式删除 conda 环境 conda env remove -n EmotiVoice、删除项目目录与模型目录。
十一、商用许可与合规风险提示
代码协议为 Apache-2.0,允许商用、修改、分发,只需保留 LICENSE 与版权声明。但官方同时在仓库根目录附了一份《易魔声用户协议》(EmotiVoice_UserAgreement_易魔声用户协议.pdf),交互式页面的使用须遵守该协议;模型权重基于 LibriTTS、HiFiTTS 等公开数据集训练,商用前建议自行核对各数据集条款。此外,官方提供的音色库为预置音色,若用于对外发布的商业产品,建议关注网易有道官方对音色使用的进一步说明。本教程不构成法律意见。
参考链接
- GitHub 仓库:https://github.com/netease-youdao/EmotiVoice
- Wiki 文档:https://github.com/netease-youdao/EmotiVoice/wiki
- 官方 Demo:https://replicate.com/bramhooimeijer/emotivoice
- 模型下载(ModelScope):https://www.modelscope.cn/syq163/outputs