🚀 卡託菲爾-3B(基於俄耳甫斯-3B) - 合成版
卡託菲爾-3B是一個基於俄耳甫斯-3B的德語文本轉語音(TTS)模型家族,能夠生成多種說話人身份和情感表達的語音,為德語語音合成提供了豐富的選擇。
模型概述
這是一個基於俄耳甫斯-3B的德語文本轉語音(TTS)模型家族,有兩個主要版本:
- 卡託菲爾-3B-自然版:主要在自然人類語音錄音上進行微調,旨在實現逼真的語音效果。數據集基於高質量的德語音頻,包括許可的播客、講座和其他開放教育資源(OER)數據,並通過Emilia風格的管道進行處理。
- 卡託菲爾-3B-合成版:使用合成語音數據進行微調,具有豐富的情感和不同的語氣表達。數據集包含4個不同說話人的多種情感。
目前這個是合成版,適用於合成語音效果,同時支持添加情感和語氣表達。
兩個版本都支持:
- 多說話人:模型可以根據預定義的說話人身份生成不同的語音。
- 多樣表達:能夠根據輸入文本生成具有不同情感基調和表達方式的語音。
合成版可用的說話人和表達
說話人
情感
為了添加情感,可以使用以下情感類型:
- 中性
- 高興
- 悲傷
- 興奮
- 驚訝
- 幽默
- 憤怒
- 平靜
- 厭惡
- 恐懼
- 驕傲
- 浪漫
使用時,在說話人姓名後面加上情感類型,格式為[說話人姓名] - [情感類型]: [德語文本]
。例如,對於說話人馬丁和悲傷情感,正確的模板是:
馬丁 - 悲傷: 哦,我太傷心了。
語氣表達
以下語氣表達可用:
可以直接在文本中使用這些語氣表達,也可以將它們放在標籤中。請確保使用確切的文本。
推理
import torch
import torchaudio.transforms as T
import os
import torch
from snac import SNAC
from peft import PeftModel
import soundfile as sf
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained(
"SebastianBodza/Kartoffel_Orpheus-3B_german_synthetic-v0.1",
device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained(
"SebastianBodza/Kartoffel_Orpheus-3B_german_synthetic-v0.1",
)
snac_model = SNAC.from_pretrained("hubertsiuzdak/snac_24khz")
snac_model = snac_model.to("cuda")
chosen_voice = "Martin"
prompts = [
'Tief im verwunschenen Wald, wo die Bäume uralte Geheimnisse flüsterten, lebte ein kleiner Gnom namens Fips, der die Sprache der Tiere verstand.',
]
def process_single_prompt(prompt, chosen_voice):
if chosen_voice == "in_prompt" or chosen_voice == "":
full_prompt = prompt
else:
full_prompt = f"{chosen_voice}: {prompt}"
start_token = torch.tensor([[128259]], dtype=torch.int64)
end_tokens = torch.tensor([[128009, 128260]], dtype=torch.int64)
input_ids = tokenizer(full_prompt, return_tensors="pt").input_ids
modified_input_ids = torch.cat([start_token, input_ids, end_tokens], dim=1)
input_ids = modified_input_ids.to("cuda")
attention_mask = torch.ones_like(input_ids)
generated_ids = model.generate(
input_ids=input_ids,
attention_mask=attention_mask,
max_new_tokens=4000,
do_sample=True,
temperature=0.6,
top_p=0.95,
repetition_penalty=1.1,
num_return_sequences=1,
eos_token_id=128258,
use_cache=True,
)
token_to_find = 128257
token_to_remove = 128258
token_indices = (generated_ids == token_to_find).nonzero(as_tuple=True)
if len(token_indices[1]) > 0:
last_occurrence_idx = token_indices[1][-1].item()
cropped_tensor = generated_ids[:, last_occurrence_idx + 1 :]
else:
cropped_tensor = generated_ids
masked_row = cropped_tensor[0][cropped_tensor[0] != token_to_remove]
row_length = masked_row.size(0)
new_length = (row_length // 7) * 7
trimmed_row = masked_row[:new_length]
code_list = [t - 128266 for t in trimmed_row]
return code_list
def redistribute_codes(code_list):
layer_1 = []
layer_2 = []
layer_3 = []
for i in range((len(code_list) + 1) // 7):
layer_1.append(code_list[7 * i])
layer_2.append(code_list[7 * i + 1] - 4096)
layer_3.append(code_list[7 * i + 2] - (2 * 4096))
layer_3.append(code_list[7 * i + 3] - (3 * 4096))
layer_2.append(code_list[7 * i + 4] - (4 * 4096))
layer_3.append(code_list[7 * i + 5] - (5 * 4096))
layer_3.append(code_list[7 * i + 6] - (6 * 4096))
codes = [
torch.tensor(layer_1).unsqueeze(0),
torch.tensor(layer_2).unsqueeze(0),
torch.tensor(layer_3).unsqueeze(0),
]
codes = [c.to("cuda") for c in codes]
audio_hat = snac_model.decode(codes)
return audio_hat
for i, prompt in enumerate(prompts):
print(f"Processing prompt {i + 1}/{len(prompts)}")
with torch.no_grad():
code_list = process_single_prompt(prompt, chosen_voice)
samples = redistribute_codes(code_list)
audio_numpy = samples.detach().squeeze().to("cpu").numpy()
sf.write(f"output_{i}.wav", audio_numpy, 24000)
print(f"Saved output_{i}.wav")
信息表格
屬性 |
詳情 |
模型類型 |
基於俄耳甫斯-3B的德語文本轉語音(TTS)模型 |
訓練數據 |
自然版:高質量德語音頻,包括許可的播客、講座和其他開放教育資源(OER)數據;合成版:包含4個不同說話人的多種情感的合成語音數據 |
許可證 |
llama3.2 |