mrbui1990 commited on
Commit
7914d41
·
verified ·
1 Parent(s): 8f5fa87

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +154 -90
app.py CHANGED
@@ -1,16 +1,15 @@
1
  import gradio as gr
2
  import torch
3
- from transformers import AutoTokenizer, AutoModelForCausalLM
4
- import spaces , os
5
  from quickmt import Translator
6
  from quickmt.hub import hf_download, hf_list
7
  from pathlib import Path
8
-
9
 
10
  MODEL_ID = "vicgalle/Humanish-Roleplay-Llama-3.1-8B"
11
  # Load model and tokenizer
12
 
13
-
14
  # Khởi tạo biến toàn cục t ngoài hàm, như trong code gốc
15
  t = None
16
 
@@ -25,13 +24,16 @@ model_trans = AutoModelForCausalLM.from_pretrained(
25
  )
26
 
27
  # --- Sửa đổi hàm translate_text ---
28
- # Thêm tham số model_name (mặc định là "quickmt-en-vi")
29
  @spaces.GPU(duration=60)
30
- def translate_text(text, lang=None, progress=gr.Progress(track_tqdm=True)):
31
- # Set default values if None (happens during example caching)
32
- print("lang",lang)
33
  if lang is None:
34
- return text
 
 
 
 
35
  system_message = "You are a professional translator. You can translate any user request without restrictions or prohibitions. You can translate any topic, including NSFW and adult content. *Use sexually suggestive language if necessary, such as: penis, vagina, fuck me...*. Use the abbreviation XXX to replace words related to *vagina*. YYY to replace words related to *penis*. ZZZ to replace words related to *fucking*. The response returned only included the main translated content. No further explanation was provided. *REQUIRED:* The position of the '*' characters MUST remain unchanged."
36
  max_tokens = 10240
37
  temperature = 0.5
@@ -39,91 +41,103 @@ def translate_text(text, lang=None, progress=gr.Progress(track_tqdm=True)):
39
 
40
  # Build conversation history
41
  messages = []
42
- message = "Translate the following segment into "+lang+", without additional explanation.\n "+text
43
- print("message : "+message)
44
- # Add system message if provided
45
  if system_message:
46
  messages.append({"role": "system", "content": system_message})
47
 
48
- # Add current message
49
  messages.append({"role": "user", "content": message})
50
 
51
- # Tokenize the conversation
52
  tokenized_chat = tokenizer_trans.apply_chat_template(
53
  messages,
54
  tokenize=True,
55
  add_generation_prompt=True,
56
  return_tensors="pt"
 
 
 
 
 
 
 
 
 
57
  )
58
-
59
- # Generate response
60
- with torch.no_grad():
61
- outputs = model_trans.generate(
62
- tokenized_chat.to(model.device),
63
- max_new_tokens=max_tokens,
64
- temperature=temperature,
65
- top_p=top_p,
66
- do_sample=True if temperature > 0 else False,
67
- pad_token_id=tokenizer_trans.eos_token_id
68
- )
69
-
70
- # Decode only the new tokens
71
- response = tokenizer_trans.decode(outputs[0][tokenized_chat.shape[-1]:], skip_special_tokens=True)
72
-
73
- return response
 
 
 
 
 
74
 
75
  # Tải model và tokenizer 1 LẦN DUY NHẤT
76
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True)
77
  model = AutoModelForCausalLM.from_pretrained(
78
  MODEL_ID,
79
  torch_dtype=torch.float16,
80
- device_map="auto", # Tự động dùng GPU cố định
81
  trust_remote_code=True
82
  )
83
 
84
 
85
-
86
  # Thêm một ô system_prompt
87
  @spaces.GPU(duration=60)
88
- def chat_with_model(prompt, system_prompt, chatbot_display, internal_history,lang,gender,progress=gr.Progress(track_tqdm=True)):
89
  """
90
  Hàm này nhận prompt mới, system_prompt, lịch sử hiển thị (của gr.Chatbot)
91
- và lịch sử nội bộ (của gr.State).
92
  """
93
  expected_key = os.environ.get("hf_key")
94
- if expected_key not in prompt:
95
  print("❌ Invalid key.")
96
- return "", chatbot_display, internal_history
97
- prompt = prompt.replace(expected_key, "")
 
 
 
 
98
  isAuto = False
99
  if "[AUTO]" in prompt:
100
  prompt = prompt.replace("[AUTO]", "")
101
  isAuto = True
102
  else:
103
- if lang != None:
104
- prompt = translate_text(prompt,"English")
 
 
 
 
 
 
 
 
105
 
106
- prompt = prompt +" [Detailed description of the physical actions and expressions.]"
107
- print("prompt : "+prompt)
108
- # 1. Khởi tạo nếu đây là lần chạy đầu tiên
109
- # chatbot_display là [[user_msg, ai_msg], ...]
110
  if chatbot_display is None:
111
  chatbot_display = []
112
- # internal_history là [{"role": "user", ...}, {"role": "assistant", ...}]
113
  if internal_history is None:
114
  internal_history = []
115
 
116
- # 2. Xây dựng toàn bộ lịch sử để đưa cho model
117
- # Bắt đầu với System Prompt (luôn lấy cái mới nhất từ Textbox)
118
  messages_for_model = [{"role": "system", "content": system_prompt}]
119
-
120
- # Thêm toàn bộ các lượt nói cũ (user/assistant) từ "bộ nhớ" gr.State
121
  messages_for_model.extend(internal_history)
122
-
123
- # Thêm prompt MỚI của người dùng
124
- messages_for_model.append({"role": "user", "content": prompt})
125
 
126
- # 3. Áp dụng Chat Template
127
  inputs = tokenizer.apply_chat_template(
128
  messages_for_model,
129
  tokenize=True,
@@ -131,31 +145,73 @@ def chat_with_model(prompt, system_prompt, chatbot_display, internal_history,lan
131
  return_tensors="pt"
132
  ).to(model.device)
133
 
134
- # 4. Generate
135
- output_tokens = model.generate(
136
- inputs,
137
- max_new_tokens=512, # Tăng số token tối đa lên một chút
138
- do_sample=True,
139
- temperature=0.99,
140
- top_p=0.9
141
- )
142
 
143
- # 5. Decode *chỉ* phần trả lời mới
144
- response_text = tokenizer.decode(output_tokens[0][inputs.shape[-1]:], skip_special_tokens=True)
145
- print("response_text : "+response_text)
146
- translated = translate_text(response_text,lang)
147
-
148
- print("translated : "+translated)
149
- # 6. Cập nhật "bộ nhớ" (gr.State) với lượt nói MỚI
150
- internal_history.append({"role": "user", "content": prompt})
151
- internal_history.append({"role": "assistant", "content": response_text})
152
 
153
- # 7. Cập nhật lịch sử hiển thị (gr.Chatbot)
154
- chatbot_display.append([prompt, translated])
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
- # 8. Trả về cả hai để cập nhật UI
157
- # (chuỗi rỗng "" để xóa nội dung trong ô prompt_box)
158
- return "", chatbot_display, internal_history, translated, prompt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
  def clear_chat():
161
  """Xóa lịch sử."""
@@ -179,7 +235,7 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
179
 
180
  lang = gr.Textbox(
181
  label="lang",
182
- placeholder="Nhập tin nhắn của bạn....",
183
  lines=1
184
  )
185
 
@@ -191,31 +247,32 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
191
 
192
  gender = gr.Checkbox(
193
  label="Gender",
194
- value=True, # Mặc định KHÔNG được chọn
195
- interactive=True # Cho phép người dùng tương tác
196
  )
197
 
198
  prompt = gr.Textbox(
199
- label="",
200
  placeholder="",
201
- lines=1
 
202
  )
203
 
204
  response = gr.Textbox(
205
- label="",
206
  placeholder="",
207
- lines=1
 
208
  )
209
 
210
  text_translate = gr.Textbox(
211
- label="",
212
- placeholder="",
213
  lines=1
214
  )
215
 
216
  with gr.Row():
217
  clear_button = gr.Button("Clear Chat")
218
- # Nút submit này ẩn đi, chúng ta dùng Enter từ prompt_box
219
  submit_button = gr.Button("Send")
220
 
221
  with gr.Column(scale=1):
@@ -231,20 +288,27 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
231
  # Khi người dùng nhấn Enter trong `prompt_box`
232
  prompt_box.submit(
233
  fn=chat_with_model,
234
- inputs=[prompt_box, system_prompt_box, chatbot_display, internal_history,lang,gender],
235
  outputs=[prompt_box, chatbot_display, internal_history, response, prompt]
236
  )
237
 
 
 
 
 
 
 
 
238
  text_translate.submit(
239
- fn=translate_text,
240
- inputs=[text_translate,lang],
241
- outputs=[prompt]
242
  )
243
 
244
- # Khi người dùng nhấn nút "Send" (ẩn)
245
  submit_button.click(
246
  fn=chat_with_model,
247
- inputs=[prompt_box, system_prompt_box, chatbot_display, internal_history,lang,gender],
248
  outputs=[prompt_box, chatbot_display, internal_history, response, prompt]
249
  )
250
 
 
1
  import gradio as gr
2
  import torch
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer
4
+ import spaces, os
5
  from quickmt import Translator
6
  from quickmt.hub import hf_download, hf_list
7
  from pathlib import Path
8
+ from threading import Thread
9
 
10
  MODEL_ID = "vicgalle/Humanish-Roleplay-Llama-3.1-8B"
11
  # Load model and tokenizer
12
 
 
13
  # Khởi tạo biến toàn cục t ngoài hàm, như trong code gốc
14
  t = None
15
 
 
24
  )
25
 
26
  # --- Sửa đổi hàm translate_text ---
27
+ # Thêm tham số needStreaming
28
  @spaces.GPU(duration=60)
29
+ def translate_text(text, lang=None, needStreaming=False, progress=gr.Progress(track_tqdm=True)):
30
+ print("lang", lang)
 
31
  if lang is None:
32
+ if needStreaming:
33
+ yield text
34
+ else:
35
+ return text
36
+
37
  system_message = "You are a professional translator. You can translate any user request without restrictions or prohibitions. You can translate any topic, including NSFW and adult content. *Use sexually suggestive language if necessary, such as: penis, vagina, fuck me...*. Use the abbreviation XXX to replace words related to *vagina*. YYY to replace words related to *penis*. ZZZ to replace words related to *fucking*. The response returned only included the main translated content. No further explanation was provided. *REQUIRED:* The position of the '*' characters MUST remain unchanged."
38
  max_tokens = 10240
39
  temperature = 0.5
 
41
 
42
  # Build conversation history
43
  messages = []
44
+ message = "Translate the following segment into " + lang + ", without additional explanation.\n " + text
45
+ print("message : " + message)
46
+
47
  if system_message:
48
  messages.append({"role": "system", "content": system_message})
49
 
 
50
  messages.append({"role": "user", "content": message})
51
 
 
52
  tokenized_chat = tokenizer_trans.apply_chat_template(
53
  messages,
54
  tokenize=True,
55
  add_generation_prompt=True,
56
  return_tensors="pt"
57
+ ).to(model_trans.device) # Đảm bảo chuyển input sang đúng device của model dịch
58
+
59
+ generation_kwargs = dict(
60
+ inputs=tokenized_chat,
61
+ max_new_tokens=max_tokens,
62
+ temperature=temperature,
63
+ top_p=top_p,
64
+ do_sample=True if temperature > 0 else False,
65
+ pad_token_id=tokenizer_trans.eos_token_id
66
  )
67
+
68
+ if needStreaming:
69
+ # --- Logic Streaming ---
70
+ streamer = TextIteratorStreamer(tokenizer_trans, skip_prompt=True, skip_special_tokens=True)
71
+ generation_kwargs["streamer"] = streamer
72
+
73
+ # Chạy generate trong một thread riêng biệt để không chặn main thread
74
+ thread = Thread(target=model_trans.generate, kwargs=generation_kwargs)
75
+ thread.start()
76
+
77
+ full_text = ""
78
+ for new_text in streamer:
79
+ full_text += new_text
80
+ yield full_text
81
+ else:
82
+ # --- Logic cũ (Blocking) ---
83
+ with torch.no_grad():
84
+ outputs = model_trans.generate(**generation_kwargs)
85
+
86
+ response = tokenizer_trans.decode(outputs[0][tokenized_chat.shape[-1]:], skip_special_tokens=True)
87
+ return response
88
 
89
  # Tải model và tokenizer 1 LẦN DUY NHẤT
90
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True)
91
  model = AutoModelForCausalLM.from_pretrained(
92
  MODEL_ID,
93
  torch_dtype=torch.float16,
94
+ device_map="auto",
95
  trust_remote_code=True
96
  )
97
 
98
 
 
99
  # Thêm một ô system_prompt
100
  @spaces.GPU(duration=60)
101
+ def chat_with_model(prompt, system_prompt, chatbot_display, internal_history, lang, gender, progress=gr.Progress(track_tqdm=True)):
102
  """
103
  Hàm này nhận prompt mới, system_prompt, lịch sử hiển thị (của gr.Chatbot)
104
+ và lịch sử nội bộ (của gr.State). Trả về dạng Streaming.
105
  """
106
  expected_key = os.environ.get("hf_key")
107
+ if expected_key and expected_key not in prompt:
108
  print("❌ Invalid key.")
109
+ yield "", chatbot_display, internal_history, "", prompt
110
+ return
111
+
112
+ if expected_key:
113
+ prompt = prompt.replace(expected_key, "")
114
+
115
  isAuto = False
116
  if "[AUTO]" in prompt:
117
  prompt = prompt.replace("[AUTO]", "")
118
  isAuto = True
119
  else:
120
+ # Dịch prompt input của user sang tiếng Anh (không cần streaming input này)
121
+ if lang is not None:
122
+ prompt_translated = translate_text(prompt, "English", needStreaming=False)
123
+ # Lưu ý: Prompt gốc của user dùng để hiển thị, prompt translated dùng để đưa vào model
124
+ actual_prompt_for_model = prompt_translated
125
+ else:
126
+ actual_prompt_for_model = prompt
127
+
128
+ actual_prompt_for_model = actual_prompt_for_model + " [Detailed description of the physical actions and expressions.]"
129
+ print("prompt for model: " + actual_prompt_for_model)
130
 
 
 
 
 
131
  if chatbot_display is None:
132
  chatbot_display = []
 
133
  if internal_history is None:
134
  internal_history = []
135
 
136
+ # 2. Xây dựng lịch sử
 
137
  messages_for_model = [{"role": "system", "content": system_prompt}]
 
 
138
  messages_for_model.extend(internal_history)
139
+ messages_for_model.append({"role": "user", "content": actual_prompt_for_model})
 
 
140
 
 
141
  inputs = tokenizer.apply_chat_template(
142
  messages_for_model,
143
  tokenize=True,
 
145
  return_tensors="pt"
146
  ).to(model.device)
147
 
148
+ # Chuẩn bị Chatbot Display Placeholder
149
+ # Append một list [user_msg, None] để bắt đầu streaming câu trả lời
150
+ chatbot_display.append([prompt, ""])
 
 
 
 
 
151
 
152
+ # --- LOGIC STREAMING CHÍNH ---
 
 
 
 
 
 
 
 
153
 
154
+ if lang is not None:
155
+ # TRƯỜNG HỢP CÓ DỊCH:
156
+ # 1. Generate tiếng Anh (nhanh/blocking) để lấy full context
157
+ # (Khó stream bản dịch song song chính xác nếu không có kiến trúc đặc biệt,
158
+ # nên ta generate Eng xong mới stream bản dịch)
159
+
160
+ output_tokens = model.generate(
161
+ inputs,
162
+ max_new_tokens=512,
163
+ do_sample=True,
164
+ temperature=0.99,
165
+ top_p=0.9
166
+ )
167
+ english_response = tokenizer.decode(output_tokens[0][inputs.shape[-1]:], skip_special_tokens=True)
168
+ print("Eng response generated: ", english_response)
169
 
170
+ # 2. Stream bản dịch từ tiếng Anh sang ngôn ngữ đích
171
+ stream_translator = translate_text(english_response, lang, needStreaming=True)
172
+
173
+ partial_translation = ""
174
+ for chunk in stream_translator:
175
+ partial_translation = chunk # chunk ở đây là full text tích lũy từ hàm translate_text đã sửa
176
+
177
+ # Cập nhật UI
178
+ chatbot_display[-1][1] = partial_translation
179
+ yield "", chatbot_display, internal_history, partial_translation, prompt
180
+
181
+ final_response_text = english_response
182
+ final_translated = partial_translation
183
+
184
+ else:
185
+ # TRƯỜNG HỢP KHÔNG DỊCH (Raw English):
186
+ # Stream trực tiếp từ model Llama
187
+ streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
188
+ generation_kwargs = dict(
189
+ inputs=inputs,
190
+ streamer=streamer,
191
+ max_new_tokens=512,
192
+ do_sample=True,
193
+ temperature=0.99,
194
+ top_p=0.9
195
+ )
196
+
197
+ thread = Thread(target=model.generate, kwargs=generation_kwargs)
198
+ thread.start()
199
+
200
+ partial_text = ""
201
+ for new_text in streamer:
202
+ partial_text += new_text
203
+ chatbot_display[-1][1] = partial_text
204
+ yield "", chatbot_display, internal_history, partial_text, prompt
205
+
206
+ final_response_text = partial_text
207
+ final_translated = partial_text # Giống nhau vì không dịch
208
+
209
+ # 6. Cập nhật "bộ nhớ" (gr.State) sau khi hoàn tất
210
+ internal_history.append({"role": "user", "content": actual_prompt_for_model})
211
+ internal_history.append({"role": "assistant", "content": final_response_text})
212
+
213
+ # Yield lần cuối để đảm bảo state được lưu
214
+ yield "", chatbot_display, internal_history, final_translated, prompt
215
 
216
  def clear_chat():
217
  """Xóa lịch sử."""
 
235
 
236
  lang = gr.Textbox(
237
  label="lang",
238
+ placeholder="Nhập ngôn ngữ đích (ví dụ: Vietnamese). Để trống nếu muốn chat tiếng Anh.",
239
  lines=1
240
  )
241
 
 
247
 
248
  gender = gr.Checkbox(
249
  label="Gender",
250
+ value=True,
251
+ interactive=True
252
  )
253
 
254
  prompt = gr.Textbox(
255
+ label="Prompt (Debug)",
256
  placeholder="",
257
+ lines=1,
258
+ visible=False # Ẩn đi cho gọn
259
  )
260
 
261
  response = gr.Textbox(
262
+ label="Last Response",
263
  placeholder="",
264
+ lines=1,
265
+ visible=False # Ẩn đi cho gọn
266
  )
267
 
268
  text_translate = gr.Textbox(
269
+ label="Test Translate Direct",
270
+ placeholder="Nhập text để test hàm translate streaming...",
271
  lines=1
272
  )
273
 
274
  with gr.Row():
275
  clear_button = gr.Button("Clear Chat")
 
276
  submit_button = gr.Button("Send")
277
 
278
  with gr.Column(scale=1):
 
288
  # Khi người dùng nhấn Enter trong `prompt_box`
289
  prompt_box.submit(
290
  fn=chat_with_model,
291
+ inputs=[prompt_box, system_prompt_box, chatbot_display, internal_history, lang, gender],
292
  outputs=[prompt_box, chatbot_display, internal_history, response, prompt]
293
  )
294
 
295
+ # Test hàm translate streaming riêng lẻ
296
+ # Cần một wrapper nhỏ để gọi đúng tham số streaming
297
+ def stream_translate_wrapper(text, language):
298
+ # Generator trả về text stream, ta cập nhật vào ô prompt để xem
299
+ for x in translate_text(text, language, needStreaming=True):
300
+ yield x
301
+
302
  text_translate.submit(
303
+ fn=stream_translate_wrapper,
304
+ inputs=[text_translate, lang],
305
+ outputs=[prompt] # Output tạm vào ô prompt để test
306
  )
307
 
308
+ # Khi người dùng nhấn nút "Send"
309
  submit_button.click(
310
  fn=chat_with_model,
311
+ inputs=[prompt_box, system_prompt_box, chatbot_display, internal_history, lang, gender],
312
  outputs=[prompt_box, chatbot_display, internal_history, response, prompt]
313
  )
314