m-ric HF staff commited on
Commit
e20ac5c
1 Parent(s): 37b41e9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -40
app.py CHANGED
@@ -7,7 +7,6 @@ import spaces
7
  tokenizer = AutoTokenizer.from_pretrained("gpt2")
8
  model = AutoModelForCausalLM.from_pretrained("gpt2")
9
 
10
- tokenizer.pad_token_id = tokenizer.eos_token_id
11
  print("Loading finished.")
12
 
13
  print(f"Is CUDA available: {torch.cuda.is_available()}")
@@ -174,22 +173,13 @@ a:before {
174
  """
175
 
176
 
177
- def generate_nodes(token, node, step=0):
178
- """Recursively generate HTML for the tree nodes."""
179
-
180
- html_content = f" <li> <a href='#' class='{('chosen' if node.table is None else '')}' id='{('root' if step==0 else '')}'> <span> <b>{token}</b> </span> "
181
- html_content += node.table if node.table is not None else ""
182
- html_content += "</a>"
183
- if len(node.children.keys()) > 0:
184
- html_content += "<ul> "
185
- for token, subnode in node.children.items():
186
- html_content += generate_nodes(token, subnode, step=step + 1)
187
- html_content += "</ul>"
188
- html_content += "</li>"
189
- return html_content
190
 
191
 
192
- def generate_markdown_table(scores, sequence_prob, top_k=4, chosen_tokens=None):
 
 
193
  markdown_table = """
194
  <table>
195
  <tr>
@@ -204,21 +194,41 @@ def generate_markdown_table(scores, sequence_prob, top_k=4, chosen_tokens=None):
204
  item_class = "chosen"
205
  markdown_table += f"""
206
  <tr class={item_class}>
207
- <td>{token}</td>
208
  <td>{scores[token_idx]:.4f}</td>
209
- <td>{scores[token_idx] + sequence_prob:.4f}</td>
210
  </tr>"""
211
  markdown_table += """
212
  </table>"""
213
  return markdown_table
214
 
215
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  def generate_html(start_sentence, original_tree):
217
 
218
- html_output = """<div class="custom-container">
219
  <div class="tree">
220
- <ul>"""
221
- html_output += generate_nodes(start_sentence, original_tree)
 
 
 
 
 
222
 
223
  html_output += """
224
  </ul>
@@ -236,16 +246,21 @@ from dataclasses import dataclass
236
  @dataclass
237
  class BeamNode:
238
  cumulative_score: float
 
239
  table: str
240
  current_sentence: str
241
- children: Dict[str, "BeamNode"]
242
 
243
 
244
- def generate_beams(start_sentence, scores, sequences, beam_indices):
245
- print(tokenizer.batch_decode(sequences))
246
  sequences = sequences.cpu().numpy()
 
247
  original_tree = BeamNode(
248
- cumulative_score=0, table=None, current_sentence=start_sentence, children={}
 
 
 
 
249
  )
250
  n_beams = len(scores[0])
251
  beam_trees = [original_tree] * n_beams
@@ -302,6 +317,7 @@ def generate_beams(start_sentence, scores, sequences, beam_indices):
302
  markdown_table = generate_markdown_table(
303
  step_scores[beam_ix, :],
304
  current_beam.cumulative_score,
 
305
  chosen_tokens=list(selected_tokens["token"].values),
306
  )
307
  beam_trees[beam_ix].table = markdown_table
@@ -315,18 +331,18 @@ def generate_beams(start_sentence, scores, sequences, beam_indices):
315
  # Update the source tree
316
  source_beam_ix = int(top_df_selected.iloc[beam_ix]["beam_index"])
317
 
318
- previous_len = len(str(original_tree))
319
- beam_trees[source_beam_ix].children[current_token_choice] = BeamNode(
 
 
 
320
  table=None,
321
  children={},
322
  current_sentence=beam_trees[source_beam_ix].current_sentence
323
  + current_token_choice,
324
- cumulative_score=cumulative_scores[source_beam_ix]
325
- + scores[step][source_beam_ix][current_token_choice_ix].numpy(),
326
  )
327
- assert (
328
- len(str(original_tree)) > previous_len
329
- ), "Original tree has not increased size"
330
 
331
  # Reassign all beams at once
332
  beam_trees = [
@@ -337,12 +353,12 @@ def generate_beams(start_sentence, scores, sequences, beam_indices):
337
  # Advance all beams by one token
338
  for beam_ix in range(n_beams):
339
  current_token_choice_ix = top_df_selected.iloc[beam_ix]["token_index"]
340
- current_token_choice = tokenizer.decode([current_token_choice_ix])
341
- beam_trees[beam_ix] = beam_trees[beam_ix].children[current_token_choice]
342
  return original_tree
343
 
344
  @spaces.GPU
345
- def get_beam_search_html(input_text, number_steps, number_beams):
346
  inputs = tokenizer([input_text], return_tensors="pt")
347
 
348
  outputs = model.generate(
@@ -351,19 +367,21 @@ def get_beam_search_html(input_text, number_steps, number_beams):
351
  num_beams=number_beams,
352
  num_return_sequences=number_beams,
353
  return_dict_in_generate=True,
 
354
  output_scores=True,
355
- top_k=5,
356
  do_sample=False,
357
  )
 
 
 
358
 
359
  original_tree = generate_beams(
360
  input_text,
361
  outputs.scores[:],
362
  outputs.sequences[:, :],
363
- outputs.beam_indices[:, :],
364
  )
365
  html = generate_html(input_text, original_tree)
366
- print(html)
367
  return html
368
 
369
 
@@ -374,10 +392,12 @@ with gr.Blocks(
374
  css=STYLE,
375
  ) as demo:
376
  text = gr.Textbox(label="Sentence to decode from", value="Today is")
377
- steps = gr.Slider(label="Number of steps", minimum=1, maximum=8, step=1, value=4)
378
- beams = gr.Slider(label="Number of beams", minimum=2, maximum=4, step=1, value=3)
 
 
379
  button = gr.Button()
380
  out = gr.Markdown(label="Output")
381
- button.click(get_beam_search_html, inputs=[text, steps, beams], outputs=out)
382
 
383
  demo.launch()
 
7
  tokenizer = AutoTokenizer.from_pretrained("gpt2")
8
  model = AutoModelForCausalLM.from_pretrained("gpt2")
9
 
 
10
  print("Loading finished.")
11
 
12
  print(f"Is CUDA available: {torch.cuda.is_available()}")
 
173
  """
174
 
175
 
176
+ def clean(s):
177
+ return s.replace("\n", r"\n").replace("\t", r"\t")
 
 
 
 
 
 
 
 
 
 
 
178
 
179
 
180
+ def generate_markdown_table(
181
+ scores, previous_cumul_score, score_divider, top_k=4, chosen_tokens=None
182
+ ):
183
  markdown_table = """
184
  <table>
185
  <tr>
 
194
  item_class = "chosen"
195
  markdown_table += f"""
196
  <tr class={item_class}>
197
+ <td>{clean(token)}</td>
198
  <td>{scores[token_idx]:.4f}</td>
199
+ <td>{(scores[token_idx] + previous_cumul_score)/score_divider:.4f}</td>
200
  </tr>"""
201
  markdown_table += """
202
  </table>"""
203
  return markdown_table
204
 
205
 
206
+ def generate_nodes(token_ix, node, step):
207
+ """Recursively generate HTML for the tree nodes."""
208
+ token = tokenizer.decode([token_ix])
209
+ html_content = f" <li> <a href='#' class='{('chosen' if node.table is None else '')}'> <span> <b>{token_ix}:<br>{clean(token)}</b> </span> "
210
+ html_content += node.table if node.table is not None else ""
211
+ html_content += "</a>"
212
+ if len(node.children.keys()) > 0:
213
+ html_content += "<ul> "
214
+ for token_ix, subnode in node.children.items():
215
+ html_content += generate_nodes(token_ix, subnode, step=step + 1)
216
+ html_content += "</ul>"
217
+ html_content += "</li>"
218
+ return html_content
219
+
220
+
221
  def generate_html(start_sentence, original_tree):
222
 
223
+ html_output = f"""<div class="custom-container">
224
  <div class="tree">
225
+ <ul>
226
+ <li> <a href='#' id='root'> <span> <b>{start_sentence}</b> </span> {original_tree.table} </a>"""
227
+ if len(original_tree.children.keys()) > 0:
228
+ html_output += "<ul> "
229
+ for token_ix, subnode in original_tree.children.items():
230
+ html_output += generate_nodes(token_ix, subnode, step=1)
231
+ html_output += "</ul>"
232
 
233
  html_output += """
234
  </ul>
 
246
  @dataclass
247
  class BeamNode:
248
  cumulative_score: float
249
+ children_score_divider: float
250
  table: str
251
  current_sentence: str
252
+ children: Dict[int, "BeamNode"]
253
 
254
 
255
+ def generate_beams(start_sentence, scores, sequences, length_penalty):
 
256
  sequences = sequences.cpu().numpy()
257
+ input_length = len(tokenizer([start_sentence], return_tensors="pt"))
258
  original_tree = BeamNode(
259
+ cumulative_score=0,
260
+ table=None,
261
+ current_sentence=start_sentence,
262
+ children={},
263
+ children_score_divider=((input_length + 1) ** length_penalty),
264
  )
265
  n_beams = len(scores[0])
266
  beam_trees = [original_tree] * n_beams
 
317
  markdown_table = generate_markdown_table(
318
  step_scores[beam_ix, :],
319
  current_beam.cumulative_score,
320
+ current_beam.children_score_divider,
321
  chosen_tokens=list(selected_tokens["token"].values),
322
  )
323
  beam_trees[beam_ix].table = markdown_table
 
331
  # Update the source tree
332
  source_beam_ix = int(top_df_selected.iloc[beam_ix]["beam_index"])
333
 
334
+ cumulative_score = (
335
+ cumulative_scores[source_beam_ix]
336
+ + scores[step][source_beam_ix][current_token_choice_ix].numpy()
337
+ )
338
+ beam_trees[source_beam_ix].children[current_token_choice_ix] = BeamNode(
339
  table=None,
340
  children={},
341
  current_sentence=beam_trees[source_beam_ix].current_sentence
342
  + current_token_choice,
343
+ cumulative_score=cumulative_score,
344
+ children_score_divider=((input_length + step + 1) ** length_penalty),
345
  )
 
 
 
346
 
347
  # Reassign all beams at once
348
  beam_trees = [
 
353
  # Advance all beams by one token
354
  for beam_ix in range(n_beams):
355
  current_token_choice_ix = top_df_selected.iloc[beam_ix]["token_index"]
356
+ beam_trees[beam_ix] = beam_trees[beam_ix].children[current_token_choice_ix]
357
+
358
  return original_tree
359
 
360
  @spaces.GPU
361
+ def get_beam_search_html(input_text, number_steps, number_beams, length_penalty):
362
  inputs = tokenizer([input_text], return_tensors="pt")
363
 
364
  outputs = model.generate(
 
367
  num_beams=number_beams,
368
  num_return_sequences=number_beams,
369
  return_dict_in_generate=True,
370
+ length_penalty=-10.0,
371
  output_scores=True,
 
372
  do_sample=False,
373
  )
374
+ print("Sequences:")
375
+ print(tokenizer.batch_decode(outputs.sequences))
376
+ print("Scores:", outputs.sequences_scores)
377
 
378
  original_tree = generate_beams(
379
  input_text,
380
  outputs.scores[:],
381
  outputs.sequences[:, :],
382
+ length_penalty,
383
  )
384
  html = generate_html(input_text, original_tree)
 
385
  return html
386
 
387
 
 
392
  css=STYLE,
393
  ) as demo:
394
  text = gr.Textbox(label="Sentence to decode from", value="Today is")
395
+ with gr.Row():
396
+ steps = gr.Slider(label="Number of steps", minimum=1, maximum=8, step=1, value=4)
397
+ beams = gr.Slider(label="Number of beams", minimum=2, maximum=4, step=1, value=3)
398
+ length_penalty = gr.Slider(label="Length penalty", minimum=-5, maximum=5, step=0.5, value=1)
399
  button = gr.Button()
400
  out = gr.Markdown(label="Output")
401
+ button.click(get_beam_search_html, inputs=[text, steps, beams, length_penalty], outputs=out)
402
 
403
  demo.launch()