首先可以看看cosyvoice模型关于克隆音色的代码分析,要注意里面的参数都有啥 zeroshot貌似必须克隆的音色和提示词?和音频中的保持一致 然后那个instruct2?应该是 必须是要有提示词才行,我一般都写成 请以自然语调说这句话

#sys 用于操作python解释器运行环境时 os 提供操作系统接口 glob 用于文件路径通配符匹配 path面向对象的路径操作工具 

glob.glob("*.wav") 类似这样的

import sys
import os
import glob
from pathlib import Path

#sys.path.append 将tired_party/Matcha-TTS目录加入python模块搜索路径,让python能找到该目录下的模块 Matcha-TTs是一个开源tts框架 这是实现cosyvoice的子模块 (我没细看也没修改这部分代码,直接是看输出Log中有下载这个东西的部分)

sys.path.append('third_party/Matcha-TTS')

#CosyVoice2 是语音合成推理接口类,支持文本/音色输入 用于生成语音(下一篇分析一下这个类)

from cosyvoice.cli.cosyvoice import CosyVoice2

#load_wav是CosyVoice自带的音频加载工具函数,用于读取.wav文件并返回音频张量

返回音频张量
from cosyvoice.utils.file_utils import load_wav

#torchaudio是Pytorch官方的音频处理库。通常用于加载/保存音频文件,音频变换
import torchaudio

#我要加载的文件有点多,然后我很懒,懒得弄Bash文件,所以直接命令行输入txt 和要克隆的音色音频文件 和输出 和指定的模型 也就是我已经下载好的模型

# =================== 配置 ===================
TEXT_FILE = "outputastronomy.txt"          # 你的输入文本文件路径
ASSET_DIR = "asset"                        # 存放参考音频的目录(.wav 文件)
OUTPUT_DIR = "asrtronomyoutputs"                     # 输出目录
MODEL_PATH = "pretrained_models/CosyVoice2-0.5B"

# ============================================

# 初始化模型(保持不变)
cosyvoice = CosyVoice2(
    MODEL_PATH,
    load_jit=False,

#tensorrt加速
    load_trt=False,

#vllm加速
    load_vllm=False,

#启用半精度推理
    fp16=False
)

# 读取所有参考音频(只取 .wav 文件)asset_dir存放参考音频的目录路径 拼接路径,glob.glob返回所有匹配通配符的文件路径列表.wav
prompt_audio_paths = sorted(glob.glob(os.path.join(ASSET_DIR, "*.wav")))
if not prompt_audio_paths:
    raise FileNotFoundError(f"在 {ASSET_DIR} 目录下未找到任何 .wav 音频文件��")
print(f"✅ 找到 {len(prompt_audio_paths)} 个参考音色:")

#打印找到的文件列表
for p in prompt_audio_paths:
    print(f"  - {os.path.basename(p)}")

#读取每一行 去掉空格,读取的总条目

# 读取输入文本(每行一句)
with open(TEXT_FILE, "r", encoding="utf-8") as f:
    lines = [line.strip() for line in f if line.strip()]
if not lines:
    raise ValueError(f"输入文件 {TEXT_FILE} 为空!")

print(f"\n✅ 从 {TEXT_FILE} 读取到 {len(lines)} 条文本。")

#创建输出目录

os.makedirs(OUTPUT_DIR, exist_ok=True)

#轮换使用音色进行克隆 对于在Lines中的每一个

# 轮换使用音色:用 idx % len(prompt_audio_paths) 循环
for idx, text in enumerate(lines):
    # 轮换选择参考音频,使用取余数的方法选择
    prompt_path = prompt_audio_paths[idx % len(prompt_audio_paths)]

#强制将音频重采样到16khz prompt_speech_16k是一个Pytorch tensor,形状为[1,T] T为采样点数
    prompt_speech_16k = load_wav(prompt_path, 16000)
    
    # 提取音频文件名(不含扩展名)用于输出命名 stem就是文件名,包含音色标识
    prompt_name = Path(prompt_path).stem
    
    print(f"\n>>> 合成第 {idx+1} 条(使用音色: {prompt_name})")
    print(f"  文本: {text}")

    # 执行 inference_instruct2(指令固定为���用自然语调说这句话”)

#这个inference_instruct2就是可以指定用啥语调 什么地方的方言 很牛 而且不像zeroshot那样 提示词中的内容和克隆音色的音频中的文字是一致的
    instruction = "用自然语调说这句话"
    for i, j in enumerate(cosyvoice.inference_instruct2(
        tts_text=text,#这是要合成的文本
        instruct_text=instruction,#指令文本
        prompt_speech_16k=prompt_speech_16k,#参考音频,刚刚上面有
        stream=False,#非流式合成,一次性返回完整音频
        text_frontend=True
    )):
        # 构建输出文件名:00_promptName.wav

#对于输出的构造就是 前面是第几条后面加上 prompt_name,这里是构造音频文件的保存路径
        output_path = os.path.join(OUTPUT_DIR, f"{idx:03d}_{prompt_name}.wav")

#然后保存生成的语音波形,输出路径 tts_speech是模型返回的语音波形数据 sample-rate是模型输出音频的采样率 也就是上面的16000khz
        torchaudio.save(output_path, j['tts_speech'], cosyvoice.sample_rate)
        normalized = j.get('normalized_text', text)
        print(f"  实际合成文本: {normalized}")
        print(f"  ✅ 已保存: {output_path}")

简单看看代码

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐