CosyVoice是阿里开源的一个多语言语音生成大模型,可应用于TTS(Text To Speech) 工具的开发。它支持内置预制语音生成、语音克隆、自然语言控制语音生成等功能。CosyVoice的另一个亮点在于它对生成语音情感和韵律的精细控制,这是通过富文本或自然语言输入实现的。这种控制机制显著提高了合成语音的情感表达能力,使得生成的语音更加栩栩如生,充满情感色彩。这个系统支持中文、英文、日文、粤语和韩语五种语言的语音生成,并且在语音合成的效果上远超传统模型。
Github仓库地址:https://github.com/FunAudioLLM/CosyVoice
无硬性要求,普通个人电脑也可以运行,不过推理耗时较长,只能用作尝鲜体验。如果机器有NVIDIA GPU,可以用NVIDIA CUDA加速。本文部署的机器使用GPUMart的RTX A4000 VPS,其GPU为NVIDIA RTX A4000,其显存为16GB。
首先克隆官方项目,创建一套独立的Python虚拟环境。
#因为项目内部引用了Matcha-TTS项目,所以记得使用--recursive参数 git clone --recursive https://github.com/FunAudioLLM/CosyVoice.git #创建Python 3.8+环境并激活 conda create -n cosyvoice python=3.8 conda activate cosyvoice
此时已经激活了虚拟环境,现在下载项目依赖的第三方包。
#在具有美国IP的GPUMart服务器上 pip install -r requirements.txt #如果服务器在国内 pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com
Pynini是一个基于字符串的传播和转换的库,可以用于各种自然语言处理任务,如词性标注、名词短语提取和依赖句法分析。
conda install -y -c conda-forge pynini==2.1.5
根据文档要提前下载模型,这里不使用阿里的魔搭包下载,而是使用Git下载,前提是安装git lfs 插件:
# git模型下载,请确保已安装git lfs mkdir -p pretrained_models git clone https://www.modelscope.cn/iic/CosyVoice-300M.git pretrained_models/CosyVoice-300M git clone https://www.modelscope.cn/iic/CosyVoice-300M-SFT.git pretrained_models/CosyVoice-300M-SFT git clone https://www.modelscope.cn/iic/CosyVoice-300M-Instruct.git pretrained_models/CosyVoice-300M-Instruct
可选的,您可以下载、解压 ttsfrd 资源并安装 ttsfrd 包以获得更好的文本规范化性能。请注意,此步骤不是必需的。如果您不安装 ttsfrd 包,我们将默认使用 WeTextProcessing。
git clone https://www.modelscope.cn/iic/CosyVoice-ttsfrd.git pretrained_models/CosyVoice-ttsfrd cd pretrained_models/CosyVoice-ttsfrd/ unzip resource.zip -d . pip install ttsfrd-0.3.6-cp38-cp38-linux_x86_64.whl
模型文件非常大,又需要等待较长时间才能下载完成。完成后,使用以下命令启动服务:
python3 webui.py --port 50000 --model_dir pretrained_models/CosyVoice-300M
有个要注意的地方,如果需要从外网访问,需要把webui.py文件中
demo.launch(server_port=args.port)
改成
demo.launch(server_port=args.port, server_name="0.0.0.0")
如果是本机访问可以忽略。这在最新的版本里不存在,默认是支持外网访问的。这时访问局域网IP加端口号50000就能访问到这个由gradio库搭建的WebUI 网页应用了。
以语音克隆为例,第一步上传原素材的音频文件(可能需要处理以使效果更好),第二步输入原素材的音频文件对应的字幕,第三步输入想要的生成的语音的文案,最后一步点击生成,耐心等待。
在使用语音克隆功能时,除了提供文本,还需要提供一段示范性的语音样本,用于大模型模仿音色、语调、朗读习惯等。语音样本的质量对最终生成效果影响非常大。对于输入的样本语音,同样可以做一些前置处理。例如长度截取(官方建议语音样本在3-10s,过长需要耗费更多的推理性能)、降噪处理等。
如果需要基于模型做应用开发,或者调整更多细节参数,就需要对模型提供的API进行封装和二次开发。对于零样本/跨语言推理,请使用CosyVoice-300M模型。对于 sft 推理,请使用CosyVoice-300M-SFT模型。对于指令推理,请使用CosyVoice-300M-Instruct模型。首先,添加third_party/Matcha-TTS到您的PYTHONPATH。
export PYTHONPATH=third_party/Matcha-TTS
from cosyvoice.cli.cosyvoice import CosyVoice from cosyvoice.utils.file_utils import load_wav import torchaudio cosyvoice = CosyVoice('pretrained_models/CosyVoice-300M-SFT') # sft usage print(cosyvoice.list_avaliable_spks()) # change stream=True for chunk stream inference for i, j in enumerate(cosyvoice.inference_sft('你好,我是通义生成式语音大模型,请问有什么可以帮您的吗?', '中文女', stream=False)): torchaudio.save('sft_{}.wav'.format(i), j['tts_speech'], 22050) cosyvoice = CosyVoice('pretrained_models/CosyVoice-300M') # zero_shot usage, <|zh|><|en|><|jp|><|yue|><|ko|> for Chinese/English/Japanese/Cantonese/Korean prompt_speech_16k = load_wav('zero_shot_prompt.wav', 16000) for i, j in enumerate(cosyvoice.inference_zero_shot('收到好友从远方寄来的生日礼物,那份意外的惊喜与深深的祝福让我心中充满了甜蜜的快乐,笑容如花儿般绽放。', '希望你以后能够做的比我还好呦。', prompt_speech_16k, stream=False)): torchaudio.save('zero_shot_{}.wav'.format(i), j['tts_speech'], 22050) # cross_lingual usage prompt_speech_16k = load_wav('cross_lingual_prompt.wav', 16000) for i, j in enumerate(cosyvoice.inference_cross_lingual('<|en|>And then later on, fully acquiring that company. So keeping management in line, interest in line with the asset that\'s coming into the family is a reason why sometimes we don\'t buy the whole thing.', prompt_speech_16k, stream=False)): torchaudio.save('cross_lingual_{}.wav'.format(i), j['tts_speech'], 22050) cosyvoice = CosyVoice('pretrained_models/CosyVoice-300M-Instruct') # instruct usage, support[laughter][breath] for i, j in enumerate(cosyvoice.inference_instruct('在面对挑战时,他展现了非凡的勇气与智慧。', '中文男', 'Theo \'Crimson\', is a fiery, passionate rebel leader. Fights with fervor for justice, but struggles with impulsiveness.', stream=False)): torchaudio.save('instruct_{}.wav'.format(i), j['tts_speech'], 22050)