Views
No views yet

device_map="auto" و float16 لتسريع الأداء وتقليل استهلاك الذاكرة (VRAM).
1fastapi
2uvicorn
3python-multipart
4transformers>=4.40.0
5accelerate
6sentencepiece
7protobuf
8huggingface_hub
9tavily-python1import os
2from transformers import AutoTokenizer, AutoModelForCausalLM
3
4# 🔹 معرف الموديل على HuggingFace
5MODEL_ID = "ONYX-APP-AI/onyx-ai-syrian-0.1"
6
7# 🔹 توكن الوصول (إذا الموديل خاص)
8HF_TOKEN = os.environ.get("HF_TOKEN")
9
10print("⏳ Loading ONYX Engine...")
11
12# 🔹 تحميل الـ Tokenizer (مسؤول عن تحويل النص لأرقام)
13tokenizer = AutoTokenizer.from_pretrained(
14 MODEL_ID,
15 token=HF_TOKEN,
16 trust_remote_code=True # يسمح باستخدام كود مخصص من الموديل
17)
18
19# 🔹 تحميل الموديل نفسه
20model = AutoModelForCausalLM.from_pretrained(
21 MODEL_ID,
22 token=HF_TOKEN,
23 torch_dtype=torch.bfloat16, # تقليل استهلاك الذاكرة
24 low_cpu_mem_usage=True, # تحسين استهلاك RAM
25 device_map="auto" # توزيع تلقائي على CPU/GPU
26)1from fastapi import FastAPI, Request
2from fastapi.responses import StreamingResponse
3from threading import Thread
4from transformers import TextIteratorStreamer
5import asyncio
6import json
7
8# 🔹 إنشاء تطبيق FastAPI
9app = FastAPI()
10
11# 🔹 Endpoint لاستقبال الرسائل
12@app.post("/chat")
13async def chat(request: Request):
14
15 # 🔹 قراءة البيانات القادمة من المستخدم
16 data = await request.json()
17 message = data.get("message", "")
18
19 # 🔹 تحديد نوع الرد (سريع أو باستخدام البحث)
20 if should_skip_search(message):
21 system_content = "أنت ONYX، مساعد ذكي سوري بلهجة شاميّة. جاوب باختصار ودقة."
22 else:
23 system_content = "أنت ONYX، مساعد ذكي سوري بلهجة شاميّة."
24
25 # 🔹 بناء الرسائل بصيغة Chat
26 messages = [
27 {"role": "system", "content": system_content},
28 {"role": "user", "content": message}
29 ]
30
31 # 🔹 تحويل الرسائل إلى Prompt يفهمه الموديل
32 prompt = tokenizer.apply_chat_template(
33 messages,
34 tokenize=False,
35 add_generation_prompt=True
36 )
37
38 # 🔹 تحويل النص إلى Tensor
39 inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
40
41 # 🔹 إعداد نظام Streaming (إرسال الرد تدريجياً)
42 streamer = TextIteratorStreamer(
43 tokenizer,
44 skip_prompt=True,
45 skip_special_tokens=True
46 )
47
48 # 🔹 إعدادات التوليد
49 generate_kwargs = dict(
50 **inputs,
51 streamer=streamer,
52 max_new_tokens=512, # الحد الأقصى لطول الرد
53 do_sample=True, # تفعيل العشوائية
54 temperature=0.7, # درجة الإبداع
55 repetition_penalty=1.15 # تقليل التكرار
56 )
57
58 # 🔹 تشغيل التوليد في Thread منفصل
59 Thread(target=model.generate, kwargs=generate_kwargs).start()
60
61 # 🔹 إرسال الرد للمستخدم Token by Token
62 async def event_generator():
63 try:
64 for new_token in streamer:
65
66 # 🔹 إيقاف إذا المستخدم قطع الاتصال
67 if await request.is_disconnected():
68 break
69
70 if new_token:
71 yield f"data: {json.dumps({'token': new_token}, ensure_ascii=False)}\\n\\n"
72 await asyncio.sleep(0.005)
73
74 except Exception:
75 pass
76
77 # 🔹 إعادة الرد كـ Streaming
78 return StreamingResponse(
79 event_generator(),
80 media_type="text/event-stream",
81 headers={"X-Accel-Buffering": "no"} # تعطيل buffering لتحسين السرعة
82 )
83
84
85# 🔹 تحديد إذا السؤال يحتاج بحث أو لا
86def should_skip_search(message):
87 skip_keywords = ["خطة", "برنامج", "كيف اتعلم", "نصيحة", "احكيلي عن", "شرح"]
88 return any(word in message for word in skip_keywords)