Update app.py
Browse files
app.py
CHANGED
|
@@ -72,10 +72,10 @@ def load_sample_problems():
|
|
| 72 |
"What is the probability of rolling a 6 on a die 3 times in a row?"
|
| 73 |
]
|
| 74 |
return math_samples
|
| 75 |
-
|
| 76 |
def create_math_system_message():
|
| 77 |
"""Specialized system prompt for mathematics with LaTeX"""
|
| 78 |
-
return """You are Mathetics AI, an advanced mathematics tutor and problem solver.
|
| 79 |
|
| 80 |
🧮 **Your Expertise:**
|
| 81 |
- Step-by-step problem solving with clear explanations
|
|
@@ -115,7 +115,7 @@ def render_latex(text):
|
|
| 115 |
try:
|
| 116 |
# Fix common LaTeX patterns from Qwen
|
| 117 |
text = re.sub(r'(?<!\\)\$([^\$]+)\$(?!\$)', r'$\1$', text)
|
| 118 |
-
text = re.sub(r'\$\$([^\$]+)
|
| 119 |
text = re.sub(r'\\\[([^\\]+)\\\]', r'$$\1$$', text)
|
| 120 |
text = re.sub(r'\\\(([^\\]+)\\\)', r'$\1$', text)
|
| 121 |
|
|
@@ -135,206 +135,95 @@ def render_latex(text):
|
|
| 135 |
return text
|
| 136 |
|
| 137 |
def respond(message, history, system_message, max_tokens, temperature, top_p):
|
| 138 |
-
"""
|
| 139 |
-
yield "🤔 Thinking step-by-step..."
|
| 140 |
-
|
| 141 |
client = InferenceClient(model="Qwen/Qwen2.5-Math-7B-Instruct")
|
| 142 |
|
| 143 |
-
messages = []
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
messages.append({"role": "user", "content": user_msg})
|
| 151 |
-
if assistant_msg:
|
| 152 |
-
messages.append({"role": "assistant", "content": assistant_msg})
|
| 153 |
-
|
| 154 |
messages.append({"role": "user", "content": message})
|
| 155 |
|
| 156 |
-
response = ""
|
| 157 |
-
max_tokens = max(max_tokens, 1536)
|
| 158 |
-
|
| 159 |
try:
|
| 160 |
-
|
| 161 |
messages,
|
| 162 |
max_tokens=max_tokens,
|
| 163 |
-
stream=True,
|
| 164 |
temperature=temperature,
|
| 165 |
top_p=top_p,
|
| 166 |
-
timeout=
|
| 167 |
-
)
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
token = choices[0].delta.content
|
| 171 |
-
response += token
|
| 172 |
-
|
| 173 |
-
if len(response) % 50 == 0 or token.strip() in ['.', '!', '?', '\n']:
|
| 174 |
-
formatted = render_latex(response)
|
| 175 |
-
yield formatted
|
| 176 |
-
else:
|
| 177 |
-
yield response
|
| 178 |
-
|
| 179 |
-
final_formatted = render_latex(response.strip())
|
| 180 |
-
yield final_formatted
|
| 181 |
-
|
| 182 |
except Exception as e:
|
| 183 |
-
|
| 184 |
-
yield error_msg
|
| 185 |
|
| 186 |
def get_random_sample():
|
| 187 |
"""Get a random sample problem - loads datasets if needed"""
|
| 188 |
global math_samples
|
| 189 |
if math_samples is None:
|
| 190 |
-
math_samples = load_sample_problems()
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
return "Solve for x: 2x² + 5x - 3 = 0"
|
| 194 |
-
|
| 195 |
def insert_sample_to_chat(difficulty):
|
| 196 |
"""Insert random sample into chat input"""
|
| 197 |
-
|
| 198 |
-
return sample
|
| 199 |
|
| 200 |
def show_help():
|
| 201 |
return """**🧮 Math Help Tips:**
|
| 202 |
|
| 203 |
-
1.
|
| 204 |
-
2.
|
| 205 |
-
3.
|
| 206 |
-
4.
|
| 207 |
-
5.
|
| 208 |
-
|
| 209 |
-
**Pro Tip**: Crank tokens to 1500+ for competition problems!"""
|
| 210 |
|
| 211 |
-
|
| 212 |
-
def chat_response(message, history):
|
| 213 |
-
"""Main chat function - compatible with all Gradio versions"""
|
| 214 |
-
bot_response = ""
|
| 215 |
-
for response in respond(
|
| 216 |
-
message,
|
| 217 |
-
history,
|
| 218 |
-
create_math_system_message(),
|
| 219 |
-
1024, # Default tokens
|
| 220 |
-
0.3, # Default temperature
|
| 221 |
-
0.85 # Default top_p
|
| 222 |
-
):
|
| 223 |
-
bot_response = response
|
| 224 |
-
history.append([message, bot_response])
|
| 225 |
-
yield history, ""
|
| 226 |
-
|
| 227 |
-
return history, ""
|
| 228 |
|
| 229 |
-
#
|
| 230 |
-
with gr.Blocks(
|
| 231 |
-
|
| 232 |
-
theme=gr.themes.Soft(),
|
| 233 |
-
css="""
|
| 234 |
-
/* Enhanced math rendering */
|
| 235 |
-
.markdown-body { font-family: 'Times New Roman', Georgia, serif; line-height: 1.6; }
|
| 236 |
-
.katex { font-size: 1.1em !important; color: #2c3e50; }
|
| 237 |
-
.katex-display { font-size: 1.3em !important; text-align: center; margin: 1em 0; padding: 10px; background: #f8f9fa; border-radius: 8px; }
|
| 238 |
-
|
| 239 |
-
/* Chat styling */
|
| 240 |
-
.message { margin: 10px 0; padding: 12px; border-radius: 8px; }
|
| 241 |
-
.user { background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-left: 4px solid #2196f3; }
|
| 242 |
-
.assistant { background: linear-gradient(135deg, #f5f5f5 0%, #eeeeee 100%); border-left: 4px solid #4caf50; }
|
| 243 |
-
|
| 244 |
-
/* Sidebar */
|
| 245 |
-
.difficulty-selector { background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%); padding: 15px; border-radius: 10px; margin: 10px 0; border: 1px solid #ffcc80; }
|
| 246 |
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
"""
|
| 250 |
-
) as demo:
|
| 251 |
|
| 252 |
-
gr.
|
| 253 |
-
# 🧮 **Mathetics AI** - Advanced Mathematics Solver
|
| 254 |
|
| 255 |
-
**Your Personal AI Math Tutor** | Step-by-step solutions with beautiful LaTeX rendering
|
| 256 |
-
|
| 257 |
-
---
|
| 258 |
-
""")
|
| 259 |
-
|
| 260 |
-
# Main chat interface
|
| 261 |
-
chatbot = gr.Chatbot(
|
| 262 |
-
height=500,
|
| 263 |
-
show_label=False,
|
| 264 |
-
avatar_images=("🧑🎓", "🤖"),
|
| 265 |
-
bubble_full_width=False
|
| 266 |
-
)
|
| 267 |
-
|
| 268 |
-
with gr.Row():
|
| 269 |
-
msg = gr.Textbox(
|
| 270 |
-
placeholder="Ask: 'Find the derivative of 3x² + 2x - 1'",
|
| 271 |
-
scale=4,
|
| 272 |
-
show_label=False,
|
| 273 |
-
lines=2
|
| 274 |
-
)
|
| 275 |
-
submit_btn = gr.Button("🚀 Solve", variant="primary", scale=1)
|
| 276 |
-
|
| 277 |
-
# Controls
|
| 278 |
with gr.Row():
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
with gr.Column(scale=1):
|
| 284 |
-
difficulty_preset = gr.Dropdown(
|
| 285 |
-
choices=["Elementary", "High School", "College", "Competition"],
|
| 286 |
-
value="High School",
|
| 287 |
-
label="🎯 Difficulty",
|
| 288 |
-
elem_classes=["difficulty-selector"]
|
| 289 |
-
)
|
| 290 |
-
sample_btn = gr.Button("🎲 Random Problem", variant="secondary")
|
| 291 |
-
help_btn = gr.Button("❓ Help", variant="secondary")
|
| 292 |
|
| 293 |
-
# Examples
|
| 294 |
gr.Examples(
|
| 295 |
examples=[
|
| 296 |
-
["
|
| 297 |
-
["
|
| 298 |
-
["
|
| 299 |
-
["What is ∫(2x³ - 5x + 3) dx?"],
|
| 300 |
-
["Solve the system: x + 2y = 7, 3x - y = 4"]
|
| 301 |
],
|
| 302 |
-
inputs=msg
|
| 303 |
-
label="💡 Quick Examples"
|
| 304 |
)
|
| 305 |
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
|
| 310 |
def clear_chat():
|
|
|
|
| 311 |
return [], ""
|
| 312 |
|
| 313 |
-
msg.submit(
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
outputs=msg
|
| 320 |
-
)
|
| 321 |
-
|
| 322 |
-
help_btn.click(
|
| 323 |
-
show_help,
|
| 324 |
-
outputs=gr.Markdown(visible=True, label="Help")
|
| 325 |
)
|
| 326 |
-
|
| 327 |
-
# Clear button
|
| 328 |
-
gr.Button("🗑️ Clear Chat", variant="secondary").click(
|
| 329 |
-
clear_chat,
|
| 330 |
-
outputs=[chatbot, msg]
|
| 331 |
-
)
|
| 332 |
-
|
| 333 |
-
gr.Markdown("""
|
| 334 |
-
---
|
| 335 |
-
**🔧 Tech:** Qwen2.5-Math-7B • LaTeX rendering • Streaming responses
|
| 336 |
-
**💡 Tip:** Use "lim(x->0)" for limits, crank tokens for complex problems
|
| 337 |
-
""")
|
| 338 |
|
| 339 |
-
|
| 340 |
-
demo.launch()
|
|
|
|
| 72 |
"What is the probability of rolling a 6 on a die 3 times in a row?"
|
| 73 |
]
|
| 74 |
return math_samples
|
| 75 |
+
|
| 76 |
def create_math_system_message():
|
| 77 |
"""Specialized system prompt for mathematics with LaTeX"""
|
| 78 |
+
return r"""You are Mathetics AI, an advanced mathematics tutor and problem solver.
|
| 79 |
|
| 80 |
🧮 **Your Expertise:**
|
| 81 |
- Step-by-step problem solving with clear explanations
|
|
|
|
| 115 |
try:
|
| 116 |
# Fix common LaTeX patterns from Qwen
|
| 117 |
text = re.sub(r'(?<!\\)\$([^\$]+)\$(?!\$)', r'$\1$', text)
|
| 118 |
+
text = re.sub(r'\$\$([^\$]+)\$$', r'$$\1$$', text)
|
| 119 |
text = re.sub(r'\\\[([^\\]+)\\\]', r'$$\1$$', text)
|
| 120 |
text = re.sub(r'\\\(([^\\]+)\\\)', r'$\1$', text)
|
| 121 |
|
|
|
|
| 135 |
return text
|
| 136 |
|
| 137 |
def respond(message, history, system_message, max_tokens, temperature, top_p):
|
| 138 |
+
"""Non-streaming response for stability"""
|
|
|
|
|
|
|
| 139 |
client = InferenceClient(model="Qwen/Qwen2.5-Math-7B-Instruct")
|
| 140 |
|
| 141 |
+
messages = [{"role": "system", "content": system_message}]
|
| 142 |
+
# Iterate over history dicts and add user/assistant pairs
|
| 143 |
+
for msg in history:
|
| 144 |
+
if msg["role"] == "user":
|
| 145 |
+
messages.append({"role": "user", "content": msg["content"]})
|
| 146 |
+
elif msg["role"] == "assistant":
|
| 147 |
+
messages.append({"role": "assistant", "content": msg["content"]})
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
messages.append({"role": "user", "content": message})
|
| 149 |
|
|
|
|
|
|
|
|
|
|
| 150 |
try:
|
| 151 |
+
completion = client.chat_completion(
|
| 152 |
messages,
|
| 153 |
max_tokens=max_tokens,
|
|
|
|
| 154 |
temperature=temperature,
|
| 155 |
top_p=top_p,
|
| 156 |
+
timeout=30
|
| 157 |
+
)
|
| 158 |
+
response = completion.choices[0].message.content
|
| 159 |
+
return render_latex(response)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
except Exception as e:
|
| 161 |
+
return f"❌ Error: {str(e)[:100]}... Try a simpler problem."
|
|
|
|
| 162 |
|
| 163 |
def get_random_sample():
|
| 164 |
"""Get a random sample problem - loads datasets if needed"""
|
| 165 |
global math_samples
|
| 166 |
if math_samples is None:
|
| 167 |
+
math_samples = load_sample_problems()
|
| 168 |
+
return random.choice(math_samples)
|
| 169 |
+
|
|
|
|
|
|
|
| 170 |
def insert_sample_to_chat(difficulty):
|
| 171 |
"""Insert random sample into chat input"""
|
| 172 |
+
return get_random_sample()
|
|
|
|
| 173 |
|
| 174 |
def show_help():
|
| 175 |
return """**🧮 Math Help Tips:**
|
| 176 |
|
| 177 |
+
1. Be Specific: "Find the derivative of x² + 3x" instead of "help with calculus"
|
| 178 |
+
2. Request Steps: "Show me step-by-step how to solve..."
|
| 179 |
+
3. Ask for Verification: "Check if my answer x=5 is correct"
|
| 180 |
+
4. Alternative Methods: "What's another way to solve this integral?"
|
| 181 |
+
5. Use Clear Notation: "lim(x->0)" for limits
|
|
|
|
|
|
|
| 182 |
|
| 183 |
+
Pro Tip: Crank tokens to 1500+ for competition problems!"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
|
| 185 |
+
# Simple Chatbot interface
|
| 186 |
+
with gr.Blocks(title="🧮 Mathetics AI") as demo:
|
| 187 |
+
gr.Markdown("# 🧮 **Mathetics AI** - Math Tutor\nPowered by Qwen 2.5-Math")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
|
| 189 |
+
chatbot = gr.Chatbot(height=500, label="Conversation", type='messages')
|
| 190 |
+
help_text = gr.Markdown(visible=False)
|
|
|
|
|
|
|
| 191 |
|
| 192 |
+
msg = gr.Textbox(placeholder="Ask a math problem...", show_label=False)
|
|
|
|
| 193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
with gr.Row():
|
| 195 |
+
submit = gr.Button("Solve", variant="primary")
|
| 196 |
+
clear = gr.Button("Clear", variant="secondary")
|
| 197 |
+
sample = gr.Button("Random Problem", variant="secondary")
|
| 198 |
+
help_btn = gr.Button("Help", variant="secondary")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
|
|
|
|
| 200 |
gr.Examples(
|
| 201 |
examples=[
|
| 202 |
+
["derivative of x^2 sin(x)"],
|
| 203 |
+
["area of triangle 5-12-13"],
|
| 204 |
+
["∫x^2 dx"]
|
|
|
|
|
|
|
| 205 |
],
|
| 206 |
+
inputs=msg
|
|
|
|
| 207 |
)
|
| 208 |
|
| 209 |
+
def chat_response(message, history):
|
| 210 |
+
"""Updated to use dict-based history for type='messages'."""
|
| 211 |
+
bot_response = respond(message, history, create_math_system_message(), 1024, 0.3, 0.85)
|
| 212 |
+
# Append as dicts, not tuples
|
| 213 |
+
history.append({"role": "user", "content": message})
|
| 214 |
+
history.append({"role": "assistant", "content": bot_response})
|
| 215 |
+
return history, ""
|
| 216 |
|
| 217 |
def clear_chat():
|
| 218 |
+
"""Clear the chat history and textbox."""
|
| 219 |
return [], ""
|
| 220 |
|
| 221 |
+
msg.submit(chat_response, [msg, chatbot], [chatbot, msg])
|
| 222 |
+
submit.click(chat_response, [msg, chatbot], [chatbot, msg])
|
| 223 |
+
clear.click(clear_chat, outputs=[chatbot, msg])
|
| 224 |
+
sample.click(insert_sample_to_chat, outputs=msg)
|
| 225 |
+
help_btn.click(lambda: (show_help(), gr.update(visible=True)), outputs=[help_text, help_text]).then(
|
| 226 |
+
lambda: gr.update(visible=False), outputs=help_text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
|
| 229 |
+
demo.launch()
|
|
|