David-stout commited on
Commit
8e9fa5b
·
verified ·
1 Parent(s): ae2e88d

Fix blank screen during generation, stream thinking tokens, Enter to send, lower GPU duration

Browse files
Files changed (1) hide show
  1. app.py +43 -9
app.py CHANGED
@@ -123,6 +123,19 @@ HEADER = """
123
  </div>
124
  """
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  PLACEHOLDER = """
127
  <div class="twil-empty">
128
  <img class="twil-cube" src="/gradio_api/file=brand/webai-cube-256.webp" alt="" />
@@ -155,12 +168,18 @@ CSS = """
155
 
156
  * { box-shadow: none !important; text-shadow: none !important; }
157
  html, body, #root, .gradio-container, .gradio-container > .main,
158
- .gradio-container .contain, .fillable, .gradio-container .wrap,
159
  .gradio-container .column, .gradio-container .row, .contain, .wrapper {
160
  background: var(--weba-canvas) !important;
161
  box-shadow: none !important;
162
  filter: none !important;
163
  }
 
 
 
 
 
 
164
  html, body, .gradio-container, .gradio-container > .main, .fillable,
165
  .contain, .app {
166
  height: 100% !important;
@@ -651,6 +670,9 @@ def _parse_think(raw: str) -> tuple[str, str, bool]:
651
  """Return (think, answer, think_open) from a possibly streaming reply."""
652
  open_idx = raw.find(THINK_OPEN)
653
  if open_idx == -1:
 
 
 
654
  return "", raw, False
655
  rest = raw[open_idx + len(THINK_OPEN) :]
656
  close_idx = rest.find(THINK_CLOSE)
@@ -662,9 +684,11 @@ def _parse_think(raw: str) -> tuple[str, str, bool]:
662
  return think, answer, False
663
 
664
 
665
- def _gpu_seconds(history, max_new_tokens=2048, *args, **kwargs):
666
- tokens = int(max_new_tokens or 2048)
667
- return min(180, max(45, 25 + tokens // 18))
 
 
668
 
669
 
670
  def _history_for_model(history: list) -> list[dict]:
@@ -685,15 +709,20 @@ def _history_for_model(history: list) -> list[dict]:
685
 
686
  def _stream_tokens(conversation: list[dict], max_new_tokens: int, temperature: float, top_p: float, enable_thinking: bool) -> Iterator[str]:
687
  if PREVIEW:
 
 
688
  demo = (
689
  f"{THINK_OPEN}\n"
690
- "Check the premises, then the conclusion. The argument is a classic Barbara syllogism.\n"
 
 
691
  f"{THINK_CLOSE}\n\n"
692
  "Answer: entailment."
693
  )
694
  acc = ""
695
  for ch in demo:
696
  acc += ch
 
697
  yield acc
698
  return
699
 
@@ -801,6 +830,10 @@ def generate_reply(history, max_new_tokens, temperature, top_p, enable_thinking)
801
  answer_msg["content"] = raw.strip()
802
  if not any(m is answer_msg for m in history):
803
  history.append(answer_msg)
 
 
 
 
804
  yield history
805
 
806
  if think_msg["content"]:
@@ -849,7 +882,7 @@ with gr.Blocks(fill_height=True, fill_width=True, elem_id="app-root") as demo:
849
  )
850
  send = gr.Button("↑", elem_id="send-btn", scale=0)
851
  with gr.Accordion("Parameters", open=False, elem_id="params-box"):
852
- max_new_tokens = gr.Slider(256, 4096, value=2048, step=256, label="Max new tokens")
853
  temperature = gr.Slider(0, 1.5, value=0, step=0.05, label="Temperature (0 = greedy)")
854
  top_p = gr.Slider(0.1, 1.0, value=0.95, step=0.05, label="Top-p")
855
  enable_thinking = gr.Checkbox(value=True, label="Enable thinking")
@@ -876,7 +909,7 @@ with gr.Blocks(fill_height=True, fill_width=True, elem_id="app-root") as demo:
876
  [chatbot, max_new_tokens, temperature, top_p, enable_thinking],
877
  chatbot,
878
  concurrency_limit=1,
879
- show_progress="minimal",
880
  )
881
  prompt.submit(
882
  queue_message,
@@ -888,7 +921,7 @@ with gr.Blocks(fill_height=True, fill_width=True, elem_id="app-root") as demo:
888
  [chatbot, max_new_tokens, temperature, top_p, enable_thinking],
889
  chatbot,
890
  concurrency_limit=1,
891
- show_progress="minimal",
892
  )
893
  for btn, (_, template) in zip(chip_btns, CHIPS):
894
  btn.click(lambda t=template: t, outputs=prompt)
@@ -908,13 +941,14 @@ with gr.Blocks(fill_height=True, fill_width=True, elem_id="app-root") as demo:
908
  [chatbot, max_new_tokens, temperature, top_p, enable_thinking],
909
  chatbot,
910
  concurrency_limit=1,
911
- show_progress="minimal",
912
  )
913
 
914
  if __name__ == "__main__":
915
  demo.launch(
916
  theme=THEME,
917
  css=CSS,
 
918
  allowed_paths=[str(ASSETS), str(ASSETS.parent)],
919
  ssr_mode=False,
920
  )
 
123
  </div>
124
  """
125
 
126
+ HEAD = """
127
+ <script>
128
+ document.addEventListener("keydown", (e) => {
129
+ if (e.key !== "Enter" || e.shiftKey || e.isComposing) return;
130
+ const ta = document.querySelector("#twil-input textarea");
131
+ if (!ta || e.target !== ta) return;
132
+ e.preventDefault();
133
+ e.stopPropagation();
134
+ document.querySelector("#send-btn")?.click();
135
+ }, true);
136
+ </script>
137
+ """
138
+
139
  PLACEHOLDER = """
140
  <div class="twil-empty">
141
  <img class="twil-cube" src="/gradio_api/file=brand/webai-cube-256.webp" alt="" />
 
168
 
169
  * { box-shadow: none !important; text-shadow: none !important; }
170
  html, body, #root, .gradio-container, .gradio-container > .main,
171
+ .gradio-container .contain, .fillable,
172
  .gradio-container .column, .gradio-container .row, .contain, .wrapper {
173
  background: var(--weba-canvas) !important;
174
  box-shadow: none !important;
175
  filter: none !important;
176
  }
177
+ /* Never paint over content while a job is running: the status tracker
178
+ overlay must stay transparent or the chat looks blank mid-generation. */
179
+ .gradio-container [data-testid="status-tracker"],
180
+ .gradio-container .wrap.default {
181
+ background: transparent !important;
182
+ }
183
  html, body, .gradio-container, .gradio-container > .main, .fillable,
184
  .contain, .app {
185
  height: 100% !important;
 
670
  """Return (think, answer, think_open) from a possibly streaming reply."""
671
  open_idx = raw.find(THINK_OPEN)
672
  if open_idx == -1:
673
+ # A partially streamed opening tag is not an answer yet.
674
+ if raw.strip() and THINK_OPEN.startswith(raw.strip()):
675
+ return "", "", False
676
  return "", raw, False
677
  rest = raw[open_idx + len(THINK_OPEN) :]
678
  close_idx = rest.find(THINK_CLOSE)
 
684
  return think, answer, False
685
 
686
 
687
+ def _gpu_seconds(history, max_new_tokens=1024, *args, **kwargs):
688
+ # ZeroGPU adds its own startup overhead on top of this request, and
689
+ # anonymous visitors have a small quota — keep the ask modest.
690
+ tokens = int(max_new_tokens or 1024)
691
+ return min(90, max(25, 10 + tokens // 30))
692
 
693
 
694
  def _history_for_model(history: list) -> list[dict]:
 
709
 
710
  def _stream_tokens(conversation: list[dict], max_new_tokens: int, temperature: float, top_p: float, enable_thinking: bool) -> Iterator[str]:
711
  if PREVIEW:
712
+ import time
713
+
714
  demo = (
715
  f"{THINK_OPEN}\n"
716
+ "Check the premises, then the conclusion. Premise 1 gives Rain -> Wet. "
717
+ "Premise 2 observes Wet. Inferring Rain from Wet affirms the consequent, "
718
+ "which is invalid. The argument is a classic Barbara syllogism otherwise.\n"
719
  f"{THINK_CLOSE}\n\n"
720
  "Answer: entailment."
721
  )
722
  acc = ""
723
  for ch in demo:
724
  acc += ch
725
+ time.sleep(0.02)
726
  yield acc
727
  return
728
 
 
830
  answer_msg["content"] = raw.strip()
831
  if not any(m is answer_msg for m in history):
832
  history.append(answer_msg)
833
+ elif any(m is answer_msg for m in history):
834
+ # A partial tag was mistaken for an answer earlier; retract it.
835
+ history.remove(answer_msg)
836
+ answer_msg["content"] = ""
837
  yield history
838
 
839
  if think_msg["content"]:
 
882
  )
883
  send = gr.Button("↑", elem_id="send-btn", scale=0)
884
  with gr.Accordion("Parameters", open=False, elem_id="params-box"):
885
+ max_new_tokens = gr.Slider(256, 4096, value=1024, step=256, label="Max new tokens")
886
  temperature = gr.Slider(0, 1.5, value=0, step=0.05, label="Temperature (0 = greedy)")
887
  top_p = gr.Slider(0.1, 1.0, value=0.95, step=0.05, label="Top-p")
888
  enable_thinking = gr.Checkbox(value=True, label="Enable thinking")
 
909
  [chatbot, max_new_tokens, temperature, top_p, enable_thinking],
910
  chatbot,
911
  concurrency_limit=1,
912
+ show_progress="hidden",
913
  )
914
  prompt.submit(
915
  queue_message,
 
921
  [chatbot, max_new_tokens, temperature, top_p, enable_thinking],
922
  chatbot,
923
  concurrency_limit=1,
924
+ show_progress="hidden",
925
  )
926
  for btn, (_, template) in zip(chip_btns, CHIPS):
927
  btn.click(lambda t=template: t, outputs=prompt)
 
941
  [chatbot, max_new_tokens, temperature, top_p, enable_thinking],
942
  chatbot,
943
  concurrency_limit=1,
944
+ show_progress="hidden",
945
  )
946
 
947
  if __name__ == "__main__":
948
  demo.launch(
949
  theme=THEME,
950
  css=CSS,
951
+ head=HEAD,
952
  allowed_paths=[str(ASSETS), str(ASSETS.parent)],
953
  ssr_mode=False,
954
  )