MaskGCT,AI语音克隆大模型本地部署(Windows11),基于Python3.11,TTS,文字转语音

在这里插入图片描述

前几天,又一款非自回归的文字转语音的AI模型:MaskGCT,开放了源码,和同样非自回归的F5-TTS模型一样,MaskGCT模型也是基于10万小时数据集Emilia训练而来的,精通中英日韩法德6种语言的跨语种合成。数据集Emilia是全球最大且最为多样的高质量多语种语音数据集之一。

本次分享一下如何在本地部署MaskGCT项目,让您的显卡再次发烧。

安装基础依赖

首先确保本地已经安装好Python3.11环境,安装包可以去Python的官方下载:

python.org

随后克隆官方项目:

git clone https://github.com/open-mmlab/Amphion.git

官方提供了基于linux的安装shell脚本:

pip install setuptools ruamel.yaml tqdm   
pip install tensorboard tensorboardX torch==2.0.1  
pip install transformers===4.41.1  
pip install -U encodec  
pip install black==24.1.1  
pip install oss2  
sudo apt-get install espeak-ng  
pip install phonemizer  
pip install g2p_en  
pip install accelerate==0.31.0  
pip install funasr zhconv zhon modelscope  
# pip install git+https://github.com/lhotse-speech/lhotse  
pip install timm  
pip install jieba cn2an  
pip install unidecode  
pip install -U cos-python-sdk-v5  
pip install pypinyin  
pip install jiwer  
pip install omegaconf  
pip install pyworld  
pip install py3langid==0.2.2 LangSegment  
pip install onnxruntime  
pip install pyopenjtalk  
pip install pykakasi  
pip install -U openai-whisper

这里笔者为大家转换为适合Windows的requirements.txt依赖文件:

setuptools   
ruamel.yaml   
tqdm   
transformers===4.41.1  
encodec  
black==24.1.1  
oss2  
phonemizer  
g2p_en  
accelerate==0.31.0  
funasr   
zhconv   
zhon   
modelscope  
timm  
jieba   
cn2an  
unidecode  
cos-python-sdk-v5  
pypinyin  
jiwer  
omegaconf  
pyworld  
py3langid==0.2.2  
LangSegment  
onnxruntime  
pyopenjtalk  
pykakasi  
openai-whisper  
json5

运行命令:

pip3 install -r requirements.txt

安装依赖即可。

安装onnxruntime-gpu:

pip3 install onnxruntime-gpu

安装torch三件套:

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 

Windows配置espeak-ng

由于MaskGCT项目后端依赖espeak软件,所以需要在本地进行配置,eSpeak 是一个紧凑的开源文本转语音 (TTS) 合成器,支持多种语言和口音 。它使用“共振峰合成”方法,允许以较小的体积提供多种语言 。语音清晰,可以高速使用,但不如基于人类语音录音的较大合成器自然流畅,而MaskGCT就是在espeak的合成基础上进行二次推理。

首先运行命令安装espeak:

winget install espeak

如果装不上,也可以下载安装包手动安装:

https://sourceforge.net/projects/espeak/files/espeak/espeak-1.48/setup_espeak-1.48.04.exe/download

随后下载espeak-ng安装包:

https://github.com/espeak-ng/espeak-ng/releases

下载后双击安装。

接着把 C:\Program Files\eSpeak NG\libespeak-ng.dll 拷贝到 C:\Program Files (x86)\eSpeak\command_line 目录。

然后把 libespeak-ng.dll 重命名为 espeak-ng.dll

最后把 C:\Program Files (x86)\eSpeak\command_line 目录配置到环境变量即可。

MaskGCT本地推理

都配置好之后,编写推理脚本 local_test.py:

from models.tts.maskgct.maskgct_utils import *  
from huggingface_hub import hf_hub_download  
import safetensors  
import soundfile as sf  
import os  
import argparse  
os.environ['HF_HOME'] = os.path.join(os.path.dirname(__file__), 'hf_download')  
  
print(os.path.join(os.path.dirname(__file__), 'hf_download'))  
  
parser = argparse.ArgumentParser(description="GPT-SoVITS api")  
parser.add_argument("-p", "--prompt_text", type=str, default="说得好像您带我以来我考好过几次一样")  
parser.add_argument("-a", "--audio", type=str, default="./说得好像您带我以来我考好过几次一样.wav")  
parser.add_argument("-t", "--text", type=str, default="你好")  
parser.add_argument("-l", "--language", type=str, default="zh")  
parser.add_argument("-lt", "--target_language", type=str, default="zh")  
args = parser.parse_args()  
  
if __name__ == "__main__":  
  
    # download semantic codec ckpt  
    semantic_code_ckpt = hf_hub_download("amphion/MaskGCT", filename="semantic_codec/model.safetensors")  
  
    # download acoustic codec ckpt  
    codec_encoder_ckpt = hf_hub_download("amphion/MaskGCT", filename="acoustic_codec/model.safetensors")  
    codec_decoder_ckpt = hf_hub_download("amphion/MaskGCT", filename="acoustic_codec/model_1.safetensors")  
  
    # download t2s model ckpt  
    t2s_model_ckpt = hf_hub_download("amphion/MaskGCT", filename="t2s_model/model.safetensors")  
  
    # download s2a model ckpt  
    s2a_1layer_ckpt = hf_hub_download("amphion/MaskGCT", filename="s2a_model/s2a_model_1layer/model.safetensors")  
    s2a_full_ckpt = hf_hub_download("amphion/MaskGCT", filename="s2a_model/s2a_model_full/model.safetensors")  
  
    # build model  
    device = torch.device("cuda")  
    cfg_path = "./models/tts/maskgct/config/maskgct.json"  
    cfg = load_config(cfg_path)  
    # 1. build semantic model (w2v-bert-2.0)  
    semantic_model, semantic_mean, semantic_std = build_semantic_model(device)  
    # 2. build semantic codec  
    semantic_codec = build_semantic_codec(cfg.model.semantic_codec, device)  
    # 3. build acoustic codec  
    codec_encoder, codec_decoder = build_acoustic_codec(cfg.model.acoustic_codec, device)  
    # 4. build t2s model  
    t2s_model = build_t2s_model(cfg.model.t2s_model, device)  
    # 5. build s2a model  
    s2a_model_1layer = build_s2a_model(cfg.model.s2a_model.s2a_1layer, device)  
    s2a_model_full =  build_s2a_model(cfg.model.s2a_model.s2a_full, device)  
  
  
    # load semantic codec  
    safetensors.torch.load_model(semantic_codec, semantic_code_ckpt)  
    # load acoustic codec  
    safetensors.torch.load_model(codec_encoder, codec_encoder_ckpt)  
    safetensors.torch.load_model(codec_decoder, codec_decoder_ckpt)  
    # load t2s model  
    safetensors.torch.load_model(t2s_model, t2s_model_ckpt)  
    # load s2a model  
    safetensors.torch.load_model(s2a_model_1layer, s2a_1layer_ckpt)  
    safetensors.torch.load_model(s2a_model_full, s2a_full_ckpt)  
  
    # inference  
    prompt_wav_path = args.audio  
    save_path = "output.wav"  
    prompt_text = args.prompt_text  
    target_text = args.text  
    # Specify the target duration (in seconds). If target_len = None, we use a simple rule to predict the target duration.  
    target_len = None  
  
    maskgct_inference_pipeline = MaskGCT_Inference_Pipeline(  
        semantic_model,  
        semantic_codec,  
        codec_encoder,  
        codec_decoder,  
        t2s_model,  
        s2a_model_1layer,  
        s2a_model_full,  
        semantic_mean,  
        semantic_std,  
        device,  
    )  
  
    recovered_audio = maskgct_inference_pipeline.maskgct_inference(  
        prompt_wav_path, prompt_text, target_text,args.language,args.target_language, target_len=target_len  
    )  
    sf.write(save_path, recovered_audio, 24000)

首次推理会在hf_download目录下载10个G的模型。

推理过程中,会占用11G的显存:

如果您的显存低于11G,那么务必打开Nvidia控制面板的系统内存回退策略,通过系统内存来补足显存:

如果愿意,也可以基于gradio写一个简单的webui界面,app.py:

import os  
import gc  
import re  
import gradio as gr  
import numpy as np  
import subprocess  
os.environ['HF_HOME'] = os.path.join(os.path.dirname(__file__), 'hf_download')  
# 设置HF_ENDPOINT环境变量  
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"  
  
  
  
reference_wavs = ["请选择参考音频或者自己上传"]  
for name in os.listdir("./参考音频/"):  
    reference_wavs.append(name)  
  
def change_choices():  
  
    reference_wavs = ["请选择参考音频或者自己上传"]  
  
    for name in os.listdir("./参考音频/"):  
        reference_wavs.append(name)  
      
    return {"choices":reference_wavs, "__type__": "update"}  
  
  
def change_wav(audio_path):  
  
    text = audio_path.replace(".wav","").replace(".mp3","").replace(".WAV","")  
  
    # text = replace_speaker(text)  
  
    return f"./参考音频/{audio_path}",text  
  
  
def do_cloth(gen_text_input,ref_audio_input,model_choice_text,model_choice_re,ref_text_input):  
  
    cmd = fr'.\py311_cu118\python.exe local_test.py -t "{gen_text_input}" -p "{ref_text_input}" -a "{ref_audio_input}" -l {model_choice_re} -lt {model_choice_text} '  
  
    print(cmd)  
    res = subprocess.Popen(cmd)  
    res.wait()  
      
    return "output.wav"  
  
  
  
with gr.Blocks() as app_demo:  
    gr.Markdown(  
        """  
项目地址:https://github.com/open-mmlab/Amphion/tree/main/models/tts/maskgct  
  
整合包制作:刘悦的技术博客 https://space.bilibili.com/3031494  
"""  
    )  
    gen_text_input = gr.Textbox(label="生成文本", lines=4)  
    model_choice_text = gr.Radio(  
        choices=["zh", "en"], label="生成文本语种", value="zh",interactive=True)  
    wavs_dropdown = gr.Dropdown(label="参考音频列表",choices=reference_wavs,value="选择参考音频或者自己上传",interactive=True)  
    refresh_button = gr.Button("刷新参考音频")  
    refresh_button.click(fn=change_choices, inputs=[], outputs=[wavs_dropdown])  
    ref_audio_input = gr.Audio(label="Reference Audio", type="filepath")  
    ref_text_input = gr.Textbox(  
        label="Reference Text",  
        info="Leave blank to automatically transcribe the reference audio. If you enter text it will override automatic transcription.",  
        lines=2,  
    )  
    model_choice_re = gr.Radio(  
        choices=["zh", "en"], label="参考音频语种", value="zh",interactive=True  
    )  
    wavs_dropdown.change(change_wav,[wavs_dropdown],[ref_audio_input,ref_text_input])  
    generate_btn = gr.Button("Synthesize", variant="primary")  
  
      
    audio_output = gr.Audio(label="Synthesized Audio")  
  
    generate_btn.click(do_cloth,[gen_text_input,ref_audio_input,model_choice_text,model_choice_re,ref_text_input],[audio_output])  
      
def main():  
    global app_demo  
    print(f"Starting app...")  
    app_demo.launch(inbrowser=True)  
  
  
if __name__ == "__main__":  
    main()

当然,别忘了安装gradio依赖:

pip3 install -U gradio

运行效果是这样的:

结语

MaskGCT模型的优势在于语气韵律层面十分突出,可以媲美真实语音,缺点也很明显,运行成本偏高,工程化层面优化不足。MaskGCT项目主页中已经有其商业版本模型的入口,据此推断,官方应该不会在开源版本中太过发力,最后奉上一键整合包,与众乡亲同飨:

MaskGCT一键包整合包 https://pan.quark.cn/s/e74726b84c78
<think>嗯,用户的问题是关于如何将MaskGCT TTS模块应用到基于文本的情感语音合成项目中,需要了解具体的集成方法。首先,我需要回顾一下MaskGCT的基本架构和工作原理,确保自己理解正确。根据引用[1]和[2],MaskGCT是一个两阶段的非自回归模型,首先生成语义token,然后生成声学token,不需要显式的对齐信息或时长预测。这可能在情感合成中具有优势,因为情感通常涉及韵律、音调的变化,而传统方法可能需要复杂的时长预测模块。 接下来,用户想要的是集成方法,所以需要思考如何将情感控制嵌入到MaskGCT的现有流程中。根据引用[4],MaskGCT-T2S负责从文本生成语义token,而MaskGCT-S2A则生成声学token。可能的情感控制点有几个:在文本输入中加入情感标签作为条件,或者在语义token生成阶段引入情感嵌入,或者在声学生成阶段调整参数。 然后,考虑到MaskGCT在训练时使用掩码预测的方式,可能在条件输入中添加情感相关的提示。例如,在训练时,将情感标签作为额外的条件输入,这样模型在生成语义和声学token时会考虑情感因素。引用[1]提到他们探索了情感控制的应用,说明模型本身可能具备这样的扩展能力。 另外,数据准备是关键。用户需要收集带有情感标签的语音数据,或者对现有数据进行情感标注。可能需要微调预训练模型,使用情感标注的数据集,以便模型学习到情感特征。引用[2]提到他们使用了100,000小时的Emilia数据集,但不确定是否包含情感标签。如果用户的数据有限,可能需要迁移学习或使用预训练的声码器结合情感参数。 技术实现步骤可能包括:1)准备情感标注数据集;2)在MaskGCT的条件输入中添加情感嵌入;3)调整模型结构以接受情感参数;4)训练或微调模型;5)合成时指定情感标签。需要确保条件嵌入能够有效影响生成的token,可能需要修改模型的输入层或添加适配层。 同时,要注意MaskGCT的非自回归特性,并行生成可能对情感表达的连贯性有影响。可能需要引入一些后处理或调整生成策略,比如控制生成长度或引入注意力机制来捕捉情感相关的时序特征。 最后,验证方法也很重要。用户需要客观指标(如MOS评分)和主观评估来确保情感合成的效果。引用[1]提到他们在质量、相似性和可懂度方面表现优异,但情感控制的具体评估可能需要额外的工作,比如使用情感分类模型对合成语音进行测试。</think>### 分步解答:基于MaskGCT的情感语音合成实现方法 #### **1. 理解MaskGCT的核心架构** MaskGCT采用两阶段非自回归生成流程: - **第一阶段**:`MaskGCT-T2S`模型将文本换为语义token(从语音SSL模型提取)[^1][^2] - **第二阶段**:`MaskGCT-S2A`模型将语义token换为声学token并重构波形[^4] $$ \text{Text} \xrightarrow{\text{T2S}} \text{Semantic Tokens} \xrightarrow{\text{S2A}} \text{Acoustic Tokens} \xrightarrow{\text{Codec}} \text{Waveform} $$ #### **2. 情感控制的集成策略** **方法一:条件嵌入扩展** - 在文本编码器中添加情感标签嵌入(如happy/angry/sad等) - 修改输入层结构: ```python # 伪代码示例 text_embed = TextEncoder(text_input) emotion_embed = EmotionEmbedding(emotion_label) combined_embed = Concat([text_embed, emotion_embed]) semantic_tokens = T2S(combined_embed) ``` **方法二:提示学习机制** - 利用MaskGCT的掩码预测特性,将情感标签作为提示token: ```python # 输入格式调整示例 input_text = "[HAPPY] 今天天气真好" masked_tokens = mask_random_tokens(semantic_tokens) predicted_tokens = model(masked_tokens, text=input_text) ``` **方法三:声学参数调控** - 在声学token生成阶段引入情感相关声学特征: $$ \text{Acoustic\_tokens} = S2A(\text{Semantic\_tokens}, F_{prosody}) $$ 其中$F_{prosody}$包含基频、能量等韵律特征 #### **3. 实现步骤** **步骤1:数据准备** - 构建带情感标签的语音数据集(建议时长≥50小时/情感) - 使用`Semantic Codec`提取语义token,`Acoustic Codec`提取声学token **步骤2:模型微调** ```python # 基于预训练模型的微调示例 from maskgct import T2S, S2A t2s_model = T2S.from_pretrained("MaskGCT-T2S") s2a_model = S2A.from_pretrained("MaskGCT-S2A") # 添加情感嵌入层 t2s_model.add_embedding_layer(d_emotion=256) # 联合训练流程 for text, emotion, audio in dataset: semantic = t2s_model(text, emotion) acoustic = s2a_model(semantic, emotion) loss = compute_loss(acoustic, target) ``` **步骤3:推理控制** - 通过调节温度参数控制生成多样性: ```python synthesized_audio = pipeline( text="我爱你", emotion="romantic", temperature=0.7, # 控制情感强度 duration_scale=1.2 # 延长发音时长 ) ``` #### **4. 验证方法** - **客观指标**:F0标准差、语速、能量分布 - **主观评估**:MOS(Mean Opinion Score)情感匹配度测试 - **跨情感迁移测试**:验证模型对未见情感的泛化能力 #### **5. 优化建议** - 使用对抗训练提升情感表征解耦能力 - 引入可解释性分析工具(如Grad-CAM)定位情感相关token - 结合语音翻译模块实现跨语言情感合成[^1]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘悦的技术分享

承您打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值