File size: 6,122 Bytes
7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b 7625a4e 993c50b | 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 | import os
import subprocess
import sys
import importlib.util
# ==========================================
# 1. HÀM HỆ THỐNG & SETUP (ROBUST MODE)
# ==========================================
def run_command(command, message):
print(f"⏳ {message}...")
try:
result = subprocess.run(command, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print(f"❌ Lỗi (nhưng sẽ thử tiếp tục): {message}")
print(f"📝 Chi tiết: {result.stderr}")
return False
print(f"✅ Xong: {message}")
return True
except Exception as e:
print(f"❌ Exception: {e}")
return False
def setup_environment():
# 1. Cài System Tools
run_command("apt-get update -qq && apt-get install -y espeak-ng git build-essential -qq", "System Tools")
# 2. Clone Repo (Xử lý đường dẫn thông minh)
if not os.path.exists("VieNeu-TTS"):
run_command("git clone https://github.com/pnnbao97/VieNeu-TTS.git", "Clone VieNeu-TTS")
# 3. Cài đặt Python Dependencies (FIXED)
# Bỏ qua chỉ định CUDA cứng, để pip tự chọn bản phù hợp nhất với HF Space
print("🛠️ Đang cài đặt thư viện (Auto-detect Hardware)...")
# Cài torch trước
run_command("pip install torch torchvision torchaudio", "Install PyTorch (Auto)")
# Cài package chính
run_command("pip install neucodec", "Install Neucodec")
# Vào thư mục repo để cài requirements nội bộ nếu cần
if os.path.exists("VieNeu-TTS"):
os.chdir("VieNeu-TTS")
run_command("pip install -e .", "Install VieNeu Local")
# Quan trọng: Thêm đường dẫn repo vào hệ thống để Python tìm thấy file
sys.path.append(os.getcwd())
os.chdir("..") # Quay lại root
run_command("pip install --upgrade gradio", "Update Gradio")
# Chạy setup nếu chưa có thư viện cốt lõi
if not importlib.util.find_spec("neucodec") or not importlib.util.find_spec("torch"):
setup_environment()
else:
# Đảm bảo path vẫn đúng ngay cả khi restart space
if os.path.exists("VieNeu-TTS"):
sys.path.append(os.path.abspath("VieNeu-TTS"))
# ==========================================
# 2. LOGIC XỬ LÝ (BACKEND WRAPPER)
# ==========================================
import gradio as gr
import torch
# Hàm bọc để gọi logic từ repo gốc an toàn
def tts_wrapper(text, speed):
try:
# Import dynamic để tránh crash lúc khởi động
import gradio_app
# Tìm hàm đúng trong code gốc
if hasattr(gradio_app, 'inference'):
return gradio_app.inference(text, speed)
elif hasattr(gradio_app, 'tts_inference'):
return gradio_app.tts_inference(text, speed)
else:
# Fallback: Nếu không tìm thấy hàm, thử tìm model global
if hasattr(gradio_app, 'model'):
return gradio_app.model.infer(text, speed)
return None, "⚠️ Không tìm thấy hàm inference trong gradio_app.py"
except ImportError:
return None, "❌ Lỗi: Không thể import module 'gradio_app'. Kiểm tra lại cấu trúc thư mục."
except Exception as e:
return None, f"❌ Lỗi Runtime: {str(e)}"
# ==========================================
# 3. UI/UX HIỆN ĐẠI (GRADIO 4/5 COMPATIBLE)
# ==========================================
# CSS đã sửa lỗi tương thích
css = """
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&display=swap');
body { font-family: 'Inter', sans-serif; background: #0f172a; }
.header-container {
background: linear-gradient(135deg, #1e40af 0%, #3b82f6 100%);
padding: 2rem;
border-radius: 1rem;
margin-bottom: 1.5rem;
text-align: center;
color: white;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}
.header-title { font-size: 2.2rem; font-weight: 800; margin: 0; }
.header-sub { opacity: 0.9; margin-top: 0.5rem; }
/* Thay thế Box cũ bằng custom classes */
.panel-container {
background: #1e293b;
border: 1px solid #334155;
border-radius: 12px;
padding: 20px;
}
#gen-btn {
background: linear-gradient(90deg, #059669 0%, #10b981 100%);
border: none;
color: white;
font-size: 1.1rem;
font-weight: bold;
}
"""
# Sử dụng cú pháp mới chuẩn Gradio 4+
with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
# Header Section (Dùng HTML thay vì gr.Box đã bị xóa)
gr.HTML("""
<div class="header-container">
<h1 class="header-title">🇻🇳 VieNeu-TTS Studio</h1>
<div class="header-sub">Deep Learning Neural Text-to-Speech | High Fidelity</div>
</div>
""")
with gr.Row():
# Cột trái: Input
with gr.Column(elem_classes="panel-container"):
gr.Markdown("### 📝 Nhập liệu")
inp_text = gr.Textbox(
label="Văn bản",
placeholder="Nhập tiếng Việt...",
lines=6,
value="Xin chào, hệ thống VieNeu TTS đã hoạt động trở lại."
)
inp_speed = gr.Slider(0.5, 2.0, value=1.0, step=0.1, label="⚡ Tốc độ")
btn_run = gr.Button("▶️ TẠO GIỌNG ĐỌC", elem_id="gen-btn", scale=1)
# Cột phải: Output
with gr.Column(elem_classes="panel-container"):
gr.Markdown("### 🎧 Kết quả")
out_audio = gr.Audio(label="Audio Output", type="filepath")
out_msg = gr.Markdown("Sẵn sàng xử lý...")
# Footer
gr.Markdown("<center style='color: #64748b; margin-top: 20px;'>VieNeu-TTS Community Build</center>")
# Xử lý sự kiện
btn_run.click(fn=tts_wrapper, inputs=[inp_text, inp_speed], outputs=[out_audio, out_msg])
# ==========================================
# 4. RUN
# ==========================================
if __name__ == "__main__":
demo.queue().launch(share=True) |