sassil commited on
Commit
9af31e9
·
1 Parent(s): 07726ac
Files changed (1) hide show
  1. app.py +88 -146
app.py CHANGED
@@ -3,7 +3,7 @@ import torch
3
  from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
4
  import spaces
5
 
6
- # إعدادات quantization لـ Qwen3
7
  quantization_config = BitsAndBytesConfig(
8
  load_in_4bit=True,
9
  bnb_4bit_compute_dtype=torch.bfloat16,
@@ -11,17 +11,24 @@ quantization_config = BitsAndBytesConfig(
11
  bnb_4bit_quant_type="nf4"
12
  )
13
 
14
- # اختر الموديل حسب العتاد المتاح
15
- # للحصول على أفضل أداء على H100، استخدم Qwen3-32B
16
- MODEL_NAME = "Qwen/Qwen3-32B-Instruct"
17
 
18
- # بدائل حسب العتاد:
19
- # "Qwen/Qwen3-8B-Instruct" # للعتاد المتوسط (A10G)
20
- # "Qwen/Qwen3-14B-Instruct" # للعتاد القوي
21
- # "Qwen/Qwen3-32B-Instruct" # للعتاد الممتاز (H100)
22
- # "Qwen/Qwen3-235B-A22B-Instruct" # للعتاد الضخم (8xH100)
23
 
24
- print(f"جاري تحميل {MODEL_NAME}...")
 
 
 
 
 
 
 
 
 
 
25
 
26
  tokenizer = AutoTokenizer.from_pretrained(
27
  MODEL_NAME,
@@ -39,6 +46,9 @@ model = AutoModelForCausalLM.from_pretrained(
39
 
40
  print("✅ تم تحميل الموديل بنجاح!")
41
 
 
 
 
42
  @spaces.GPU(duration=180)
43
  def generate_response(
44
  message,
@@ -48,52 +58,54 @@ def generate_response(
48
  temperature=0.7,
49
  top_p=0.95,
50
  top_k=20,
51
- min_p=0.0,
52
  repetition_penalty=1.05,
53
- enable_thinking=False
54
  ):
55
  """
56
  توليد الردود باستخدام Qwen 3
57
- يدعم وضع التفكير (Thinking Mode) للمهام المعقدة
58
  """
59
  # بناء المحادثة
60
- messages = [{"role": "system", "content": system_prompt}]
61
-
62
- for human, assistant in history:
63
- messages.append({"role": "user", "content": human})
64
- if assistant:
65
- messages.append({"role": "assistant", "content": assistant})
66
-
67
- messages.append({"role": "user", "content": message})
68
-
69
- # تطبيق قالب المحادثة
70
- text = tokenizer.apply_chat_template(
71
- messages,
72
- tokenize=False,
73
- add_generation_prompt=True,
74
- enable_thinking=enable_thinking
75
- )
 
 
 
 
 
 
 
 
 
 
 
76
 
77
  model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
78
 
79
- # إعدادات التوليد
80
- generation_kwargs = {
81
- "max_new_tokens": max_tokens,
82
- "temperature": temperature,
83
- "top_p": top_p,
84
- "top_k": top_k,
85
- "min_p": min_p,
86
- "repetition_penalty": repetition_penalty,
87
- "do_sample": True,
88
- "pad_token_id": tokenizer.pad_token_id or tokenizer.eos_token_id,
89
- "eos_token_id": tokenizer.eos_token_id,
90
- }
91
-
92
  # التوليد
93
  with torch.no_grad():
94
  generated_ids = model.generate(
95
  **model_inputs,
96
- **generation_kwargs
 
 
 
 
 
 
 
97
  )
98
 
99
  generated_ids = [
@@ -103,22 +115,11 @@ def generate_response(
103
 
104
  response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
105
 
106
- # إذا كان في وضع التفكير، استخرج الإجابة النهائية
107
- if enable_thinking and "<think>" in response:
108
- parts = response.split("</think>")
109
- if len(parts) > 1:
110
- thinking_process = parts[0].replace("<think>", "").strip()
111
- final_answer = parts[1].strip()
112
- response = f"**🧠 عملية التفكير:**\n{thinking_process}\n\n**✅ الإجابة النهائية:**\n{final_answer}"
113
-
114
  return response
115
 
116
- # واجهة Gradio محسّنة
117
  with gr.Blocks(
118
- theme=gr.themes.Soft(
119
- primary_hue="blue",
120
- secondary_hue="purple",
121
- ),
122
  css="""
123
  .container {max-width: 1400px; margin: auto;}
124
  .rtl {direction: rtl; text-align: right;}
@@ -132,10 +133,11 @@ with gr.Blocks(
132
  """
133
  ) as demo:
134
 
135
- gr.HTML("""
136
  <div class="header">
137
  <h1>🚀 Qwen 3 - أحدث موديل من Alibaba Cloud</h1>
138
- <p>النسخة الأحدث (أبريل 2025) - يعمل بتقنية 4-bit quantization على Nvidia H100</p>
 
139
  </div>
140
  """)
141
 
@@ -146,33 +148,25 @@ with gr.Blocks(
146
  height=600,
147
  rtl=True,
148
  show_copy_button=True,
149
- avatar_images=(None, "🤖")
150
  )
151
 
152
- with gr.Row():
153
- msg = gr.Textbox(
154
- label="✍️ رسالتك",
155
- placeholder="اكتب رسالتك هنا... اضغط Enter للإرسال",
156
- lines=3,
157
- rtl=True,
158
- scale=4
159
- )
160
 
161
  with gr.Row():
162
- submit = gr.Button("إرسال 📤", variant="primary", scale=2)
163
- clear = gr.Button("مسح المحادثة 🗑️", scale=1)
164
- thinking_toggle = gr.Checkbox(
165
- label="🧠 تفعيل وضع التفكير العميق",
166
- value=False,
167
- info="للمسائل الرياضية والبرمجية المعقدة"
168
- )
169
 
170
  with gr.Column(scale=1):
171
- gr.Markdown("### ⚙️ إعدادات متقدمة", elem_classes=["rtl"])
172
 
173
  system_prompt = gr.Textbox(
174
  label="📋 System Prompt",
175
- value="أنت مساعد ذكي ومفيد يتحدث العربية بطلاقة ويتمتع بخبرة واسعة في مختلف المجالات",
176
  lines=4,
177
  rtl=True
178
  )
@@ -181,7 +175,7 @@ with gr.Blocks(
181
  max_tokens = gr.Slider(
182
  minimum=256,
183
  maximum=8192,
184
- value=4096,
185
  step=256,
186
  label="الحد الأقصى للتوكنات"
187
  )
@@ -191,7 +185,7 @@ with gr.Blocks(
191
  maximum=2.0,
192
  value=0.7,
193
  step=0.1,
194
- label="Temperature (الإبداع)"
195
  )
196
 
197
  top_p = gr.Slider(
@@ -199,7 +193,7 @@ with gr.Blocks(
199
  maximum=1.0,
200
  value=0.95,
201
  step=0.05,
202
- label="Top-p (Nucleus Sampling)"
203
  )
204
 
205
  top_k = gr.Slider(
@@ -210,14 +204,6 @@ with gr.Blocks(
210
  label="Top-k"
211
  )
212
 
213
- min_p = gr.Slider(
214
- minimum=0.0,
215
- maximum=0.5,
216
- value=0.0,
217
- step=0.05,
218
- label="Min-p"
219
- )
220
-
221
  repetition_penalty = gr.Slider(
222
  minimum=1.0,
223
  maximum=2.0,
@@ -226,53 +212,22 @@ with gr.Blocks(
226
  label="عقوبة التكرار"
227
  )
228
 
229
- gr.Markdown("""
230
- ### 💡 ن��ائح الاستخدام
231
 
232
- **وضع التفكير العميق** 🧠:
233
- - مفيد للرياضيات والبرمجة
234
- - يُظهر عملية التفكير
235
- - يستغرق وقتاً أطول
 
 
236
 
237
- **الإعدادات الموصى بها**:
238
- - للمحادثة العادية: Temp=0.7
239
- - للبرمجة: Temp=0.3, TopK=20
240
- - للإبداع: Temp=1.0, TopP=0.95
241
- """, elem_classes=["rtl"])
242
-
243
- with gr.Row():
244
- gr.Markdown("""
245
- ### 📊 معلومات الموديل
246
-
247
- | المعلومة | القيمة |
248
- |----------|--------|
249
- | **الموديل** | Qwen3-32B-Instruct |
250
- | **تاريخ الإصدار** | أبريل 2025 |
251
- | **المعمارية** | 32 مليار معامل |
252
- | **طول السياق** | 128K توكن |
253
- | **التقنية** | 4-bit NF4 Quantization |
254
- | **العتاد** | Nvidia H100 (80GB) |
255
- | **الأداء** | ~25-40 توكن/ثانية |
256
- | **اللغات** | متعدد اللغات (عربي، إنجليزي، صيني...) |
257
-
258
- ---
259
-
260
- ### 🌟 ميزات Qwen 3 الجديدة
261
-
262
- ✅ **وضع التفكير العميق** - للمسائل المعقدة
263
- ✅ **سياق 128K توكن** - للمستندات الطويلة
264
- ✅ **أداء محسّن** - أسرع من Qwen 2.5
265
- ✅ **دعم متعدد اللغات** - مع تحسينات للعربية
266
-
267
- """, elem_classes=["rtl"])
268
 
269
  def user_message(user_msg, history):
270
  return "", history + [[user_msg, None]]
271
 
272
- def bot_response(
273
- history, sys_prompt, max_tok, temp,
274
- top_p_val, top_k_val, min_p_val, rep_pen, think_mode
275
- ):
276
  user_msg = history[-1][0]
277
  bot_msg = generate_response(
278
  user_msg,
@@ -282,14 +237,11 @@ with gr.Blocks(
282
  temp,
283
  top_p_val,
284
  top_k_val,
285
- min_p_val,
286
- rep_pen,
287
- think_mode
288
  )
289
  history[-1][1] = bot_msg
290
  return history
291
 
292
- # ربط الأحداث
293
  msg.submit(
294
  user_message,
295
  [msg, chatbot],
@@ -297,10 +249,7 @@ with gr.Blocks(
297
  queue=False
298
  ).then(
299
  bot_response,
300
- [
301
- chatbot, system_prompt, max_tokens, temperature,
302
- top_p, top_k, min_p, repetition_penalty, thinking_toggle
303
- ],
304
  chatbot
305
  )
306
 
@@ -311,23 +260,16 @@ with gr.Blocks(
311
  queue=False
312
  ).then(
313
  bot_response,
314
- [
315
- chatbot, system_prompt, max_tokens, temperature,
316
- top_p, top_k, min_p, repetition_penalty, thinking_toggle
317
- ],
318
  chatbot
319
  )
320
 
321
  clear.click(lambda: None, None, chatbot, queue=False)
322
 
323
  if __name__ == "__main__":
324
- demo.queue(
325
- max_size=30,
326
- default_concurrency_limit=5
327
- )
328
  demo.launch(
329
  server_name="0.0.0.0",
330
  server_port=7860,
331
- share=False,
332
- show_error=True
333
  )
 
3
  from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
4
  import spaces
5
 
6
+ # إعدادات quantization
7
  quantization_config = BitsAndBytesConfig(
8
  load_in_4bit=True,
9
  bnb_4bit_compute_dtype=torch.bfloat16,
 
11
  bnb_4bit_quant_type="nf4"
12
  )
13
 
14
+ # الأسماء الصحيحة للموديلات على Hugging Face
15
+ # اختر حسب العتاد المتاح:
 
16
 
17
+ # للعتاد الضخم (8xH100 أو 4xL40S):
18
+ # MODEL_NAME = "Qwen/Qwen3-235B-A22B-Instruct-2507" # النسخة الأحدث مع Instruct
19
+ # MODEL_NAME = "Qwen/Qwen3-235B-A22B" # Base model
 
 
20
 
21
+ # للعتاد القوي (H100 80GB) - الموصى به:
22
+ MODEL_NAME = "Qwen/Qwen3-32B" # 33B parameters
23
+
24
+ # بدائل أخرى:
25
+ # MODEL_NAME = "Qwen/Qwen3-30B-A3B-Instruct-2507" # 31B with Instruct (أحدث)
26
+ # MODEL_NAME = "Qwen/Qwen3-30B-A3B" # 31B MoE Base
27
+ # MODEL_NAME = "Qwen/Qwen3-14B" # 15B للعتاد المتوسط
28
+ # MODEL_NAME = "Qwen/Qwen3-8B" # 8B للعتاد العادي
29
+ # MODEL_NAME = "Qwen/Qwen3-4B" # 4B للعتاد الخفيف
30
+
31
+ print(f"🚀 جاري تحميل {MODEL_NAME}...")
32
 
33
  tokenizer = AutoTokenizer.from_pretrained(
34
  MODEL_NAME,
 
46
 
47
  print("✅ تم تحميل الموديل بنجاح!")
48
 
49
+ # تحديد ما إذا كان الموديل يدعم chat template
50
+ HAS_CHAT_TEMPLATE = "Instruct" in MODEL_NAME or "2507" in MODEL_NAME
51
+
52
  @spaces.GPU(duration=180)
53
  def generate_response(
54
  message,
 
58
  temperature=0.7,
59
  top_p=0.95,
60
  top_k=20,
 
61
  repetition_penalty=1.05,
 
62
  ):
63
  """
64
  توليد الردود باستخدام Qwen 3
 
65
  """
66
  # بناء المحادثة
67
+ if HAS_CHAT_TEMPLATE:
68
+ # استخدام chat template للموديلات Instruct
69
+ messages = [{"role": "system", "content": system_prompt}]
70
+
71
+ for human, assistant in history:
72
+ messages.append({"role": "user", "content": human})
73
+ if assistant:
74
+ messages.append({"role": "assistant", "content": assistant})
75
+
76
+ messages.append({"role": "user", "content": message})
77
+
78
+ text = tokenizer.apply_chat_template(
79
+ messages,
80
+ tokenize=False,
81
+ add_generation_prompt=True
82
+ )
83
+ else:
84
+ # للموديلات Base، استخدم format بسيط
85
+ conversation = f"### System:\n{system_prompt}\n\n"
86
+
87
+ for human, assistant in history:
88
+ conversation += f"### User:\n{human}\n\n"
89
+ if assistant:
90
+ conversation += f"### Assistant:\n{assistant}\n\n"
91
+
92
+ conversation += f"### User:\n{message}\n\n### Assistant:\n"
93
+ text = conversation
94
 
95
  model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  # التوليد
98
  with torch.no_grad():
99
  generated_ids = model.generate(
100
  **model_inputs,
101
+ max_new_tokens=max_tokens,
102
+ temperature=temperature,
103
+ top_p=top_p,
104
+ top_k=top_k,
105
+ repetition_penalty=repetition_penalty,
106
+ do_sample=True,
107
+ pad_token_id=tokenizer.pad_token_id or tokenizer.eos_token_id,
108
+ eos_token_id=tokenizer.eos_token_id,
109
  )
110
 
111
  generated_ids = [
 
115
 
116
  response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
117
 
 
 
 
 
 
 
 
 
118
  return response
119
 
120
+ # واجهة Gradio
121
  with gr.Blocks(
122
+ theme=gr.themes.Soft(primary_hue="blue"),
 
 
 
123
  css="""
124
  .container {max-width: 1400px; margin: auto;}
125
  .rtl {direction: rtl; text-align: right;}
 
133
  """
134
  ) as demo:
135
 
136
+ gr.HTML(f"""
137
  <div class="header">
138
  <h1>🚀 Qwen 3 - أحدث موديل من Alibaba Cloud</h1>
139
+ <p><strong>الموديل المستخدم:</strong> {MODEL_NAME}</p>
140
+ <p>يعمل بتقنية 4-bit quantization على Nvidia H100</p>
141
  </div>
142
  """)
143
 
 
148
  height=600,
149
  rtl=True,
150
  show_copy_button=True,
 
151
  )
152
 
153
+ msg = gr.Textbox(
154
+ label="✍️ رسالتك",
155
+ placeholder="اكتب رسالتك هنا...",
156
+ lines=3,
157
+ rtl=True
158
+ )
 
 
159
 
160
  with gr.Row():
161
+ submit = gr.Button("إرسال 📤", variant="primary")
162
+ clear = gr.Button("مسح 🗑️")
 
 
 
 
 
163
 
164
  with gr.Column(scale=1):
165
+ gr.Markdown("### ⚙️ الإعدادات", elem_classes=["rtl"])
166
 
167
  system_prompt = gr.Textbox(
168
  label="📋 System Prompt",
169
+ value="أنت مساعد ذكي ومفيد يتحدث العربية بطلاقة",
170
  lines=4,
171
  rtl=True
172
  )
 
175
  max_tokens = gr.Slider(
176
  minimum=256,
177
  maximum=8192,
178
+ value=2048,
179
  step=256,
180
  label="الحد الأقصى للتوكنات"
181
  )
 
185
  maximum=2.0,
186
  value=0.7,
187
  step=0.1,
188
+ label="Temperature"
189
  )
190
 
191
  top_p = gr.Slider(
 
193
  maximum=1.0,
194
  value=0.95,
195
  step=0.05,
196
+ label="Top-p"
197
  )
198
 
199
  top_k = gr.Slider(
 
204
  label="Top-k"
205
  )
206
 
 
 
 
 
 
 
 
 
207
  repetition_penalty = gr.Slider(
208
  minimum=1.0,
209
  maximum=2.0,
 
212
  label="عقوبة التكرار"
213
  )
214
 
215
+ model_info = f"""
216
+ ### 📊 معلومات الموديل
217
 
218
+ - **الاسم**: {MODEL_NAME}
219
+ - **النوع**: {'Instruct' if HAS_CHAT_TEMPLATE else 'Base'}
220
+ - **الحجم**: {'32B' if '32B' in MODEL_NAME else '30B' if '30B' in MODEL_NAME else '235B' if '235B' in MODEL_NAME else 'متغير'}
221
+ - **Quantization**: 4-bit NF4
222
+ - **العتاد**: ZeroGPU / H100
223
+ """
224
 
225
+ gr.Markdown(model_info, elem_classes=["rtl"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
  def user_message(user_msg, history):
228
  return "", history + [[user_msg, None]]
229
 
230
+ def bot_response(history, sys_prompt, max_tok, temp, top_p_val, top_k_val, rep_pen):
 
 
 
231
  user_msg = history[-1][0]
232
  bot_msg = generate_response(
233
  user_msg,
 
237
  temp,
238
  top_p_val,
239
  top_k_val,
240
+ rep_pen
 
 
241
  )
242
  history[-1][1] = bot_msg
243
  return history
244
 
 
245
  msg.submit(
246
  user_message,
247
  [msg, chatbot],
 
249
  queue=False
250
  ).then(
251
  bot_response,
252
+ [chatbot, system_prompt, max_tokens, temperature, top_p, top_k, repetition_penalty],
 
 
 
253
  chatbot
254
  )
255
 
 
260
  queue=False
261
  ).then(
262
  bot_response,
263
+ [chatbot, system_prompt, max_tokens, temperature, top_p, top_k, repetition_penalty],
 
 
 
264
  chatbot
265
  )
266
 
267
  clear.click(lambda: None, None, chatbot, queue=False)
268
 
269
  if __name__ == "__main__":
270
+ demo.queue(max_size=30)
 
 
 
271
  demo.launch(
272
  server_name="0.0.0.0",
273
  server_port=7860,
274
+ share=False
 
275
  )