Downloads · 30 days
17
19% of all-time downloads
lgris/orpheus-tts-zeroshot-tagarela_v2
orpheus-tts-zeroshot-tagarela_v2 is a text-to-speech model from lgris. Use it when you need text read aloud.
Modelo Orpheus-TTS ajustado em modo condicionado utilizando o dataset freds0/TAGARELAv2. Este modelo realiza síntese de voz (TTS) Zero-Shot: ele recebe um áudio de referência e o texto que foi dito nele, junto com o n…
Downloads · 30 days
17
19% of all-time downloads
All-time downloads
90
Public
Parameters
3.3B
39.6 GB on disk
Likes
1
Public
Click a slice to open those files.
.pt26.4 GB · 67%
From the Hugging Face model README
Modelo Orpheus-TTS ajustado em modo condicionado utilizando o dataset freds0/TAGARELA_v2. Este modelo realiza síntese de voz (TTS) Zero-Shot: ele recebe um áudio de referência e o texto que foi dito nele, junto com o novo texto que deve ser gerado, e produz a nova fala seguindo o ritmo e o timbre da voz original.
Nota sobre o formato do prompt: Apenas treinamos o modelo de forma zero-shot mantendo estritamente o formato original do modelo pré-treinado. Ou seja, a entrada consiste apenas em concatenar o texto de referência com o texto a ser gerado, seguidos pelos códigos do áudio de referência codificado (ref codes).
Abaixo está o script completo que carrega o modelo, processa um áudio de referência, e possui o loop de retry com repetition_penalty para lidar com falhas na predição do token [EOSP].
import torch
import torchaudio
import soundfile as sf
import numpy as np
from transformers import AutoModelForCausalLM, AutoTokenizer
from snac import SNAC
# Offsets específicos da arquitetura Orpheus-TTS / SNAC 24kHz
BASE_OFFSET = 128266
OFFSETS = [0, 4096, 2 * 4096, 3 * 4096, 4 * 4096, 5 * 4096, 6 * 4096]
def process_audio_to_codes(audio_path, snac_model, device="cuda"):
"""Converte o áudio de referência para os códigos SNAC com os offsets do Orpheus."""
audio_array, sr = sf.read(audio_path)
if len(audio_array.shape) > 1:
audio_array = np.mean(audio_array, axis=1)
audio_tensor = torch.from_numpy(audio_array).float().unsqueeze(0)
if sr != 24000:
resampler = torchaudio.transforms.Resample(sr, 24000)
audio_tensor = resampler(audio_tensor)
with torch.no_grad():
audio_tensor = audio_tensor.to(device)
codes = snac_model.encode(audio_tensor.unsqueeze(0))
codes_list = []
num_frames = codes[0].shape[1]
# Intercalação hierárquica oficial dos 7 tokens por frame com seus devidos offsets
for i in range(num_frames):
codes_list.append(codes[0][0, i].item() + BASE_OFFSET + OFFSETS[0])
codes_list.append(codes[1][0, 2 * i].item() + BASE_OFFSET + OFFSETS[1])
codes_list.append(codes[2][0, 4 * i].item() + BASE_OFFSET + OFFSETS[2])
codes_list.append(codes[2][0, 4 * i + 1].item() + BASE_OFFSET + OFFSETS[3])
codes_list.append(codes[1][0, 2 * i + 1].item() + BASE_OFFSET + OFFSETS[4])
codes_list.append(codes[2][0, 4 * i + 2].item() + BASE_OFFSET + OFFSETS[5])
codes_list.append(codes[2][0, 4 * i + 3].item() + BASE_OFFSET + OFFSETS[6])
return codes_list
def decode_codes_to_audio(codes_list, snac_model, device="cuda"):
"""Decodifica os tokens previstos pelo Orpheus de volta para áudio numpy a 24kHz."""
raw_codes = [c - BASE_OFFSET for c in codes_list]
num_frames = len(raw_codes) // 7
if num_frames == 0:
return None
codes_0, codes_1, codes_2 = [], [], []
for i in range(num_frames):
idx = i * 7
codes_0.append(raw_codes[idx] - OFFSETS[0])
codes_1.append(raw_codes[idx + 1] - OFFSETS[1])
codes_2.append(raw_codes[idx + 2] - OFFSETS[2])
codes_2.append(raw_codes[idx + 3] - OFFSETS[3])
codes_1.append(raw_codes[idx + 4] - OFFSETS[4])
codes_2.append(raw_codes[idx + 5] - OFFSETS[5])
codes_2.append(raw_codes[idx + 6] - OFFSETS[6])
codes_0_t = torch.tensor([codes_0], dtype=torch.long, device=device)
codes_1_t = torch.tensor([codes_1], dtype=torch.long, device=device)
codes_2_t = torch.tensor([codes_2], dtype=torch.long, device=device)
with torch.no_grad():
audio = snac_model.decode([codes_0_t, codes_1_t, codes_2_t])
return audio.squeeze().cpu().numpy()
# 1. Carregar os modelos
device = "cuda" if torch.cuda.is_available() else "cpu"
model_path = "lgris/orpheus-tts-zeroshot-tagarela_v2"
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.bfloat16).to(device)
model.eval()
tokenizer = AutoTokenizer.from_pretrained(model_path)
snac_model = SNAC.from_pretrained("hubertsiuzdak/snac_24khz").to(device).eval()
# IDs Especiais
start_of_human = 128259
end_of_human = 128260
start_of_ai = 128261
start_of_speech = 128257
end_of_speech = 128258
start_of_text = 128000
end_of_text = 128009
# 2. Preparar os inputs
ref_text = "Texto falado no áudio de referência."
target_text = "Texto que você deseja sintetizar com essa voz."
ref_audio_path = "referencia.wav"
text_ids = tokenizer.encode(f"{ref_text} {target_text}".strip(), add_special_tokens=False)
ref_codes = process_audio_to_codes(ref_audio_path, snac_model, device)
input_ids = (
[start_of_human, start_of_text] + text_ids + [end_of_text, end_of_human] +
[start_of_ai, start_of_speech] + ref_codes
)
input_tensor = torch.tensor([input_ids], dtype=torch.long, device=device)
# 3. Loop de Geração (com Retry para garantir finalização com EOSP)
max_retries = 3
final_audio_np = None
for attempt in range(max_retries):
with torch.no_grad():
output = model.generate(
input_tensor,
max_new_tokens=1500,
min_new_tokens=40,
do_sample=True,
temperature=0.7,
top_p=0.95,
repetition_penalty=1.2, # Evita loops de silêncio e força emissão do EOS
pad_token_id=tokenizer.pad_token_id,
eos_token_id=end_of_speech,
)
generated = output[0].tolist()
generated_codes = generated[len(input_ids):]
if end_of_speech in generated_codes:
end_idx = generated_codes.index(end_of_speech)
generated_codes = generated_codes[:end_idx]
final_audio_np = decode_codes_to_audio(generated_codes, snac_model, device)
print("Áudio gerado com sucesso!")
break
else:
print(f"Tentativa {attempt + 1}: EOS não encontrado. Repetindo...")
if final_audio_np is not None:
sf.write("output.wav", final_audio_np, 24000)
else:
print("Falha na geração.")
Abaixo estão alguns exemplos de áudios gerados por este checkpoint (os arquivos originais estão na pasta samples/).
Exemplo 1 (Referência 1) <audio controls> <source src="https://huggingface.co/lgris/orpheus-tts-zeroshot-tagarela_v2/resolve/main/samples/ref1_sample1.wav" type="audio/wav"> </audio>
Exemplo 2 (Referência 2) <audio controls> <source src="https://huggingface.co/lgris/orpheus-tts-zeroshot-tagarela_v2/resolve/main/samples/ref2_sample1.wav" type="audio/wav"> </audio>