Spaces:
Sleeping
refactor: Replace ChatInterface with pure Blocks to fix HTTP/2 errors
Browse filesBREAKING CHANGE: Complete rewrite of chat interface
- Remove ChatInterface completely (causes forced SSE usage)
- Implement manual chat UI using gr.Blocks
- Use tuple format for chat history [[user, bot], ...]
- No queue system, no SSE, no HTTP/2 protocol errors
This is the definitive fix for ERR_HTTP2_PROTOCOL_ERROR and
500 Internal Server Error issues on Hugging Face Spaces.
ChatInterface internally enforces queue/SSE which is incompatible
with HF Spaces infrastructure. Pure Blocks gives full control.
Changes:
- chat_response() now returns updated history list
- Manual gr.Chatbot + gr.Textbox + gr.Button layout
- Direct .click() and .submit() event handlers
- No .queue() call anywhere
π€ Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
@@ -119,32 +119,35 @@ def load_model(model_name):
|
|
| 119 |
|
| 120 |
def chat_response(message, history, model_name):
|
| 121 |
"""
|
| 122 |
-
Generate chatbot response
|
| 123 |
|
| 124 |
Args:
|
| 125 |
message: User input
|
| 126 |
-
history: Chat history
|
| 127 |
model_name: Selected model
|
| 128 |
|
| 129 |
Returns:
|
| 130 |
-
|
| 131 |
"""
|
|
|
|
|
|
|
|
|
|
| 132 |
try:
|
| 133 |
# Load model and tokenizer
|
| 134 |
model, tokenizer = load_model(model_name)
|
| 135 |
|
| 136 |
if model is None or tokenizer is None:
|
| 137 |
-
return f"β λͺ¨λΈ '{model_name}'μ λ‘λν μ μμ΅λλ€.
|
| 138 |
|
| 139 |
model_config = MODELS[model_name]
|
| 140 |
|
| 141 |
-
# Build conversation context
|
| 142 |
conversation = ""
|
| 143 |
-
for
|
| 144 |
-
if
|
| 145 |
-
conversation += f"{
|
| 146 |
-
|
| 147 |
-
conversation += f"{
|
| 148 |
|
| 149 |
# Add current message
|
| 150 |
conversation += f"{message}\n"
|
|
@@ -173,7 +176,7 @@ def chat_response(message, history, model_name):
|
|
| 173 |
if not response:
|
| 174 |
response = "I understand. Could you tell me more?"
|
| 175 |
|
| 176 |
-
return response
|
| 177 |
|
| 178 |
except Exception as e:
|
| 179 |
import traceback
|
|
@@ -187,11 +190,11 @@ def chat_response(message, history, model_name):
|
|
| 187 |
print("=" * 50)
|
| 188 |
|
| 189 |
if "out of memory" in error_msg.lower() or "oom" in error_msg.lower():
|
| 190 |
-
return "β λ©λͺ¨λ¦¬ λΆμ‘±. λ μμ λͺ¨λΈμ μ ννκ±°λ μ±μ μ¬μμνμΈμ."
|
| 191 |
elif "cuda" in error_msg.lower() and device == "cpu":
|
| 192 |
-
return "β οΈ GPU μμ΄ CPUλ‘ μ€ν μ€μ
λλ€. μλ΅μ΄ λ릴 μ μμ΅λλ€."
|
| 193 |
else:
|
| 194 |
-
return f"β μ€λ₯: {error_type}\n{error_msg[:200]}
|
| 195 |
|
| 196 |
|
| 197 |
# Global state
|
|
@@ -257,25 +260,49 @@ with gr.Blocks(
|
|
| 257 |
# Warning message for model requirements
|
| 258 |
model_warning = gr.Markdown("", visible=False)
|
| 259 |
|
| 260 |
-
# Chat interface
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
textbox=gr.Textbox(
|
| 271 |
placeholder="π¬ λ©μμ§λ₯Ό μ
λ ₯νμΈμ (μμ΄ κΆμ₯)...",
|
| 272 |
-
|
| 273 |
-
scale=
|
| 274 |
autofocus=True,
|
| 275 |
elem_classes="chatbot-input",
|
| 276 |
-
|
| 277 |
-
)
|
| 278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 279 |
)
|
| 280 |
|
| 281 |
# Examples section with model switching
|
|
@@ -305,10 +332,10 @@ with gr.Blocks(
|
|
| 305 |
def set_example_4():
|
| 306 |
return "kyujinpy/KoT-Llama2-7B-Chat", "μΈκ³΅μ§λ₯μ λν΄ κ°λ¨ν μ€λͺ
ν΄μ£ΌμΈμ."
|
| 307 |
|
| 308 |
-
example_btn_1.click(set_example_1, outputs=[model_dropdown,
|
| 309 |
-
example_btn_2.click(set_example_2, outputs=[model_dropdown,
|
| 310 |
-
example_btn_3.click(set_example_3, outputs=[model_dropdown,
|
| 311 |
-
example_btn_4.click(set_example_4, outputs=[model_dropdown,
|
| 312 |
|
| 313 |
# Show warning and clear chat when model changes
|
| 314 |
def on_model_change(new_model):
|
|
@@ -331,7 +358,7 @@ with gr.Blocks(
|
|
| 331 |
model_dropdown.change(
|
| 332 |
fn=on_model_change,
|
| 333 |
inputs=[model_dropdown],
|
| 334 |
-
outputs=[
|
| 335 |
)
|
| 336 |
|
| 337 |
gr.Markdown(
|
|
|
|
| 119 |
|
| 120 |
def chat_response(message, history, model_name):
|
| 121 |
"""
|
| 122 |
+
Generate chatbot response - Returns updated history (for Blocks)
|
| 123 |
|
| 124 |
Args:
|
| 125 |
message: User input
|
| 126 |
+
history: Chat history as list of [user_msg, bot_msg] pairs
|
| 127 |
model_name: Selected model
|
| 128 |
|
| 129 |
Returns:
|
| 130 |
+
Updated history list
|
| 131 |
"""
|
| 132 |
+
if not message or not message.strip():
|
| 133 |
+
return history
|
| 134 |
+
|
| 135 |
try:
|
| 136 |
# Load model and tokenizer
|
| 137 |
model, tokenizer = load_model(model_name)
|
| 138 |
|
| 139 |
if model is None or tokenizer is None:
|
| 140 |
+
return history + [[message, f"β λͺ¨λΈ '{model_name}'μ λ‘λν μ μμ΅λλ€."]]
|
| 141 |
|
| 142 |
model_config = MODELS[model_name]
|
| 143 |
|
| 144 |
+
# Build conversation context from history
|
| 145 |
conversation = ""
|
| 146 |
+
for user_msg, bot_msg in history:
|
| 147 |
+
if user_msg:
|
| 148 |
+
conversation += f"{user_msg}\n"
|
| 149 |
+
if bot_msg:
|
| 150 |
+
conversation += f"{bot_msg}\n"
|
| 151 |
|
| 152 |
# Add current message
|
| 153 |
conversation += f"{message}\n"
|
|
|
|
| 176 |
if not response:
|
| 177 |
response = "I understand. Could you tell me more?"
|
| 178 |
|
| 179 |
+
return history + [[message, response]]
|
| 180 |
|
| 181 |
except Exception as e:
|
| 182 |
import traceback
|
|
|
|
| 190 |
print("=" * 50)
|
| 191 |
|
| 192 |
if "out of memory" in error_msg.lower() or "oom" in error_msg.lower():
|
| 193 |
+
return history + [[message, "β λ©λͺ¨λ¦¬ λΆμ‘±. λ μμ λͺ¨λΈμ μ ννκ±°λ μ±μ μ¬μμνμΈμ."]]
|
| 194 |
elif "cuda" in error_msg.lower() and device == "cpu":
|
| 195 |
+
return history + [[message, "β οΈ GPU μμ΄ CPUλ‘ μ€ν μ€μ
λλ€. μλ΅μ΄ λ릴 μ μμ΅λλ€."]]
|
| 196 |
else:
|
| 197 |
+
return history + [[message, f"β μ€λ₯: {error_type}\n{error_msg[:200]}"]]
|
| 198 |
|
| 199 |
|
| 200 |
# Global state
|
|
|
|
| 260 |
# Warning message for model requirements
|
| 261 |
model_warning = gr.Markdown("", visible=False)
|
| 262 |
|
| 263 |
+
# Chat interface using pure Blocks (NO ChatInterface to avoid SSE issues)
|
| 264 |
+
chatbot_display = gr.Chatbot(
|
| 265 |
+
height=500,
|
| 266 |
+
label="π¬ λν",
|
| 267 |
+
show_label=False,
|
| 268 |
+
type="tuples", # Use tuple format [[user_msg, bot_msg], ...]
|
| 269 |
+
)
|
| 270 |
+
|
| 271 |
+
with gr.Row():
|
| 272 |
+
msg_input = gr.Textbox(
|
|
|
|
| 273 |
placeholder="π¬ λ©μμ§λ₯Ό μ
λ ₯νμΈμ (μμ΄ κΆμ₯)...",
|
| 274 |
+
show_label=False,
|
| 275 |
+
scale=9,
|
| 276 |
autofocus=True,
|
| 277 |
elem_classes="chatbot-input",
|
| 278 |
+
)
|
| 279 |
+
submit_btn = gr.Button("μ μ‘", scale=1, variant="primary")
|
| 280 |
+
|
| 281 |
+
clear_btn = gr.Button("ποΈ λν μ΄κΈ°ν", size="sm")
|
| 282 |
+
|
| 283 |
+
# Message submission handler
|
| 284 |
+
def submit_message(message, history, model):
|
| 285 |
+
updated_history = chat_response(message, history, model)
|
| 286 |
+
return updated_history, "" # Return updated history and clear input
|
| 287 |
+
|
| 288 |
+
# Button click event (NO queue)
|
| 289 |
+
submit_btn.click(
|
| 290 |
+
fn=submit_message,
|
| 291 |
+
inputs=[msg_input, chatbot_display, model_dropdown],
|
| 292 |
+
outputs=[chatbot_display, msg_input],
|
| 293 |
+
)
|
| 294 |
+
|
| 295 |
+
# Enter key event
|
| 296 |
+
msg_input.submit(
|
| 297 |
+
fn=submit_message,
|
| 298 |
+
inputs=[msg_input, chatbot_display, model_dropdown],
|
| 299 |
+
outputs=[chatbot_display, msg_input],
|
| 300 |
+
)
|
| 301 |
+
|
| 302 |
+
# Clear button
|
| 303 |
+
clear_btn.click(
|
| 304 |
+
fn=lambda: [],
|
| 305 |
+
outputs=chatbot_display,
|
| 306 |
)
|
| 307 |
|
| 308 |
# Examples section with model switching
|
|
|
|
| 332 |
def set_example_4():
|
| 333 |
return "kyujinpy/KoT-Llama2-7B-Chat", "μΈκ³΅μ§λ₯μ λν΄ κ°λ¨ν μ€λͺ
ν΄μ£ΌμΈμ."
|
| 334 |
|
| 335 |
+
example_btn_1.click(set_example_1, outputs=[model_dropdown, msg_input])
|
| 336 |
+
example_btn_2.click(set_example_2, outputs=[model_dropdown, msg_input])
|
| 337 |
+
example_btn_3.click(set_example_3, outputs=[model_dropdown, msg_input])
|
| 338 |
+
example_btn_4.click(set_example_4, outputs=[model_dropdown, msg_input])
|
| 339 |
|
| 340 |
# Show warning and clear chat when model changes
|
| 341 |
def on_model_change(new_model):
|
|
|
|
| 358 |
model_dropdown.change(
|
| 359 |
fn=on_model_change,
|
| 360 |
inputs=[model_dropdown],
|
| 361 |
+
outputs=[chatbot_display, model_warning, model_warning],
|
| 362 |
)
|
| 363 |
|
| 364 |
gr.Markdown(
|