Arabic250 commited on
Commit
52614c9
·
verified ·
1 Parent(s): 92ea782

Create main.py

Browse files
Files changed (1) hide show
  1. main.py +117 -0
main.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.responses import HTMLResponse
3
+ from pydantic import BaseModel
4
+ from huggingface_hub import hf_hub_download
5
+ from llama_cpp import Llama
6
+
7
+ app = FastAPI()
8
+
9
+ # 1. تحميل النموذج من المستودع المحدد
10
+ model_path = hf_hub_download(
11
+ repo_id="Arabic250/gemma-4-gguf-export",
12
+ filename="gemma-4-e4b.gguf"
13
+ )
14
+
15
+ # 2. تهيئة النموذج للعمل على CPU فقط
16
+ llm = Llama(
17
+ model_path=model_path,
18
+ n_ctx=2048,
19
+ n_threads=4, # مناسب لموارد Hugging Face المجانية
20
+ n_gpu_layers=0 # تعطيل طبقات معالج الرسوميات (CPU Only)
21
+ )
22
+
23
+ class ChatRequest(BaseModel):
24
+ message: str
25
+
26
+ # 3. واجهة React الأمامية مدمجة كـ HTML
27
+ HTML_CONTENT = """
28
+ <!DOCTYPE html>
29
+ <html lang="ar" dir="rtl">
30
+ <head>
31
+ <meta charset="UTF-8">
32
+ <title>Gemma 4 Chat</title>
33
+ <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
34
+ <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
35
+ <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
36
+ <script src="https://cdn.tailwindcss.com"></script>
37
+ </head>
38
+ <body class="bg-gray-100 p-4 font-sans">
39
+ <div id="root"></div>
40
+ <script type="text/babel">
41
+ function App() {
42
+ const [messages, setMessages] = React.useState([]);
43
+ const [input, setInput] = React.useState("");
44
+ const [loading, setLoading] = React.useState(false);
45
+
46
+ const sendMessage = async () => {
47
+ if (!input.trim()) return;
48
+ const newMessages = [...messages, { role: 'user', text: input }];
49
+ setMessages(newMessages);
50
+ setInput("");
51
+ setLoading(true);
52
+
53
+ try {
54
+ const res = await fetch("/chat", {
55
+ method: "POST",
56
+ headers: { "Content-Type": "application/json" },
57
+ body: JSON.stringify({ message: input })
58
+ });
59
+ const data = await res.json();
60
+ setMessages([...newMessages, { role: 'model', text: data.response }]);
61
+ } catch (error) {
62
+ console.error(error);
63
+ }
64
+ setLoading(false);
65
+ };
66
+
67
+ return (
68
+ <div className="max-w-3xl mx-auto bg-white p-6 rounded-lg shadow-lg mt-10 border-t-4 border-blue-500">
69
+ <h1 className="text-2xl font-bold mb-6 text-center text-gray-800">محادثة Gemma 4 (React)</h1>
70
+ <div className="h-[28rem] overflow-y-auto mb-4 p-4 border rounded bg-gray-50 flex flex-col gap-3">
71
+ {messages.map((msg, idx) => (
72
+ <div key={idx} className={`p-3 rounded-lg w-fit max-w-[80%] ${msg.role === 'user' ? 'bg-blue-100 self-start' : 'bg-green-100 self-end'}`}>
73
+ <strong className="block mb-1 text-xs text-gray-500">{msg.role === 'user' ? 'أنت' : 'النموذج'}</strong>
74
+ <span className="text-gray-800">{msg.text}</span>
75
+ </div>
76
+ ))}
77
+ {loading && <div className="text-gray-500 text-sm animate-pulse self-end">النموذج يقوم بالمعالجة الآن...</div>}
78
+ </div>
79
+ <div className="flex gap-2">
80
+ <input
81
+ type="text"
82
+ value={input}
83
+ onChange={(e) => setInput(e.target.value)}
84
+ onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
85
+ className="flex-1 p-3 border rounded focus:outline-none focus:ring-2 focus:ring-blue-400"
86
+ placeholder="اكتب استفسارك هنا..."
87
+ />
88
+ <button onClick={sendMessage} disabled={loading} className="bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700 disabled:opacity-50 transition-colors font-semibold">
89
+ إرسال
90
+ </button>
91
+ </div>
92
+ </div>
93
+ );
94
+ }
95
+ const root = ReactDOM.createRoot(document.getElementById('root'));
96
+ root.render(<App />);
97
+ </script>
98
+ </body>
99
+ </html>
100
+ """
101
+
102
+ @app.get("/")
103
+ def read_root():
104
+ return HTMLResponse(content=HTML_CONTENT)
105
+
106
+ @app.post("/chat")
107
+ def chat(request: ChatRequest):
108
+ # بناء سياق Gemma بالشكل الصحيح
109
+ prompt = f"<start_of_turn>user\n{request.message}<end_of_turn>\n<start_of_turn>model\n"
110
+
111
+ response = llm(
112
+ prompt,
113
+ max_tokens=512,
114
+ stop=["<end_of_turn>"]
115
+ )
116
+
117
+ return {"response": response['choices'][0]['text'].strip()}