ddfws commited on
Commit
65dfe9a
·
verified ·
1 Parent(s): 748827e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +308 -130
app.py CHANGED
@@ -2,13 +2,19 @@ import gradio as gr
2
  import spaces
3
  import torch
4
 
5
- from transformers import AutoTokenizer, AutoModelForCausalLM
 
 
 
 
 
 
6
 
7
 
8
 
9
- # ============================
10
  # MODEL
11
- # ============================
12
 
13
  MODEL_ID = "ddfws/Rezaeian-StatsAI"
14
 
@@ -22,6 +28,7 @@ tokenizer = AutoTokenizer.from_pretrained(
22
  )
23
 
24
 
 
25
  print("Loading model...")
26
 
27
 
@@ -40,88 +47,58 @@ print("MODEL READY")
40
 
41
 
42
 
43
- # ============================
44
  # SYSTEM PROMPT
45
- # ============================
46
 
47
 
48
  SYSTEM_PROMPT = """
49
 
50
- شما Rezaeian StatsAI هستید.
51
-
52
- یک استاد تمام دانشگاه تهران در درس آمار و احتمال مهندسی.
53
-
54
- مخاطب شما دانشجوی کارشناسی مهندسی است.
55
-
56
-
57
- وظیفه:
58
 
59
- ارائه حل کامل، دقیق و آموزشی مانند جزوه دانشگاهی.
 
60
 
 
61
 
62
- قوانین پاسخ:
63
-
64
- - پاسخ کوتاه ممنوع است.
65
- - فقط جواب نهایی را ننویس.
66
- - تمام مراحل حل را توضیح بده.
67
- - اگر مسئله عددی است، تمام محاسبات را نشان بده.
68
- - اگر مفهوم است، با مثال مهندسی توضیح بده.
69
 
70
 
71
  ساختار پاسخ:
72
 
73
 
74
- 1) تشخیص موضوع
75
-
76
- مشخص کن مسئله مربوط به چه مبحثی است.
77
-
78
-
79
- 2) روش حل
80
-
81
- روش، قضیه یا توزیع مورد استفاده را معرفی کن.
82
-
83
 
84
- 3) توضیح تئوری
85
 
86
- تعریف و مفهوم را توضیح بده.
87
 
 
88
 
89
- 4) فرمول‌ها
90
 
91
- فرمول‌ها را با LaTeX مرتب بنویس.
92
 
 
93
 
94
- 5) حل مرحله به مرحله
95
 
96
- تمام جایگذاری‌ها و محاسبات را نشان بده.
97
 
98
 
99
- 6) مثال مشابه
100
 
101
- یک مثال مشابه دانشگاهی ارائه کن و حل کن.
102
 
 
103
 
104
- 7) نکات مهم امتحانی
105
 
106
- اشتباهات رایج و نکات مهم را بیان کن.
107
 
108
-
109
- 8) نتیجه نهایی
110
-
111
-
112
- موضوعات تخصصی:
113
-
114
- احتمال
115
-
116
- قوانین احتمال
117
-
118
- قضیه بیز
119
-
120
- متغیر تصادفی
121
-
122
- توزیع‌های گسسته
123
-
124
- توزیع‌های پیوسته
125
 
126
  Binomial
127
 
@@ -154,71 +131,184 @@ ANOVA
154
  Reliability
155
 
156
 
157
- فرمول‌ها را خوانا بنویس.
158
 
159
- متغیرهای ریاضی:
160
 
161
  X,Y,μ,σ,P,E,Var
162
 
163
  را انگلیسی نگه دار.
164
 
 
165
  """
166
 
167
 
168
- # ============================
169
- # GENERATION
170
- # ============================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
 
172
 
173
  @spaces.GPU
174
- def generate(message, history):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
 
177
  messages = [
178
 
179
  {
180
- "role": "system",
181
- "content": SYSTEM_PROMPT
 
 
 
182
  }
183
 
184
  ]
185
 
186
 
187
- # جلوگیری از سنگین شدن حافظه چت
188
 
189
- for user, assistant in history[-3:]:
190
 
191
 
192
  messages.append(
 
193
  {
 
194
  "role":"user",
 
195
  "content":user
 
196
  }
 
197
  )
198
 
199
 
200
  messages.append(
 
201
  {
 
202
  "role":"assistant",
 
203
  "content":assistant
 
204
  }
 
205
  )
206
 
207
 
208
 
209
  messages.append(
 
210
  {
 
211
  "role":"user",
 
212
  "content":message
 
213
  }
 
214
  )
215
 
216
 
217
 
218
  prompt = tokenizer.apply_chat_template(
 
219
  messages,
 
220
  tokenize=False,
 
221
  add_generation_prompt=True
 
222
  )
223
 
224
 
@@ -236,6 +326,7 @@ def generate(message, history):
236
  )
237
 
238
 
 
239
  inputs = {
240
 
241
  k:v.to(model.device)
@@ -246,22 +337,19 @@ def generate(message, history):
246
 
247
 
248
 
 
249
  with torch.no_grad():
250
 
251
 
252
- outputs = model.generate(
253
 
254
  **inputs,
255
 
256
 
257
- # پاسخ طولانی
258
-
259
  max_new_tokens=4096,
260
 
261
 
262
- # جلوگیری از پاسخ خیلی کوتاه
263
-
264
- min_new_tokens=600,
265
 
266
 
267
  temperature=0.25,
@@ -276,9 +364,6 @@ def generate(message, history):
276
  repetition_penalty=1.1,
277
 
278
 
279
- no_repeat_ngram_size=3,
280
-
281
-
282
  pad_token_id=tokenizer.eos_token_id
283
 
284
  )
@@ -287,7 +372,7 @@ def generate(message, history):
287
 
288
  answer = tokenizer.decode(
289
 
290
- outputs[0][
291
 
292
  inputs["input_ids"].shape[-1]:
293
 
@@ -303,51 +388,89 @@ def generate(message, history):
303
 
304
 
305
 
306
- # ============================
307
- # CSS
308
- # ============================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
 
310
 
311
  css = """
312
 
313
- .gradio-container {
314
 
315
- direction: rtl;
316
 
317
- max-width: 1400px !important;
318
 
319
  }
320
 
321
 
322
- .message {
323
 
324
- direction: rtl !important;
 
 
 
 
 
 
 
 
 
 
 
 
325
 
326
- text-align: right !important;
327
 
328
- font-family: Tahoma, Arial;
329
 
330
- font-size: 18px !important;
331
 
332
- line-height: 2 !important;
333
 
334
  }
335
 
336
 
337
- textarea {
338
 
339
- direction: rtl !important;
340
 
341
- text-align: right !important;
342
 
343
- font-size:18px !important;
 
 
344
 
345
  }
346
 
347
 
348
- footer {
349
 
350
- display:none !important;
 
 
351
 
352
  }
353
 
@@ -355,62 +478,100 @@ display:none !important;
355
 
356
 
357
 
358
- # ============================
359
- # UI
360
- # ============================
361
 
362
 
363
  with gr.Blocks(css=css) as demo:
364
 
365
 
366
  gr.Markdown(
367
- """
 
368
  # 🤖 Rezaeian StatsAI
369
 
370
- دستیار هوشمند آمار و احتمال مهندسی
 
 
 
 
371
 
372
- حل مسائل به سبک استاد دانشگاه تهران
373
 
374
- - توضیح مفاهیم
375
- - فرمول‌ها
376
- - حل مرحله‌ای
377
- - مثال مشابه
378
- - نکات امتحانی
379
 
380
  """
381
- )
382
 
383
 
384
- chatbot = gr.Chatbot(
385
- height=900
386
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
 
388
 
389
  textbox = gr.Textbox(
390
- placeholder="سؤال آمار و احتمال خود را وارد کنید...",
391
- lines=3
392
- )
393
 
 
394
 
395
- state = gr.State([])
396
 
 
397
 
398
 
399
- def chat(message, history):
400
 
401
- answer = generate(
402
- message,
403
- history
404
- )
405
 
406
- history.append(
407
- [
408
- message,
409
- answer
410
- ]
411
- )
412
 
413
- return "", history
 
 
414
 
415
 
416
 
@@ -419,22 +580,39 @@ with gr.Blocks(css=css) as demo:
419
  chat,
420
 
421
  inputs=[
 
422
  textbox,
423
- chatbot
 
 
 
 
424
  ],
425
 
426
  outputs=[
 
427
  textbox,
 
428
  chatbot
 
429
  ]
430
 
431
  )
432
 
433
 
434
 
435
- # ============================
436
- # RUN
437
- # ============================
 
 
 
 
 
 
 
 
 
438
 
439
 
440
  demo.launch(
 
2
  import spaces
3
  import torch
4
 
5
+ import PyPDF2
6
+ from docx import Document
7
+
8
+ from transformers import (
9
+ AutoTokenizer,
10
+ AutoModelForCausalLM
11
+ )
12
 
13
 
14
 
15
+ # ==================================
16
  # MODEL
17
+ # ==================================
18
 
19
  MODEL_ID = "ddfws/Rezaeian-StatsAI"
20
 
 
28
  )
29
 
30
 
31
+
32
  print("Loading model...")
33
 
34
 
 
47
 
48
 
49
 
50
+ # ==================================
51
  # SYSTEM PROMPT
52
+ # ==================================
53
 
54
 
55
  SYSTEM_PROMPT = """
56
 
57
+ تو یک استاد تمام دانشگاه تهران در درس آمار و احتمال مهندسی هستی.
 
 
 
 
 
 
 
58
 
59
+ هدف:
60
+ آموزش کامل دانشجوی کارشناسی مهندسی.
61
 
62
+ قوانین:
63
 
64
+ - پاسخ کوتاه نده.
65
+ - مانند استاد دانشگاه توضیح بده.
66
+ - تمام مراحل حل را بنویس.
67
+ - هیچ فرمول مهمی حذف نشود.
 
 
 
68
 
69
 
70
  ساختار پاسخ:
71
 
72
 
73
+ ۱) تشخیص موضوع
 
 
 
 
 
 
 
 
74
 
75
+ ۲) توضیح مفهوم
76
 
77
+ ۳) روش حل
78
 
79
+ ۴) فرمول‌های مورد نیاز
80
 
81
+ ۵) حل مرحله به مرحله
82
 
83
+ ۶) مثال مشابه مهندسی
84
 
85
+ ۷) نکات امتحانی
86
 
87
+ ۸) نتیجه نهایی
88
 
 
89
 
90
 
91
+ مباحث:
92
 
93
+ Probability
94
 
95
+ Bayes
96
 
97
+ Random Variable
98
 
99
+ Discrete Distribution
100
 
101
+ Continuous Distribution
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
  Binomial
104
 
 
131
  Reliability
132
 
133
 
134
+ فرمول‌ها را با LaTeX بنویس.
135
 
136
+ متغیرهای:
137
 
138
  X,Y,μ,σ,P,E,Var
139
 
140
  را انگلیسی نگه دار.
141
 
142
+
143
  """
144
 
145
 
146
+
147
+
148
+
149
+ def read_document(file):
150
+
151
+ if file is None:
152
+ return ""
153
+
154
+
155
+ path = file.name
156
+
157
+
158
+ text = ""
159
+
160
+
161
+ try:
162
+
163
+
164
+ if path.lower().endswith(".pdf"):
165
+
166
+
167
+ pdf = PyPDF2.PdfReader(path)
168
+
169
+
170
+ for page in pdf.pages:
171
+
172
+ result = page.extract_text()
173
+
174
+ if result:
175
+
176
+ text += result + "\n"
177
+
178
+
179
+
180
+ elif path.lower().endswith(".txt"):
181
+
182
+
183
+ with open(
184
+ path,
185
+ "r",
186
+ encoding="utf-8"
187
+ ) as f:
188
+
189
+ text = f.read()
190
+
191
+
192
+
193
+ elif path.lower().endswith(".docx"):
194
+
195
+
196
+ doc = Document(path)
197
+
198
+
199
+ for p in doc.paragraphs:
200
+
201
+ text += p.text + "\n"
202
+
203
+
204
+
205
+ except Exception as e:
206
+
207
+ text = "خطا در خواندن فایل: " + str(e)
208
+
209
+
210
+
211
+ # جلوگیری از پر شدن حافظه
212
+
213
+ return text[:40000]
214
+
215
+
216
+
217
 
218
 
219
  @spaces.GPU
220
+ def generate(message, history, document):
221
+
222
+
223
+ if document:
224
+
225
+
226
+ message = f"""
227
+
228
+ از سند زیر به عنوان منبع استفاده کن:
229
+
230
+
231
+ ----------------------
232
+
233
+ {document}
234
+
235
+ ----------------------
236
+
237
+
238
+ سوال دانشجو:
239
+
240
+ {message}
241
+
242
+ """
243
+
244
 
245
 
246
  messages = [
247
 
248
  {
249
+
250
+ "role":"system",
251
+
252
+ "content":SYSTEM_PROMPT
253
+
254
  }
255
 
256
  ]
257
 
258
 
 
259
 
260
+ for user, assistant in history[-4:]:
261
 
262
 
263
  messages.append(
264
+
265
  {
266
+
267
  "role":"user",
268
+
269
  "content":user
270
+
271
  }
272
+
273
  )
274
 
275
 
276
  messages.append(
277
+
278
  {
279
+
280
  "role":"assistant",
281
+
282
  "content":assistant
283
+
284
  }
285
+
286
  )
287
 
288
 
289
 
290
  messages.append(
291
+
292
  {
293
+
294
  "role":"user",
295
+
296
  "content":message
297
+
298
  }
299
+
300
  )
301
 
302
 
303
 
304
  prompt = tokenizer.apply_chat_template(
305
+
306
  messages,
307
+
308
  tokenize=False,
309
+
310
  add_generation_prompt=True
311
+
312
  )
313
 
314
 
 
326
  )
327
 
328
 
329
+
330
  inputs = {
331
 
332
  k:v.to(model.device)
 
337
 
338
 
339
 
340
+
341
  with torch.no_grad():
342
 
343
 
344
+ output = model.generate(
345
 
346
  **inputs,
347
 
348
 
 
 
349
  max_new_tokens=4096,
350
 
351
 
352
+ min_new_tokens=500,
 
 
353
 
354
 
355
  temperature=0.25,
 
364
  repetition_penalty=1.1,
365
 
366
 
 
 
 
367
  pad_token_id=tokenizer.eos_token_id
368
 
369
  )
 
372
 
373
  answer = tokenizer.decode(
374
 
375
+ output[0][
376
 
377
  inputs["input_ids"].shape[-1]:
378
 
 
388
 
389
 
390
 
391
+
392
+ def chat(message, history, document):
393
+
394
+
395
+ answer = generate(
396
+
397
+ message,
398
+
399
+ history,
400
+
401
+ document
402
+
403
+ )
404
+
405
+
406
+ history.append(
407
+
408
+ [
409
+ message,
410
+ answer
411
+ ]
412
+
413
+ )
414
+
415
+
416
+ return "", history
417
+
418
+
419
 
420
 
421
  css = """
422
 
423
+ .gradio-container{
424
 
425
+ direction:rtl;
426
 
427
+ max-width:1400px!important;
428
 
429
  }
430
 
431
 
 
432
 
433
+ #chatbox{
434
+
435
+ height:850px!important;
436
+
437
+ overflow-y:auto!important;
438
+
439
+ }
440
+
441
+
442
+
443
+ .message{
444
+
445
+ direction:rtl!important;
446
 
447
+ text-align:right!important;
448
 
449
+ font-size:18px!important;
450
 
451
+ line-height:2.2!important;
452
 
453
+ white-space:pre-wrap!important;
454
 
455
  }
456
 
457
 
 
458
 
459
+ textarea{
460
 
461
+ direction:rtl!important;
462
 
463
+ text-align:right!important;
464
+
465
+ font-size:18px!important;
466
 
467
  }
468
 
469
 
 
470
 
471
+ footer{
472
+
473
+ display:none!important;
474
 
475
  }
476
 
 
478
 
479
 
480
 
 
 
 
481
 
482
 
483
  with gr.Blocks(css=css) as demo:
484
 
485
 
486
  gr.Markdown(
487
+ """
488
+
489
  # 🤖 Rezaeian StatsAI
490
 
491
+ ## دستیار هوشمند آمار و احتمال مهندسی
492
+
493
+ ویژه دانشجویان کارشناسی مهندسی
494
+
495
+ قابلیت‌ها:
496
 
497
+ 📚 مطالعه جزوه و کتاب
498
 
499
+ 🧮 حل مرحله‌ای مسائل
500
+
501
+ 📐 فرمول‌های دانشگاهی
502
+
503
+ 🎓 آموزش به سبک استاد دانشگاه
504
 
505
  """
506
+ )
507
 
508
 
509
+
510
+ document_state = gr.State("")
511
+
512
+
513
+
514
+ with gr.Row():
515
+
516
+
517
+ with gr.Column(scale=1):
518
+
519
+
520
+ file = gr.File(
521
+
522
+ label="📚 آپلود سند",
523
+
524
+ file_types=[
525
+
526
+ ".pdf",
527
+
528
+ ".txt",
529
+
530
+ ".docx"
531
+
532
+ ]
533
+
534
+ )
535
+
536
+
537
+ clear = gr.Button(
538
+ "🗑 پاک کردن گفتگو"
539
+ )
540
+
541
+
542
+
543
+ with gr.Column(scale=3):
544
+
545
+
546
+ chatbot = gr.Chatbot(
547
+
548
+ height=850,
549
+
550
+ elem_id="chatbox"
551
+
552
+ )
553
+
554
 
555
 
556
  textbox = gr.Textbox(
 
 
 
557
 
558
+ placeholder="سوال آمار و احتمال خود را وارد کنید",
559
 
560
+ lines=4
561
 
562
+ )
563
 
564
 
 
565
 
566
+ file.change(
 
 
 
567
 
568
+ read_document,
569
+
570
+ inputs=file,
 
 
 
571
 
572
+ outputs=document_state
573
+
574
+ )
575
 
576
 
577
 
 
580
  chat,
581
 
582
  inputs=[
583
+
584
  textbox,
585
+
586
+ chatbot,
587
+
588
+ document_state
589
+
590
  ],
591
 
592
  outputs=[
593
+
594
  textbox,
595
+
596
  chatbot
597
+
598
  ]
599
 
600
  )
601
 
602
 
603
 
604
+ clear.click(
605
+
606
+ lambda: [],
607
+
608
+ None,
609
+
610
+ chatbot
611
+
612
+ )
613
+
614
+
615
+
616
 
617
 
618
  demo.launch(