ChatTTS(一款适用于日常对话的生成式语音模型)
1.开发板教程
1.拉取代码 git clone https://github.com/2noise/ChatTTS.git
2.需要安装对应的库和,安装依赖cd ChatTTS (pip install --upgrade -r requirements.txt)( pip install torchaudio==2.3.0+cu121 -f https://download.pytorch.org/whl/torch_stable.html )
import torch
import torchaudio
3.需要下载需要下载https://github.com/fumiama/RVC-Models-Downloader/releases/download/v0.2.6/rvcmd_windows_amd64.zip放到这里
import ChatTTS
import torch
import torchaudio
# 设置音频后端
torchaudio.set_audio_backend("sox_io")
# 初始化 ChatTTS 实例
chat = ChatTTS.Chat()
# 加载模型
chat.load(compile=False) # 设置为 True 以获得更好的性能
# 示例中文文本列表
texts = [
"欢迎使用语音合成系统,我们提供高质量的语音合成服务。",
"今天的天气很好,非常适合户外活动。",
"如果您有任何问题,请随时联系我们的客服团队。",
"祝您工作顺利,生活愉快。"
]
# 推理生成音频
wavs = chat.infer(texts)
# 合并所有音频成一个文件
combined_wav = torch.cat([torch.tensor(wav) for wav in wavs], dim=1)
# 确保合并后的音频张量有正确的维度
if len(combined_wav.shape) == 1:
combined_wav = combined_wav.unsqueeze(0) # 添加通道维度
torchaudio.save("output_combined.wav", combined_wav, 24000)
print("Combined audio saved to: output_combined.wav")
import ChatTTS
import torch
import torchaudio
# 设置音频后端
torchaudio.set_audio_backend("sox_io")
# 初始化 ChatTTS 实例
chat = ChatTTS.Chat()
# 加载模型
chat.load(compile=False) # 设置为 True 以获得更好的性能
# 示例中文文本列表
texts = [
"欢迎使用语音合成系统,我们提供高质量的语音合成服务。",
"今天的天气很好,非常适合户外活动。",
"如果您有任何问题,请随时联系我们的客服团队。",
"祝您工作顺利,生活愉快。"
]
###################################
# 从高斯分布中采样一个说话人
rand_spk = chat.sample_random_speaker()
print(rand_spk) # 保存以供日后使用
# 设置推理代码的参数,包括采样的说话人、温度、top_P和top_K解码
params_infer_code = ChatTTS.Chat.InferCodeParams(
spk_emb = rand_spk, # 添加采样的说话人
temperature = .3, # 使用自定义温度
top_P = 0.7, # top P 解码
top_K = 20, # top K 解码
)
###################################
# 句子级别的手动控制
# 使用 oral_(0-9), laugh_(0-2), break_(0-7)
# 在文本中生成特殊标记进行合成
params_refine_text = ChatTTS.Chat.RefineTextParams(
prompt='[oral_2][laugh_0][break_6]',
)
# 推理生成音频
wavs = chat.infer(
texts,
params_refine_text=params_refine_text,
params_infer_code=params_infer_code,
)
# 保存每个文本生成的音频到单独的文件
for i, wav in enumerate(wavs):
audio_tensor = torch.tensor(wav)
# 确保音频张量有正确的维度
if len(audio_tensor.shape) == 1:
audio_tensor = audio_tensor.unsqueeze(0) # 添加通道维度
output_file = f"output_{i+1}.wav"
torchaudio.save(output_file, audio_tensor, 24000)
print(f"Audio saved to: {output_file}")
###################################
# 单词级别的手动控制
text = 'What is [uv_break]your favorite english food?[laugh][lbreak]'
wavs = chat.infer(text, skip_refine_text=True, params_refine_text=params_refine_text, params_infer_code=params_infer_code)
# 保存生成的音频
audio_tensor = torch.tensor(wavs[0])
if len(audio_tensor.shape) == 1:
audio_tensor = audio_tensor.unsqueeze(0) # 添加通道维度
torchaudio.save("output2.wav", audio_tensor, 24000)
print("Audio saved to: output2.wav")
2.进阶用法
import ChatTTS
import torch
import torchaudio
# 设置音频后端
torchaudio.set_audio_backend("sox_io")
# 初始化 ChatTTS 实例
chat = ChatTTS.Chat()
# 加载模型
chat.load(compile=False) # 设置为 True 以获得更好的性能
# 示例中文文本列表
texts = [
"欢迎使用语音合成系统,我们提供高质量的语音合成服务。",
"今天的天气很好,非常适合户外活动。",
"如果您有任何问题,请随时联系我们的客服团队。",
"祝您工作顺利,生活愉快。"
]
###################################
# 从高斯分布中采样一个说话人
rand_spk = chat.sample_random_speaker()
print(rand_spk) # 保存以供日后使用
# 设置推理代码的参数,包括采样的说话人、温度、top_P和top_K解码
params_infer_code = ChatTTS.Chat.InferCodeParams(
spk_emb = rand_spk, # 添加采样的说话人
temperature = .3, # 使用自定义温度
top_P = 0.7, # top P 解码
top_K = 20, # top K 解码
)
###################################
# 句子级别的手动控制
# 使用 oral_(0-9), laugh_(0-2), break_(0-7)
# 在文本中生成特殊标记进行合成
params_refine_text = ChatTTS.Chat.RefineTextParams(
prompt='[oral_2][laugh_0][break_6]',
)
# 推理生成音频
wavs = chat.infer(
texts,
params_refine_text=params_refine_text,
params_infer_code=params_infer_code,
)
# 保存每个文本生成的音频到单独的文件
for i, wav in enumerate(wavs):
audio_tensor = torch.tensor(wav)
# 确保音频张量有正确的维度
if len(audio_tensor.shape) == 1:
audio_tensor = audio_tensor.unsqueeze(0) # 添加通道维度
output_file = f"output_{i+1}.wav"
torchaudio.save(output_file, audio_tensor, 24000)
print(f"Audio saved to: {output_file}")
###################################
# 单词级别的手动控制
text = 'What is [uv_break]your favorite english food?[laugh][lbreak]'
wavs = chat.infer(text, skip_refine_text=True, params_refine_text=params_refine_text, params_infer_code=params_infer_code)
# 保存生成的音频
audio_tensor = torch.tensor(wavs[0])
if len(audio_tensor.shape) == 1:
audio_tensor = audio_tensor.unsqueeze(0) # 添加通道维度
torchaudio.save("output2.wav", audio_tensor, 24000)
print("Audio saved to: output2.wav")
3.他这个默认转换的就20多秒,如果想要长的就要拼接转换
import os
import torch
import torchaudio
import ChatTTS
from pydub import AudioSegment
def generate_audio(text, chat, params_refine_text, params_infer_code):
wavs = chat.infer(
text,
params_refine_text=params_refine_text,
params_infer_code=params_infer_code,
)
return wavs[0]
def save_audio(wav_data, filename):
torchaudio.save(filename, torch.from_numpy(wav_data), 24000)
def cleanup_files(file_list):
for file in file_list:
if os.path.exists(file):
os.remove(file)
def fade_in_out(audio_segment, duration_ms=500):
“”“对音频段添加渐变效果以平滑过渡”“”
faded_audio = audio_segment.fade_in(duration_ms).fade_out(duration_ms)
return faded_audio
初始化 ChatTTS 实例
chat = ChatTTS.Chat()
chat.load(compile=False)
检查是否存在 rand_spk.pt 文件
if os.path.exists(‘rand_spk.pt’):
rand_spk = torch.load(‘rand_spk.pt’)
print(“Loaded saved speaker embedding:”, rand_spk)
else:
rand_spk = chat.sample_random_speaker()
print(“Sampled new speaker embedding:”, rand_spk)
torch.save(rand_spk, ‘rand_spk.pt’)
设置推理编码参数,只生成一次并在后续调用中复用
params_infer_code = ChatTTS.Chat.InferCodeParams(
spk_emb=rand_spk,
temperature=.3,
top_P=0.7,
top_K=20,
)
对句子级别进行手动控制
params_refine_text = ChatTTS.Chat.RefineTextParams(
prompt=‘[oral_2][laugh_0][break_4]’,
)
输入文本
full_text = ‘在一个宁静的小镇上,住着一位名叫李明的年轻人。他从小就对大自然充满了好奇心,喜欢在周末的时候独自一人去附近的森林探险。李明的父母都是教师,他们希望李明能够继承他们的职业,但李明对大自然的热爱使他选择了生物学作为自己的专业。大学毕业后,李明回到了家乡,成为了一名环境保护志愿者。他每天都在森林里巡逻,记录下各种动植物的生活习性和生存状态。他还组织了一些环保活动,呼吁更多的人加入保护环境的行列。一天,李明在森林深处发现了一片从未有人涉足过的区域,那里有着丰富的生物多样性,让他感到无比兴奋。他决定在这里进行长期的生态研究,以便更好地保护这片宝贵的自然资源。在研究过程中,李明遇到了不少困难,比如天气恶劣、设备故障等,但他从未放弃。他的坚持和努力最终得到了回报,研究成果不仅得到了学术界的认可,还为当地政府制定环境保护政策提供了重要的参考依据。李明的故事感动了很多人,越来越多的志愿者加入了他的团队,一起为保护地球而努力。通过他们的不懈努力,森林里的生态环境得到了明显的改善,许多濒危物种也得到了有效的保护。李明感到无比自豪和欣慰,他相信,只要大家齐心协力,地球的未来一定会更加美好。’
将输入文本分段(每段最大支持200字符)
segments = [full_text[i:i + 150] for i in range(0, len(full_text), 150)]
生成并保存每个段落的音频
audio_segments = []
temp_files = []
for i, segment in enumerate(segments):
try:
wav_data = generate_audio(segment, chat, params_refine_text, params_infer_code)
filename = f’output_segment_{i}.wav’
save_audio(wav_data, filename)
temp_files.append(filename)
audio_segments.append(fade_in_out(AudioSegment.from_wav(filename)))
except Exception as e:
print(f"Error generating or saving audio for segment {i}: {e}")
拼接所有音频段落
combined_audio = AudioSegment.empty()
for i, audio in enumerate(audio_segments):
combined_audio += audio
# 在段落之间添加停顿
if i < len(audio_segments) - 1:
combined_audio += AudioSegment.silent(duration=500)
保存拼接后的音频文件
combined_audio.export(“output_combined.wav”, format=“wav”)
删除临时音频文件
cleanup_files(temp_files)