yueyulin's picture
Upload folder using huggingface_hub
ee3b868 verified
metadata
license: apache-2.0

ReSpark TTS 模型

本仓库包含 ReSpark 文本转语音 (TTS) 模型,这是一个强大而高效的模型,可以从文本生成高质量的语音。它基于 RWKV 架构,并利用 BiCodec-Tokenizer 进行音频处理。

安装

首先,请安装所需的依赖库:

pip install transformers rwkv-fla torch torchaudio torchvision transformers soundfile numpy librosa omegaconf soxr soundfile einx librosa

使用方法

tts.py 脚本提供了一个完整的使用该模型进行文本转语音合成(带声音克隆功能)的示例。

运行测试脚本

要生成语音,只需运行以下脚本:

python tts.py

工作原理

该脚本执行以下步骤:

  1. 从当前目录加载预训练的 AutoModelForCausalLMAutoTokenizer
  2. 初始化用于音频编码和解码的 BiCodecTokenizer
  3. 加载一个参考音频文件 (kafka.wav) 及其对应的文本 (prompt_text) 以提供声音提示(voice prompt)。
  4. 如果需要,将参考音频重采样以匹配模型期望的采样率 (24000 Hz)。
  5. 指定一个需要被合成的目标文本 (text)。
  6. 调用 generate_speech 函数,该函数会根据目标文本和参考音频中的声音生成音频。
  7. 将生成的音频保存到 output.wav

您可以修改 tts.py 文件中的 prompt_textprompt_audio_filetext 变量,以使用不同的声音合成不同的文本。

示例代码 (tts.py)

import os
import sys
current_dir = os.path.dirname(os.path.abspath(__file__))
print('add current dir to sys.path', current_dir)
sys.path.append(current_dir)
from sparktts.models.audio_tokenizer import BiCodecTokenizer
from transformers import AutoTokenizer, AutoModelForCausalLM
import soundfile as sf
import numpy as np
import torch
from utilities import generate_embeddings

def generate_speech(model, tokenizer, text, bicodec, prompt_text=None, prompt_audio=None, 
                   max_new_tokens=3000, do_sample=True, top_k=50, top_p=0.95, 
                   temperature=1.0, device="cuda:0"):
    """
    生成语音的函数
    """
    eos_token_id = model.config.vocab_size - 1
    
    embeddings = generate_embeddings(
        model=model,
        tokenizer=tokenizer,
        text=text,
        bicodec=bicodec,
        prompt_text=prompt_text,
        prompt_audio=prompt_audio
    )
    
    global_tokens = embeddings['global_tokens'].unsqueeze(0)
    model.eval()
    
    with torch.no_grad():
        generated_outputs = model.generate(
            inputs_embeds=embeddings['input_embs'],
            attention_mask=torch.ones((1, embeddings['input_embs'].shape[1]),dtype=torch.long,device=device),
            max_new_tokens=max_new_tokens,
            do_sample=do_sample,
            top_k=top_k,
            top_p=top_p,
            temperature=temperature,
            eos_token_id=eos_token_id,
            pad_token_id=tokenizer.pad_token_id if hasattr(tokenizer, 'pad_token_id') else tokenizer.eos_token_id,
            use_cache=True
        )
    
    semantic_tokens_tensor = generated_outputs[:,:-1]
    
    with torch.no_grad():
        wav = bicodec.detokenize(global_tokens, semantic_tokens_tensor)
    
    return wav

# --- 主程序 ---
device = 'cuda:0'

# 初始化分词器和模型
audio_tokenizer = BiCodecTokenizer(model_dir=current_dir, device=device)
tokenizer = AutoTokenizer.from_pretrained(current_dir, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(current_dir, trust_remote_code=True)

model = model.bfloat16().to(device)
model.eval()

# 准备用于声音克隆的提示音频和文本
prompt_text = "我们并不是通过物理移动手段找到星河的。"
prompt_audio_file = os.path.join(current_dir, 'kafka.wav')
prompt_audio, sampling_rate = sf.read(prompt_audio_file)

# 如果需要,重采样音频
target_sample_rate = audio_tokenizer.config['sample_rate']
if sampling_rate != target_sample_rate:
    from librosa import resample
    prompt_audio = resample(prompt_audio, orig_sr=sampling_rate, target_sr=target_sample_rate)
    prompt_audio = np.array(prompt_audio, dtype=np.float32)

# 要合成的文本
text = "科学技术是第一生产力,最近 AI的迅猛发展让我们看到了迈向星辰大海的希望。"

# 生成语音
wav = generate_speech(model, tokenizer, text, audio_tokenizer, prompt_audio=prompt_audio, device=device)

# 保存输出
sf.write('output.wav', wav, target_sample_rate)
print("生成的音频已保存到 output.wav")