SagarVelamuri commited on
Commit
683b0a0
·
verified ·
1 Parent(s): a0b8bba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -193
app.py CHANGED
@@ -1,26 +1,25 @@
1
- import os, traceback, types, torch
2
- import gradio as gr
3
  from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
4
 
5
- # Robust import for IndicProcessor (fallback too)
6
  try:
7
  from IndicTransToolkit import IndicProcessor
8
  except Exception:
9
  from IndicTransToolkit.IndicTransToolkit import IndicProcessor
10
 
 
11
  # -------- Config --------
12
  TOKENIZER_ID = os.getenv("TOKENIZER_ID", "ai4bharat/indictrans2-en-indic-1B")
13
  MODEL_ID = os.getenv("MODEL_ID", "law-ai/InLegalTrans-En2Indic-1B")
14
- TOKENIZER_REV = os.getenv("TOKENIZER_REV", None)
15
- MODEL_REV = os.getenv("MODEL_REV", None)
16
 
17
  SRC_CODE = "eng_Latn"
18
  HI_CODE = "hin_Deva"
19
  TE_CODE = "tel_Telu"
20
 
21
- # ------- Load model -------
22
  device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
23
- dtype = torch.float16 if torch.cuda.is_available() else torch.float32
24
 
25
  tok_kwargs = dict(trust_remote_code=True, use_fast=True)
26
  if TOKENIZER_REV: tok_kwargs["revision"] = TOKENIZER_REV
@@ -29,53 +28,45 @@ tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_ID, **tok_kwargs)
29
  mdl_kwargs = dict(trust_remote_code=True, attn_implementation="eager",
30
  low_cpu_mem_usage=True, dtype=dtype)
31
  if MODEL_REV: mdl_kwargs["revision"] = MODEL_REV
32
- model = AutoModelForSeq2SeqLM.from_pretrained(MODEL_ID, **mdl_kwargs).to(device)
33
- model.eval()
34
 
 
35
  if getattr(model.generation_config, "pad_token_id", None) is None:
36
- model.generation_config.pad_token_id = (
37
- getattr(tokenizer, "pad_token_id", None) or getattr(tokenizer, "eos_token_id", 0)
38
- )
39
- if getattr(model.generation_config, "eos_token_id", None) is None and getattr(tokenizer, "eos_token_id", None) is not None:
40
  model.generation_config.eos_token_id = tokenizer.eos_token_id
41
 
42
  def _ensure_vocab_consistency(md, tok):
43
  try:
44
  actual_vocab = md.get_output_embeddings().weight.shape[0]
45
- except Exception:
46
- actual_vocab = None
47
- if actual_vocab is not None:
48
  md.config.vocab_size = actual_vocab
49
- try: md.generation_config.vocab_size = actual_vocab
50
- except Exception: pass
51
  else:
52
- vs = getattr(tok, "vocab_size", None)
53
- if vs is None:
54
- try: vs = len(tok)
55
- except Exception: vs = 64000
56
  md.config.vocab_size = vs
57
- try: md.generation_config.vocab_size = vs
58
- except Exception: pass
59
- if not hasattr(md.config, "get_text_config") or not callable(getattr(md.config, "get_text_config", None)):
60
- def _get_text_config(self): return self
61
- md.config.get_text_config = types.MethodType(_get_text_config, md.config)
62
 
63
  _ensure_vocab_consistency(model, tokenizer)
 
64
  for obj in (model.config, model.generation_config):
65
  try: setattr(obj, "use_cache", False)
66
- except Exception: pass
67
 
 
68
  ip = IndicProcessor(inference=True)
69
 
 
70
  # -------- Inference --------
71
  @torch.inference_mode()
72
  def _translate_to_lang(text, tgt_code, num_beams, max_new_tokens, temperature, top_p, top_k):
73
  batch = ip.preprocess_batch([text], src_lang=SRC_CODE, tgt_lang=tgt_code)
74
- enc = tokenizer(
75
- batch, max_length=256, truncation=True, padding="longest",
76
- return_tensors="pt", return_attention_mask=True
77
- ).to(device)
78
- do_sample = (temperature is not None) and (float(temperature) > 0)
79
  out = model.generate(
80
  **enc,
81
  max_new_tokens=int(max_new_tokens),
@@ -84,195 +75,103 @@ def _translate_to_lang(text, tgt_code, num_beams, max_new_tokens, temperature, t
84
  temperature=float(temperature) if do_sample else None,
85
  top_p=float(top_p) if do_sample else None,
86
  top_k=int(top_k) if do_sample else None,
87
- use_cache=False, early_stopping=False,
88
- pad_token_id=model.generation_config.pad_token_id,
89
  )
90
- decoded = tokenizer.batch_decode(out, skip_special_tokens=True, clean_up_tokenization_spaces=True)
91
  final = ip.postprocess_batch(decoded, lang=tgt_code)
92
  return final[0].strip()
93
 
94
  def translate_dual(text, num_beams, max_new_tokens, temperature, top_p, top_k):
95
- text = (text or "").strip()
96
  if not text: return "", ""
97
  try:
98
  hi = _translate_to_lang(text, HI_CODE, num_beams, max_new_tokens, temperature, top_p, top_k)
99
  except Exception as e:
100
- print("HI ERROR:\n", traceback.format_exc())
101
- hi = f"⚠️ Hindi translation failed: {type(e).__name__}: {str(e).splitlines()[-1]}"
102
  try:
103
  te = _translate_to_lang(text, TE_CODE, num_beams, max_new_tokens, temperature, top_p, top_k)
104
  except Exception as e:
105
- print("TE ERROR:\n", traceback.format_exc())
106
- te = f"⚠️ Telugu translation failed: {type(e).__name__}: {str(e).splitlines()[-1]}"
107
  return hi, te
108
 
109
- # -------- Theme --------
110
- THEME = gr.themes.Soft(primary_hue="blue", neutral_hue="slate").set(
111
- body_background_fill="#0b1220",
112
- body_text_color="#f2f6ff",
113
- body_text_color_subdued="#cbd5e1",
114
- block_background_fill="#0f172a",
115
- block_border_color="#223144",
116
- block_title_text_color="#ffffff",
117
- input_background_fill="#0b1220",
118
- input_border_color="#3b516c",
119
- button_primary_background_fill="#3b82f6",
120
- button_primary_text_color="#ffffff",
121
  )
122
 
123
- # -------- CSS --------
124
  CUSTOM_CSS = """
125
- * { box-sizing: border-box; }
126
- html, body { height: 100%; background:#0b1220; margin:0; padding:0; }
127
- .gradio-container { height: 100vh !important; width: 100vw !important; max-width: 100vw !important; margin: 0; padding: 8px; }
128
-
129
- /* Header */
130
- #hdr { height: 60px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
131
- background:#162434; border:1px solid #223144; border-radius:12px; margin-bottom:8px; }
132
- #title { color:#ffffff; font-weight:900; font-size:20px; margin:0; letter-spacing:.2px; }
133
- #subtitle { color:#b8cae1; font-size:12.5px; margin:0; }
134
-
135
- /* Main grid (use Group, not Row -> no split-handles) */
136
- #main {
137
- height: calc(100vh - 60px - 16px); /* header + outer padding */
138
- display: grid;
139
- grid-template-columns: 20% 40% 40%;
140
- gap: 10px;
141
  }
 
 
142
 
143
- /* Panels */
144
- .panel { border:1px solid #223144; border-radius:12px; background:#0f172a;
145
- display:flex; flex-direction:column; min-height:0; overflow:hidden; }
146
- .panel-h {
147
- display:flex; align-items:center; justify-content:space-between;
148
- padding:10px 12px; background:#081422; border-bottom:1px solid #243244;
149
- color:#ffffff; font-weight:900; letter-spacing:.25px; font-size:15px;
150
  }
151
- .panel-b { flex:1 1 auto; min-height:0; padding:10px 12px; }
152
-
153
- /* Left column: internal scroll only */
154
- #left { height: 100%; }
155
- #adv-inner { height: 100%; overflow:auto; padding-right:6px; }
156
-
157
- /* Remove pill-like label chips; make labels crisp */
158
- .gradio-container label,
159
- .gradio-container .label,
160
- .gradio-container .label > span {
161
- background: transparent !important;
162
- box-shadow: none !important;
163
- border: none !important;
164
- color: #ffffff !important;
165
- font-weight: 800 !important;
166
  }
167
-
168
- /* Middle split: 75% input / 25% buttons */
169
- #middle { display:grid; grid-template-rows: 75% 25%; height:100%; gap:10px; }
170
-
171
- /* Right split: 50% / 50% */
172
- #right { display:grid; grid-template-rows: 1fr 1fr; height:100%; gap:10px; }
173
-
174
- /* Text areas fill */
175
- .textwrap { height:100%; min-height:0; display:flex; }
176
- .textwrap > div { flex:1 1 auto; min-height:0; }
177
- .textwrap textarea { height:100% !important; }
178
-
179
- /* Inputs */
180
- textarea, textarea:focus {
181
- background:#0b1220 !important; color:#f9fbff !important;
182
- font-size:17px !important; line-height:1.55 !important;
183
- padding:10px 12px !important; border:1.6px solid #3b516c !important; border-radius:10px !important;
184
  }
185
- textarea::placeholder { color:#a6bdd9 !important; }
186
- textarea:hover { border-color:#6b8db6 !important; }
187
- textarea:focus { border-color:#60a5fa !important; outline:none !important; }
188
-
189
- /* Buttons area */
190
- #btnrow { display:flex; align-items:center; justify-content:center; gap:16px; height:100%; }
191
- #btnrow > button { min-width:180px; height:46px; font-weight:800; border-radius:10px; }
192
-
193
- /* Maximize buttons */
194
- .max { font-weight:900; padding:4px 10px; border-radius:10px; border:1px solid #3c5a86;
195
- background:#122037; color:#ffffff; }
196
- .max:hover { border-color:#60a5fa; }
197
-
198
- /* Modal */
199
- #modal { position: fixed; inset: 0; z-index: 9999; background: rgba(2,6,23,.88); display:none; align-items:center; justify-content:center; padding:12px; }
200
- #modal[style*="display: block"] { display:flex !important; }
201
- .modal-card { width:min(1280px,96vw); height:min(92vh,900px); background:#0f172a; border:1px solid #335070; border-radius:14px;
202
- box-shadow:0 18px 40px rgba(2,6,23,.6); display:flex; flex-direction:column; gap:8px; padding:10px; }
203
- .modal-title { color:#ffffff; font-weight:800; font-size:18px; margin:0; }
204
- #fs_box textarea { height: calc(100% - 52px) !important; }
205
- .modal-actions { display:flex; gap:8px; justify-content:flex-end; }
206
  """
207
 
208
- # ------------- UI -------------
209
- with gr.Blocks(theme=THEME, css=CUSTOM_CSS, title="EN→HI / EN→TE Translator") as demo:
210
- modal_state = gr.State(value="") # 'hi' or 'te'
211
-
212
  with gr.Group(elem_id="hdr"):
213
- gr.Markdown('<p id="title">English → Hindi & Telugu Translator</p>')
214
- gr.Markdown('<p id="subtitle">IndicTrans2 pipeline · law-ai/InLegalTrans-En2Indic-1B</p>')
215
-
216
- # Main grid built with Group (no split handles)
217
- with gr.Group(elem_id="main"):
218
- # LEFT (20%) — Advanced Settings
219
- with gr.Group(elem_id="left", elem_classes=["panel"]):
220
- gr.Markdown('<div class="panel-h">Advanced Settings</div>')
221
- with gr.Group(elem_id="adv-inner", elem_classes=["panel-b"]):
222
- num_beams = gr.Slider(1, 8, value=4, step=1, label="Beam search: num_beams")
223
- max_new = gr.Slider(16, 512, value=128, step=8, label="Max new tokens")
224
- temperature = gr.Slider(0.0, 1.5, value=0.0, step=0.05, label="Temperature (0 = deterministic)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  top_p = gr.Slider(0.0, 1.0, value=1.0, step=0.01, label="Top-p")
226
  top_k = gr.Slider(0, 100, value=50, step=1, label="Top-k")
227
 
228
- # MIDDLE (40%) — English (75% input / 25% buttons)
229
- with gr.Group(elem_id="middle"):
230
- with gr.Group(elem_classes=["panel"]):
231
- gr.Markdown('<div class="panel-h">English Text</div>')
232
- with gr.Group(elem_classes=["panel-b","textwrap"]):
233
- src = gr.Textbox(placeholder="Type English here…", show_label=False, lines=14)
234
- with gr.Group(elem_classes=["panel"]):
235
- gr.Markdown('<div class="panel-h">Actions</div>')
236
- with gr.Group(elem_classes=["panel-b"], elem_id="btnrow"):
237
- translate_btn = gr.Button("Translate", variant="primary")
238
- clear_btn = gr.Button("Clear", variant="secondary")
239
-
240
- # RIGHT (40%) — Hindi (50%) / Telugu (50%)
241
- with gr.Group(elem_id="right"):
242
- with gr.Group(elem_classes=["panel"]):
243
- gr.Markdown('<div class="panel-h">Hindi (hin_Deva)<span></span></div>')
244
- with gr.Group(elem_classes=["panel-b","textwrap"]):
245
- hi_out = gr.Textbox(show_copy_button=True, show_label=False, lines=10)
246
- with gr.Row(): # small row under box for maximize
247
- hi_max = gr.Button("⤢ Maximize", elem_classes=["max"])
248
-
249
- with gr.Group(elem_classes=["panel"]):
250
- gr.Markdown('<div class="panel-h">Telugu (tel_Telu)<span></span></div>')
251
- with gr.Group(elem_classes=["panel-b","textwrap"]):
252
- te_out = gr.Textbox(show_copy_button=True, show_label=False, lines=10)
253
- with gr.Row():
254
- te_max = gr.Button("⤢ Maximize", elem_classes=["max"])
255
-
256
- # Modal
257
- with gr.Group(visible=False, elem_id="modal") as modal:
258
- modal_title = gr.Markdown('<div class="modal-title">Fullscreen</div>')
259
- fs_text = gr.Textbox(lines=22, elem_id="fs_box")
260
- with gr.Row(elem_classes=["modal-actions"]):
261
- fs_close = gr.Button("Close", variant="secondary")
262
-
263
  # Wiring
264
- translate_btn.click(
265
- translate_dual,
266
- inputs=[src, num_beams, max_new, temperature, top_p, top_k],
267
- outputs=[hi_out, te_out],
268
- api_name="translate"
269
- )
270
  clear_btn.click(lambda: ("", "", ""), outputs=[src, hi_out, te_out])
271
 
272
- def open_hi(h): return gr.update(visible=True), "hi", '<div class="modal-title">Hindi (Fullscreen)</div>', h
273
- def open_te(t): return gr.update(visible=True), "te", '<div class="modal-title">Telugu (Fullscreen)</div>', t
274
- hi_max.click(open_hi, inputs=[hi_out], outputs=[modal, modal_state, modal_title, fs_text])
275
- te_max.click(open_te, inputs=[te_out], outputs=[modal, modal_state, modal_title, fs_text])
276
- fs_close.click(lambda: (gr.update(visible=False), ""), outputs=[modal, modal_state])
277
-
278
  demo.queue(max_size=48).launch()
 
1
+ import os, traceback, types, torch, gradio as gr
 
2
  from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
3
 
4
+ # Robust import for IndicProcessor
5
  try:
6
  from IndicTransToolkit import IndicProcessor
7
  except Exception:
8
  from IndicTransToolkit.IndicTransToolkit import IndicProcessor
9
 
10
+
11
  # -------- Config --------
12
  TOKENIZER_ID = os.getenv("TOKENIZER_ID", "ai4bharat/indictrans2-en-indic-1B")
13
  MODEL_ID = os.getenv("MODEL_ID", "law-ai/InLegalTrans-En2Indic-1B")
14
+ TOKENIZER_REV, MODEL_REV = os.getenv("TOKENIZER_REV"), os.getenv("MODEL_REV")
 
15
 
16
  SRC_CODE = "eng_Latn"
17
  HI_CODE = "hin_Deva"
18
  TE_CODE = "tel_Telu"
19
 
20
+ # -------- Model Load --------
21
  device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
22
+ dtype = torch.float16 if torch.cuda.is_available() else torch.float32
23
 
24
  tok_kwargs = dict(trust_remote_code=True, use_fast=True)
25
  if TOKENIZER_REV: tok_kwargs["revision"] = TOKENIZER_REV
 
28
  mdl_kwargs = dict(trust_remote_code=True, attn_implementation="eager",
29
  low_cpu_mem_usage=True, dtype=dtype)
30
  if MODEL_REV: mdl_kwargs["revision"] = MODEL_REV
31
+ model = AutoModelForSeq2SeqLM.from_pretrained(MODEL_ID, **mdl_kwargs).to(device).eval()
 
32
 
33
+ # Ensure generation config is correct
34
  if getattr(model.generation_config, "pad_token_id", None) is None:
35
+ model.generation_config.pad_token_id = tokenizer.pad_token_id or tokenizer.eos_token_id
36
+ if getattr(model.generation_config, "eos_token_id", None) is None and tokenizer.eos_token_id is not None:
 
 
37
  model.generation_config.eos_token_id = tokenizer.eos_token_id
38
 
39
  def _ensure_vocab_consistency(md, tok):
40
  try:
41
  actual_vocab = md.get_output_embeddings().weight.shape[0]
42
+ except Exception: actual_vocab = None
43
+ if actual_vocab:
 
44
  md.config.vocab_size = actual_vocab
45
+ md.generation_config.vocab_size = actual_vocab
 
46
  else:
47
+ vs = getattr(tok, "vocab_size", len(tok) if hasattr(tok, "__len__") else 64000)
 
 
 
48
  md.config.vocab_size = vs
49
+ md.generation_config.vocab_size = vs
50
+ if not hasattr(md.config, "get_text_config"):
51
+ md.config.get_text_config = types.MethodType(lambda self: self, md.config)
 
 
52
 
53
  _ensure_vocab_consistency(model, tokenizer)
54
+
55
  for obj in (model.config, model.generation_config):
56
  try: setattr(obj, "use_cache", False)
57
+ except: pass
58
 
59
+ # Processor
60
  ip = IndicProcessor(inference=True)
61
 
62
+
63
  # -------- Inference --------
64
  @torch.inference_mode()
65
  def _translate_to_lang(text, tgt_code, num_beams, max_new_tokens, temperature, top_p, top_k):
66
  batch = ip.preprocess_batch([text], src_lang=SRC_CODE, tgt_lang=tgt_code)
67
+ enc = tokenizer(batch, max_length=256, truncation=True, padding="longest",
68
+ return_tensors="pt").to(device)
69
+ do_sample = (temperature and float(temperature) > 0)
 
 
70
  out = model.generate(
71
  **enc,
72
  max_new_tokens=int(max_new_tokens),
 
75
  temperature=float(temperature) if do_sample else None,
76
  top_p=float(top_p) if do_sample else None,
77
  top_k=int(top_k) if do_sample else None,
78
+ use_cache=False,
 
79
  )
80
+ decoded = tokenizer.batch_decode(out, skip_special_tokens=True)
81
  final = ip.postprocess_batch(decoded, lang=tgt_code)
82
  return final[0].strip()
83
 
84
  def translate_dual(text, num_beams, max_new_tokens, temperature, top_p, top_k):
85
+ text = text.strip()
86
  if not text: return "", ""
87
  try:
88
  hi = _translate_to_lang(text, HI_CODE, num_beams, max_new_tokens, temperature, top_p, top_k)
89
  except Exception as e:
90
+ hi = f"⚠️ Hindi error: {type(e).__name__}: {str(e).splitlines()[-1]}"
 
91
  try:
92
  te = _translate_to_lang(text, TE_CODE, num_beams, max_new_tokens, temperature, top_p, top_k)
93
  except Exception as e:
94
+ te = f"⚠️ Telugu error: {type(e).__name__}: {str(e).splitlines()[-1]}"
 
95
  return hi, te
96
 
97
+
98
+ # -------- Theme & Styling --------
99
+ THEME = gr.themes.Base(
100
+ primary_hue="blue", neutral_hue="slate"
101
+ ).set(
102
+ body_background_fill="#f9fafb",
103
+ body_text_color="#111827",
104
+ block_background_fill="#ffffff",
105
+ block_border_color="#e5e7eb",
106
+ block_title_text_color="#111827",
107
+ button_primary_background_fill="#2563eb",
108
+ button_primary_text_color="#ffffff"
109
  )
110
 
 
111
  CUSTOM_CSS = """
112
+ #hdr {
113
+ text-align:center; padding:16px; margin-bottom:16px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  }
115
+ #hdr h1 { font-size:24px; font-weight:700; margin:0; color:#111827; }
116
+ #hdr p { font-size:14px; color:#6b7280; margin:4px 0 0; }
117
 
118
+ .panel {
119
+ border:1px solid #e5e7eb; border-radius:12px;
120
+ background:white; box-shadow:0 1px 3px rgba(0,0,0,0.08);
121
+ padding:12px; display:flex; flex-direction:column;
 
 
 
122
  }
123
+ .panel h2 {
124
+ font-size:16px; font-weight:600; margin-bottom:8px; color:#374151;
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  }
126
+ textarea {
127
+ font-size:15px !important; line-height:1.55 !important;
128
+ padding:10px 12px !important;
129
+ border:1px solid #d1d5db !important; border-radius:8px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  }
131
+ button { font-weight:600 !important; border-radius:8px !important; }
132
+ button:hover { opacity:0.9; transition:opacity 0.2s; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  """
134
 
135
+ # -------- UI --------
136
+ with gr.Blocks(theme=THEME, css=CUSTOM_CSS, title="EN Hindi / Telugu Translator") as demo:
 
 
137
  with gr.Group(elem_id="hdr"):
138
+ gr.Markdown("<h1>English → Hindi & Telugu Translator</h1>")
139
+ gr.Markdown("<p>Powered by IndicTrans2 · law-ai/InLegalTrans-En2Indic-1B</p>")
140
+
141
+ with gr.Row():
142
+ # Input Column
143
+ with gr.Column(scale=2):
144
+ with gr.Group(elem_classes="panel"):
145
+ gr.Markdown("<h2>English Input</h2>")
146
+ src = gr.Textbox(placeholder="Type English text...", lines=12, show_label=False)
147
+
148
+ with gr.Row():
149
+ translate_btn = gr.Button("👉 Translate", variant="primary")
150
+ clear_btn = gr.Button("Clear", variant="secondary")
151
+
152
+ # Output Column
153
+ with gr.Column(scale=2):
154
+ with gr.Group(elem_classes="panel"):
155
+ gr.Markdown("<h2>Hindi Translation</h2>")
156
+ hi_out = gr.Textbox(lines=6, show_copy_button=True, show_label=False)
157
+
158
+ with gr.Group(elem_classes="panel"):
159
+ gr.Markdown("<h2>Telugu Translation</h2>")
160
+ te_out = gr.Textbox(lines=6, show_copy_button=True, show_label=False)
161
+
162
+ # Settings Column
163
+ with gr.Column(scale=1):
164
+ with gr.Group(elem_classes="panel"):
165
+ gr.Markdown("<h2>Advanced Settings</h2>")
166
+ num_beams = gr.Slider(1, 8, value=4, step=1, label="Num Beams")
167
+ max_new = gr.Slider(16, 512, value=128, step=8, label="Max Tokens")
168
+ temperature = gr.Slider(0.0, 1.5, value=0.0, step=0.05, label="Temperature")
169
  top_p = gr.Slider(0.0, 1.0, value=1.0, step=0.01, label="Top-p")
170
  top_k = gr.Slider(0, 100, value=50, step=1, label="Top-k")
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  # Wiring
173
+ translate_btn.click(translate_dual, inputs=[src, num_beams, max_new, temperature, top_p, top_k],
174
+ outputs=[hi_out, te_out])
 
 
 
 
175
  clear_btn.click(lambda: ("", "", ""), outputs=[src, hi_out, te_out])
176
 
 
 
 
 
 
 
177
  demo.queue(max_size=48).launch()