Havyle commited on
Commit
0fc5a71
·
verified ·
1 Parent(s): aa9a24c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +179 -40
app.py CHANGED
@@ -2,19 +2,25 @@ import torch
2
  import gradio as gr
3
  from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
4
 
5
- # --- PHẦN 1: CẤU HÌNH & LOAD MODEL ---
 
 
6
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
7
 
8
- # 1. Load PhoWhisper (Nhận dạng giọng nói)
9
  print("Đang tải model PhoWhisper...")
10
- asr_pipeline = pipeline(
11
- "automatic-speech-recognition",
12
- model="vinai/PhoWhisper-small",
13
- device=0 if torch.cuda.is_available() else -1
14
- )
 
 
 
 
15
 
16
- # 2. Load Model Dịch (ViT5)
17
- # LƯU Ý QUAN TRỌNG:
18
  TRANSLATION_MODEL_PATH = "."
19
 
20
  print(f"Đang tải model dịch...")
@@ -26,15 +32,17 @@ except Exception as e:
26
  print(f"Lỗi load model dịch: {e}")
27
  trans_model = None
28
 
29
-
30
- # --- PHẦN 2: CÁC HÀM XỬ LÝ (LOGIC) ---
 
31
  def speech_to_text(audio_path):
32
  if audio_path is None: return ""
 
33
  try:
34
  output = asr_pipeline(audio_path)
35
  return output['text']
36
  except Exception as e:
37
- return f"Lỗi: {str(e)}"
38
 
39
  def text_to_gloss(vietnamese_text):
40
  if not vietnamese_text: return ""
@@ -61,47 +69,178 @@ def full_pipeline(audio, text_input, mode):
61
  elif mode == "Văn bản (Nhập tay)" and text_input:
62
  vietnamese_output = text_input
63
  else:
64
- return "Vui lòng nhập dữ liệu.", ""
 
 
 
 
65
 
66
  gloss_output = text_to_gloss(vietnamese_output)
67
  return vietnamese_output, gloss_output
68
 
 
 
 
69
 
70
- # --- PHẦN 3: GIAO DIỆN (UI) - ĐOẠN CODE CỦA BẠN ---
71
  custom_css = """
72
- .container {max-width: 1200px; margin: auto; padding-top: 20px}
73
- .header-text {text-align: center; font-family: 'Arial', sans-serif;}
74
- .uni-name {font-size: 24px; font-weight: bold; color: #003366; margin-bottom: 5px;}
75
- .faculty-name {font-size: 18px; font-weight: normal; color: #cc0000; margin-bottom: 20px;}
76
- .project-title {font-size: 28px; font-weight: bold; color: #2c3e50; margin-bottom: 10px; border-bottom: 2px solid #eee; padding-bottom: 10px;}
77
- .note-text {font-size: 14px; font-style: italic; color: #7f8c8d; margin-top: 20px; border-top: 1px solid #eee; padding-top: 10px;}
78
- .output-box {border: 1px solid #e0e0e0; background-color: #f9f9f9; border-radius: 8px;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  """
80
 
81
- with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
82
- # ... (Dán phần giao diện của bạn vào đây, y hệt đoạn bạn gửi) ...
83
- # Để cho gọn, mình viết tắt, bạn giữ nguyên code UI của bạn nhé
84
- with gr.Column(elem_classes="header-text"):
85
- gr.Markdown("""<div class="project-title">HỆ THỐNG D���CH VSL DEMO</div>""")
 
 
 
 
 
86
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  with gr.Row():
88
- with gr.Column():
 
 
 
 
89
  with gr.Tabs():
90
- with gr.TabItem("Giọng nói"):
91
- input_audio = gr.Audio(sources=["microphone", "upload"], type="filepath")
 
 
 
 
 
92
  mode_audio = gr.State(value="Giọng nói (Microphone/File)")
93
- btn_audio = gr.Button("Xử lý Giọng nói", variant="primary")
94
- with gr.TabItem("Văn bản"):
95
- input_text = gr.Textbox(label="Nhập text")
 
 
 
 
 
 
96
  mode_text = gr.State(value="Văn bản (Nhập tay)")
97
- btn_text = gr.Button("Dịch Văn bản", variant="primary")
98
-
99
- with gr.Column():
100
- output_vi = gr.Textbox(label="Tiếng Việt")
101
- output_gloss = gr.Textbox(label="VSL Gloss")
102
-
103
- btn_audio.click(fn=full_pipeline, inputs=[input_audio, input_text, mode_audio], outputs=[output_vi, output_gloss])
104
- btn_text.click(fn=full_pipeline, inputs=[input_audio, input_text, mode_text], outputs=[output_vi, output_gloss])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  # Chạy app
107
  if __name__ == "__main__":
 
2
  import gradio as gr
3
  from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
4
 
5
+ # ==========================================
6
+ # 1. CẤU HÌNH & LOAD MODEL (BACKEND)
7
+ # ==========================================
8
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
9
 
10
+ # --- Load PhoWhisper ---
11
  print("Đang tải model PhoWhisper...")
12
+ try:
13
+ asr_pipeline = pipeline(
14
+ "automatic-speech-recognition",
15
+ model="vinai/PhoWhisper-small",
16
+ device=0 if torch.cuda.is_available() else -1
17
+ )
18
+ except Exception as e:
19
+ print(f"Lỗi load PhoWhisper: {e}")
20
+ asr_pipeline = None
21
 
22
+ # --- Load ViT5 Translation ---
23
+ # Lưu ý: Đảm bảo bạn đã upload các file model ra ngoài cùng (root) như hướng dẫn trước
24
  TRANSLATION_MODEL_PATH = "."
25
 
26
  print(f"Đang tải model dịch...")
 
32
  print(f"Lỗi load model dịch: {e}")
33
  trans_model = None
34
 
35
+ # ==========================================
36
+ # 2. HÀM XỬ LÝ LOGIC
37
+ # ==========================================
38
  def speech_to_text(audio_path):
39
  if audio_path is None: return ""
40
+ if asr_pipeline is None: return "Lỗi: Chưa load được PhoWhisper."
41
  try:
42
  output = asr_pipeline(audio_path)
43
  return output['text']
44
  except Exception as e:
45
+ return f"Lỗi nhận dạng: {str(e)}"
46
 
47
  def text_to_gloss(vietnamese_text):
48
  if not vietnamese_text: return ""
 
69
  elif mode == "Văn bản (Nhập tay)" and text_input:
70
  vietnamese_output = text_input
71
  else:
72
+ # Trường hợp không input
73
+ if mode == "Giọng nói (Microphone/File)":
74
+ return "⚠️ Vui lòng thu âm hoặc tải file.", ""
75
+ else:
76
+ return "⚠️ Vui lòng nhập văn bản.", ""
77
 
78
  gloss_output = text_to_gloss(vietnamese_output)
79
  return vietnamese_output, gloss_output
80
 
81
+ # ==========================================
82
+ # 3. GIAO DIỆN ĐẸP (UI/UX)
83
+ # ==========================================
84
 
85
+ # CSS tùy chỉnh để làm đẹp
86
  custom_css = """
87
+ /* Font chữ toàn bộ app */
88
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap');
89
+ body { font-family: 'Roboto', sans-serif; }
90
+
91
+ /* Header Gradient */
92
+ .header-container {
93
+ background: linear-gradient(90deg, #003366 0%, #00509d 100%);
94
+ padding: 25px;
95
+ border-radius: 12px;
96
+ color: white;
97
+ text-align: center;
98
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
99
+ margin-bottom: 20px;
100
+ }
101
+ .uni-name { font-size: 16px; text-transform: uppercase; letter-spacing: 1px; opacity: 0.9; }
102
+ .project-name { font-size: 28px; font-weight: 700; margin: 10px 0; }
103
+ .author-name { font-size: 14px; font-style: italic; opacity: 0.8; }
104
+
105
+ /* Nút bấm xịn hơn */
106
+ button.primary-btn {
107
+ background-color: #00509d !important;
108
+ color: white !important;
109
+ font-weight: bold;
110
+ border-radius: 8px;
111
+ transition: 0.3s;
112
+ }
113
+ button.primary-btn:hover {
114
+ background-color: #003366 !important;
115
+ transform: scale(1.02);
116
+ }
117
+
118
+ /* Khung kết quả nổi bật */
119
+ .result-box textarea {
120
+ font-size: 18px !important;
121
+ font-weight: 500;
122
+ color: #2c3e50;
123
+ }
124
+ .gloss-box textarea {
125
+ font-size: 20px !important;
126
+ font-weight: bold;
127
+ color: #d32f2f; /* Màu đỏ cho Gloss */
128
+ }
129
+
130
+ /* Footer */
131
+ .footer { text-align: center; color: gray; font-size: 12px; margin-top: 30px; }
132
  """
133
 
134
+ # Chọn theme Soft để các góc bo tròn mềm mại
135
+ theme = gr.themes.Soft(
136
+ primary_hue="blue",
137
+ secondary_hue="slate",
138
+ ).set(
139
+ button_primary_background_fill="#00509d",
140
+ button_primary_background_fill_hover="#003366",
141
+ )
142
+
143
+ with gr.Blocks(css=custom_css, theme=theme, title="VSL Translator") as demo:
144
 
145
+ # --- 1. HEADER ---
146
+ gr.HTML(
147
+ """
148
+ <div class="header-container">
149
+ <div class="uni-name">Trường Đại học Kinh tế - Đại học Đà Nẵng</div>
150
+ <div class="project-name">HỆ THỐNG DỊCH TIẾNG VIỆT SANG NGÔN NGỮ KÝ HIỆU (VSL)</div>
151
+ <div class="author-name">Sinh viên thực hiện: Lê Thị Hà Vy | GVHD: Th.S Nguyễn Văn Chức</div>
152
+ </div>
153
+ """
154
+ )
155
+
156
+ # --- 2. MAIN CONTENT ---
157
  with gr.Row():
158
+
159
+ # CỘT TRÁI: INPUT (Đầu vào)
160
+ with gr.Column(scale=1, variant="panel"):
161
+ gr.Markdown("### 🎤 Nhập liệu")
162
+
163
  with gr.Tabs():
164
+ # Tab 1: Giọng nói
165
+ with gr.TabItem("🎙️ Giọng nói"):
166
+ input_audio = gr.Audio(
167
+ sources=["microphone", "upload"],
168
+ type="filepath",
169
+ label="Thu âm hoặc Tải file Audio"
170
+ )
171
  mode_audio = gr.State(value="Giọng nói (Microphone/File)")
172
+ btn_audio = gr.Button("Xử lý Giọng nói", variant="primary", elem_classes="primary-btn")
173
+
174
+ # Tab 2: Văn bản
175
+ with gr.TabItem("📝 Văn bản"):
176
+ input_text = gr.Textbox(
177
+ label="Nhập câu tiếng Việt",
178
+ placeholder="Ví dụ: Tôi muốn uống cà phê sữa...",
179
+ lines=4
180
+ )
181
  mode_text = gr.State(value="Văn bản (Nhập tay)")
182
+
183
+ # Gợi ý câu mẫu
184
+ gr.Examples(
185
+ examples=[
186
+ ["Tôi muốn uống cà phê sữa"],
187
+ ["Cho tôi một ly trà đào cam sả"],
188
+ ["Cảm ơn bạn rất nhiều"]
189
+ ],
190
+ inputs=input_text,
191
+ label="Câu mẫu (Click để chọn)"
192
+ )
193
+
194
+ btn_text = gr.Button("✨ Dịch Văn bản", variant="primary", elem_classes="primary-btn")
195
+
196
+ # CỘT PHẢI: OUTPUT (Kết quả)
197
+ with gr.Column(scale=1, variant="panel"):
198
+ gr.Markdown("### 🎯 Kết quả xử lý")
199
+
200
+ # Kết quả trung gian
201
+ gr.Label("Bước 1: Nhận dạng văn bản", show_label=False, color="blue")
202
+ output_vi = gr.Textbox(
203
+ label="Văn bản Tiếng Việt",
204
+ interactive=False,
205
+ show_copy_button=True,
206
+ elem_classes="result-box",
207
+ lines=2
208
+ )
209
+
210
+ gr.HTML("<br>") # Khoảng cách
211
+
212
+ # Kết quả cuối cùng
213
+ gr.Label("Bước 2: Cú pháp Ký hiệu (Gloss)", show_label=False, color="red")
214
+ output_gloss = gr.Textbox(
215
+ label="VSL Gloss Output",
216
+ interactive=False,
217
+ show_copy_button=True,
218
+ elem_classes="gloss-box",
219
+ lines=3
220
+ )
221
+
222
+ # --- 3. FOOTER ---
223
+ gr.HTML(
224
+ """
225
+ <div class="footer">
226
+ © 2025 VSL Translation Project. Khoa Thương mại Điện tử.<br>
227
+ Hệ thống sử dụng mô hình PhoWhisper (VinAI) và ViT5 (Fine-tuned).
228
+ </div>
229
+ """
230
+ )
231
+
232
+ # --- 4. XỬ LÝ SỰ KIỆN ---
233
+ btn_audio.click(
234
+ fn=full_pipeline,
235
+ inputs=[input_audio, input_text, mode_audio],
236
+ outputs=[output_vi, output_gloss]
237
+ )
238
+
239
+ btn_text.click(
240
+ fn=full_pipeline,
241
+ inputs=[input_audio, input_text, mode_text],
242
+ outputs=[output_vi, output_gloss]
243
+ )
244
 
245
  # Chạy app
246
  if __name__ == "__main__":