Spaces:
Running
Running
File size: 13,340 Bytes
6d75162 955241f 6d75162 955241f 6d75162 955241f 6d75162 955241f 6d75162 955241f 6d75162 |
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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
import os
import tempfile
import time
from typing import List, Tuple
import gradio as gr
import torch
import torchaudio
import spaces
from dataclasses import dataclass
from generator import Segment, load_csm_1b
from huggingface_hub import login
# Kiểm tra xem có GPU không và cấu hình thiết bị phù hợp
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Sử dụng thiết bị: {device}")
# Đăng nhập vào Hugging Face Hub nếu có token
def login_huggingface():
hf_token = os.environ.get("HF_TOKEN")
if hf_token:
print("Đang đăng nhập vào Hugging Face Hub...")
login(token=hf_token)
print("Đã đăng nhập thành công!")
else:
print("Không tìm thấy HF_TOKEN trong biến môi trường. Một số mô hình có thể không truy cập được.")
# Đăng nhập khi khởi động
login_huggingface()
# Tải mô hình CSM-1B
generator = None
def load_model():
global generator
if generator is None:
print("Đang tải mô hình CSM-1B...")
generator = load_csm_1b(device=device)
print("Đã tải xong mô hình!")
return generator
# Hàm chuyển đổi âm thanh thành tensor
def audio_to_tensor(audio_path: str) -> Tuple[torch.Tensor, int]:
waveform, sample_rate = torchaudio.load(audio_path)
waveform = waveform.mean(dim=0) # Chuyển stereo thành mono nếu cần
return waveform, sample_rate
# Hàm lưu tensor âm thanh thành file
def save_audio(audio_tensor: torch.Tensor, sample_rate: int) -> str:
temp_dir = tempfile.gettempdir()
output_path = os.path.join(temp_dir, f"csm1b_output_{int(time.time())}.wav")
torchaudio.save(output_path, audio_tensor.unsqueeze(0), sample_rate)
return output_path
# Hàm tạo âm thanh từ văn bản sử dụng ZeroGPU
@spaces.GPU
def generate_speech(
text: str,
speaker_id: int,
context_audio_path1: str = None,
context_text1: str = None,
context_speaker1: int = 0,
context_audio_path2: str = None,
context_text2: str = None,
context_speaker2: int = 1,
max_duration_ms: float = 30000,
temperature: float = 0.9,
top_k: int = 50,
progress=gr.Progress()
) -> str:
# Tải mô hình nếu chưa tải
generator = load_model()
# Chuẩn bị ngữ cảnh (context)
context = []
progress(0.1, "Đang xử lý ngữ cảnh...")
# Xử lý ngữ cảnh 1
if context_audio_path1 and context_text1:
waveform, sample_rate = audio_to_tensor(context_audio_path1)
# Resample nếu cần
if sample_rate != generator.sample_rate:
waveform = torchaudio.functional.resample(waveform, orig_freq=sample_rate, new_freq=generator.sample_rate)
context.append(Segment(speaker=context_speaker1, text=context_text1, audio=waveform))
# Xử lý ngữ cảnh 2
if context_audio_path2 and context_text2:
waveform, sample_rate = audio_to_tensor(context_audio_path2)
# Resample nếu cần
if sample_rate != generator.sample_rate:
waveform = torchaudio.functional.resample(waveform, orig_freq=sample_rate, new_freq=generator.sample_rate)
context.append(Segment(speaker=context_speaker2, text=context_text2, audio=waveform))
progress(0.3, "Đang tạo âm thanh...")
# Tạo âm thanh từ văn bản
audio = generator.generate(
text=text,
speaker=speaker_id,
context=context,
max_audio_length_ms=max_duration_ms,
temperature=temperature,
topk=top_k
)
progress(0.8, "Đang lưu âm thanh...")
# Lưu âm thanh thành file
output_path = save_audio(audio, generator.sample_rate)
progress(1.0, "Hoàn thành!")
return output_path
# Hàm tạo âm thanh đơn giản không có ngữ cảnh
@spaces.GPU
def generate_speech_simple(
text: str,
speaker_id: int,
max_duration_ms: float = 30000,
temperature: float = 0.9,
top_k: int = 50,
progress=gr.Progress()
) -> str:
# Tải mô hình nếu chưa tải
generator = load_model()
progress(0.3, "Đang tạo âm thanh...")
# Tạo âm thanh từ văn bản
audio = generator.generate(
text=text,
speaker=speaker_id,
context=[], # Không có ngữ cảnh
max_audio_length_ms=max_duration_ms,
temperature=temperature,
topk=top_k
)
progress(0.8, "Đang lưu âm thanh...")
# Lưu âm thanh thành file
output_path = save_audio(audio, generator.sample_rate)
progress(1.0, "Hoàn thành!")
return output_path
# Tạo giao diện Gradio
def create_demo():
with gr.Blocks(title="CSM-1B Text-to-Speech") as demo:
gr.Markdown("# CSM-1B Text-to-Speech Demo")
gr.Markdown("Mô hình CSM-1B (Collaborative Speech Model) là một mô hình text-to-speech tiên tiến có khả năng tạo giọng nói tự nhiên từ văn bản.")
with gr.Tab("Tạo âm thanh đơn giản"):
with gr.Row():
with gr.Column():
text_input = gr.Textbox(
label="Văn bản cần chuyển thành giọng nói",
placeholder="Nhập văn bản bạn muốn chuyển thành giọng nói...",
lines=5
)
speaker_id = gr.Number(
label="ID người nói",
value=0,
precision=0,
minimum=0,
maximum=10
)
with gr.Row():
max_duration = gr.Slider(
label="Thời lượng tối đa (ms)",
minimum=1000,
maximum=90000,
value=30000,
step=1000
)
temperature = gr.Slider(
label="Temperature",
minimum=0.1,
maximum=1.5,
value=0.9,
step=0.1
)
top_k = gr.Slider(
label="Top-K",
minimum=1,
maximum=100,
value=50,
step=1
)
generate_btn = gr.Button("Tạo âm thanh")
with gr.Column():
output_audio = gr.Audio(label="Âm thanh đầu ra", type="filepath")
with gr.Tab("Tạo âm thanh với ngữ cảnh"):
gr.Markdown("Tính năng này cho phép bạn cung cấp các đoạn âm thanh và văn bản làm ngữ cảnh để mô hình tạo ra âm thanh phù hợp hơn.")
with gr.Row():
with gr.Column():
context_text1 = gr.Textbox(label="Văn bản ngữ cảnh 1", lines=2)
context_audio1 = gr.Audio(label="Âm thanh ngữ cảnh 1", type="filepath")
context_speaker1 = gr.Number(label="ID người nói 1", value=0, precision=0)
context_text2 = gr.Textbox(label="Văn bản ngữ cảnh 2", lines=2)
context_audio2 = gr.Audio(label="Âm thanh ngữ cảnh 2", type="filepath")
context_speaker2 = gr.Number(label="ID người nói 2", value=1, precision=0)
text_input_context = gr.Textbox(
label="Văn bản cần chuyển thành giọng nói",
placeholder="Nhập văn bản bạn muốn chuyển thành giọng nói...",
lines=3
)
speaker_id_context = gr.Number(
label="ID người nói",
value=0,
precision=0
)
with gr.Row():
max_duration_context = gr.Slider(
label="Thời lượng tối đa (ms)",
minimum=1000,
maximum=90000,
value=30000,
step=1000
)
temperature_context = gr.Slider(
label="Temperature",
minimum=0.1,
maximum=1.5,
value=0.9,
step=0.1
)
top_k_context = gr.Slider(
label="Top-K",
minimum=1,
maximum=100,
value=50,
step=1
)
generate_context_btn = gr.Button("Tạo âm thanh với ngữ cảnh")
with gr.Column():
output_audio_context = gr.Audio(label="Âm thanh đầu ra", type="filepath")
# Thêm tab cấu hình Hugging Face
with gr.Tab("Cấu hình"):
gr.Markdown("### Cấu hình Hugging Face Token")
gr.Markdown("""
Để sử dụng mô hình CSM-1B, bạn cần có quyền truy cập vào mô hình trên Hugging Face.
Bạn có thể cấu hình token của mình bằng cách:
1. Tạo token tại [Hugging Face Settings](https://huggingface.co/settings/tokens)
2. Đặt biến môi trường `HF_TOKEN` với giá trị là token của bạn
Lưu ý: Trong Hugging Face Spaces, bạn có thể đặt biến môi trường trong phần Cài đặt của Space.
""")
hf_token_input = gr.Textbox(
label="Hugging Face Token (Chỉ sử dụng trong phiên này)",
placeholder="Nhập token của bạn...",
type="password"
)
def set_token(token):
if token:
os.environ["HF_TOKEN"] = token
login(token=token)
return "Đã đặt token thành công! Bạn có thể tải mô hình bây giờ."
return "Token không hợp lệ. Vui lòng nhập token hợp lệ."
set_token_btn = gr.Button("Đặt Token")
token_status = gr.Textbox(label="Trạng thái", interactive=False)
set_token_btn.click(fn=set_token, inputs=hf_token_input, outputs=token_status)
# Thêm tab thông tin về ZeroGPU
with gr.Tab("Thông tin GPU"):
gr.Markdown("### Thông tin về ZeroGPU")
gr.Markdown("""
Ứng dụng này sử dụng ZeroGPU của Hugging Face Spaces để tối ưu việc sử dụng GPU.
ZeroGPU giúp giải phóng bộ nhớ GPU khi không sử dụng, giúp tiết kiệm tài nguyên và cải thiện hiệu suất.
Khi bạn tạo âm thanh, GPU sẽ được sử dụng tự động và giải phóng sau khi hoàn thành.
""")
def check_gpu():
if torch.cuda.is_available():
gpu_name = torch.cuda.get_device_name(0)
gpu_memory = torch.cuda.get_device_properties(0).total_memory / (1024**3)
return f"GPU: {gpu_name}\nBộ nhớ: {gpu_memory:.2f} GB"
else:
return "Không tìm thấy GPU. Ứng dụng sẽ chạy trên CPU."
check_gpu_btn = gr.Button("Kiểm tra GPU")
gpu_info = gr.Textbox(label="Thông tin GPU", interactive=False)
check_gpu_btn.click(fn=check_gpu, inputs=None, outputs=gpu_info)
# Kết nối các thành phần
generate_btn.click(
fn=generate_speech_simple,
inputs=[
text_input,
speaker_id,
max_duration,
temperature,
top_k
],
outputs=output_audio
)
generate_context_btn.click(
fn=generate_speech,
inputs=[
text_input_context,
speaker_id_context,
context_audio1,
context_text1,
context_speaker1,
context_audio2,
context_text2,
context_speaker2,
max_duration_context,
temperature_context,
top_k_context
],
outputs=output_audio_context
)
# Tải mô hình khi khởi động
demo.load(fn=load_model)
return demo
# Khởi chạy ứng dụng
if __name__ == "__main__":
demo = create_demo()
demo.queue().launch() |