admin管理员组

文章数量:1036092

肝了4天,我用ChatTTS和LLM让deeplearning.ai课程说上流畅中文

我们都知道外网上有很多优秀的视频教程平台,比如 Coursera 和 deeplearning.ai。尤其是后者,由吴恩达老师与OpenAI、Langchain、LlamaIndex、AutoGen等公司和作者合作,推出了一系列广受好评的LLM教程,如Prompt Engineering、Langchain教程、LlamaIndex教程和AutoGen教程。deeplearning.ai 的课程紧跟时下热点,是大语言模型爱好者和从业者不可或缺的资源。然而,deepleaning.ai 的课程通常没有中文字幕,这无疑提高了学习的门槛。即使有些同学坚持学习,也可能因为语言障碍只能学到皮毛。我肝了4天,我成功地让这些课程说上流畅地道的普通话。话不多说,让我们直接看看效果视频。

.f10002.mp4?

下面我将详细介绍实现的过程。本文以 deeplearning.ai 上的 ChatGPT Prompt Engineering for Developers[1] 课程为例,通过下载视频和字幕、使用LLama3和反思策略翻译字幕、然后使用 ChatTTS 将字幕转换为流畅的普通话,最终通过 FFmpeg 将字幕、音频和视频合并在一起。你或许会有疑问为什么我的TTS说话如此流畅,音色如此统一?且听我娓娓道来。如何下载视频和字幕文件不在本文讨论范围,本文仅作为教育用途。

注:本文中有很多关于字幕处理和音视频处理的库都是与GPT交互得知,我本人对字幕和音视频处理并不是很了解~,如果其中对于音视频处理有疑问的地方,还望指出,感谢~ 再注:翻译部分参考了吴恩达老师的translate_agent,对于Prompt部分有所修改以便更符合字幕翻译。

1. ChatTTS

ChatTTS最近开源后引起了广泛关注,相信大家已经有所耳闻。我在周末简单学习了一下,发现其使用非常简单。你可以先去官网chattts[2]体验一下生成的语音,非常自然和流畅,可以说非常丝滑自然了。

按照官方ChatTTS[3]安装,注意你可能需要使用conda或者venv提前建立虚拟环境,此处按下不表。

代码语言:javascript代码运行次数:0运行复制
pip install git+

如果希望使用WebUI,可以按照官方说明文档启用python examples/web/webui.py。这里介绍的是如何通过编程方式使用ChatTTS。首先,我们导入必要的库并初始化 ChatTTS 实例,然后加载模型,并使用 ChatTTS 将文本转换为语音,最后保存生成的音频文件。

代码语言:javascript代码运行次数:0运行复制
import ChatTTS
import torch
import torchaudio

chat = ChatTTS.Chat()
chat.load(compile=False) # Set to True for better performance
texts = ["你好,这里是公众号深入LLM Agent应用开发,感谢你的收听与关注"]
wavs = chat.infer(texts)

torchaudio.save("output1.wav", torch.from_numpy(wavs[0]), 24000)

注意:不要使用官网的教程,API已经落后无法运行了,以github官方repo为准。

生成的语音非常流畅,可以听听看。

但是我的Apple M1使用torchaudio.save会报错,如下所示。

经过与ChatGPT的一番交流,终于解决了运行错误,得到了可运行的numpy_array_to_mp3函数,可以将numpy数组转换成mp3,需要安装pydub。

代码语言:javascript代码运行次数:0运行复制
def numpy_array_to_mp3(numpy_array, output_file):
    # 将 numpy 数组规范化到 [-1, 1] 范围
    numpy_array = np.clip(numpy_array, -1, 1)
    numpy_array = (numpy_array * 32767).astype(np.int16)
# 将 numpy 数组转换为 int16 类型的 WAV 格式字节流
    byte_stream = numpy_array.tobytes()
# 创建一个新的 AudioSegment 对象
    audio_segment = AudioSegment(
        data=byte_stream,
        sample_width=2,
        frame_rate=24000,
        channels=1
    )
# 将 AudioSegment 对象保存为 MP3 文件
    audio_segment.export(output_file, format="mp3")

新的运行代码如下:

代码语言:javascript代码运行次数:0运行复制
    mp3_filename = "output_audio1.mp3"
    num_array_to_mp3(wavs[0], mp3_filename)

如果你亲自尝试,你会发现为什么我的音色不固定啊,我这一长串句子怎么一会这个人一会儿那个人,甚至是一会儿语气大一会儿语气小。音色就像抽卡一样,好在已经有大神对音色评测并开源HuggingFace[4],如下图所示。你可以根据需要过滤音色,选择合适的seed_id进行试听,如果满意,可以下载pt文件来固定音色。

根据我个人测试,seed_1332发音语气平稳、中英文穿插也能很好的合成,在长句合成上也未见到音色切换,推荐大家使用。上面那段欢迎公众号的音频就是来自seed_1332。但是现在新发布的ChatTTS已经不支持直接采用pt权重文件固定音色了,如何办呢?

我在issue中看到有人提到这个PR,再次经过与GPT一番友好交流并修修改改后,得到如下函数compress_and_encode。要说的是这里b14是pybase16384包,而不是base64。而我在将PR中修改给到GPT时,GPT多次生成成的代码都是b14,导致一直报错。

代码语言:javascript代码运行次数:0运行复制
def compress_and_encode(tensor):
    np_array = tensor.numpy().astype(np.float16)
    compressed = lzmapress(np_array.tobytes(), format=lzma.FORMAT_RAW, filters=[{"id": lzma.FILTER_LZMA2, "preset": 9 | lzma.PRESET_EXTREME}])
    encoded = b14.encode_to_string(compressed)
    return encoded

所以在下载好音色之后,我们就可以通过如下方式加载pt文件来固定音色。

代码语言:javascript代码运行次数:0运行复制
spk = torch.load("asset/seed_1332_restored_emb.pt", map_location=torch.device('cpu')).detach()
spk_emb_str = compress_and_encode(spk)
print(spk_emb_str)  # save it for later timbre recovery

params_infer_code = ChatTTS.Chat.InferCodeParams(
    spk_emb=spk_emb_str,  # add sampled speaker
    temperature=.0003,  # using custom temperature
    top_P=0.7,  # top P decode
    top_K=20,  # top K decode
)

text = "你好,这里是公众号深入LLM Agent应用开发,感谢你的收听与关注"
wavs = chat.infer([text], use_decoder=True, params_infer_code=params_infer_code)

这就是ChatTTS的基本使用和音色固定。接下来,我们看看如何使用LLM翻译字幕。

2. 翻译字幕文件

我原本采用的是通义千问大模型,只是在6月29号免费的Token到期了。幸运的是,我还可以使用Groq提供的免费Llama3模型。(希望阿里云能再给我几百万免费的Token就好了

肝了4天,我用ChatTTS和LLM让deeplearning.ai课程说上流畅中文

我们都知道外网上有很多优秀的视频教程平台,比如 Coursera 和 deeplearning.ai。尤其是后者,由吴恩达老师与OpenAI、Langchain、LlamaIndex、AutoGen等公司和作者合作,推出了一系列广受好评的LLM教程,如Prompt Engineering、Langchain教程、LlamaIndex教程和AutoGen教程。deeplearning.ai 的课程紧跟时下热点,是大语言模型爱好者和从业者不可或缺的资源。然而,deepleaning.ai 的课程通常没有中文字幕,这无疑提高了学习的门槛。即使有些同学坚持学习,也可能因为语言障碍只能学到皮毛。我肝了4天,我成功地让这些课程说上流畅地道的普通话。话不多说,让我们直接看看效果视频。

.f10002.mp4?

下面我将详细介绍实现的过程。本文以 deeplearning.ai 上的 ChatGPT Prompt Engineering for Developers[1] 课程为例,通过下载视频和字幕、使用LLama3和反思策略翻译字幕、然后使用 ChatTTS 将字幕转换为流畅的普通话,最终通过 FFmpeg 将字幕、音频和视频合并在一起。你或许会有疑问为什么我的TTS说话如此流畅,音色如此统一?且听我娓娓道来。如何下载视频和字幕文件不在本文讨论范围,本文仅作为教育用途。

注:本文中有很多关于字幕处理和音视频处理的库都是与GPT交互得知,我本人对字幕和音视频处理并不是很了解~,如果其中对于音视频处理有疑问的地方,还望指出,感谢~ 再注:翻译部分参考了吴恩达老师的translate_agent,对于Prompt部分有所修改以便更符合字幕翻译。

1. ChatTTS

ChatTTS最近开源后引起了广泛关注,相信大家已经有所耳闻。我在周末简单学习了一下,发现其使用非常简单。你可以先去官网chattts[2]体验一下生成的语音,非常自然和流畅,可以说非常丝滑自然了。

按照官方ChatTTS[3]安装,注意你可能需要使用conda或者venv提前建立虚拟环境,此处按下不表。

代码语言:javascript代码运行次数:0运行复制
pip install git+

如果希望使用WebUI,可以按照官方说明文档启用python examples/web/webui.py。这里介绍的是如何通过编程方式使用ChatTTS。首先,我们导入必要的库并初始化 ChatTTS 实例,然后加载模型,并使用 ChatTTS 将文本转换为语音,最后保存生成的音频文件。

代码语言:javascript代码运行次数:0运行复制
import ChatTTS
import torch
import torchaudio

chat = ChatTTS.Chat()
chat.load(compile=False) # Set to True for better performance
texts = ["你好,这里是公众号深入LLM Agent应用开发,感谢你的收听与关注"]
wavs = chat.infer(texts)

torchaudio.save("output1.wav", torch.from_numpy(wavs[0]), 24000)

注意:不要使用官网的教程,API已经落后无法运行了,以github官方repo为准。

生成的语音非常流畅,可以听听看。

但是我的Apple M1使用torchaudio.save会报错,如下所示。

经过与ChatGPT的一番交流,终于解决了运行错误,得到了可运行的numpy_array_to_mp3函数,可以将numpy数组转换成mp3,需要安装pydub。

代码语言:javascript代码运行次数:0运行复制
def numpy_array_to_mp3(numpy_array, output_file):
    # 将 numpy 数组规范化到 [-1, 1] 范围
    numpy_array = np.clip(numpy_array, -1, 1)
    numpy_array = (numpy_array * 32767).astype(np.int16)
# 将 numpy 数组转换为 int16 类型的 WAV 格式字节流
    byte_stream = numpy_array.tobytes()
# 创建一个新的 AudioSegment 对象
    audio_segment = AudioSegment(
        data=byte_stream,
        sample_width=2,
        frame_rate=24000,
        channels=1
    )
# 将 AudioSegment 对象保存为 MP3 文件
    audio_segment.export(output_file, format="mp3")

新的运行代码如下:

代码语言:javascript代码运行次数:0运行复制
    mp3_filename = "output_audio1.mp3"
    num_array_to_mp3(wavs[0], mp3_filename)

如果你亲自尝试,你会发现为什么我的音色不固定啊,我这一长串句子怎么一会这个人一会儿那个人,甚至是一会儿语气大一会儿语气小。音色就像抽卡一样,好在已经有大神对音色评测并开源HuggingFace[4],如下图所示。你可以根据需要过滤音色,选择合适的seed_id进行试听,如果满意,可以下载pt文件来固定音色。

根据我个人测试,seed_1332发音语气平稳、中英文穿插也能很好的合成,在长句合成上也未见到音色切换,推荐大家使用。上面那段欢迎公众号的音频就是来自seed_1332。但是现在新发布的ChatTTS已经不支持直接采用pt权重文件固定音色了,如何办呢?

我在issue中看到有人提到这个PR,再次经过与GPT一番友好交流并修修改改后,得到如下函数compress_and_encode。要说的是这里b14是pybase16384包,而不是base64。而我在将PR中修改给到GPT时,GPT多次生成成的代码都是b14,导致一直报错。

代码语言:javascript代码运行次数:0运行复制
def compress_and_encode(tensor):
    np_array = tensor.numpy().astype(np.float16)
    compressed = lzmapress(np_array.tobytes(), format=lzma.FORMAT_RAW, filters=[{"id": lzma.FILTER_LZMA2, "preset": 9 | lzma.PRESET_EXTREME}])
    encoded = b14.encode_to_string(compressed)
    return encoded

所以在下载好音色之后,我们就可以通过如下方式加载pt文件来固定音色。

代码语言:javascript代码运行次数:0运行复制
spk = torch.load("asset/seed_1332_restored_emb.pt", map_location=torch.device('cpu')).detach()
spk_emb_str = compress_and_encode(spk)
print(spk_emb_str)  # save it for later timbre recovery

params_infer_code = ChatTTS.Chat.InferCodeParams(
    spk_emb=spk_emb_str,  # add sampled speaker
    temperature=.0003,  # using custom temperature
    top_P=0.7,  # top P decode
    top_K=20,  # top K decode
)

text = "你好,这里是公众号深入LLM Agent应用开发,感谢你的收听与关注"
wavs = chat.infer([text], use_decoder=True, params_infer_code=params_infer_code)

这就是ChatTTS的基本使用和音色固定。接下来,我们看看如何使用LLM翻译字幕。

2. 翻译字幕文件

我原本采用的是通义千问大模型,只是在6月29号免费的Token到期了。幸运的是,我还可以使用Groq提供的免费Llama3模型。(希望阿里云能再给我几百万免费的Token就好了

本文标签: 肝了4天,我用ChatTTS和LLM让deeplearningai课程说上流畅中文