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("""

🇻🇳 VieNeu-TTS Studio

Deep Learning Neural Text-to-Speech | High Fidelity
""") 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("
VieNeu-TTS Community Build
") # 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)