tonyassi commited on
Commit
cea4ad7
·
verified ·
1 Parent(s): d22272b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +140 -149
app.py CHANGED
@@ -7,12 +7,12 @@ import gradio as gr
7
  from threading import Thread
8
  from huggingface_hub import login
9
  from icrawler.builtin import BingImageCrawler
10
- import os
11
 
12
  MODEL_LIST = ["mistralai/Mistral-Nemo-Instruct-2407"]
13
  HF_TOKEN = os.environ.get("HF_TOKEN", None)
14
  login(token=HF_TOKEN)
15
- #MODEL = os.environ.get("MODEL_ID")
 
16
  MODEL = "mistralai/Mistral-Nemo-Instruct-2407"
17
 
18
  TITLE = "<h1><center>Mistral-Nemo</center></h1>"
@@ -23,7 +23,6 @@ PLACEHOLDER = """
23
  </center>
24
  """
25
 
26
-
27
  CSS = """
28
  .duplicate-button {
29
  margin: auto !important;
@@ -45,118 +44,157 @@ h3 {
45
  footer{visibility: hidden}
46
  """
47
 
48
- device = "cuda" # for GPU usage or "cpu" for CPU usage
49
 
50
- tokenizer = AutoTokenizer.from_pretrained(MODEL)
 
51
  model = AutoModelForCausalLM.from_pretrained(
52
  MODEL,
53
- torch_dtype=torch.bfloat16,
54
  device_map="auto",
55
- ignore_mismatched_sizes=True)
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  @spaces.GPU()
58
  def get_response(conversation):
59
- temperature = 0.3
60
  max_new_tokens = 512
61
  top_p = 1.0
62
- top_k = 20
63
  penalty = 1.2
64
 
65
- input_text=tokenizer.apply_chat_template(conversation, tokenize=False)
 
66
  inputs = tokenizer.encode(input_text, return_tensors="pt").to(device)
67
- streamer = TextIteratorStreamer(tokenizer, timeout=60.0, skip_prompt=True, skip_special_tokens=True)
68
-
 
 
 
 
 
69
  generate_kwargs = dict(
70
- input_ids=inputs,
71
- max_new_tokens = max_new_tokens,
72
- do_sample = False if temperature == 0 else True,
73
- top_p = top_p,
74
- top_k = top_k,
75
- temperature = temperature,
76
  streamer=streamer,
77
  repetition_penalty=penalty,
78
- pad_token_id = 10,
79
  )
80
 
81
  with torch.no_grad():
82
  thread = Thread(target=model.generate, kwargs=generate_kwargs)
83
  thread.start()
84
-
85
  buffer = ""
86
  for new_text in streamer:
87
  buffer += new_text
88
- #yield buffer
89
 
90
  return buffer
91
-
92
 
93
  @spaces.GPU()
94
  def stream_chat(history, character_a, character_b):
 
 
 
 
 
 
 
95
 
96
- # From A to B
97
- if(history==[]):
98
- conversation_a = [{"role": "system", "content": "You should respond like " + character_b + ". You should have a meaningful conversation. Don't repeat yourself. You should only output your response. You don't need to put quotes around what your saying. You don't need to put your name at the beginning of your response."}]
99
- for answer, prompt in history:
100
- conversation_a.extend([
101
- {"role": "user", "content": prompt},
102
- {"role": "assistant", "content": answer},
103
- ])
104
- conversation_a.append({"role": "user", "content": "You are having a conversation with " + character_a + ". Introduce yourself."})
105
- response_b = get_response(conversation_a)
106
- print('response_b', response_b)
 
 
 
107
  else:
108
- conversation_a = [{"role": "system", "content": "You should respond like " + character_b + ". You should have a meaningful conversation. Don't repeat yourself. You should only output your response. You don't need to put quotes around what your saying. You don't need to put your name at the beginning of your response."}]
109
- for answer, prompt in history:
110
- conversation_a.extend([
111
- {"role": "user", "content": prompt},
112
- {"role": "assistant", "content": answer},
113
- ])
114
- conversation_a.append({"role": "user", "content": history[-1][0] })
115
- response_b = get_response(conversation_a)
116
- print('response_b', response_b)
117
-
118
-
119
- # From B to A
120
- conversation_b = [{"role": "system", "content": "You should respond like " + character_a + ". You should have a meaningful conversation. Don't repeat yourself. You should only output your response. You don't need to put quotes around what your saying. You don't need to put your name at the beginning of your response."}]
121
- for prompt, answer in history:
122
- conversation_b.extend([
123
- {"role": "user", "content": prompt},
124
- {"role": "assistant", "content": answer},
125
- ])
126
- conversation_b.append({"role": "user", "content": response_b })
127
- response_a = get_response(conversation_b)
128
- print('response_a', response_a)
129
-
130
- # Append responses to history
131
- history.append((response_b , response_a ))
132
- print('history', history)
133
-
134
- return history
 
 
 
 
 
 
135
 
136
 
137
  def get_img(keyword):
138
- path = './' + keyword
139
  os.makedirs(path, exist_ok=True)
140
- bing_crawler = BingImageCrawler(storage={'root_dir': path})
141
  bing_crawler.crawl(keyword=keyword, max_num=1)
142
 
143
  # Look for image files in the folder
144
  for file_name in os.listdir(path):
145
- if file_name.lower().endswith(('.png', '.PNG', '.JPG', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff')):
 
 
146
  return os.path.join(path, file_name)
147
-
148
  # If no image is found
149
  return None
150
 
 
151
  def set_characters(a, b):
152
  img_a = get_img(a)
153
- img_b = get_img(b)
154
- return img_a, img_b, gr.update(avatar_images=(img_b, img_a))
155
-
156
- chatbot = gr.Chatbot(height=600,show_label=False)
 
 
 
157
 
158
- theme = gr.themes.Base(
159
- ).set(
160
  body_background_fill="#e1fceb",
161
  color_accent_soft="#ffffff",
162
  border_color_accent="#e1fceb",
@@ -169,94 +207,47 @@ theme = gr.themes.Base(
169
  )
170
 
171
  with gr.Blocks() as demo:
172
- gr.HTML("""
173
-
174
  <center> <h1> Bot vs Bot </h1> </center>
175
-
176
  <center> by <a href="https://www.tonyassi.com/">Tony Assi</a> </center>
177
-
178
  <center> <h3> Pick two icons and watch them have a conversation </h3> </center>
179
- """)
 
 
180
  with gr.Row():
181
- character_a = gr.Textbox(label='Character A', info='Choose a person', placeholder='Socrates, Edgar Allen Poe, George Washington')
182
- character_b = gr.Textbox(label='Character B', info='Choose a person', placeholder='Madonna, Paris Hilton, Liza Minnelli')
183
- character_button = gr.Button('Initiate Characters')
184
- #characters_html = gr.HTML()
 
 
 
 
 
 
 
 
 
185
  with gr.Row():
186
  image_a = gr.Image(show_label=False, interactive=False)
187
- gr.Markdown(' ')
188
  image_b = gr.Image(show_label=False, interactive=False)
189
-
190
-
191
- chat = gr.Chatbot(show_label=False)
192
- submit_button = gr.Button()
193
-
194
- character_button.click(set_characters, inputs=[character_a, character_b], outputs=[image_a, image_b, chat])
195
- submit_button.click(stream_chat, inputs=[chat, character_a, character_b], outputs=[chat])
196
-
197
-
198
- #gr.HTML(TITLE)
199
- #gr.DuplicateButton(value="Duplicate Space for private use", elem_classes="duplicate-button")
200
- #video = gr.HTML("""
201
- # <video src="https://huggingface.co/spaces/ahjvdjf33/moods/resolve/main/Paris-Moods-2/passive3.mp4"
202
- # playsinline autoplay loop muted></video>
203
- #""", elem_id="output_video")
204
- """
205
- gr.ChatInterface(
206
- fn=stream_chat,
207
- chatbot=chatbot,
208
- textbox=gr.Textbox(visible=False),
209
- fill_height=True,
210
- retry_btn=None,
211
- undo_btn=None,
212
- clear_btn=None,
213
- additional_inputs_accordion=gr.Accordion(label="⚙️ Parameters", open=False, render=False, visible=False),
214
- additional_inputs=[
215
- gr.Slider(
216
- minimum=0,
217
- maximum=1,
218
- step=0.1,
219
- value=0.3,
220
- label="Temperature",
221
- render=False,
222
- ),
223
- gr.Slider(
224
- minimum=128,
225
- maximum=8192,
226
- step=1,
227
- value=1024,
228
- label="Max new tokens",
229
- render=False,
230
- ),
231
- gr.Slider(
232
- minimum=0.0,
233
- maximum=1.0,
234
- step=0.1,
235
- value=1.0,
236
- label="top_p",
237
- render=False,
238
- ),
239
- gr.Slider(
240
- minimum=1,
241
- maximum=20,
242
- step=1,
243
- value=20,
244
- label="top_k",
245
- render=False,
246
- ),
247
- gr.Slider(
248
- minimum=0.0,
249
- maximum=2.0,
250
- step=0.1,
251
- value=1.2,
252
- label="Repetition penalty",
253
- render=False,
254
- ),
255
- ],
256
- )
257
- """
258
 
 
 
 
259
 
 
 
 
 
 
 
 
 
 
 
260
 
261
  if __name__ == "__main__":
262
  demo.launch(css=CSS, theme=theme)
 
7
  from threading import Thread
8
  from huggingface_hub import login
9
  from icrawler.builtin import BingImageCrawler
 
10
 
11
  MODEL_LIST = ["mistralai/Mistral-Nemo-Instruct-2407"]
12
  HF_TOKEN = os.environ.get("HF_TOKEN", None)
13
  login(token=HF_TOKEN)
14
+
15
+ # MODEL = os.environ.get("MODEL_ID")
16
  MODEL = "mistralai/Mistral-Nemo-Instruct-2407"
17
 
18
  TITLE = "<h1><center>Mistral-Nemo</center></h1>"
 
23
  </center>
24
  """
25
 
 
26
  CSS = """
27
  .duplicate-button {
28
  margin: auto !important;
 
44
  footer{visibility: hidden}
45
  """
46
 
47
+ device = "cuda" # or "cpu"
48
 
49
+ # NOTE: fix_mistral_regex=True is recommended for this tokenizer
50
+ tokenizer = AutoTokenizer.from_pretrained(MODEL, fix_mistral_regex=True)
51
  model = AutoModelForCausalLM.from_pretrained(
52
  MODEL,
53
+ dtype=torch.bfloat16, # torch_dtype is deprecated in newer transformers
54
  device_map="auto",
55
+ ignore_mismatched_sizes=True
56
+ )
57
+
58
+
59
+ def _system_prompt_for(name: str) -> str:
60
+ return (
61
+ f"You should respond like {name}. "
62
+ "You should have a meaningful conversation. Don't repeat yourself. "
63
+ "You should only output your response. "
64
+ "You don't need to put quotes around what you're saying. "
65
+ "You don't need to put your name at the beginning of your response."
66
+ )
67
+
68
 
69
  @spaces.GPU()
70
  def get_response(conversation):
71
+ temperature = 0.3
72
  max_new_tokens = 512
73
  top_p = 1.0
74
+ top_k = 20
75
  penalty = 1.2
76
 
77
+ # conversation is already in messages format [{'role', 'content'}, ...]
78
+ input_text = tokenizer.apply_chat_template(conversation, tokenize=False)
79
  inputs = tokenizer.encode(input_text, return_tensors="pt").to(device)
80
+ streamer = TextIteratorStreamer(
81
+ tokenizer,
82
+ timeout=60.0,
83
+ skip_prompt=True,
84
+ skip_special_tokens=True,
85
+ )
86
+
87
  generate_kwargs = dict(
88
+ input_ids=inputs,
89
+ max_new_tokens=max_new_tokens,
90
+ do_sample=False if temperature == 0 else True,
91
+ top_p=top_p,
92
+ top_k=top_k,
93
+ temperature=temperature,
94
  streamer=streamer,
95
  repetition_penalty=penalty,
96
+ pad_token_id=10,
97
  )
98
 
99
  with torch.no_grad():
100
  thread = Thread(target=model.generate, kwargs=generate_kwargs)
101
  thread.start()
102
+
103
  buffer = ""
104
  for new_text in streamer:
105
  buffer += new_text
 
106
 
107
  return buffer
108
+
109
 
110
  @spaces.GPU()
111
  def stream_chat(history, character_a, character_b):
112
+ """
113
+ history: list of messages in messages format:
114
+ [{"role": "user" | "assistant", "content": "..."}, ...]
115
+
116
+ In the UI:
117
+ - 'user' messages are Character B
118
+ - 'assistant' messages are Character A
119
 
120
+ Each button click:
121
+ 1. B says something new (as 'user')
122
+ 2. A replies (as 'assistant')
123
+ """
124
+ if history is None:
125
+ history = []
126
+
127
+ # ---------- B speaks ----------
128
+ if len(history) == 0:
129
+ # First turn: B introduces themselves to A
130
+ b_user_prompt = (
131
+ f"You are {character_b}. You are having a conversation with {character_a}. "
132
+ "Introduce yourself and start the conversation."
133
+ )
134
  else:
135
+ # Last A message is what B is responding to
136
+ last_msg = history[-1]
137
+ last_text = last_msg["content"]
138
+ b_user_prompt = (
139
+ f"{character_a} just said: \"{last_text}\". "
140
+ f"Respond in character as {character_b} and continue the conversation."
141
+ )
142
+
143
+ conv_for_b = [
144
+ {"role": "system", "content": _system_prompt_for(character_b)},
145
+ *history,
146
+ {"role": "user", "content": b_user_prompt},
147
+ ]
148
+ response_b = get_response(conv_for_b)
149
+ print("response_b:", response_b)
150
+
151
+ # ---------- A speaks ----------
152
+ conv_for_a = [
153
+ {"role": "system", "content": _system_prompt_for(character_a)},
154
+ *history,
155
+ {"role": "user", "content": response_b},
156
+ ]
157
+ response_a = get_response(conv_for_a)
158
+ print("response_a:", response_a)
159
+
160
+ # ---------- Append to chat history for UI ----------
161
+ new_history = history + [
162
+ {"role": "user", "content": response_b}, # B side
163
+ {"role": "assistant", "content": response_a}, # A side
164
+ ]
165
+ print("history:", new_history)
166
+
167
+ return new_history
168
 
169
 
170
  def get_img(keyword):
171
+ path = "./" + keyword
172
  os.makedirs(path, exist_ok=True)
173
+ bing_crawler = BingImageCrawler(storage={"root_dir": path})
174
  bing_crawler.crawl(keyword=keyword, max_num=1)
175
 
176
  # Look for image files in the folder
177
  for file_name in os.listdir(path):
178
+ if file_name.lower().endswith(
179
+ (".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff")
180
+ ):
181
  return os.path.join(path, file_name)
182
+
183
  # If no image is found
184
  return None
185
 
186
+
187
  def set_characters(a, b):
188
  img_a = get_img(a)
189
+ img_b = get_img(b)
190
+ # avatar_images=(user_avatar, assistant_avatar) => (B, A)
191
+ # Also reset chat history when characters change
192
+ return img_a, img_b, gr.update(avatar_images=(img_b, img_a), value=[])
193
+
194
+
195
+ chatbot = gr.Chatbot(height=600, show_label=False)
196
 
197
+ theme = gr.themes.Base().set(
 
198
  body_background_fill="#e1fceb",
199
  color_accent_soft="#ffffff",
200
  border_color_accent="#e1fceb",
 
207
  )
208
 
209
  with gr.Blocks() as demo:
210
+ gr.HTML(
211
+ """
212
  <center> <h1> Bot vs Bot </h1> </center>
 
213
  <center> by <a href="https://www.tonyassi.com/">Tony Assi</a> </center>
 
214
  <center> <h3> Pick two icons and watch them have a conversation </h3> </center>
215
+ """
216
+ )
217
+
218
  with gr.Row():
219
+ character_a = gr.Textbox(
220
+ label="Character A",
221
+ info="Choose a person",
222
+ placeholder="Socrates, Edgar Allen Poe, George Washington",
223
+ )
224
+ character_b = gr.Textbox(
225
+ label="Character B",
226
+ info="Choose a person",
227
+ placeholder="Madonna, Paris Hilton, Liza Minnelli",
228
+ )
229
+
230
+ character_button = gr.Button("Initiate Characters")
231
+
232
  with gr.Row():
233
  image_a = gr.Image(show_label=False, interactive=False)
234
+ gr.Markdown(" ")
235
  image_b = gr.Image(show_label=False, interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
+ # IMPORTANT: type="messages" for Gradio 6
238
+ chat = gr.Chatbot(show_label=False, type="messages")
239
+ submit_button = gr.Button("Start Conversation")
240
 
241
+ character_button.click(
242
+ set_characters,
243
+ inputs=[character_a, character_b],
244
+ outputs=[image_a, image_b, chat],
245
+ )
246
+ submit_button.click(
247
+ stream_chat,
248
+ inputs=[chat, character_a, character_b],
249
+ outputs=[chat],
250
+ )
251
 
252
  if __name__ == "__main__":
253
  demo.launch(css=CSS, theme=theme)