Spaces:
Sleeping
Sleeping
File size: 9,489 Bytes
de8e74f 0fc5a71 de8e74f 0fc5a71 de8e74f 0fc5a71 de8e74f 0fc5a71 de8e74f 0fc5a71 de8e74f 0fc5a71 de8e74f 0fc5a71 de8e74f 0fc5a71 de8e74f 0fc5a71 310e7d6 0fc5a71 de8e74f 37cbc4d de8e74f 310e7d6 0fc5a71 310e7d6 f1d545e 310e7d6 e2e277e 0fc5a71 310e7d6 0fc5a71 310e7d6 e2e277e 310e7d6 e2e277e 310e7d6 e2e277e 0fc5a71 310e7d6 f1d545e 310e7d6 e2e277e 310e7d6 e2e277e 310e7d6 e2e277e 0fc5a71 310e7d6 0fc5a71 310e7d6 0fc5a71 310e7d6 f1d545e 0fc5a71 310e7d6 0fc5a71 f1d545e 310e7d6 0fc5a71 e2e277e 310e7d6 0fc5a71 310e7d6 0fc5a71 310e7d6 0fc5a71 f1d545e 310e7d6 0fc5a71 310e7d6 de8e74f 37cbc4d 310e7d6 e2e277e f1d545e e2e277e 0fc5a71 f1d545e 310e7d6 e2e277e 310e7d6 0fc5a71 310e7d6 de8e74f 310e7d6 0fc5a71 310e7d6 0fc5a71 310e7d6 de8e74f 0fc5a71 310e7d6 0fc5a71 310e7d6 0fc5a71 de8e74f 310e7d6 0fc5a71 310e7d6 0fc5a71 de8e74f 310e7d6 0fc5a71 310e7d6 0fc5a71 310e7d6 0fc5a71 de8e74f 0fc5a71 f1d545e 0fc5a71 37cbc4d 310e7d6 0fc5a71 310e7d6 0fc5a71 310e7d6 0fc5a71 310e7d6 0fc5a71 310e7d6 0fc5a71 f1d545e 0fc5a71 e2e277e 0fc5a71 37cbc4d 0fc5a71 f1d545e 0fc5a71 310e7d6 0fc5a71 310e7d6 0fc5a71 310e7d6 0fc5a71 de8e74f 76354f7 |
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 |
import torch
import gradio as gr
from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
# ==========================================
# 1. CẤU HÌNH & LOAD MODEL (BACKEND)
# ==========================================
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
# --- Load PhoWhisper ---
print("Đang tải model PhoWhisper...")
try:
asr_pipeline = pipeline(
"automatic-speech-recognition",
model="vinai/PhoWhisper-small",
device=0 if torch.cuda.is_available() else -1
)
except Exception as e:
print(f"Lỗi load PhoWhisper: {e}")
asr_pipeline = None
# --- Load ViT5 Translation ---
TRANSLATION_MODEL_PATH = "."
print(f"Đang tải model dịch...")
try:
trans_tokenizer = AutoTokenizer.from_pretrained(TRANSLATION_MODEL_PATH)
trans_model = AutoModelForSeq2SeqLM.from_pretrained(TRANSLATION_MODEL_PATH).to(DEVICE)
print("Load model dịch thành công!")
except Exception as e:
print(f"Lỗi load model dịch: {e}")
trans_model = None
# ==========================================
# 2. HÀM XỬ LÝ LOGIC
# ==========================================
def speech_to_text(audio_path):
if audio_path is None: return ""
if asr_pipeline is None: return "Lỗi: Chưa load được PhoWhisper."
try:
output = asr_pipeline(audio_path)
return output['text']
except Exception as e:
return f"Lỗi nhận dạng: {str(e)}"
def text_to_gloss(vietnamese_text):
if not vietnamese_text: return ""
if trans_model is None: return "Lỗi: Chưa load được model dịch."
input_text = f"vi: {vietnamese_text}"
inputs = trans_tokenizer(input_text, return_tensors="pt", max_length=128, truncation=True).to(DEVICE)
with torch.no_grad():
outputs = trans_model.generate(
inputs["input_ids"],
max_length=128,
num_beams=5,
early_stopping=True
)
gloss_text = trans_tokenizer.decode(outputs[0], skip_special_tokens=True)
return gloss_text.replace("vsl: ", "") if gloss_text.startswith("vsl: ") else gloss_text
def full_pipeline(audio, text_input, mode):
vietnamese_output = ""
if mode == "Giọng nói (Microphone/File)" and audio is not None:
vietnamese_output = speech_to_text(audio)
elif mode == "Văn bản (Nhập tay)" and text_input:
vietnamese_output = text_input
else:
if mode == "Giọng nói (Microphone/File)":
return "⚠️ Vui lòng thu âm hoặc tải file.", ""
else:
return "⚠️ Vui lòng nhập văn bản.", ""
gloss_output = text_to_gloss(vietnamese_output)
return vietnamese_output, gloss_output
# ==========================================
# 3. GIAO DIỆN COFFEE THEME (UI/UX)
# ==========================================
# CSS Tông màu Cà phê
custom_css = """
@import url('https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,700;1,400&family=Roboto:wght@300;400;500&display=swap');
body {
font-family: 'Roboto', sans-serif;
background-color: #fdfbf7;
}
/* --- HEADER --- */
.header-container {
background: linear-gradient(135deg, #3e2723 0%, #5d4037 100%);
padding: 30px;
border-radius: 15px;
text-align: center;
box-shadow: 0 6px 12px rgba(62, 39, 35, 0.3);
margin-bottom: 25px;
border-bottom: 4px solid #8d6e63;
}
/* Ép màu trắng bằng !important */
.uni-name {
font-family: 'Roboto', sans-serif;
font-size: 16px;
text-transform: uppercase;
letter-spacing: 2px;
color: #ffffff !important; /* Màu trắng */
font-weight: bold;
opacity: 0.9;
}
.project-name {
font-family: 'Lora', serif;
font-size: 32px;
font-weight: 700;
margin: 15px 0;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
color: #ffffff !important; /* Màu trắng */
}
.author-name {
font-size: 14px;
font-style: italic;
color: #ffffff !important; /* Màu trắng */
border-top: 1px solid rgba(255,255,255,0.3);
display: inline-block;
padding-top: 10px;
margin-top: 5px;
}
/* --- BUTTONS --- */
button.primary-btn {
background-color: #6d4c41 !important;
color: white !important;
font-weight: 600;
border-radius: 8px;
border: none;
transition: all 0.3s;
}
button.primary-btn:hover {
background-color: #5d4037 !important;
transform: translateY(-2px);
box-shadow: 0 6px 10px rgba(109, 76, 65, 0.3);
}
/* --- OTHER --- */
.label-text {
font-weight: bold;
color: #4e342e;
margin-bottom: 5px;
font-size: 1.1em;
}
.gloss-box textarea {
font-family: 'Roboto', sans-serif;
font-size: 22px !important;
font-weight: bold;
color: #bf360c !important;
background-color: #fff3e0 !important;
border: 1px solid #ffccbc !important;
}
.footer {
text-align: center;
color: #8d6e63;
font-size: 12px;
margin-top: 40px;
border-top: 1px solid #d7ccc8;
padding-top: 20px;
}
"""
# Tạo Theme
coffee_theme = gr.themes.Soft(
primary_hue="orange",
secondary_hue="yellow",
neutral_hue="gray",
).set(
body_background_fill="#fcf9f2",
block_background_fill="#ffffff",
block_border_width="1px",
block_shadow="0 2px 4px rgba(0,0,0,0.05)",
button_primary_background_fill="#6d4c41",
button_primary_background_fill_hover="#5d4037",
button_primary_text_color="white",
slider_color="#8d6e63"
)
with gr.Blocks(css=custom_css, theme=coffee_theme, title="VSL Coffee Translator") as demo:
# --- HEADER ---
gr.HTML(
"""
<div class="header-container">
<div class="uni-name">Trường Đại học Kinh tế - Đại học Đà Nẵng</div>
<div class="project-name">☕ HỆ THỐNG DỊCH VSL - ANGEL COFFEE ☕</div>
<div class="author-name">Sinh viên: Lê Thị Hà Vy | GVHD: Th.S Nguyễn Văn Chức</div>
</div>
"""
)
# --- MAIN CONTENT ---
with gr.Row():
# CỘT TRÁI: INPUT
with gr.Column(scale=1, variant="panel"):
gr.Markdown("### 🎙️ Nhập yêu cầu gọi món", elem_classes="label-text")
with gr.Tabs():
# Tab Audio
with gr.TabItem("Ghi âm / Tải file"):
input_audio = gr.Audio(
sources=["microphone", "upload"],
type="filepath",
label="Nói câu gọi món..."
)
mode_audio = gr.State(value="Giọng nói (Microphone/File)")
btn_audio = gr.Button("☕ Xử lý Giọng nói", variant="primary", elem_classes="primary-btn")
# Tab Text
with gr.TabItem("Nhập văn bản"):
input_text = gr.Textbox(
label="Nhập câu tiếng Việt",
placeholder="Ví dụ: Cho tôi một ly cà phê sữa ít đường...",
lines=4
)
mode_text = gr.State(value="Văn bản (Nhập tay)")
# Gợi ý câu mẫu
gr.Examples(
examples=[
["Tôi gọi một ly cà phê muối"],
["Lấy cho mình một bạc xỉu ít ngọt"],
["Tôi muốn thanh toán tiền"],
["Cảm ơn bạn rất nhiều"]
],
inputs=input_text,
label="Gợi ý gọi món"
)
btn_text = gr.Button("☕ Dịch Văn bản", variant="primary", elem_classes="primary-btn")
# CỘT PHẢI: OUTPUT
with gr.Column(scale=1, variant="panel"):
gr.Markdown("### ✨ Kết quả dịch (VSL Gloss)", elem_classes="label-text")
# Kết quả trung gian
gr.Label("Bước 1: Nhận dạng Tiếng Việt", show_label=False, color="orange")
output_vi = gr.Textbox(
label="Văn bản Tiếng Việt",
interactive=False,
show_copy_button=True,
lines=2
)
gr.HTML("<br>")
# Kết quả cuối cùng
gr.Label("Bước 2: Cú pháp Ký hiệu (VSL)", show_label=False, color="yellow")
output_gloss = gr.Textbox(
label="VSL Gloss Output",
interactive=False,
show_copy_button=True,
elem_classes="gloss-box",
lines=3
)
# --- FOOTER ---
gr.HTML(
"""
<div class="footer">
Dự án hỗ trợ giao tiếp cho người khiếm thính tại Angel Coffee Đà Nẵng.<br>
Powered by <b>PhoWhisper</b> & <b>ViT5</b> (Fine-tuned on Coffee Dataset).
</div>
"""
)
# --- XỬ LÝ SỰ KIỆN ---
btn_audio.click(
fn=full_pipeline,
inputs=[input_audio, input_text, mode_audio],
outputs=[output_vi, output_gloss]
)
btn_text.click(
fn=full_pipeline,
inputs=[input_audio, input_text, mode_text],
outputs=[output_vi, output_gloss]
)
# Chạy app
if __name__ == "__main__":
demo.launch() |