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()
    
Logo

免费领 200 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐