Khoi1234210 commited on
Commit
819a580
ยท
verified ยท
1 Parent(s): 2066847

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -163
app.py CHANGED
@@ -6,7 +6,7 @@ import random
6
  import re
7
 
8
  # Load math datasets for sample problems
9
- print("Loading datasets...")
10
  fw = load_dataset("HuggingFaceFW/fineweb-edu", name="sample-10BT", split="train", streaming=True)
11
  ds = load_dataset("HuggingFaceH4/ultrachat_200k", streaming=True)
12
 
@@ -59,12 +59,11 @@ def create_math_system_message():
59
 
60
  **LaTeX Guidelines:**
61
  - Use $...$ for inline math: $x^2 + y^2 = z^2$
62
- - Use $$...$$ or \[...\] for display math
63
  - Box final answers: \boxed{answer}
64
  - Fractions: \frac{numerator}{denominator}
65
  - Limits: \lim_{x \to 0}
66
  - Derivatives: \frac{d}{dx} or f'(x)
67
- - Integrals: \int f(x) \, dx
68
 
69
  Always be precise, educational, and encourage mathematical thinking."""
70
 
@@ -75,21 +74,16 @@ def render_latex(text):
75
 
76
  try:
77
  # Fix common LaTeX patterns from Qwen
78
- # Ensure proper inline math delimiters
79
  text = re.sub(r'(?<!\\)\$([^\$]+)\$(?!\$)', r'$\1$', text)
80
-
81
- # Convert display math
82
  text = re.sub(r'\$\$([^\$]+)\$\$', r'$$\1$$', text)
83
  text = re.sub(r'\\\[([^\\]+)\\\]', r'$$\1$$', text)
84
  text = re.sub(r'\\\(([^\\]+)\\\)', r'$\1$', text)
85
 
86
  # Fix escaped LaTeX commands
87
- text = re.sub(r'\\(lim|frac|sqrt|int|sum|prod|partial|nabla|infty|to|le|ge|neq|approx|cdot|times|div|deg|prime|log|ln|log|sin|cos|tan|cot|sec|csc|arcsin|arccos|arctan|sinh|cosh)', r'\1', text)
88
 
89
  # Ensure boxed answers render
90
  text = re.sub(r'\\boxed\{([^}]+)\}', r'$$\boxed{\1}$$', text)
91
-
92
- # Fix fractions
93
  text = re.sub(r'\\frac\{([^}]+)\}\{([^}]+)\}', r'$\frac{\1}{\2}$', text)
94
 
95
  # Clean up extra spaces
@@ -97,34 +91,30 @@ def render_latex(text):
97
 
98
  except Exception as e:
99
  print(f"โš ๏ธ LaTeX formatting error: {e}")
100
- # Return original if processing fails
101
 
102
  return text
103
 
104
  def respond(message, history, system_message, max_tokens, temperature, top_p):
105
  """Enhanced response with proper LaTeX streaming"""
106
- # Show initial thinking
107
  yield "๐Ÿค” Thinking step-by-step..."
108
 
109
- # Use Qwen Math model
110
  client = InferenceClient(model="Qwen/Qwen2.5-Math-7B-Instruct")
111
 
112
- # Build messages properly
113
  messages = []
114
  if system_message:
115
  messages.append({"role": "system", "content": system_message})
116
 
117
- # Add conversation history
118
- for msg in history:
119
- if msg.get("role") == "user":
120
- messages.append({"role": "user", "content": msg["content"]})
121
- elif msg.get("role") == "assistant":
122
- messages.append({"role": "assistant", "content": msg["content"]})
123
 
124
  messages.append({"role": "user", "content": message})
125
 
126
  response = ""
127
- max_tokens = max(max_tokens, 1536) # Ensure no truncation
128
 
129
  try:
130
  for message_chunk in client.chat_completion(
@@ -133,26 +123,24 @@ def respond(message, history, system_message, max_tokens, temperature, top_p):
133
  stream=True,
134
  temperature=temperature,
135
  top_p=top_p,
136
- timeout=60 # Add timeout for stability
137
  ):
138
  choices = message_chunk.choices
139
  if len(choices) and choices[0].delta.content:
140
  token = choices[0].delta.content
141
  response += token
142
 
143
- # Stream with formatting every few tokens
144
  if len(response) % 50 == 0 or token.strip() in ['.', '!', '?', '\n']:
145
  formatted = render_latex(response)
146
  yield formatted
147
  else:
148
  yield response
149
 
150
- # Final formatted response
151
  final_formatted = render_latex(response.strip())
152
  yield final_formatted
153
 
154
  except Exception as e:
155
- error_msg = f"โŒ **Error**: {str(e)[:100]}...\n\n๐Ÿ’ก **Troubleshooting**:\nโ€ข Try a simpler problem\nโ€ข Check your connection\nโ€ข Wait a moment and retry"
156
  yield error_msg
157
 
158
  def get_random_sample():
@@ -164,7 +152,7 @@ def get_random_sample():
164
  def insert_sample_to_chat(difficulty):
165
  """Insert random sample into chat input"""
166
  sample = get_random_sample()
167
- return sample, "" # Return sample for input, clear status
168
 
169
  def show_help():
170
  return """**๐Ÿงฎ Math Help Tips:**
@@ -173,181 +161,137 @@ def show_help():
173
  2. **Request Steps**: "Show me step-by-step how to solve..."
174
  3. **Ask for Verification**: "Check if my answer x=5 is correct"
175
  4. **Alternative Methods**: "What's another way to solve this integral?"
176
- 5. **Use Clear Notation**: "lim(x->0)" instead of arrows for mobile
177
-
178
- **LaTeX Examples:**
179
- - Inline: $x^2 + y^2 = z^2$
180
- - Display: $$\int x^2 \, dx = \frac{x^3}{3} + C$$
181
- - Boxed: $$\boxed{x = 5}$$
182
 
183
  **Pro Tip**: Crank tokens to 1500+ for competition problems!"""
184
 
185
- # Enhanced ChatInterface with better LaTeX support
186
- chatbot = gr.ChatInterface(
187
- respond,
188
- type="messages",
189
- title="๐Ÿงฎ **Mathetics AI** - Advanced Mathematics Solver",
190
- description="""
191
- **Powered by Qwen 2.5-Math** | **Specialized for Mathematical Problem Solving**
 
 
 
 
 
 
 
 
192
 
193
- โœจ **Capabilities**: Algebra โ€ข Geometry โ€ข Calculus โ€ข Statistics โ€ข Competition Math
194
- ๐Ÿ“š **Features**: Step-by-step solutions โ€ข Multiple approaches โ€ข Beautiful LaTeX rendering
195
- """,
196
- additional_inputs=[
197
- gr.Textbox(
198
- value=create_math_system_message(),
199
- label="๐Ÿง  System Message (Math Tutor Personality)",
200
- lines=4,
201
- max_lines=12
202
- ),
203
- gr.Slider(minimum=256, maximum=2048, value=1024, step=128, label="๐Ÿ“ Max Tokens (Longer = More Detail)"),
204
- gr.Slider(minimum=0.1, maximum=1.0, value=0.3, step=0.1, label="๐ŸŽฏ Temperature (Creativity vs Precision)"),
205
- gr.Slider(minimum=0.1, maximum=1.0, value=0.85, step=0.05, label="๐Ÿ” Top-p (Response Diversity)"),
206
- ],
207
- examples=[
208
- ["Find the derivative of f(x) = 3xยฒ + 2x - 1"],
209
- ["A triangle has sides 5, 12, and 13. What is its area?"],
210
- ["Solve: lim(x->0) (sin(x)/x)"],
211
- ["What is โˆซ(2xยณ - 5x + 3) dx?"],
212
- ["Solve the system: x + 2y = 7, 3x - y = 4"]
213
- ],
214
- cache_examples=False,
215
- concurrency_limit=5, # Reduce for stability
216
- retry_btn="๐Ÿ”„ Retry",
217
- undo_btn="โ†ถ Undo",
218
- clear_btn="๐Ÿ—‘๏ธ Clear"
219
- )
220
 
221
- # Main interface with enhanced LaTeX CSS
222
  with gr.Blocks(
223
  title="๐Ÿงฎ Mathetics AI",
224
  theme=gr.themes.Soft(),
225
  css="""
226
  /* Enhanced math rendering */
227
- .markdown-body {
228
- font-family: 'Times New Roman', Georgia, serif;
229
- line-height: 1.6;
230
- }
231
-
232
- /* Katex math rendering */
233
- .katex {
234
- font-size: 1.1em !important;
235
- color: #2c3e50;
236
- }
237
- .katex-display {
238
- font-size: 1.3em !important;
239
- text-align: center;
240
- margin: 1em 0;
241
- padding: 10px;
242
- background: #f8f9fa;
243
- border-radius: 8px;
244
- }
245
 
246
- /* Boxed answers */
247
- .katex .mord.text { font-weight: bold; }
 
 
248
 
249
- /* Chat message styling */
250
- .message {
251
- margin: 10px 0;
252
- padding: 12px;
253
- border-radius: 8px;
254
- }
255
- .user {
256
- background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
257
- border-left: 4px solid #2196f3;
258
- }
259
- .assistant {
260
- background: linear-gradient(135deg, #f5f5f5 0%, #eeeeee 100%);
261
- border-left: 4px solid #4caf50;
262
- }
263
 
264
- /* Sidebar styling */
265
- .difficulty-selector {
266
- background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
267
- padding: 15px;
268
- border-radius: 10px;
269
- margin: 10px 0;
270
- border: 1px solid #ffcc80;
271
- }
272
-
273
- .math-highlight {
274
- background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 100%);
275
- padding: 12px;
276
- border-left: 4px solid #4caf50;
277
- margin: 10px 0;
278
- border-radius: 8px;
279
- }
280
-
281
- /* Responsive design */
282
- @media (max-width: 768px) {
283
- .katex { font-size: 1em !important; }
284
- .katex-display { font-size: 1.1em !important; }
285
- }
286
  """
287
  ) as demo:
288
 
289
  gr.Markdown("""
290
  # ๐Ÿงฎ **Mathetics AI** - Advanced Mathematics Solver
291
 
292
- **Your Personal AI Math Tutor** | Specialized in step-by-step problem solving with beautiful LaTeX rendering
293
 
294
  ---
295
  """)
296
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  with gr.Row():
298
- with gr.Column(scale=4):
299
- chatbot.render()
 
300
 
301
  with gr.Column(scale=1):
302
- with gr.Accordion("๐ŸŽฒ **Quick Actions**", open=True):
303
- difficulty_preset = gr.Dropdown(
304
- choices=["Elementary", "High School", "College", "Competition"],
305
- value="High School",
306
- label="๐ŸŽฏ Problem Difficulty",
307
- elem_classes=["difficulty-selector"]
308
- )
309
-
310
- sample_btn = gr.Button("๐ŸŽฏ Get Sample Problem", variant="secondary", size="sm")
311
- help_btn = gr.Button("โ“ Math Help Tips", variant="secondary", size="sm")
312
-
313
- gr.Markdown("### ๐Ÿ”ง **Quick Tools**")
314
- gr.Markdown("""
315
- - **Algebra**: Equations, inequalities, factoring
316
- - **Geometry**: Area, volume, trigonometry
317
- - **Calculus**: Derivatives, integrals, limits
318
- - **Statistics**: Probability, distributions
319
- - **Number Theory**: Prime factorization, GCD/LCM
320
- """)
321
 
322
- # Footer with enhanced info
323
- gr.Markdown("""
324
- ---
325
- **๐Ÿ”ง Technical Details:**
326
- - **Model**: Qwen/Qwen2.5-Math-7B-Instruct (Specialized for Mathematics)
327
- - **Features**: Real-time streaming โ€ข LaTeX rendering โ€ข Step-by-step solutions
328
-
329
- **๐Ÿ’ก Usage Tips:**
330
- - Be specific about what you want to solve
331
- - Request step-by-step solutions explicitly
332
- - Use "lim(x->0)" for limits (mobile-friendly)
333
- - Crank tokens to 1500+ for complex problems
334
- """)
335
 
336
  # Event handlers
337
- def handle_sample(difficulty):
338
- sample = get_random_sample()
339
- return sample
 
 
 
 
 
340
 
341
  sample_btn.click(
342
- handle_sample,
343
  inputs=[difficulty_preset],
344
- outputs=gr.Textbox(visible=False) # This will trigger the chat input
345
  )
346
 
347
  help_btn.click(
348
  show_help,
349
- outputs=gr.Markdown(label="Help", visible=True)
350
  )
 
 
 
 
 
 
 
 
 
 
 
 
351
 
352
  if __name__ == "__main__":
353
  demo.launch()
 
6
  import re
7
 
8
  # Load math datasets for sample problems
9
+ print("๐Ÿ”„ Loading datasets...")
10
  fw = load_dataset("HuggingFaceFW/fineweb-edu", name="sample-10BT", split="train", streaming=True)
11
  ds = load_dataset("HuggingFaceH4/ultrachat_200k", streaming=True)
12
 
 
59
 
60
  **LaTeX Guidelines:**
61
  - Use $...$ for inline math: $x^2 + y^2 = z^2$
62
+ - Use $$...$$ for display math
63
  - Box final answers: \boxed{answer}
64
  - Fractions: \frac{numerator}{denominator}
65
  - Limits: \lim_{x \to 0}
66
  - Derivatives: \frac{d}{dx} or f'(x)
 
67
 
68
  Always be precise, educational, and encourage mathematical thinking."""
69
 
 
74
 
75
  try:
76
  # Fix common LaTeX patterns from Qwen
 
77
  text = re.sub(r'(?<!\\)\$([^\$]+)\$(?!\$)', r'$\1$', text)
 
 
78
  text = re.sub(r'\$\$([^\$]+)\$\$', r'$$\1$$', text)
79
  text = re.sub(r'\\\[([^\\]+)\\\]', r'$$\1$$', text)
80
  text = re.sub(r'\\\(([^\\]+)\\\)', r'$\1$', text)
81
 
82
  # Fix escaped LaTeX commands
83
+ text = re.sub(r'\\(lim|frac|sqrt|int|sum|prod|partial|nabla|infty|to|le|ge|neq|approx|cdot|times|div|deg|prime|log|ln|sin|cos|tan|cot|sec|csc|arcsin|arccos|arctan|sinh|cosh)', r'\1', text)
84
 
85
  # Ensure boxed answers render
86
  text = re.sub(r'\\boxed\{([^}]+)\}', r'$$\boxed{\1}$$', text)
 
 
87
  text = re.sub(r'\\frac\{([^}]+)\}\{([^}]+)\}', r'$\frac{\1}{\2}$', text)
88
 
89
  # Clean up extra spaces
 
91
 
92
  except Exception as e:
93
  print(f"โš ๏ธ LaTeX formatting error: {e}")
 
94
 
95
  return text
96
 
97
  def respond(message, history, system_message, max_tokens, temperature, top_p):
98
  """Enhanced response with proper LaTeX streaming"""
 
99
  yield "๐Ÿค” Thinking step-by-step..."
100
 
 
101
  client = InferenceClient(model="Qwen/Qwen2.5-Math-7B-Instruct")
102
 
 
103
  messages = []
104
  if system_message:
105
  messages.append({"role": "system", "content": system_message})
106
 
107
+ # Convert history to proper format
108
+ for user_msg, assistant_msg in history:
109
+ if user_msg:
110
+ messages.append({"role": "user", "content": user_msg})
111
+ if assistant_msg:
112
+ messages.append({"role": "assistant", "content": assistant_msg})
113
 
114
  messages.append({"role": "user", "content": message})
115
 
116
  response = ""
117
+ max_tokens = max(max_tokens, 1536)
118
 
119
  try:
120
  for message_chunk in client.chat_completion(
 
123
  stream=True,
124
  temperature=temperature,
125
  top_p=top_p,
126
+ timeout=60
127
  ):
128
  choices = message_chunk.choices
129
  if len(choices) and choices[0].delta.content:
130
  token = choices[0].delta.content
131
  response += token
132
 
 
133
  if len(response) % 50 == 0 or token.strip() in ['.', '!', '?', '\n']:
134
  formatted = render_latex(response)
135
  yield formatted
136
  else:
137
  yield response
138
 
 
139
  final_formatted = render_latex(response.strip())
140
  yield final_formatted
141
 
142
  except Exception as e:
143
+ error_msg = f"โŒ **Error**: {str(e)[:100]}...\n\n๐Ÿ’ก Try a simpler problem or wait a moment."
144
  yield error_msg
145
 
146
  def get_random_sample():
 
152
  def insert_sample_to_chat(difficulty):
153
  """Insert random sample into chat input"""
154
  sample = get_random_sample()
155
+ return sample
156
 
157
  def show_help():
158
  return """**๐Ÿงฎ Math Help Tips:**
 
161
  2. **Request Steps**: "Show me step-by-step how to solve..."
162
  3. **Ask for Verification**: "Check if my answer x=5 is correct"
163
  4. **Alternative Methods**: "What's another way to solve this integral?"
164
+ 5. **Use Clear Notation**: "lim(x->0)" for limits
 
 
 
 
 
165
 
166
  **Pro Tip**: Crank tokens to 1500+ for competition problems!"""
167
 
168
+ # CLASSIC Chatbot interface (Gradio 3.x compatible)
169
+ def chat_response(message, history):
170
+ """Main chat function - compatible with all Gradio versions"""
171
+ bot_response = ""
172
+ for response in respond(
173
+ message,
174
+ history,
175
+ create_math_system_message(),
176
+ 1024, # Default tokens
177
+ 0.3, # Default temperature
178
+ 0.85 # Default top_p
179
+ ):
180
+ bot_response = response
181
+ history.append([message, bot_response])
182
+ yield history, ""
183
 
184
+ return history, ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
+ # Build the interface
187
  with gr.Blocks(
188
  title="๐Ÿงฎ Mathetics AI",
189
  theme=gr.themes.Soft(),
190
  css="""
191
  /* Enhanced math rendering */
192
+ .markdown-body { font-family: 'Times New Roman', Georgia, serif; line-height: 1.6; }
193
+ .katex { font-size: 1.1em !important; color: #2c3e50; }
194
+ .katex-display { font-size: 1.3em !important; text-align: center; margin: 1em 0; padding: 10px; background: #f8f9fa; border-radius: 8px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
 
196
+ /* Chat styling */
197
+ .message { margin: 10px 0; padding: 12px; border-radius: 8px; }
198
+ .user { background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-left: 4px solid #2196f3; }
199
+ .assistant { background: linear-gradient(135deg, #f5f5f5 0%, #eeeeee 100%); border-left: 4px solid #4caf50; }
200
 
201
+ /* Sidebar */
202
+ .difficulty-selector { background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%); padding: 15px; border-radius: 10px; margin: 10px 0; border: 1px solid #ffcc80; }
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
+ /* Responsive */
205
+ @media (max-width: 768px) { .katex { font-size: 1em !important; } .katex-display { font-size: 1.1em !important; } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  """
207
  ) as demo:
208
 
209
  gr.Markdown("""
210
  # ๐Ÿงฎ **Mathetics AI** - Advanced Mathematics Solver
211
 
212
+ **Your Personal AI Math Tutor** | Step-by-step solutions with beautiful LaTeX rendering
213
 
214
  ---
215
  """)
216
 
217
+ # Main chat interface
218
+ chatbot = gr.Chatbot(
219
+ height=500,
220
+ show_label=False,
221
+ avatar_images=("๐Ÿง‘โ€๐ŸŽ“", "๐Ÿค–"),
222
+ bubble_full_width=False
223
+ )
224
+
225
+ with gr.Row():
226
+ msg = gr.Textbox(
227
+ placeholder="Ask: 'Find the derivative of 3xยฒ + 2x - 1'",
228
+ scale=4,
229
+ show_label=False,
230
+ lines=2
231
+ )
232
+ submit_btn = gr.Button("๐Ÿš€ Solve", variant="primary", scale=1)
233
+
234
+ # Controls
235
  with gr.Row():
236
+ with gr.Column(scale=2):
237
+ token_slider = gr.Slider(256, 2048, value=1024, step=128, label="๐Ÿ“ Max Tokens")
238
+ temp_slider = gr.Slider(0.1, 1.0, value=0.3, step=0.1, label="๐ŸŽฏ Temperature")
239
 
240
  with gr.Column(scale=1):
241
+ difficulty_preset = gr.Dropdown(
242
+ choices=["Elementary", "High School", "College", "Competition"],
243
+ value="High School",
244
+ label="๐ŸŽฏ Difficulty",
245
+ elem_classes=["difficulty-selector"]
246
+ )
247
+ sample_btn = gr.Button("๐ŸŽฒ Random Problem", variant="secondary")
248
+ help_btn = gr.Button("โ“ Help", variant="secondary")
 
 
 
 
 
 
 
 
 
 
 
249
 
250
+ # Examples
251
+ gr.Examples(
252
+ examples=[
253
+ ["Find the derivative of f(x) = 3xยฒ + 2x - 1"],
254
+ ["A triangle has sides 5, 12, and 13. What is its area?"],
255
+ ["Solve: lim(x->0) sin(x)/x"],
256
+ ["What is โˆซ(2xยณ - 5x + 3) dx?"],
257
+ ["Solve the system: x + 2y = 7, 3x - y = 4"]
258
+ ],
259
+ inputs=msg,
260
+ label="๐Ÿ’ก Quick Examples"
261
+ )
 
262
 
263
  # Event handlers
264
+ def submit_message(message, history):
265
+ return chat_response(message, history)
266
+
267
+ def clear_chat():
268
+ return [], ""
269
+
270
+ msg.submit(submit_message, [msg, chatbot], [msg, chatbot])
271
+ submit_btn.click(submit_message, [msg, chatbot], [msg, chatbot])
272
 
273
  sample_btn.click(
274
+ insert_sample_to_chat,
275
  inputs=[difficulty_preset],
276
+ outputs=msg
277
  )
278
 
279
  help_btn.click(
280
  show_help,
281
+ outputs=gr.Markdown(visible=True, label="Help")
282
  )
283
+
284
+ # Clear button
285
+ gr.Button("๐Ÿ—‘๏ธ Clear Chat", variant="secondary").click(
286
+ clear_chat,
287
+ outputs=[chatbot, msg]
288
+ )
289
+
290
+ gr.Markdown("""
291
+ ---
292
+ **๐Ÿ”ง Tech:** Qwen2.5-Math-7B โ€ข LaTeX rendering โ€ข Streaming responses
293
+ **๐Ÿ’ก Tip:** Use "lim(x->0)" for limits, crank tokens for complex problems
294
+ """)
295
 
296
  if __name__ == "__main__":
297
  demo.launch()