CosyVoice2支持Nvidia 5090及vLLM加速
·
CosyVoice2支持Nvidia 5090及vLLM加速,以下是具体的支持方法及可能遇到的问题和解决思路:
- 支持Nvidia 5090:
- 核心问题:torch 2.8.0以下版本不支持sm_120架构,而Nvidia 5090采用的是sm_120架构,所以需要安装torch 2.8.0及以上版本。
- 解决方法:可以尝试从PyTorch官方网站下载适合Nvidia 5090和你系统环境的torch 2.8.0及以上版本进行安装。在安装过程中,可能会遇到依赖项不兼容等问题,需要根据具体的错误提示信息,通过更新或安装相应的依赖库来解决。例如,如果提示缺少某个CUDA版本的支持,可能需要安装对应的CUDA Toolkit。
- 典型安装命令:
pip install torch==2.7.1+cu128 torchvision==0.18.1+cu128 torchaudio==2.7.1 --index-url https://download.pytorch.org/whl/cu128
- 支持vLLM加速:
- 安装vllm:可以使用pip install vllm命令来安装vllm。但安装后可能会遇到与CosyVoice2或其他已安装库不兼容的情况。
- 解决方法:如果遇到不兼容问题,可以先查看vllm的官方文档,了解其对环境和依赖库的要求,确保你的环境满足这些要求。同时,也可以查看CosyVoice2的官方文档或相关的开源社区,看是否有关于CosyVoice2与vllm集成的具体说明和解决方案。例如,可能需要调整vllm的一些配置参数,或者对CosyVoice2的代码进行一些修改来使其与vllm更好地兼容。
此外,还有一些其他的优化和注意事项:
- 确保驱动和CUDA版本匹配:要保证Nvidia显卡驱动和CUDA Toolkit的版本相互匹配,并且与torch和vllm都兼容。可以参考Nvidia官方文档来选择合适的驱动和CUDA版本进行安装。
- 模型加载和推理设置:在使用CosyVoice2时,合理设置模型加载和推理的参数,例如是否使用半精度浮点数(fp16)、最大批处理tokens数(max_num_batched_tokens)、最大并发序列数(max_num_seqs)等,这些参数的设置会影响推理的性能和资源占用。可以根据你的Nvidia 5090的显存大小和实际需求来进行调整。
vLLM测试代码
#vllm_test.py
import sys
import os
import wave
import time
import numpy as np
import torch # 新增:导入PyTorch用于张量操作
from datetime import timedelta
sys.path.append('third_party/Matcha-TTS')
from vllm import ModelRegistry
from cosyvoice.vllm.cosyvoice2 import CosyVoice2ForCausalLM
ModelRegistry.register_model("CosyVoice2ForCausalLM", CosyVoice2ForCausalLM)
from cosyvoice.cli.cosyvoice import CosyVoice2
from cosyvoice.utils.file_utils import load_wav
from cosyvoice.utils.common import set_all_random_seed
from tqdm import tqdm
def save_wav(audio_data_tensor, sample_rate, file_path):
"""
将音频张量保存为WAV文件
参数:
audio_data_tensor: 音频数据张量(CPU上的浮点数张量,范围[-1, 1])
sample_rate: 采样率
file_path: 保存路径
"""
# 新增:调试信息 - 打印输入张量的基本信息
tqdm.write(f"调试信息:保存前的张量信息 - 类型: {type(audio_data_tensor)}, 设备: {audio_data_tensor.device}, 形状: {audio_data_tensor.shape}, 数据类型: {audio_data_tensor.dtype}")
# 确保音频张量在CPU上
if audio_data_tensor.is_cuda:
audio_data_tensor = audio_data_tensor.cpu()
tqdm.write(f"调试信息:已将张量从CUDA移至CPU")
# 修复:先将PyTorch张量转换为NumPy数组,再使用astype
try:
audio_data_np = audio_data_tensor.numpy() # 转换为NumPy数组
tqdm.write(f"调试信息:转换为NumPy数组后的形状: {audio_data_np.shape}, 数据类型: {audio_data_np.dtype}")
# 检查数据范围是否在[-1, 1]之间(音频张量的常见范围)
if np.min(audio_data_np) < -1 or np.max(audio_data_np) > 1:
tqdm.write(f"警告:音频数据超出[-1, 1]范围,可能导致失真(最小值: {np.min(audio_data_np)}, 最大值: {np.max(audio_data_np)})")
# 转换为16位整数格式(WAV文件标准)
audio_data_int16 = (audio_data_np * 32767).astype(np.int16)
except Exception as e:
tqdm.write(f"错误:张量转换失败 - {str(e)}")
raise # 抛出异常,终止程序
# 创建输出目录(不存在则自动创建)
os.makedirs(os.path.dirname(file_path), exist_ok=True)
# 写入WAV文件(单声道,16位深度)
with wave.open(file_path, 'wb') as wf:
wf.setnchannels(1) # 单声道
wf.setsampwidth(2) # 16位采样深度
wf.setframerate(sample_rate) # 匹配采样率
wf.writeframes(audio_data_int16.tobytes())
tqdm.write(f"调试信息:WAV文件保存成功 - {file_path}")
def main():
total_start_time = time.time()
# 模型初始化
init_start_time = time.time()
cosyvoice = CosyVoice2(
'iic/CosyVoice2-0.5B',
load_jit=True,
load_trt=False,
load_vllm=True,
fp16=True
)
init_end_time = time.time()
print(f"模型初始化耗时: {init_end_time - init_start_time:.2f}秒")
# 加载提示音频
load_audio_start = time.time()
prompt_speech_16k = load_wav('./asset/zero_shot_prompt.wav', 16000)
load_audio_end = time.time()
print(f"提示音频加载耗时: {load_audio_end - load_audio_start:.2f}秒")
# 新增:调试提示音频的类型和形状
tqdm.write(f"调试信息:提示音频 - 类型: {type(prompt_speech_16k)}, 形状: {prompt_speech_16k.shape if hasattr(prompt_speech_16k, 'shape') else '未知'}")
output_dir = './output_audios'
print(f"音频将保存至: {os.path.abspath(output_dir)}")
iteration_times = []
total_segments = 0
for i in tqdm(range(100), desc="总进度"):
iter_start_time = time.time()
set_all_random_seed(i)
# 调用推理接口
inference_iter = cosyvoice.inference_zero_shot(
tts_text='你好,我是通义千问语音合成大模型,请问有什么可以帮您的吗?',
prompt_text='希望你以后能够做的比我还好呦。',
prompt_speech_16k=prompt_speech_16k,
stream=False
)
segment_count = 0
for idx, audio_dict in enumerate(inference_iter):
# 新增:调试音频字典的结构
tqdm.write(f"调试信息:第{i+1}轮-第{idx+1}段 - 音频字典键值: {audio_dict.keys()}")
# 提取音频张量
tts_speech_tensor = audio_dict['tts_speech'].squeeze()
# 生成保存路径
save_path = f"{output_dir}/output_round_{i}_segment_{idx}.wav"
# 保存为WAV文件(使用22050采样率)
save_wav(tts_speech_tensor, 22050, save_path)
segment_count += 1
total_segments += 1
tqdm.write(f"第{i+1}轮-第{idx+1}段:已保存至 {save_path}")
iter_end_time = time.time()
iter_duration = iter_end_time - iter_start_time
iteration_times.append(iter_duration)
tqdm.write(f"第{i+1}轮完成,耗时: {iter_duration:.2f}秒, 本轮生成{segment_count}段音频, 累计{total_segments}段")
total_end_time = time.time()
total_duration = total_end_time - total_start_time
print("\n===== 总统计信息 =====")
print(f"总耗时: {str(timedelta(seconds=int(total_duration)))}")
print(f"平均每轮耗时: {np.mean(iteration_times):.2f}秒")
print(f"最快轮次耗时: {np.min(iteration_times):.2f}秒")
print(f"最慢轮次耗时: {np.max(iteration_times):.2f}秒")
print(f"总生成音频段数: {total_segments}段")
print(f"平均每段音频耗时: {total_duration / total_segments:.2f}秒")
if __name__ == '__main__':
main()
更多推荐


所有评论(0)