File size: 3,435 Bytes
4eeb5fe
38b7ebd
 
 
88c80d0
38b7ebd
 
 
88c80d0
38b7ebd
 
 
 
 
 
88c80d0
 
 
 
 
 
 
 
 
 
 
 
78505ef
38b7ebd
 
 
 
 
88c80d0
 
 
 
 
 
 
 
38b7ebd
 
 
 
 
 
 
78505ef
38b7ebd
88c80d0
38b7ebd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b7935b6
93ff1fe
38b7ebd
 
88c80d0
38b7ebd
88c80d0
93ff1fe
38b7ebd
 
88c80d0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a7ba2cd
78505ef
38b7ebd
93ff1fe
c34c848
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import os
import re
import torch
import torchaudio
from huggingface_hub import hf_hub_download
from TTS.tts.configs.xtts_config import XttsConfig
from TTS.tts.models.xtts import Xtts
from vinorm import TTSnorm
from torch.cuda.amp import autocast

# Cấu hình đường dẫn và tải mô hình
checkpoint_dir = "model/"
repo_id = "capleaf/viXTTS"
use_deepspeed = False

# Kiểm tra GPU và hỗ trợ FP16
if torch.cuda.is_available():
    device = "cuda"
    if "A100" in torch.cuda.get_device_name(0):
        print("Đang sử dụng GPU A100 với hỗ trợ FP16.")
        use_fp16 = True
    else:
        print(f"Đang sử dụng GPU: {torch.cuda.get_device_name(0)}")
        use_fp16 = False
else:
    device = "cpu"
    use_fp16 = False

# Tạo thư mục nếu chưa tồn tại
os.makedirs(checkpoint_dir, exist_ok=True)

# Kiểm tra và tải các file cần thiết
required_files = ["model.pth", "config.json", "vocab.json", "speakers_xtts.pth"]
for file in required_files:
    file_path = os.path.join(checkpoint_dir, file)
    if not os.path.exists(file_path):
        hf_hub_download(
            repo_id=repo_id if file != "speakers_xtts.pth" else "coqui/XTTS-v2",
            filename=file,
            local_dir=checkpoint_dir,
        )

# Tải cấu hình và mô hình
xtts_config = os.path.join(checkpoint_dir, "config.json")
config = XttsConfig()
config.load_json(xtts_config)
MODEL = Xtts.init_from_config(config)
MODEL.load_checkpoint(config, checkpoint_dir=checkpoint_dir, use_deepspeed=use_deepspeed)
MODEL.to(device)

# Danh sách ngôn ngữ được hỗ trợ
supported_languages = ["vi", "en"]

def normalize_vietnamese_text(text):
    text = (
        TTSnorm(text, unknown=False, lower=False, rule=True)
        .replace("..", ".")
        .replace("!.", "!")
        .replace("?.", "?")
        .replace(" .", ".")
        .replace(" ,", ",")
        .replace('"', "")
        .replace("'", "")
        .replace("AI", "Ây Ai")
        .replace("A.I", "Ây Ai")
    )
    return text

def generate_speech(text, language="vi", speaker_wav=None, normalize_text=True):
    if language not in supported_languages:
        raise ValueError(f"Ngôn ngữ {language} không được hỗ trợ.")
    if len(text) < 2:
        raise ValueError("Văn bản quá ngắn.")
    try:
        if normalize_text and language == "vi":
            text = normalize_vietnamese_text(text)
        with torch.no_grad():
            with autocast(enabled=use_fp16):
                gpt_cond_latent, speaker_embedding = MODEL.get_conditioning_latents(
                    audio_path=speaker_wav,
                    gpt_cond_len=30 if device == "cuda" else 15,
                    gpt_cond_chunk_len=8 if device == "cuda" else 4,
                    max_ref_length=60 if device == "cuda" else 30,
                )
                out = MODEL.inference(
                    text,
                    language,
                    gpt_cond_latent,
                    speaker_embedding,
                    repetition_penalty=5.0,
                    temperature=0.75,
                    enable_text_splitting=True,
                )
        output_file = f"output_{os.urandom(4).hex()}.wav"
        torchaudio.save(output_file, torch.tensor(out["wav"]).unsqueeze(0).to("cpu"), 24000)
        return output_file
    except Exception as e:
        raise RuntimeError(f"Lỗi khi tạo giọng nói: {str(e)}")