<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Local AI on kenji.blog</title><link>http://kenji.blog/ar/tags/local-ai/</link><description>Recent content in Local AI on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ar</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 16:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ar/tags/local-ai/index.xml" rel="self" type="application/rss+xml"/><item><title>كيفية ضبط TinyLLaMA بأسرع طريقة في بيئة محلية</title><link>http://kenji.blog/ar/p/tinyllama-on-premises-fast-tuning-guide/</link><pubDate>Fri, 11 Sep 2026 16:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/tinyllama-on-premises-fast-tuning-guide/</guid><description>&lt;img src="http://kenji.blog/p/tinyllama-on-premises-fast-tuning-guide/img/eyecatch.jpg" alt="Featured image of post كيفية ضبط TinyLLaMA بأسرع طريقة في بيئة محلية" />&lt;h2 id="1-مقدمة-لماذا-tinyllama-والبيئة-المحلية-الآن">1. مقدمة: لماذا TinyLLaMA والبيئة المحلية الآن؟
&lt;/h2>&lt;p>يتقدم تطور النماذج اللغوية الكبيرة (LLMs) بسرعة هائلة، ومع ذلك يستمر عدد معلمات النماذج (Parameters) في التضخم ليصل إلى مئات المليارات. في حين أن النماذج الضخمة مثل GPT-4 و Claude 3 تتمتع بأداء لا مثيل له، إلا أن التكلفة الحسابية اللازمة للاستنتاج (Inference) والتدريب، بالإضافة إلى المخاوف المتعلقة بالأمان وخصوصية البيانات عند استخدام واجهات برمجة التطبيقات (APIs) الخارجية، تشكل عقبات كبيرة للشركات. خاصة في الأعمال التي تتعامل مع بيانات داخلية سرية للغاية أو معلومات شخصية، فإن إرسال البيانات إلى واجهات برمجة تطبيقات LLM عامة على السحابة (Cloud) غالباً ما يكون غير مقبول من منظور الامتثال (مثل GDPR و APPI).&lt;/p>
&lt;p>لذلك، تتجه الأنظار نحو &lt;strong>النماذج اللغوية الصغيرة (SLM: Small Language Models)&lt;/strong> و &lt;strong>التشغيل المحلي في بيئات محلية (On-premises)&lt;/strong>. من بينها، يتميز &amp;ldquo;&lt;strong>TinyLLaMA&lt;/strong>&amp;rdquo; بحجمه المدمج الذي يبلغ 1.1 مليار معلمة فقط (1.1B)، إلا أنه تم تدريبه مسبقًا على مجموعة بيانات ضخمة تبلغ حوالي 3 تريليون رمز (Tokens)، مما يجعله يظهر أداءً مذهلاً مقارنة بالنماذج من نفس الفئة.&lt;/p>
&lt;p>في هذا المقال، سنقدم دليلاً كاملاً للضبط الدقيق (Fine-tuning) لـ TinyLLaMA في بيئة محلية (خادم محلي أو محطة عمل) للمهام الخاصة بشركتك، بـ &amp;ldquo;أسرع وأعلى كفاءة&amp;rdquo;. سنشرح كل شيء بشمولية، بدءًا من الخلفية الرياضية وتقنيات التحسين الحديثة، وصولاً إلى أكواد التنفيذ الفعلية باستخدام PyTorch.&lt;/p>
&lt;hr>
&lt;h2 id="2-بنية-tinyllama-وخصائصه">2. بنية TinyLLaMA وخصائصه
&lt;/h2>&lt;p>يعتمد TinyLLaMA على بنية LLaMA (Large Language Model Meta AI) التي طورتها شركة Meta. على الرغم من إبقاء عدد المعلمات عند 1.1B، إلا أنه يستخدم نفس حزمة التقنيات المستخدمة في LLaMA 2، مما يتميز بتوافق عالٍ جداً مع النظام البيئي.&lt;/p>
&lt;h3 id="مكونات-البنية-الأساسية">مكونات البنية الأساسية
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>RMSNorm (Root Mean Square Normalization):&lt;/strong>
تقنية تطبيع (Normalization) تعمل على تحسين الكفاءة الحسابية عن طريق حذف طرح المتوسط من حسابات LayerNorm التقليدية. إنها تزيد من الإنتاجية مع الحفاظ على استقرار التدريب.&lt;/li>
&lt;li>&lt;strong>دالة التنشيط SwiGLU:&lt;/strong>
في شبكة التغذية الأمامية (Feed Forward Network - FFN)، يتم استخدام SwiGLU بدلاً من ReLU أو GELU التقليدية. يتم التعبير عن هذا رياضياً على النحو التالي:
$$ \text{SwiGLU}(x, W, V) = \text{Swish}(xW) \otimes (xV) $$
هنا، يمثل $\otimes$ الضرب على مستوى العناصر (Hadamard product)، ودالة Swish هي $\text{Swish}(z) = z \cdot \sigma(\beta z)$. هذا يحسن من القدرة التعبيرية بشكل كبير.&lt;/li>
&lt;li>&lt;strong>RoPE (Rotary Position Embedding):&lt;/strong>
طريقة تجمع بين مزايا التضمين الموضعي المطلق (Absolute position encoding) والنسبي (Relative position encoding). تتمتع بأداء تعميمي عالٍ حتى عند تمديد طول التسلسل.&lt;/li>
&lt;li>&lt;strong>Grouped Query Attention (GQA):&lt;/strong>
نهج وسط بين Multi-Head Attention (MHA) و Multi-Query Attention (MQA)، ومن خلال تجميع رؤوس المفاتيح (Keys) والقيم (Values)، فإنه يوفر عرض النطاق الترددي للذاكرة ويزيد من سرعة الاستنتاج بشكل كبير.&lt;/li>
&lt;/ol>
&lt;p>يوضح مخطط Mermaid أدناه تدفق البيانات العام لـ TinyLLaMA وبنية كتلة المحول (Transformer block).&lt;/p>
&lt;div class="mermaid">graph TD
A["النص المدخل"] --> B["المرمز (BPE)"]
B --> C["طبقة التضمين"]
C --> D["كتل المحول (22 طبقة لـ TinyLLaMA)"]
D --> E["RMSNorm (نهائي)"]
E --> F["الإسقاط الخطي (حجم المفردات)"]
F --> G["احتمالات المخرجات (Softmax)"]
subgraph "تشريح كتلة المحول"
D1["حالة الإخفاء المدخلة"] --> D2["RMSNorm"]
D2 --> D3["انتباه الاستعلام المجمع (GQA)"]
D3 --> D4["إضافة متبقية"]
D4 --> D5["RMSNorm"]
D5 --> D6["SwiGLU FFN"]
D6 --> D7["إضافة متبقية"]
D7 --> D8["المخرجات للطبقة التالية"]
D1 -.-> D4
D4 -.-> D7
end&lt;/div>
&lt;hr>
&lt;h2 id="3-اختراق-في-الضبط-الدقيق-lora-و-qlora">3. اختراق في الضبط الدقيق: LoRA و QLoRA
&lt;/h2>&lt;p>لإجراء ضبط دقيق كامل المعلمات (Full parameter fine-tuning) في بيئة محلية، حتى بالنسبة لنموذج 1.1B، فإنه يستهلك عشرات الجيجابايت من ذاكرة VRAM (ذاكرة الفيديو) للاحتفاظ بحالة المحسن (Optimizer) والتدرجات (Gradients). لتحقيق تدريب فعال بموارد محدودة، من الضروري استخدام طريقة &lt;strong>PEFT (Parameter-Efficient Fine-Tuning)&lt;/strong> وهي &amp;ldquo;&lt;strong>LoRA&lt;/strong>&amp;rdquo; وامتداد التكميم (Quantization) الخاص بها &amp;ldquo;&lt;strong>QLoRA&lt;/strong>&amp;rdquo;.&lt;/p>
&lt;h3 id="31-الخلفية-الرياضية-لـ-lora-low-rank-adaptation">3.1 الخلفية الرياضية لـ LoRA (Low-Rank Adaptation)
&lt;/h3>&lt;p>LoRA هي طريقة تقوم بتجميد (Freeze) مصفوفات الأوزان المدربة مسبقًا، وتقريب مقدار تحديث الوزن ($\Delta W$) كحاصل ضرب مصفوفتين صغيرتين منخفضتي الرتبة (Low-rank).&lt;/p>
&lt;p>لنفترض أن الأوزان المدربة مسبقًا هي $W_0 \in \mathbb{R}^{d \times k}$. في الضبط الدقيق الكامل، يتم تحديث $W_0$ نفسها لتصبح $W_0 + \Delta W$، ولكن في LoRA يتم تحليل مصفوفة التحديث $\Delta W$ على النحو التالي:&lt;/p>
$$ \Delta W = B \times A $$
&lt;p>هنا، $B \in \mathbb{R}^{d \times r}$، و $A \in \mathbb{R}^{r \times k}$، و $r$ هي معلمة فائقة (Hyperparameter) تسمى الرتبة (Rank)، وهي قيمة صغيرة جداً (عادة 8، 16، 32، وما إلى ذلك) تلبي $r \ll \min(d, k)$.&lt;/p>
&lt;p>يكون حساب التمرير الأمامي (Forward pass) على النحو التالي:&lt;/p>
$$ h = W_0 x + \Delta W x = W_0 x + B A x $$
&lt;p>في الحالة الأولية، تتم تهيئة المصفوفة $A$ بشكل عشوائي بتوزيع طبيعي (Gaussian distribution)، وتتم تهيئة المصفوفة $B$ كمصفوفة صفرية. وبسبب هذا، تكون $\Delta W$ في بداية التدريب صفراً، مما يسمح ببدء التدريب مع الاحتفاظ بمخرجات النموذج الأساسي (Base model) بالكامل.&lt;/p>
&lt;div class="mermaid">graph LR
X["متجه الإدخال x"] --> W0["الوزن المجمد المدرب مسبقًا (W_0)"]
X --> A["مصفوفة LoRA القابلة للتدريب A (r x k)"]
A --> B["مصفوفة LoRA القابلة للتدريب B (d x r)"]
W0 --> Add["جمع المتجهات"]
B --> Add
Add --> Y["متجه الإخراج h"]&lt;/div>
&lt;h3 id="32-ابتكار-qlora-quantized-lora">3.2 ابتكار QLoRA (Quantized LoRA)
&lt;/h3>&lt;p>تدفع QLoRA بنهج LoRA خطوة أبعد، وهي طريقة تقوم بتكميم (Quantize) النموذج الأساسي $W_0$ إلى دقة 4-bit (NormalFloat 4, NF4) وتحميله في الذاكرة. هذا يقلل بشكل كبير من استهلاك VRAM.&lt;/p>
&lt;p>تتضمن QLoRA ثلاث تقنيات مهمة:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>تكميم 4-bit NormalFloat (NF4):&lt;/strong> نوع بيانات مثالي نظرياً ومحسن للأوزان التي تتبع توزيعاً طبيعياً.&lt;/li>
&lt;li>&lt;strong>التكميم المزدوج (Double Quantization):&lt;/strong> يوفر المزيد من الذاكرة عن طريق تكميم ثوابت التكميم (معاملات المقياس - Scale factors) نفسها.&lt;/li>
&lt;li>&lt;strong>Paged Optimizers:&lt;/strong> آلية تستخدم ميزة الذاكرة الموحدة من NVIDIA لتفريغ (Evict) حالة المحسن مؤقتاً إلى ذاكرة الوصول العشوائي (RAM) الخاصة بوحدة المعالجة المركزية (CPU) عند نفاد VRAM.&lt;/li>
&lt;/ol>
&lt;p>نتيجة لذلك، فإن الضبط الذي يتطلب عادةً من 16 جيجابايت إلى 24 جيجابايت من VRAM يمكن إجراؤه بسهولة على وحدات معالجة رسومات استهلاكية (مثل RTX 3060 12GB أو RTX 4070).&lt;/p>
&lt;hr>
&lt;h2 id="4-متطلبات-الأجهزة-والإعداد-في-البيئة-المحلية">4. متطلبات الأجهزة والإعداد في البيئة المحلية
&lt;/h2>&lt;p>تعتبر متطلبات الأجهزة لضبط TinyLLaMA (1.1B) باستخدام QLoRA منخفضة جداً.&lt;/p>
&lt;h3 id="مواصفات-الأجهزة-الموصى-بها">مواصفات الأجهزة الموصى بها
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>وحدة معالجة الرسومات (GPU):&lt;/strong> NVIDIA RTX 3060 (12GB) أو RTX 3090/4090 (24GB) أو NVIDIA A10G/A100 وغيرها. تعمل إذا كان هناك 8 جيجابايت من VRAM على الأقل، ولكن يوصى بـ 12 جيجابايت أو أكثر لزيادة حجم الدفعة (Batch size).&lt;/li>
&lt;li>&lt;strong>وحدة المعالجة المركزية (CPU):&lt;/strong> وحدة معالجة مركزية حديثة بـ 8 نوى أو أكثر (Intel Core i7/i9، AMD Ryzen 7/9)&lt;/li>
&lt;li>&lt;strong>ذاكرة الوصول العشوائي (RAM):&lt;/strong> 32 جيجابايت أو أكثر (مهمة كوجهة إخلاء من VRAM عند استخدام Paged Optimizers)&lt;/li>
&lt;li>&lt;strong>مساحة التخزين:&lt;/strong> NVMe SSD (لتسريع قراءة مجموعة البيانات وحفظ النموذج)&lt;/li>
&lt;/ul>
&lt;h3 id="إعداد-بيئة-البرامج">إعداد بيئة البرامج
&lt;/h3>&lt;p>هذه إرشادات الإعداد بفرض استخدام بيئة Ubuntu 22.04 LTS. سنستخدم Python 3.10 أو أحدث.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># إنشاء بيئة افتراضية وتفعيلها&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">python3 -m venv tinyllama_env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> tinyllama_env/bin/activate
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># تثبيت PyTorch (لـ CUDA 12.1)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># تثبيت المكتبات المتعلقة بالمحولات (Transformers)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install transformers datasets peft trl accelerate bitsandbytes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="5-تقنيات-التحسين-للحصول-على-أسرع-ضبط">5. تقنيات التحسين للحصول على أسرع ضبط
&lt;/h2>&lt;p>لإكمال الضبط بـ &amp;ldquo;أسرع&amp;rdquo; طريقة، لا يكفي مجرد تشغيل النص البرمجي، بل يجب الجمع بين تقنيات التحسين التالية.&lt;/p>
&lt;h3 id="51-flash-attention-2">5.1 Flash Attention 2
&lt;/h3>&lt;p>في آلية الانتباه (Attention) القياسية، يكون التعقيد الزمني والمكاني $O(N^2)$ بالنسبة لطول التسلسل $N$. تعمل تقنية Flash Attention 2 على تحسين الوصول إلى الذاكرة بين SRAM و HBM (الذاكرة ذات النطاق الترددي العالي) في GPU، مما يزيل اختناقات الإدخال/الإخراج (IO bottlenecks) دون تقليل كمية الحسابات، ويرفع سرعة التدريب عدة مرات، ويقلل استهلاك الذاكرة بشكل كبير.&lt;/p>
&lt;h3 id="52-gradient-checkpointing-نقاط-فحص-التدرج">5.2 Gradient Checkpointing (نقاط فحص التدرج)
&lt;/h3>&lt;p>بدلاً من حفظ جميع التنشيطات الوسيطة (Intermediate activations) المحسوبة في التمرير الأمامي في VRAM، تقوم هذه الطريقة بحفظ جزء منها فقط، وإعادة حسابها عند الحاجة في التمرير الخلفي (Backward pass). يزداد وقت الحساب بنسبة 20٪ تقريبًا، ولكن يمكن تقليل استهلاك الذاكرة بشكل كبير، مما يسمح بتعيين حجم دفعة (Batch size) أكبر، وبالتالي تحسين الإنتاجية الإجمالية.&lt;/p>
&lt;h3 id="53-mixed-precision-training-التدريب-بالدقة-المختلطة-و-bfloat16">5.3 Mixed Precision Training (التدريب بالدقة المختلطة) و Bfloat16
&lt;/h3>&lt;p>لتحقيق أقصى استفادة من Tensor Cores في GPU، نستخدم &lt;code>bfloat16&lt;/code> (Brain Floating Point) للحسابات أثناء التدريب. بالمقارنة مع &lt;code>float16&lt;/code>، فإن طول البت للأس هو نفسه في &lt;code>float32&lt;/code>، لذلك يكون خطر تجاوز السعة (Overflow) وانخفاض السعة (Underflow) منخفضًا جدًا، مما يجعل التدريب مستقرًا.&lt;/p>
&lt;hr>
&lt;h2 id="6-عملي-كود-الضبط-الدقيق-qlora-لـ-tinyllama">6. عملي: كود الضبط الدقيق QLoRA لـ TinyLLaMA
&lt;/h2>&lt;p>الآن، سنشرح نص PyTorch المخصص لأسرع ضبط، والذي يتضمن جميع التحسينات المذكورة أعلاه. هنا نستخدم &lt;code>SFTTrainer&lt;/code> من مكتبة &lt;code>trl&lt;/code> (Transformer Reinforcement Learning) الخاصة بـ Hugging Face.&lt;/p>
&lt;h3 id="61-تجهيز-مجموعة-البيانات-وتحميل-النموذج">6.1 تجهيز مجموعة البيانات وتحميل النموذج
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">torch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">datasets&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">load_dataset&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">transformers&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">AutoModelForCausalLM&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">AutoTokenizer&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BitsAndBytesConfig&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TrainingArguments&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">peft&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">LoraConfig&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">get_peft_model&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">prepare_model_for_kbit_training&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">trl&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">SFTTrainer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. تحديد النموذج والمرمز (Tokenizer)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model_id&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;TinyLlama/TinyLlama-1.1B-Chat-v1.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. إعدادات تكميم 4-bit لـ QLoRA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">bnb_config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">BitsAndBytesConfig&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">load_in_4bit&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bnb_4bit_use_double_quant&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bnb_4bit_quant_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;nf4&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bnb_4bit_compute_dtype&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">torch&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">bfloat16&lt;/span> &lt;span class="c1"># إجراء الحسابات باستخدام bfloat16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. تحميل النموذج (تفعيل Flash Attention 2)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Loading model...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoModelForCausalLM&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model_id&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">quantization_config&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">bnb_config&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">device_map&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;auto&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">use_flash_attention_2&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span> &lt;span class="c1"># مفتاح التسريع&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 4. تحميل المرمز (Tokenizer)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoTokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model_id&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">trust_remote_code&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pad_token&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">eos_token&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">padding_side&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;right&amp;#34;&lt;/span> &lt;span class="c1"># التعيين إلى right لتجنب الأخطاء أثناء التدريب باستخدام fp16/bf16&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="62-تطبيق-محول-lora-وتنسيق-مجموعة-البيانات">6.2 تطبيق محول LoRA وتنسيق مجموعة البيانات
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 5. التحضير لتدريب k-bit وتفعيل نقاط فحص التدرج&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gradient_checkpointing_enable&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">prepare_model_for_kbit_training&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 6. إعدادات LoRA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">peft_config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">LoraConfig&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># الرتبة&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lora_alpha&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">32&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># معامل التحجيم&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lora_dropout&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.05&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bias&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;none&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">task_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;CAUSAL_LM&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">target_modules&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;q_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;k_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;v_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;o_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;gate_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;up_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;down_proj&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="c1"># استهداف جميع الطبقات الخطية يحسن الأداء&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">get_peft_model&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">peft_config&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">print_trainable_parameters&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># مثال للمخرجات: trainable params: 14,286,848 || all params: 1,114,335,232 || trainable%: 1.282%&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 7. تحميل مجموعة البيانات (نستخدم هنا مجموعة بيانات Instruction باللغة اليابانية كمثال)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># في الواقع، ستقوم بتحميل ملف JSONL خاص بك من البيئة المحلية&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">dataset&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">load_dataset&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;kunishou/databricks-dolly-15k-ja&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">split&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;train&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">format_instruction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> تنسيق السلسلة لتتناسب مع تنسيق ChatML أو قالب الموجه (Prompt template)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&amp;lt;|im_start|&amp;gt;user&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;instruction&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">sample&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;input&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;input&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&amp;lt;|im_end|&amp;gt;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;lt;|im_start|&amp;gt;assistant&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;output&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;lt;|im_end|&amp;gt;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">prompt&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">dataset&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dataset&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">format_instruction&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="63-تنفيذ-التدريب">6.3 تنفيذ التدريب
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 8. إعداد وسائط التدريب&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">training_args&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">TrainingArguments&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">output_dir&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-lora-output&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">per_device_train_batch_size&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">8&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># يمكن زيادته إذا كانت هناك مساحة في VRAM&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">gradient_accumulation_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># حجم الدفعة الفعلي = 8 * 2 = 16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">optim&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;paged_adamw_32bit&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># توفير VRAM باستخدام Paged Optimizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">save_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logging_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">learning_rate&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">2e-4&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">fp16&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bf16&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># التدريب بالدقة المختلطة (bfloat16)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">max_grad_norm&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.3&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">max_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># 500 خطوة للاختبار. في الإنتاج، حدد عدد الحقبات (Epochs)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">warmup_ratio&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.03&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">group_by_length&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lr_scheduler_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;cosine&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 9. بدء التدريب باستخدام SFTTrainer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">trainer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">SFTTrainer&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">train_dataset&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">dataset&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">peft_config&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">peft_config&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dataset_text_field&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">max_seq_length&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1024&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># تعديل ليناسب طول الإدخال المتوقع&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tokenizer&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">tokenizer&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">args&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">training_args&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Starting training...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">trainer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">train&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 10. حفظ محول LoRA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">trainer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-lora-final&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-lora-final&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Training complete and model saved.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="7-تقييم-الأداء-واستكشاف-الأخطاء-وإصلاحها">7. تقييم الأداء واستكشاف الأخطاء وإصلاحها
&lt;/h2>&lt;p>إليك المشكلات الشائعة والحلول الخاصة بها عند تشغيل التدريب في بيئة محلية.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>حدوث OOM (Out Of Memory):&lt;/strong>
&lt;ul>
&lt;li>قلل &lt;code>per_device_train_batch_size&lt;/code> إلى &lt;code>1&lt;/code>.&lt;/li>
&lt;li>قم بزيادة &lt;code>gradient_accumulation_steps&lt;/code> للحفاظ على حجم الدفعة الفعلي.&lt;/li>
&lt;li>قم بتقصير &lt;code>max_seq_length&lt;/code> من &lt;code>2048&lt;/code> إلى &lt;code>1024&lt;/code> أو &lt;code>512&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>الخسارة (Loss) لا تنخفض أو تتباعد:&lt;/strong>
&lt;ul>
&lt;li>قد يكون معدل التعلم (&lt;code>learning_rate&lt;/code>) مرتفعًا جدًا. حاول تقليله من &lt;code>2e-4&lt;/code> إلى حوالي &lt;code>5e-5&lt;/code>.&lt;/li>
&lt;li>إذا كنت تستخدم Float16 بدلاً من Bfloat16، فقد يحدث انخفاض في سعة التدرجات (Underflow). تحقق من &lt;code>bf16=True&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>توليد سلاسل نصية غامضة أثناء الاستنتاج:&lt;/strong>
&lt;ul>
&lt;li>تأكد من تعيين &lt;code>padding_side=&amp;quot;right&amp;quot;&lt;/code> بشكل صحيح. بالإضافة إلى ذلك، تحقق مما إذا كان تنسيق مجموعة البيانات (مثل الرموز المميزة الخاصة &lt;code>&amp;lt;|im_start|&amp;gt;&lt;/code>) متوافقًا مع التنسيق المستخدم أثناء التدريب المسبق للنموذج الأساسي.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="8-نشر-النموذج-بعد-الضبط-deployment">8. نشر النموذج بعد الضبط (Deployment)
&lt;/h2>&lt;p>عند اكتمال الضبط، ما يتم حفظه ليس &amp;ldquo;النموذج الأساسي بأكمله&amp;rdquo;، بل فقط &amp;ldquo;&lt;strong>محول LoRA (أوزان الفروق)&lt;/strong>&amp;rdquo; الذي يبلغ حجمه بضعة ميغابايت إلى عشرات الميغابايت. لإجراء الاستنتاج بسرعة، يجب دمج (Merge) أوزان LoRA هذه في النموذج الأساسي الأصلي وتصديرها كنموذج واحد.&lt;/p>
&lt;h3 id="نص-دمج-النموذج-merge-script">نص دمج النموذج (Merge script)
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">torch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">peft&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AutoPeftModelForCausalLM&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">transformers&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AutoTokenizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">output_dir&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;./tinyllama-lora-final&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># تحميل النموذج والمحول باستخدام FP16/BF16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoPeftModelForCausalLM&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">output_dir&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">device_map&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;auto&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">torch_dtype&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">torch&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">bfloat16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoTokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">output_dir&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># دمج الأوزان وحفظها&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">merged_model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">merge_and_unload&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">merged_model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-merged&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">safe_serialization&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-merged&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Model merged and saved successfully!&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="تشغيل-خادم-استنتاج-فائق-السرعة-باستخدام-vllm">تشغيل خادم استنتاج فائق السرعة باستخدام vLLM
&lt;/h3>&lt;p>عند النشر في بيئة محلية، ولتحقيق أقصى قدر من سرعة الاستنتاج (الرموز في الثانية - Tokens per second)، يوصى بشدة باستخدام &lt;strong>vLLM&lt;/strong> أو &lt;strong>TGI (Text Generation Inference)&lt;/strong> بدلاً من خط الأنابيب القياسي (&lt;code>pipeline&lt;/code>) الخاص بـ Hugging Face. يستخدم vLLM تقنية PagedAttention لمنع تجزئة ذاكرة GPU، مما يحسن من قدرة معالجة الطلبات المتزامنة بشكل كبير.&lt;/p>
&lt;p>يوضح مخطط Mermaid أدناه مسار العمل (Pipeline) من التدريب إلى نشر خادم الاستنتاج.&lt;/p>
&lt;div class="mermaid">graph TD
A["بيانات خاصة خام"] --> B["المعالجة المسبقة والتنسيق (JSONL)"]
B --> C["الضبط الدقيق QLoRA (باستخدام SFTTrainer)"]
C --> D["أوزان محول LoRA (.safetensors)"]
D --> E["الدمج مع النموذج الأساسي TinyLLaMA 1.1B"]
E --> F["النموذج المدمج"]
F --> G["النشر عبر خادم vLLM"]
G --> H["نقطة نهاية API / واجهة مستخدم (مثال: روبوت دردشة)"]&lt;/div>
&lt;p>يمكن إكمال بدء تشغيل خادم API باستخدام vLLM بأمر واحد فقط:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">python -m vllm.entrypoints.openai.api_server &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --model ./tinyllama-merged &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --host 0.0.0.0 &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --port &lt;span class="m">8000&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --max-model-len &lt;span class="m">2048&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --dtype bfloat16
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>بهذا، يتم بناء نقطة نهاية متوافقة مع OpenAI API في البيئة المحلية، مما يسمح باستخدام الذكاء الاصطناعي المحلي بشكل آمن وسريع.&lt;/p>
&lt;hr>
&lt;h2 id="9-الخلاصة">9. الخلاصة
&lt;/h2>&lt;p>في هذا المقال، شرحنا كيفية إجراء ضبط دقيق (Fine-tuning) لنموذج &amp;ldquo;TinyLLaMA&amp;rdquo;، الذي يتميز بأداء عالٍ على الرغم من خفة وزنه (1.1 مليار معلمة)، بأسرع طريقة وأكثرها كفاءة في استخدام الذاكرة في بيئة محلية (On-premises).&lt;/p>
&lt;ul>
&lt;li>من خلال &lt;strong>LoRA / QLoRA&lt;/strong>، أصبح من الممكن إجراء ضبط لـ LLM بشكل احترافي حتى على وحدات معالجة الرسومات المخصصة للمستهلكين.&lt;/li>
&lt;li>من خلال الاستفادة من &lt;strong>Flash Attention 2&lt;/strong> و &lt;strong>Gradient Checkpointing&lt;/strong>، قمنا بتحسين وقت التدريب واستهلاك VRAM إلى أقصى حد.&lt;/li>
&lt;li>من خلال النشر باستخدام &lt;strong>vLLM&lt;/strong>، حققنا إنتاجية عالية حتى في بيئة الإنتاج.&lt;/li>
&lt;/ul>
&lt;p>لا يحافظ تشغيل LLM المحلي في بيئة محلية على سرية البيانات فحسب، بل يعمل أيضاً كأقوى سلاح لبناء ذكاء اصطناعي متخصص في مجالات معينة (مثل الشؤون القانونية والطبية واللوائح الداخلية) بتكلفة منخفضة. نأمل أن تستخدم هذا الدليل كمرجع لتدريب نموذج TinyLLaMA الخاص بشركتك.&lt;/p></description></item><item><title>دليل تطوير نماذج الذكاء الاصطناعي الصغيرة (مثل TinyLLaMA) باستخدام C++</title><link>http://kenji.blog/ar/p/cpp-small-ai-model-tinyllama-dev-guide/</link><pubDate>Fri, 11 Sep 2026 14:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/cpp-small-ai-model-tinyllama-dev-guide/</guid><description>&lt;img src="http://kenji.blog/p/cpp-small-ai-model-tinyllama-dev-guide/img/eyecatch.jpg" alt="Featured image of post دليل تطوير نماذج الذكاء الاصطناعي الصغيرة (مثل TinyLLaMA) باستخدام C++" />&lt;h1 id="دليل-تطوير-نماذج-الذكاء-الاصطناعي-الصغيرة-مثل-tinyllama-باستخدام-c">دليل تطوير نماذج الذكاء الاصطناعي الصغيرة (مثل TinyLLaMA) باستخدام C++
&lt;/h1>&lt;p>في الآونة الأخيرة، ازداد الاهتمام بشكل سريع بتشغيل النماذج اللغوية الكبيرة (LLM) في البيئات المحلية. على وجه الخصوص، يمكن للنماذج الصغيرة مثل TinyLLaMA (بحجم 1.1 مليار معلمة) إجراء الاستدلال بسرعة عملية حتى على الأجهزة الطرفية ذات الموارد المحدودة أو أجهزة الكمبيوتر المحمولة العادية (بما في ذلك بيئات Windows). بينما يعتبر التطوير باستخدام Python و PyTorch هو السائد، إلا أنه عند السعي لتحقيق الأداء الأمثل وكفاءة الذاكرة، يصبح الجمع بين C++ ومكتبة التنسور &amp;ldquo;ggml&amp;rdquo; المعتمدة على لغة C هو المعيار الفعلي.&lt;/p>
&lt;p>في هذا المقال، سنشرح خطوات تطوير مفصلة للغاية لبناء محرك استدلال من الصفر (أو فهم البنية الداخلية لـ llama.cpp الحالية بعمق) لتحميل TinyLLaMA وتوليد النصوص باستخدام C++.&lt;/p>
&lt;hr>
&lt;h2 id="1-لماذا-c-و-ggml">1. لماذا C++ و ggml؟
&lt;/h2>&lt;p>في مرحلة تدريب الذكاء الاصطناعي، تتفوق Python بفضل مرونتها ونظامها البيئي الغني. ومع ذلك، في مرحلة النشر أو &amp;ldquo;الاستدلال (Inference)&amp;quot;، تصبح C++ خياراً قوياً للأسباب التالية:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>تقليل النفقات العامة (Overhead)&lt;/strong>: يمكن القضاء تماماً على قفل المترجم العالمي (GIL) والنفقات العامة لوقت التشغيل في Python.&lt;/li>
&lt;li>&lt;strong>كفاءة الذاكرة وتخصيص الساحة (Arena Allocation)&lt;/strong>: نظراً لإمكانية التحكم اليدوي في تخصيص وتحرير الذاكرة، يمكن منع الزيادات غير المتوقعة الناتجة عن جمع القمامة (Garbage Collection).&lt;/li>
&lt;li>&lt;strong>الوصول المباشر إلى الأجهزة&lt;/strong>: استدعاء الوظائف المضمنة لـ SIMD (Intrinsics) مباشرة مثل AVX-512 و AVX2 و ARM NEON، مما يتيح استغلال قدرات الحوسبة لوحدة المعالجة المركزية إلى أقصى حد.&lt;/li>
&lt;li>&lt;strong>التخلص من التبعيات&lt;/strong>: ggml هي مكتبة C/C++ خالية من التبعيات (Zero dependencies)، ويمكن بناؤها بسهولة حتى في بيئة MSVC على Windows بمجرد توفر مترجم.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="2-النظرة-العامة-على-البنية">2. النظرة العامة على البنية
&lt;/h2>&lt;p>يوضح مخطط Mermaid التالي سير العمل في خط أنابيب الاستدلال بالكامل. إنها سلسلة من العمليات تبدأ من النص المدخل من قبل المستخدم وصولاً إلى توليد الرمز (Token) التالي.&lt;/p>
&lt;div class="mermaid">graph TD
A["نص إدخال المستخدم"] --> B["BPE Tokenizer"]
B --> C["مصفوفة معرفات الرموز (Token IDs)"]
C --> D["البحث في طبقة التضمين (Embedding Layer Lookup)"]
D --> E["كتل المحول (Transformer Blocks)"]
E --> F["RMSNorm"]
F --> G["طبقة رأس LM (LM Head Layer)"]
G --> H["مصفوفة اللوغاريتمات (Logits)"]
H --> I["وحدة أخذ العينات (Sampler)"]
I --> J["معرف الرمز التالي (Next Token ID)"]
J --> K["Detokenizer"]
K --> L["قطعة النص المخرجة"]
J -.-> |"إضافة إلى السياق"| C&lt;/div>
&lt;p>نظراً لأنه نموذج انحدار ذاتي (Autoregressive)، تتم إضافة الرموز المخرجة مرة أخرى إلى السياق، وتدور كمدخلات لتوقع الرمز التالي (الجزء المتقطع في المخطط).&lt;/p>
&lt;hr>
&lt;h2 id="3-تنسيق-النموذج-وتخطيط-الذاكرة-mmap">3. تنسيق النموذج وتخطيط الذاكرة (mmap)
&lt;/h2>&lt;p>تعد القراءة/الكتابة على القرص واستهلاك الذاكرة العائق الأكبر عند التعامل مع أوزان الشبكات العصبية الضخمة. في تطبيقات C++، يتم حل ذلك باستخدام &lt;strong>تخطيط الذاكرة (Memory Mapping - mmap)&lt;/strong>.&lt;/p>
&lt;h3 id="31-كيفية-عمل-تخطيط-الذاكرة-وتطبيقه-في-windows">3.1 كيفية عمل تخطيط الذاكرة وتطبيقه في Windows
&lt;/h3>&lt;p>باستخدام mmap، يمكن تعيين محتويات الملف مباشرة إلى مساحة الذاكرة الافتراضية للعملية.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>نسخ صفري (Zero-copy)&lt;/strong>: يتم تحميل البيانات مباشرة من القرص إلى ذاكرة التخزين المؤقت للصفحات في النواة (Kernel)، ولا يحدث نسخ إضافي إلى مساحة المستخدم.&lt;/li>
&lt;li>&lt;strong>التحميل عند الطلب (Page Fault)&lt;/strong>: في اللحظة التي تصل فيها وحدة المعالجة المركزية فعلياً إلى عنوان الذاكرة ذلك، يحدث خطأ في الصفحة (Page Fault)، ويتم تحميل الكتلة المطلوبة فقط (عادة 4 كيلوبايت) في الذاكرة الفعلية.&lt;/li>
&lt;/ul>
&lt;p>في بيئة Windows، بدلاً من &lt;code>mmap&lt;/code> الخاصة بـ POSIX، يتم استخدام واجهات برمجة تطبيقات Win32 &lt;code>CreateFileMapping&lt;/code> و &lt;code>MapViewOfFile&lt;/code>.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant OS["نظام التشغيل Windows"]
participant RAM["الذاكرة الفعلية (Physical Memory)"]
participant App["تطبيق C++"]
App->>OS: "CreateFileMapping / MapViewOfFile"
OS-->>App: "مؤشر عنوان الذاكرة الافتراضية"
App->>App: "قراءة بيانات التنسور عند المؤشر"
OS->>RAM: "Page Fault / تحميل الصفحة من القرص"
RAM-->>App: "البيانات جاهزة لحسابات SIMD"&lt;/div>
&lt;h3 id="32-البنية-الثنائية-لتنسيق-gguf">3.2 البنية الثنائية لتنسيق GGUF
&lt;/h3>&lt;p>يعد &lt;strong>GGUF (GPT-Generated Unified Format)&lt;/strong>، المحول من تنسيقات مثل &lt;code>.safetensors&lt;/code> الخاصة بـ Hugging Face، التنسيق النهائي للاستدلال. يحتوي على المخطط الثنائي الصارم التالي:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>البتات السحرية (Magic Bytes)&lt;/strong>: &lt;code>0x46554747&lt;/code> (GGUF).&lt;/li>
&lt;li>&lt;strong>الإصدار (Version)&lt;/strong>: رقم إصدار التنسيق.&lt;/li>
&lt;li>&lt;strong>عدد التنسورات وعدد البيانات الوصفية (Tensor &amp;amp; Metadata Count)&lt;/strong>: عدد التنسورات وأزواج المفتاح-القيمة للبيانات الوصفية.&lt;/li>
&lt;li>&lt;strong>البيانات الوصفية (Metadata)&lt;/strong>: مفاتيح ببادئات طول السلسلة وقيم محددة النوع.&lt;/li>
&lt;li>&lt;strong>معلومات التنسور (Tensor Info)&lt;/strong>: اسم كل تنسور، عدد الأبعاد، نوع البيانات (FP16، Q4_K، إلخ)، وموقع الإزاحة داخل الملف.&lt;/li>
&lt;li>&lt;strong>الحشو (Padding)&lt;/strong>: حشوات مدرجة لمحاذاة بيانات التنسور مع حدود معينة (عادة 32 بايت أو 64 بايت). هذا ضروري للوصول السريع للذاكرة في تعليمات SIMD (وخاصة AVX).&lt;/li>
&lt;li>&lt;strong>بيانات التنسور (Tensor Data)&lt;/strong>: مصفوفة بيانات الأوزان الفعلية المحاذاة.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="4-الأساس-الرياضي-لـ-tinyllama-وخوارزميات-c">4. الأساس الرياضي لـ TinyLLaMA وخوارزميات C++
&lt;/h2>&lt;p>يعتمد TinyLLaMA بعض الابتكارات المعمارية المتقدمة لزيادة الكفاءة. سنشرح التمثيلات الرياضية لتنفيذها بشكل صحيح في C++.&lt;/p>
&lt;h3 id="41-التقييس-الجذري-لمتوسط-المربعات-rmsnorm">4.1 التقييس الجذري لمتوسط المربعات (RMSNorm)
&lt;/h3>&lt;p>يقلل التكلفة الحسابية عن طريق حذف مركزة المتوسط من LayerNorm وتنفيذ قياس التباين فقط.&lt;/p>
$$ \text{RMSNorm}(x) = \frac{x}{\sqrt{\frac{1}{d}\sum_{i=1}^{d} x_i^2 + \epsilon}} \odot \gamma $$
&lt;p>حيث $d$ هو عدد الأبعاد، و $\gamma$ هو تنسور المقياس المُدرَّب.
عند التنفيذ بـ C++، نقوم أولاً بحساب مجموع مربعات المصفوفة بسرعة باستخدام &lt;code>_mm256_fmadd_ps&lt;/code> في AVX2، وتحسينه عن طريق ضربه بالجذر التربيعي العكسي (مثل تعليمة &lt;code>_mm256_rsqrt_ps&lt;/code>).&lt;/p>
&lt;h3 id="42-التضمين-الموضعي-الدوار-rope">4.2 التضمين الموضعي الدوار (RoPE)
&lt;/h3>&lt;p>هي تقنية لتطبيق معلومات موقع الرمز كدوران (Rotate) في مساحة التنسور. يمكن اعتبارها دوراناً على مستوى الأعداد المركبة، ويتم تطبيق الدوران التالي على الأزواج البعدية المتجاورة $(x_1, x_2)$ للمتجه $x$:&lt;/p>
$$ \text{RoPE}(x, m) = \begin{pmatrix} x_{1} \cos(m\theta) - x_{2} \sin(m\theta) \\ x_{1} \sin(m\theta) + x_{2} \cos(m\theta) \end{pmatrix} $$
&lt;p>حيث $m$ هو المؤشر الموضعي المطلق للرمز، و $\theta$ هو التردد الأساسي المحسوب مسبقاً. في ggml، يتم تنفيذه بالتوازي ببساطة عن طريق إضافة عامل &lt;code>ggml_rope&lt;/code> أثناء بناء رسم الاستدلال البياني.&lt;/p>
&lt;h3 id="43-الانتباه-المجمع-للاستعلام-grouped-query-attention---gqa">4.3 الانتباه المجمع للاستعلام (Grouped-Query Attention - GQA)
&lt;/h3>&lt;p>في الانتباه متعدد الرؤوس (MHA) العادي، يوجد نفس عدد الرؤوس لكل من Query و Key و Value. ومع ذلك، لتقليل استهلاك عرض النطاق الترددي للذاكرة وذاكرة التخزين المؤقت KV بشكل كبير، يعتمد TinyLLaMA &lt;strong>Grouped-Query Attention (GQA)&lt;/strong>.&lt;/p>
$$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q K^T}{\sqrt{d_k}}\right) V $$
&lt;p>في GQA، تشترك عدة رؤوس Query في رأس Key/Value واحد. في تطبيق C++، قبل إجراء ضرب المصفوفات &lt;code>ggml_mul_mat&lt;/code>، من الضروري إجراء عملية بث (Broadcast) لتنسورات KV لتتناسب مع عدد Query.&lt;/p>
&lt;h3 id="44-دالة-التنشيط-swiglu">4.4 دالة التنشيط SwiGLU
&lt;/h3>&lt;p>في طبقة الشبكة المغذية للأمام (FFN)، يتم استخدام SwiGLU بدلاً من GELU.&lt;/p>
$$ \text{SwiGLU}(x) = \text{Swish}(x W_{\text{gate}}) \otimes (x W_{\text{up}}) $$
$$ \text{Swish}(z) = z \cdot \sigma(z) = z \cdot \frac{1}{1 + e^{-z}} $$
&lt;p>يتم تمثيله في الرسم البياني الحسابي بدمج عاملي &lt;code>ggml_silu&lt;/code> و &lt;code>ggml_mul&lt;/code>.&lt;/p>
&lt;hr>
&lt;h2 id="5-بناء-الرسم-البياني-الحسابي-وإدارة-الذاكرة-باستخدام-ggml">5. بناء الرسم البياني الحسابي وإدارة الذاكرة باستخدام ggml
&lt;/h2>&lt;p>تعتمد ggml نهج &amp;ldquo;التحديد والتنفيذ (Define-and-Run)&amp;quot;، حيث تقوم ببناء رسم بياني حسابي ثابت للاستدلال ثم تقييمه (evaluate) لاحقاً.&lt;/p>
&lt;h3 id="51-ggml_context-ومخصص-الساحة-arena-allocator">5.1 ggml_context ومخصص الساحة (Arena Allocator)
&lt;/h3>&lt;p>الميزة الأكثر تميزاً في ggml هي &amp;ldquo;تخصيص الساحة&amp;rdquo;، الذي لا ينفذ أي تخصيص ديناميكي للذاكرة (&lt;code>malloc&lt;/code> أو &lt;code>new&lt;/code>) داخل حلقة الاستدلال.
يتم تخصيص منطقة ذاكرة متصلة ضخمة (الساحة) عند التهيئة، وفي كل مرة يتم فيها استدعاء &lt;code>ggml_new_tensor&lt;/code> وغيره، يزداد مؤشر هذه المنطقة. عند اكتمال خطوة استدلال واحدة، يتم فقط إعادة تعيين مؤشر التخصيص إلى الموضع الأولي، وبذلك يكتمل تخصيص الذاكرة لخطوة الاستدلال التالية على الفور.&lt;/p>
&lt;h3 id="52-مثال-عملي-لبناء-الرسم-البياني">5.2 مثال عملي لبناء الرسم البياني
&lt;/h3>&lt;p>في كل خطوة استدلال، يتم تجميع الرسم البياني الحسابي التالي في الذاكرة.&lt;/p>
&lt;div class="mermaid">graph TD
A["معرف رمز الإدخال (Tokens Input ID)"] --> B["البحث عن التضمين (Embed Lookup)"]
B --> C["ggml_rms_norm"]
C --> D["إسقاطات Q / K / V"]
D --> E["ggml_rope Positional"]
E --> F["حفظ في KV Cache"]
E --> G["تحميل من KV Cache"]
G --> H["الانتباه الذاتي (Self Attention)"]
H --> I["المقياس و Softmax"]
I --> J["مخرجات الانتباه (Attention Output)"]
J --> K["الإسقاط الخارجي (Out Projection)"]
K --> L["إضافة المتبقي (Add Residual)"]&lt;/div>
&lt;hr>
&lt;h2 id="6-التكميم-quantization-وتحسين-windows--simd">6. التكميم (Quantization) وتحسين Windows / SIMD
&lt;/h2>&lt;p>يتطلب التعامل مع TinyLLaMA (1.1B) بصيغة FP16 حوالي 2.2 جيجابايت من الذاكرة، ولكن باستخدام تكميم 4-بت (مثل Q4_K) يمكن ضغطه بشكل كبير إلى حوالي 600 ميجابايت.&lt;/p>
&lt;h3 id="61-بنية-التكميم-الكتلي-block-quantization">6.1 بنية التكميم الكتلي (Block Quantization)
&lt;/h3>&lt;p>لا تقوم ggml بتكميم التنسور بأكمله بشكل موحد، بل يتم ذلك على أساس &amp;ldquo;الكتلة&amp;rdquo;.
في تنسيق &lt;code>Q4_0&lt;/code>، يتم تجميع 32 قيمة FP16 في كتلة واحدة.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>عامل المقياس (Scale Factor)&lt;/strong>: قيمة واحدة FP16 (2 بايت)&lt;/li>
&lt;li>&lt;strong>البيانات المكممة&lt;/strong>: 32 قيمة 4-بت (16 بايت)
هذا يقلل من تأثير القيم المتطرفة المحلية.&lt;/li>
&lt;/ul>
&lt;h3 id="62-تسريع-الضرب-النقطي-باستخدام-avx2">6.2 تسريع الضرب النقطي باستخدام AVX2
&lt;/h3>&lt;p>عند البناء لأحدث وحدات المعالجة المركزية x86 في بيئة Windows، مع الاستفادة من علامات المترجم مثل &lt;code>/arch:AVX2&lt;/code>، تتم معالجة SIMD عبر التدفق التالي:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>التحميل (Load)&lt;/strong>: تحميل بيانات التكميم 4-بت من الذاكرة إلى سجلات AVX بحجم 256 بت.&lt;/li>
&lt;li>&lt;strong>التوسيع وفك الحزم (Unpack)&lt;/strong>: استخدام أقنعة البت (Bitmasks) وعمليات الإزاحة لتوسيع قيم 4-بت إلى Int8 أو Int16.&lt;/li>
&lt;li>&lt;strong>إلغاء التكميم (Dequantize)&lt;/strong>: الضرب في عامل المقياس للتحويل إلى فاصلة عائمة.&lt;/li>
&lt;li>&lt;strong>عمليات FMA&lt;/strong>: تنفيذ عمليات الضرب والجمع بالتوازي على قيم التنشيط باستخدام &lt;code>_mm256_fmadd_ps&lt;/code> (Fused Multiply-Add).&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="7-تفاصيل-تنفيذ-ذاكرة-التخزين-المؤقت-kv-kv-cache">7. تفاصيل تنفيذ ذاكرة التخزين المؤقت KV (KV Cache)
&lt;/h2>&lt;p>في التوليد التلقائي الانحداري، تعد &amp;ldquo;ذاكرة التخزين المؤقت KV&amp;rdquo; لتجاوز حسابات Key و Value للرموز السابقة ميزة أساسية.&lt;/p>
&lt;p>فيما يلي النقاط الرئيسية عند تنفيذ ذلك بـ C++:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>التخصيص المسبق للتنسور&lt;/strong>: تهيئة تنسور ضخم لذاكرة التخزين المؤقت KV بحجم الحد الأقصى لطول السياق (مثال: 2048 رمزاً) (يُفضل FP16).&lt;/li>
&lt;li>&lt;strong>نسخ الإزاحة (Offset Copy)&lt;/strong>: عند الحساب للموضع الرمزي $N$، يتم تخزين متجهات K و V الناتجة في تلك الخطوة في الصف $N$ من تنسور التخزين المؤقت KV باستخدام دوال مثل &lt;code>ggml_cpy&lt;/code>.&lt;/li>
&lt;li>&lt;strong>إنشاء مشهد (View) أثناء الانتباه&lt;/strong>: عند حساب الانتباه، يتم تمرير &amp;ldquo;مشهد&amp;rdquo; يشير فقط إلى أجزاء الرموز من 0 إلى $N$ لضرب المصفوفات.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="8-bpe-tokenizer-وفك-التشفير-decoding">8. BPE Tokenizer وفك التشفير (Decoding)
&lt;/h2>&lt;p>تتم معالجة السلسلة المدخلة كتسلسل بايتات UTF-8 وتتم مطابقتها مع مفردات محددة مسبقاً. في C++، لتسريع البحث في المفردات، يتم تنفيذ خوارزميات مثل &lt;strong>شجرة البادئة (Trie Tree)&lt;/strong> أو قوائم الانتظار ذات الأولوية.&lt;/p>
&lt;p>من سجلات Logits الناتجة عن LM Head، يتم قياس الاحتمالات باستخدام معلمة درجة الحرارة (Temperature)، ويتم تضييق المرشحين باستخدام استخراج Top-K أو أساليب Top-P (Nucleus Sampling)، ويتم تحديد الرمز التالي النهائي باستخدام أرقام عشوائية.&lt;/p>
&lt;hr>
&lt;h2 id="9-إعداد-مشروع-c-بيئة-windows--powershell">9. إعداد مشروع C++ (بيئة Windows / PowerShell)
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cmake_minimum_required&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">VERSION&lt;/span> &lt;span class="s">3.14&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">project&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">TinyLLaMACpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD&lt;/span> &lt;span class="s">17&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># إعدادات التحسين وعلامات AVX2 لـ Windows (MSVC)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MSVC&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">/O2&lt;/span> &lt;span class="s">/arch:AVX2&lt;/span> &lt;span class="s">/fp:fast&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_link_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">/STACK:8388608&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">else&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">-O3&lt;/span> &lt;span class="s">-march=native&lt;/span> &lt;span class="s">-ffast-math&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ggml&lt;/span> &lt;span class="s">OBJECT&lt;/span> &lt;span class="s">ggml/ggml.c&lt;/span> &lt;span class="s">ggml/ggml-alloc.c&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_compile_definitions&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ggml&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">GGML_USE_AVX2&lt;/span> &lt;span class="s">GGML_USE_F16C&lt;/span> &lt;span class="s">GGML_USE_FMA&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">main&lt;/span> &lt;span class="s">main.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">main&lt;/span> &lt;span class="s">ggml&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>مثال لأمر البناء في PowerShell:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">mkdir&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">..&lt;/span> &lt;span class="n">-G&lt;/span> &lt;span class="s2">&amp;#34;Visual Studio 17 2022&amp;#34;&lt;/span> &lt;span class="n">-A&lt;/span> &lt;span class="n">x64&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-build&lt;/span> &lt;span class="p">.&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">Release&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="10-الخلاصة">10. الخلاصة
&lt;/h2>&lt;p>يعد تنفيذ محرك استدلال لنموذج ذكاء اصطناعي صغير مثل TinyLLaMA من الصفر باستخدام C++ و ggml فرصة رائعة لكشف الصندوق الأسود للتعلم العميق وتعلم جمال التحكم في الأجهزة منخفضة المستوى. باستخدام التحميل بنسخ صفري المعتمد على تخطيط الذاكرة، وتحسينات SIMD، وبناء ذاكرة التخزين المؤقت KV، دعونا نفتح آفاقاً جديدة لمستقبل الذكاء الاصطناعي الطرفي (Edge AI) بينما نستمتع بجوهر برمجة الأنظمة.&lt;/p></description></item><item><title>【مقدمة في تنفيذ RAG】كيفية جعل الذكاء الاصطناعي المحلي يقرأ مستنداتك</title><link>http://kenji.blog/ar/p/rag-local-ai-implementation-guide/</link><pubDate>Fri, 11 Sep 2026 13:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/rag-local-ai-implementation-guide/</guid><description>&lt;img src="http://kenji.blog/p/rag-local-ai-implementation-guide/img/eyecatch.jpg" alt="Featured image of post 【مقدمة في تنفيذ RAG】كيفية جعل الذكاء الاصطناعي المحلي يقرأ مستنداتك" />&lt;h1 id="مقدمة">مقدمة
&lt;/h1>&lt;p>في السنوات الأخيرة، كان التطور في نماذج اللغة الكبيرة (LLM) ملحوظًا، حيث تغلغل العديد من أنظمة الذكاء الاصطناعي مثل ChatGPT و Claude في حياتنا وأعمالنا. ومع ذلك، هناك نقطة ضعف واضحة في نماذج LLM العامة. وهي أنها لا تعرف سوى &amp;ldquo;المعلومات العامة المتاحة وقت التدريب&amp;rdquo;. بالطبع، لا يمكنها الإجابة على الأسئلة المتعلقة بـ &amp;ldquo;المستندات الخاصة&amp;rdquo; مثل لوائح الشركة، والمذكرات الشخصية، ومواد المشاريع غير المنشورة. إذا حاولت إجبارها على الإجابة، فهناك خطر كبير من أنها ستولد أكاذيب تبدو معقولة ولكنها بعيدة عن الحقيقة (الهلوسة - Hallucination).&lt;/p>
&lt;p>لذلك، فإن البنية المعمارية التقنية التي تنتشر حاليًا بشكل هائل في جميع أنحاء العالم هي &lt;strong>RAG (Retrieval-Augmented Generation: التوليد المعزز بالاسترجاع)&lt;/strong>. باستخدام RAG، يصبح من الممكن تزويد LLM بالمعرفة الخاصة ديناميكيًا من قاعدة بيانات خارجية، وجعلها تولد إجابات دقيقة وموثوقة بناءً على ذلك.&lt;/p>
&lt;p>علاوة على ذلك، عند التعامل مع مجال الشركات أو المعلومات الشخصية السرية، غالبًا ما يكون إرسال البيانات إلى واجهات برمجة التطبيقات (APIs) المستندة إلى السحابة مثل OpenAI غير مسموح به بموجب سياسة الأمان. ما هو مطلوب هنا هو بناء &amp;ldquo;RAG محلي&amp;rdquo; مدمج مع &lt;strong>الذكاء الاصطناعي المحلي&lt;/strong> (LLM يعمل بالكامل على جهاز الكمبيوتر الخاص بك أو الخادم المحلي - On-Premise).&lt;/p>
&lt;p>في هذه المقالة، سنشرح بالتفصيل كل شيء بدءًا من النظريات الأساسية لـ RAG، وطرق التنفيذ المحددة لـ RAG المحلي باستخدام Python، والخلفية الرياضية (آلية البحث عن المتجهات)، إلى التقنيات المتقدمة لتشغيل النظام في بيئة الإنتاج.&lt;/p>
&lt;hr>
&lt;h1 id="1-البنية-المعمارية-العامة-لـ-rag">1. البنية المعمارية العامة لـ RAG
&lt;/h1>&lt;p>RAG ليس نموذج ذكاء اصطناعي واحد، بل هو بنية نظام تتعاون فيها مكونات متعددة. يتكون بشكل رئيسي من مرحلتين: &amp;ldquo;مرحلة الاستيعاب (إدخال البيانات)&amp;rdquo; و &amp;ldquo;مرحلة الاسترجاع والتوليد (البحث والتوليد)&amp;rdquo;.&lt;/p>
&lt;p>يوضح مخطط Mermaid التالي الصورة العامة لنظام RAG.&lt;/p>
&lt;div class="mermaid">graph TD
subgraph "مرحلة الاستيعاب (التحضير المسبق)"
Doc["مستندات خاصة (PDF, TXT, إلخ.)"] --> Loader["محمل المستندات"]
Loader --> Splitter["تقسيم النص (Chunking)"]
Splitter --> EmbedModel1["نموذج التضمين (Embedding)"]
EmbedModel1 --> VectorDB["قاعدة بيانات المتجهات"]
end
subgraph "مرحلة الاستدلال (عند استعلام المستخدم)"
User["سؤال من المستخدم (استعلام)"] --> EmbedModel2["نموذج التضمين (Embedding)"]
EmbedModel2 --> QueryVector["متجه الاستعلام"]
QueryVector --> Search["بحث التشابه (بحث المتجهات)"]
VectorDB --> Search
Search --> Context["استخراج القطع ذات الصلة (السياق)"]
User --> PromptBuilder["بناء الموجه (Prompt)"]
Context --> PromptBuilder
PromptBuilder --> LocalLLM["LLM محلي"]
LocalLLM --> Answer["توليد الإجابة النهائية"]
end&lt;/div>
&lt;h2 id="مرحلة-الاستيعاب-التحضير-المسبق">مرحلة الاستيعاب (التحضير المسبق)
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>تحميل المستندات&lt;/strong>: تحميل البيانات غير المهيكلة مثل ملفات PDF، Word، والملفات النصية.&lt;/li>
&lt;li>&lt;strong>التقسيم (Chunking)&lt;/strong>: تقسيم النصوص الطويلة إلى كتل ذات معنى (Chunks) لتتناسب مع قيود الإدخال في LLM (نافذة السياق) ولتحسين دقة البحث.&lt;/li>
&lt;li>&lt;strong>التضمين (Embedding / تحويل إلى متجهات)&lt;/strong>: إدخال الكتل المقسمة إلى نموذج التضمين (Embedding Model) وتحويلها إلى مصفوفات من الأرقام (متجهات) ذات مئات إلى آلاف الأبعاد.&lt;/li>
&lt;li>&lt;strong>الحفظ في قاعدة البيانات&lt;/strong>: حفظ المتجهات المحولة مرتبطة بالبيانات النصية الأصلية في قاعدة بيانات المتجهات (Vector DB).&lt;/li>
&lt;/ol>
&lt;h2 id="مرحلة-الاستدلال-أثناء-التشغيل">مرحلة الاستدلال (أثناء التشغيل)
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>تحويل الاستعلام إلى متجهات&lt;/strong>: تحويل سؤال المستخدم إلى متجه باستخدام نفس نموذج التضمين المستخدم في التحضير المسبق.&lt;/li>
&lt;li>&lt;strong>بحث التشابه&lt;/strong>: حساب التشابه بين متجه الاستعلام ومتجهات المستندات في قاعدة البيانات، واسترداد أعلى الكتل النصية الأقرب دلاليًا (ذات الصلة العالية).&lt;/li>
&lt;li>&lt;strong>بناء الموجه (Prompt)&lt;/strong>: دمج النصوص المستردة ذات الصلة كـ &amp;ldquo;سياق (معرفة خلفية)&amp;rdquo; مع سؤال المستخدم لإنشاء موجه الإدخال لـ LLM.&lt;/li>
&lt;li>&lt;strong>توليد الإجابة&lt;/strong>: يتلقى LLM الموجه الموسع ويولد إجابة بناءً على معلومات السياق المرفقة.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="2-الفهم-العميق-للبحث-في-المتجهات-والتضمين-embeddings">2. الفهم العميق للبحث في المتجهات والتضمين (Embeddings)
&lt;/h1>&lt;p>جوهر RAG هو &amp;ldquo;البحث في المتجهات (البحث الدلالي)&amp;rdquo;. بينما يعتمد بحث الكلمات الرئيسية التقليدي (مثل BM25) على المطابقة التامة للكلمات وتكرارها، يعتمد البحث في المتجهات على &amp;ldquo;التشابه الدلالي&amp;rdquo;. على سبيل المثال، حتى الكلمات المختلفة مثل &amp;ldquo;كلب&amp;rdquo; و &amp;ldquo;جرو&amp;rdquo;، أو &amp;ldquo;حاسوب&amp;rdquo; و &amp;ldquo;كمبيوتر&amp;rdquo;، ستظهر في نتائج البحث إذا كانت معانيها متقاربة.&lt;/p>
&lt;h2 id="ما-هو-نموذج-التضمين-embedding-model">ما هو نموذج التضمين (Embedding Model)؟
&lt;/h2>&lt;p>نموذج التضمين هو شبكة عصبية تأخذ النصوص باللغة الطبيعية كإدخال وتخرج متجهًا كثيفًا ثابت الطول (Dense Vector). النماذج الشائعة (مثل &lt;code>text-embedding-3-small&lt;/code> أو النماذج مفتوحة المصدر مثل &lt;code>multilingual-e5-large&lt;/code>) تقوم بتعيين النص إلى متجه حقيقي بأبعاد 384 أو 1024.&lt;/p>
&lt;p>في هذا الفضاء متعدد الأبعاد (الفضاء الكامن - Latent Space)، يتم تدريب النموذج بحيث تكون المسافة في فضاء الإحداثيات أقرب كلما كانت الجمل متشابهة في المعنى.&lt;/p>
&lt;h2 id="الخلفية-الرياضية-لحساب-التشابه-تشابه-جيب-التمام-cosine-similarity">الخلفية الرياضية لحساب التشابه: تشابه جيب التمام (Cosine Similarity)
&lt;/h2>&lt;p>عندما تبحث قاعدة بيانات المتجهات عن المستندات ذات الصلة، فإن مقياس المسافة الأكثر استخدامًا هو &lt;strong>تشابه جيب التمام (Cosine Similarity)&lt;/strong>. على عكس المسافة الإقليدية (المسافة المطلقة المكانية)، يركز تشابه جيب التمام على &amp;ldquo;الزاوية بين متجهين&amp;rdquo;. نظرًا لأنه أقل تأثرًا بطول الجملة (معيار المتجه)، فهو مناسب جدًا لحساب تشابه النصوص.&lt;/p>
&lt;p>يتم التعبير عن تشابه جيب التمام للمتجهين $\mathbf{A}$ و $\mathbf{B}$ رياضياً كالتالي:&lt;/p>
$$ \text{Cosine Similarity}(\mathbf{A}, \mathbf{B}) = \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}} $$
&lt;ul>
&lt;li>$\mathbf{A} \cdot \mathbf{B}$ يمثل الجداء النقطي (Dot Product).&lt;/li>
&lt;li>$\|\mathbf{A}\|$ يمثل معيار L2 (الطول) للمتجه $\mathbf{A}$.&lt;/li>
&lt;li>$n$ هو عدد أبعاد المتجه.&lt;/li>
&lt;/ul>
&lt;p>يأخذ تشابه جيب التمام قيمًا من -1 إلى 1.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>قريب من 1&lt;/strong>: اتجاه كلا المتجهين هو نفسه تقريبًا (المعنى متشابه جدًا)&lt;/li>
&lt;li>&lt;strong>قريب من 0&lt;/strong>: المتجهان متعامدان (غير مرتبطين)&lt;/li>
&lt;li>&lt;strong>قريب من -1&lt;/strong>: المتجهان في اتجاهين متعاكسين (المعنى معاكس)&lt;/li>
&lt;/ul>
&lt;p>تستخدم قواعد بيانات المتجهات الحديثة (مثل Chroma، FAISS، Qdrant) خوارزمية بحث أقرب جار تقريبي (ANN) تسمى HNSW (Hierarchical Navigable Small World)، والتي تم تحسينها للبحث عن المستندات ذات تشابه جيب التمام العالي من بين ملايين البيانات المتجهة في أجزاء من الثانية.&lt;/p>
&lt;hr>
&lt;h1 id="3-حزمة-التقنيات-لبناء-rag-محلي">3. حزمة التقنيات لبناء RAG محلي
&lt;/h1>&lt;p>لبناء RAG محلي بالكامل لا يعتمد على السحابة، سنستفيد من نظام المصادر المفتوحة. نوصي بحزمة التقنيات التالية:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>نموذج اللغة (LLM)&lt;/strong>
&lt;ul>
&lt;li>الأداة: &lt;code>Ollama&lt;/code> أو &lt;code>Llama.cpp&lt;/code>&lt;/li>
&lt;li>النماذج: نماذج مفتوحة خفيفة وعالية الأداء مثل &lt;code>Llama-3-8B-Instruct&lt;/code>، &lt;code>Gemma-2-9B-It&lt;/code>، &lt;code>Qwen2-7B-Instruct&lt;/code>. للمهام باللغة اليابانية، تعتبر النماذج المضبوطة لليابانية مثل &lt;code>Llama-3-ELYZA-JP-8B&lt;/code> مناسبة (يمكن استخدام نماذج تدعم اللغة العربية للمهام العربية).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>نموذج التضمين (Embedding)&lt;/strong>
&lt;ul>
&lt;li>النماذج: &lt;code>intfloat/multilingual-e5-large&lt;/code> أو &lt;code>BAAI/bge-m3&lt;/code>. لتشغيله محليًا، من الشائع تنزيله من Hugging Face وتشغيله باستخدام Sentence-Transformers.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>قاعدة بيانات المتجهات (Vector DB)&lt;/strong>
&lt;ul>
&lt;li>&lt;code>ChromaDB&lt;/code>: مبني على Python وسهل الإعداد للغاية. مثالي للتطوير المحلي.&lt;/li>
&lt;li>&lt;code>FAISS&lt;/code>: مكتبة بحث متجهات سريعة طورتها Meta.&lt;/li>
&lt;li>&lt;code>Qdrant&lt;/code> / &lt;code>Milvus&lt;/code>: مخصص للبيئات الأكبر وبيئات الإنتاج.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>إطار عمل التنسيق (Orchestration Framework)&lt;/strong>
&lt;ul>
&lt;li>&lt;code>LangChain&lt;/code>: المعيار الفعلي لربط المكونات (Chain).&lt;/li>
&lt;li>&lt;code>LlamaIndex&lt;/code>: إطار عمل للاتصال بالبيانات متخصص بشكل خاص في RAG.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>في هذه المرة، سنقوم بالتنفيذ باستخدام المزيج الأسهل في التقديم: &lt;strong>LangChain + ChromaDB + Ollama + HuggingFaceEmbeddings&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h1 id="4-دورة-تعليمية-للتنفيذ-بناء-rag-محلي-كامل-باستخدام-python">4. دورة تعليمية للتنفيذ: بناء RAG محلي كامل باستخدام Python
&lt;/h1>&lt;p>من هنا، سنقوم ببناء RAG محلي من خلال كتابة كود Python فعليًا. مسبقًا، يرجى تثبيت Ollama على جهاز الكمبيوتر الخاص بك وتشغيله في الخلفية. أيضًا، قم بسحب (Pull) النموذج على Ollama (مثال: &lt;code>ollama run llama3&lt;/code>).&lt;/p>
&lt;h2 id="الخطوة-1-تثبيت-المكتبات-المطلوبة">الخطوة 1: تثبيت المكتبات المطلوبة
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install langchain langchain-community langchain-huggingface
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install chromadb sentence-transformers pypdf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="الخطوة-2-الكود-البرمجي-الكامل-للتنفيذ">الخطوة 2: الكود البرمجي الكامل للتنفيذ
&lt;/h2>&lt;p>فيما يلي برنامج نصي كامل بلغة Python لقراءة ملف PDF، وتحويله إلى متجهات، وجعل نموذج LLM المحلي يجيب على الأسئلة.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;span class="lnt">85
&lt;/span>&lt;span class="lnt">86
&lt;/span>&lt;span class="lnt">87
&lt;/span>&lt;span class="lnt">88
&lt;/span>&lt;span class="lnt">89
&lt;/span>&lt;span class="lnt">90
&lt;/span>&lt;span class="lnt">91
&lt;/span>&lt;span class="lnt">92
&lt;/span>&lt;span class="lnt">93
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">os&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.document_loaders&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">PyPDFLoader&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_text_splitters&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RecursiveCharacterTextSplitter&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_huggingface&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">HuggingFaceEmbeddings&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.vectorstores&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Chroma&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.llms&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Ollama&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_core.prompts&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">PromptTemplate&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain.chains&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RetrievalQA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 1. تحميل المستندات&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;جاري تحميل المستندات...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># حدد مسار ملف PDF الذي تريد قراءته&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">file_path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;sample_company_policy.pdf&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">loader&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PyPDFLoader&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file_path&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">documents&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">loader&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 2. تقسيم النص (Text Splitting)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># التقسيم إلى أحجام مناسبة دون تدمير معنى الجمل&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">text_splitter&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RecursiveCharacterTextSplitter&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunk_size&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># أقصى عدد من الأحرف لكل كتلة&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunk_overlap&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># عدد الأحرف المتداخلة بين الكتل (لمنع انقطاع السياق)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">separators&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;。&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;、&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunks&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">text_splitter&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">split_documents&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">documents&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;تم التقسيم إلى &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunks&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> كتلة.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 3. تهيئة نموذج التضمين (Local HuggingFace Model)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># استخدام نموذج متعدد اللغات&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;جاري تحميل نموذج التضمين...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">embeddings&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">HuggingFaceEmbeddings&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model_name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;intfloat/multilingual-e5-large&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;device&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;cpu&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="c1"># &amp;#39;cuda&amp;#39; أو &amp;#39;mps&amp;#39; إذا كان لديك وحدة معالجة رسومات (GPU)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 4. بناء قاعدة بيانات المتجهات (Chroma)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;جاري بناء قاعدة بيانات المتجهات...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">persist_directory&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;./chroma_db&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vectorstore&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Chroma&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_documents&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">documents&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">chunks&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">embedding&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">embeddings&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">persist_directory&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">persist_directory&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># إنشاء المسترد (Retriever). إعداد لجلب أفضل 3 مستندات ذات صلة&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">retriever&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">vectorstore&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">as_retriever&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">search_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;k&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 5. تهيئة LLM المحلي (Ollama)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;جاري الاتصال بـ LLM المحلي...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># تأكد من الحصول على النموذج مسبقًا باستخدام شيء مثل &amp;#39;ollama pull llama3&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llm&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;llama3&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 6. تعريف قالب الموجه (Prompt Template)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt_template&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;أنت مساعد ممتاز على دراية بلوائح الشركة والمعلومات الداخلية.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">يرجى الإجابة على سؤال المستخدم بالتفصيل باستخدام السياق (معلومات الخلفية) التالي فقط.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">إذا لم تتمكن من العثور على الإجابة في السياق، فلا تخمن من نفسك وأجب بصدق &amp;#34;لا يمكن المعرفة من المعلومات المقدمة&amp;#34;.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【السياق】
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&lt;/span>&lt;span class="si">{context}&lt;/span>&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【السؤال】
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&lt;/span>&lt;span class="si">{question}&lt;/span>&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【الإجابة】:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PROMPT&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PromptTemplate&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">template&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">prompt_template&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">input_variables&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;context&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;question&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 7. بناء سلسلة RAG&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qa_chain&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RetrievalQA&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_chain_type&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llm&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">llm&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chain_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;stuff&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">retriever&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">retriever&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">return_source_documents&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># إعداد لإرجاع مصدر المعلومات&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chain_type_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;prompt&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">PROMPT&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 8. تنفيذ السؤال&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">query&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;يرجى إخباري عن شروط دفع نفقات النقل المتعلقة بالعمل عن بعد.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">السؤال: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">qa_chain&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">invoke&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;query&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">query&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【الإجابة】&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;result&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">---&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【مصادر المعلومات المرجعية】&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">doc&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;source_documents&amp;#39;&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;- صفحة &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">metadata&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;غير معروف&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">page_content&lt;/span>&lt;span class="p">[:&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">main&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="شرح-نقاط-الكود">شرح نقاط الكود
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>RecursiveCharacterTextSplitter&lt;/strong>:
وهو المقسم الموصى به بشدة عند تقسيم اللغة الطبيعية. يحاول التقسيم بترتيب الفقرات (&lt;code>\n\n&lt;/code>)، الأسطر (&lt;code>\n&lt;/code>)، وعلامات الترقيم (&lt;code>。&lt;/code>)، بحيث يتناسب مع &lt;code>chunk_size&lt;/code> المحدد مع الحفاظ على وحدة المعنى قدر الإمكان. عن طريق تعيين &lt;code>chunk_overlap&lt;/code>، فإنه يمنع فقدان المعلومات بسبب انقطاع الحدود السياقية.&lt;/li>
&lt;li>&lt;strong>HuggingFaceEmbeddings&lt;/strong>:
&lt;code>intfloat/multilingual-e5-large&lt;/code> هو نموذج تضمين مفتوح المصدر قوي جدًا يدعم لغات متعددة. يتيح لك تحويل النصوص إلى متجهات على الذاكرة المحلية دون اتصال بالإنترنت، دون استخدام واجهات برمجة التطبيقات السحابية (مثل &lt;code>text-embedding-ada-002&lt;/code> الخاص بـ OpenAI).&lt;/li>
&lt;li>&lt;strong>ChromaDB&lt;/strong>:
نظرًا لأنه يعمل في الذاكرة (In-memory) أو في التخزين المحلي (مبني على SQLite)، فلا حاجة لإعداد خادم قاعدة بيانات معقد. بتحديد &lt;code>persist_directory&lt;/code>، يمكنك تخطي عملية التحويل إلى متجهات عند إعادة التشغيل وقراءة قاعدة البيانات من القرص.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="5-تقنيات-rag-المتقدمة-advanced-rag-techniques">5. تقنيات RAG المتقدمة (Advanced RAG Techniques)
&lt;/h1>&lt;p>النظام الأساسي (Naive RAG) الذي بنيناه في الدورة التعليمية أعلاه يعمل، ولكن إذا كانت هناك حاجة إلى دقة إجابة عالية في بيئة الإنتاج، فمن الضروري تقديم تقنيات متقدمة مثل ما يلي.&lt;/p>
&lt;h2 id="51-البحث-الهجين-hybrid-search">5.1 البحث الهجين (Hybrid Search)
&lt;/h2>&lt;p>البحث في المتجهات ممتاز في التقاط &amp;ldquo;المعنى&amp;rdquo;، ولكنه قد يعاني مع عمليات البحث الدقيقة بالكلمات الرئيسية مثل &amp;ldquo;أسماء الأعلام الخاصة&amp;rdquo;، &amp;ldquo;أرقام طرازات المنتجات&amp;rdquo;، أو &amp;ldquo;معرفات الموظفين&amp;rdquo;.
لذلك، من خلال إجراء &lt;strong>البحث الدلالي&lt;/strong> عبر بحث المتجهات والبحث بالكلمات الرئيسية باستخدام خوارزميات مثل BM25 بشكل متوازٍ، ثم تسجيل ودمج نتائج كليهما (باستخدام طرق مثل دمج الترتيب المتبادل؛ Reciprocal Rank Fusion; RRF)، يمكن تقليل حالات الإخفاق في البحث بشكل كبير.&lt;/p>
&lt;h2 id="52-إعادة-الترتيب-re-ranking">5.2 إعادة الترتيب (Re-ranking)
&lt;/h2>&lt;p>البحث في المتجهات سريع، ولكنه لا يقيّم بالضرورة الملاءمة السياقية الدقيقة للسياق. خط أنابيب المعالجة (Pipeline) الشائع لتحسين دقة البحث هو كالتالي:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>البحث الأولي (First-stage Retrieval)&lt;/strong>: استرجاع حوالي 20 إلى 30 كتلة نصية ذات صلة بشكل واسع وسطحي من قاعدة بيانات المتجهات.&lt;/li>
&lt;li>&lt;strong>إعادة التقييم (Re-ranking)&lt;/strong>: استخدام نموذج تعلم آلي آخر أثقل يُعرف باسم Cross-Encoder (مثل &lt;code>bge-reranker&lt;/code>)، وإدخال زوج من استعلام المستخدم والكتل المستردة لإعادة حساب درجة الملاءمة الدلالية.&lt;/li>
&lt;li>&lt;strong>الفرز&lt;/strong>: تمرير أفضل 3 إلى 5 كتل ذات أعلى الدرجات كـسياق نهائي إلى موجه LLM.&lt;/li>
&lt;/ol>
&lt;p>من خلال هذه الطريقة، يمكن منع تمرير معلومات الضوضاء غير ذات الصلة إلى LLM، مما يزيد بشكل كبير من دقة الإجابة (Precision).&lt;/p>
&lt;div class="mermaid">graph LR
Query["استعلام"] --> VSearch["بحث المتجهات (أفضل 20)"]
VSearch --> Reranker["نموذج إعادة الترتيب (Cross-Encoder)"]
Query --> Reranker
Reranker --> TopK["أفضل 3 بدقة عالية"]
TopK --> LLM["توليد LLM"]&lt;/div>
&lt;h2 id="53-التقسيم-الدلالي-semantic-chunking-والبحث-في-المستند-الأصلي">5.3 التقسيم الدلالي (Semantic Chunking) والبحث في المستند الأصلي
&lt;/h2>&lt;p>بدلاً من تقسيم النص ميكانيكيًا بعدد ثابت من الأحرف، توجد طريقة تسمى &amp;ldquo;التقسيم الدلالي&amp;rdquo; (Semantic Chunking) تكتشف تغيرات المعنى في الجملة باستخدام الذكاء الاصطناعي لتقسيمها.
أيضًا، في طريقة تُعرف باسم &amp;ldquo;البحث في المستند الأصل&amp;rdquo; (Parent Document Retriever)، يتم تحويل النص إلى متجهات بوحدات صغيرة جدًا (مثل الجمل) لأغراض البحث لتحقيق بحث عالي الدقة، وعند تمريره إلى LLM، يتم تمرير &amp;ldquo;الفقرة الكبيرة الأصلية (المستند الأصل)&amp;rdquo; التي تحتوي على تلك الجملة، مما يوفر سياقًا كافيًا لـ LLM.&lt;/p>
&lt;hr>
&lt;h1 id="6-تحديات-وحلول-عند-تشغيل-rag-محلي">6. تحديات وحلول عند تشغيل RAG محلي
&lt;/h1>&lt;p>عند بناء وتشغيل RAG في بيئة محلية، توجد عقبات محددة.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>نفاد ذاكرة الفيديو (VRAM)&lt;/strong>:
لتشغيل LLM محلي بسرعة عملية (عشرات الرموز في الثانية)، يجب تحميل النموذج في ذاكرة الفيديو (VRAM) الخاصة بوحدة المعالجة الرسومية (GPU). لتشغيل نموذج من فئة 8B بصيغة fp16 (نقطة عائمة 16 بت)، يتطلب الأمر حوالي 16 غيغابايت من VRAM، ولكن باستخدام تقنيات &lt;strong>التكميم (Quantization)&lt;/strong> (تقنيات الضغط إلى 4 بت أو 8 بت مثل صيغ GGUF و AWQ)، من الممكن تشغيلها بسرعة كافية حتى على 8 غيغابايت من VRAM (مثل أجهزة الكمبيوتر المخصصة للألعاب). يدعم كل من Llama.cpp و Ollama تنسيقات التكميم هذه افتراضيًا.&lt;/li>
&lt;li>&lt;strong>حدود نافذة السياق&lt;/strong>:
إذا كان حجم السياق المسترد كبيرًا جدًا، فقد يتجاوز الحد الأقصى لإدخال LLM (حد الرموز)، أو قد ينسى النموذج الجزء الأوسط من المعلومات (ظاهرة الضياع في المنتصف - Lost in the middle). من الضروري تعديل عدد الكتل المستخرجة والاختيار الدقيق من خلال تقنية إعادة الترتيب المذكورة أعلاه.&lt;/li>
&lt;li>&lt;strong>إدارة حداثة البيانات&lt;/strong>:
عند تحديث المستندات المصدرية، يجب أيضًا تحديث المتجهات أو حذفها (عمليات CRUD) للمستندات المقابلة في قاعدة بيانات المتجهات. نظرًا لأن ChromaDB يدعم التحديثات بناءً على معرف المستند (Document ID)، فمن العملي إدارة قيم التجزئة (Hash) للملفات وإعداد معالجة مجمعة (Batch Processing) لمزامنة التغييرات فقط.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="الخاتمة">الخاتمة
&lt;/h1>&lt;p>RAG (التوليد المعزز بالاسترجاع) هو نموذج قوي يطور الذكاء الاصطناعي من مساعد عام عادي إلى &amp;ldquo;خبيرك الشخصي&amp;rdquo; أو &amp;ldquo;خبير متخصص في الأعمال الداخلية&amp;rdquo;.&lt;/p>
&lt;p>حتى في المتطلبات شديدة السرية حيث لا يمكن استخدام الخدمات السحابية، وجدنا أنه من السهل نسبيًا بناء بيئة &amp;ldquo;RAG محلي&amp;rdquo; كاملة من خلال الجمع بين أنظمة المصادر المفتوحة مثل Ollama، LangChain، و ChromaDB.&lt;/p>
&lt;p>بناءً على الفهم الرياضي للفضاء المتجه، والأساليب المتقدمة مثل تقسيم النصوص وإعادة الترتيب الموضحة في هذه المقالة، يرجى محاولة تطوير نظام ذكاء اصطناعي خاص بك باستخدام بياناتك الخاصة. إن سرعة تطور الذكاء الاصطناعي المحلي مذهلة، والنظام الذي تبنيه اليوم يمكن ترقية أدائه في لحظة بمجرد استبداله بنموذج خفيف الوزن وأكثر ذكاءً قد يظهر غدًا.&lt;/p>
&lt;hr>
&lt;p>&lt;em>في هذه المدونة، سنستمر في نشر مقالات متعمقة حول تكنولوجيا الذكاء الاصطناعي و RAG. إذا كان لديك أي أسئلة أو ملاحظات، يرجى تركها في قسم التعليقات.&lt;/em>&lt;/p></description></item><item><title>【أحدث إصدار لعام 2026】الدليل الشامل لتشغيل النماذج اللغوية الكبيرة (LLM) المحلية على بيئة ويندوز</title><link>http://kenji.blog/ar/p/local-llm-windows-2026/</link><pubDate>Fri, 11 Sep 2026 10:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/local-llm-windows-2026/</guid><description>&lt;img src="http://kenji.blog/p/local-llm-windows-2026/img/eyecatch.jpg" alt="Featured image of post 【أحدث إصدار لعام 2026】الدليل الشامل لتشغيل النماذج اللغوية الكبيرة (LLM) المحلية على بيئة ويندوز" />&lt;h1 id="1-مقدمة-لماذا-نماذج-llm-المحلية-على-ويندوز-الآن">1. مقدمة: لماذا نماذج LLM المحلية على ويندوز الآن؟
&lt;/h1>&lt;p>في عام 2026، يشهد تطور الذكاء الاصطناعي التوليدي والنماذج اللغوية الكبيرة (LLM) نقلة نوعية كبرى من خدمات واجهة برمجة التطبيقات (API) الضخمة على السحابة إلى &amp;ldquo;نماذج LLM المحلية&amp;rdquo; التي تعمل على أجهزة الكمبيوتر الشخصية والبيئات المحلية (On-Premises). على الرغم من أن نماذج الذكاء الاصطناعي السحابية مثل GPT-5 من OpenAI و Claude 3.5 من Anthropic قوية جدًا، إلا أنه لا يمكن للشركات والأفراد إرسال جميع بياناتهم إلى السحابة. من منظور الخصوصية، والأمان، وزمن الوصول (Latency)، والتكلفة المستدامة طويلة الأجل، فقد زاد الطلب على نماذج LLM المحلية بشكل غير مسبوق وبشكل هائل.&lt;/p>
&lt;p>تطور النظام البيئي لنماذج LLM المحلية في بيئة ويندوز (Windows) بشكل خاص كان مذهلًا. حتى سنوات قليلة مضت، كان من المتعارف عليه أن &amp;ldquo;تطوير وتشغيل الذكاء الاصطناعي يعني Linux&amp;rdquo;، ولكن في عام 2026، تحول نظام ويندوز إلى منصة ذكاء اصطناعي قوية وسهلة الاستخدام للغاية.&lt;/p>
&lt;p>في هذه المقالة، وبناءً على أحدث الاتجاهات التقنية لعام 2026، نقدم دليلاً شاملاً لبناء، وتشغيل، وتحسين نماذج LLM المحلية في بيئة ويندوز. سنقوم بشرح مفصل بحجم هائل يغطي كل شيء بدءًا من الإعداد البسيط للمبتدئين باستخدام Ollama، والتحسين الأقصى للمتقدمين باستخدام llama.cpp، وحتى الفهم العميق للبنية (Architecture) والنهج الرياضي لحساب ذاكرة الوصول العشوائي للفيديو (VRAM)، بالإضافة إلى الضبط الدقيق (Fine-tuning) محليًا.&lt;/p>
&lt;h2 id="11-الاتجاهات-التقنية-المحيطة-بنماذج-llm-المحلية-في-عام-2026">1.1 الاتجاهات التقنية المحيطة بنماذج LLM المحلية في عام 2026
&lt;/h2>&lt;p>تتمثل الاتجاهات الرئيسية التي تشكل النظام البيئي الحالي لنماذج LLM المحلية فيما يلي:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>الانتشار الكامل لتنسيق GGUF&lt;/strong>: أصبح تنسيق GGUF (GPT-Generated Unified Format)، الذي يدمج البيانات الوصفية (Metadata) والموترات (Tensors) في ملف واحد، معيارًا أساسيًا (De facto standard) بالكامل. وبفضل هذا، أصبح من الممكن تشغيل النماذج في أي بيئة بمجرد تنزيل ملف واحد من Hugging Face.&lt;/li>
&lt;li>&lt;strong>إضفاء الطابع الديمقراطي على بنية MoE (مزيج الخبراء)&lt;/strong>: تم إطلاق العديد من نماذج MoE صغيرة الحجم ولكنها عالية الأداء. ومن خلال تنشيط بعض الخبراء فقط أثناء الاستدلال (Inference)، فإنها تحقق أداءً يضاهي النماذج الضخمة مع تقليل العبء الحسابي على أجهزة الكمبيوتر الشخصية الاستهلاكية.&lt;/li>
&lt;li>&lt;strong>التجريد العالي والتحسين لمحركات الاستدلال&lt;/strong>: تم تحسين أدوات مثل Ollama، LM Studio، و AnythingLLM، ولم يعد المستخدمون بحاجة إلى القلق بشأن التبعيات المعقدة مثل تثبيت برامج تشغيل CUDA. بالإضافة إلى ذلك، بفضل الدعم الأصلي (Native) لـ FlashAttention 3 على ويندوز، زادت سرعة الاستدلال بشكل كبير.&lt;/li>
&lt;li>&lt;strong>الاستفادة من وحدات المعالجة العصبية (NPU) وظهور أجهزة كمبيوتر Windows Copilot+&lt;/strong>: حتى بالنسبة لأجهزة الكمبيوتر المحمولة التي لا تحتوي على وحدة معالجة رسومات (GPU)، فقد دخلت تقنية تشغيل النماذج اللغوية الصغيرة (SLM) باستهلاك منخفض للطاقة باستخدام وحدة المعالجة العصبية (NPU) المدمجة مرحلة الاستخدام العملي.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="2-متطلبات-الأجهزة-hardware-وإعداد-نظام-التشغيل">2. متطلبات الأجهزة (Hardware) وإعداد نظام التشغيل
&lt;/h1>&lt;p>لكي تعمل نماذج LLM المحلية بسرعة عملية (أكثر من 15 إلى 30 رمزًا مميزًا &amp;ldquo;Token&amp;rdquo; في الثانية)، يعد اختيار الأجهزة (Hardware) هو الأمر الأكثر أهمية.&lt;/p>
&lt;h2 id="21-تكوين-الأجهزة-الموصى-به">2.1 تكوين الأجهزة الموصى به
&lt;/h2>&lt;p>مع تطور أجهزة الكمبيوتر الخاصة بالذكاء الاصطناعي (AI PC)، تتغير أيضًا المواصفات المطلوبة.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>نظام التشغيل (OS)&lt;/strong>: Windows 11 Pro (إصدار 24H2 أو أحدث). يعد هذا ضروريًا للاستفادة الكاملة من ميزات WSL2، والإدارة المتقدمة للذاكرة، بالإضافة إلى استخدام أحدث واجهات برمجة التطبيقات (API) الخاصة بـ DirectML.&lt;/li>
&lt;li>&lt;strong>وحدة المعالجة المركزية (CPU)&lt;/strong>: سلسلة Intel Core Ultra 200 أو أحدث، أو سلسلة AMD Ryzen 9000 أو أحدث. عند استخدام استدلال CPU معًا، فإن الاتصال بذاكرة ذات نطاق ترددي عالي يعد أمرًا لا غنى عنه.&lt;/li>
&lt;li>&lt;strong>ذاكرة الوصول العشوائي (RAM)&lt;/strong>: الحد الأدنى 32 جيجابايت، ويُوصى بـ 64 جيجابايت أو أكثر. يصبح النطاق الترددي للذاكرة الرئيسية (بالجيجابايت/ثانية) هو عنق الزجاجة (Bottleneck) الحاسم أثناء استدلال CPU أو عند تفريغ التحميل (Offloading). يُفضل استخدام ذاكرة عالية السرعة DDR5-6000 أو أعلى.&lt;/li>
&lt;li>&lt;strong>وحدة معالجة الرسومات (GPU)&lt;/strong>: سلسلة NVIDIA RTX 4000/5000. الأهم في نماذج LLM المحلية ليس أداء الحوسبة بل &amp;ldquo;سعة ذاكرة الوصول العشوائي للفيديو (VRAM)&amp;rdquo;.
&lt;ul>
&lt;li>&lt;strong>فئة البداية (Entry)&lt;/strong>: RTX 4060 Ti (نسخة 16 جيجابايت) - الأفضل من حيث التكلفة والأداء. مثالية لنماذج بحجم 8B إلى 14B.&lt;/li>
&lt;li>&lt;strong>الفئة المتوسطة (Mid-range)&lt;/strong>: RTX 4070 Ti SUPER (16 جيجابايت) / RTX 4080 SUPER (16 جيجابايت).&lt;/li>
&lt;li>&lt;strong>الفئة المتقدمة (High-end)&lt;/strong>: RTX 4090 (24 جيجابايت) / RTX 5090 (32 جيجابايت) - مطلوبة لتشغيل النماذج المكممة (Quantized models) بحجم 30B إلى 70B.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>التخزين (Storage)&lt;/strong>: محرك أقراص PCIe Gen4 أو Gen5 NVMe SSD. يقلل من وقت تحميل النماذج التي تبلغ مساحتها عشرات الجيجابايت بشكل كبير.&lt;/li>
&lt;/ul>
&lt;h2 id="22-إعداد-wsl2-نظام-ويندوز-الفرعي-لنظام-لينكس-2">2.2 إعداد WSL2 (نظام ويندوز الفرعي لنظام لينكس 2)
&lt;/h2>&lt;p>تعمل العديد من أدوات واجهة المستخدم الرسومية (GUI) بشكل أصلي (Native) على ويندوز، ولكن WSL2 مفيد جدًا للتطوير باستخدام بايثون (Python)، وتجميع أحدث الأدوات، وإجراء الضبط الدقيق (LoRA Fine-tuning) الذي سيتم شرحه لاحقًا. في أحدث بيئة لـ Windows 11، يمكنك استخدام GPU (CUDA) بشفافية من WSL2 بمجرد تثبيت برنامج تشغيل NVIDIA على النظام المضيف.&lt;/p>
&lt;p>افتح PowerShell بصلاحيات المسؤول (Administrator) وقم بتشغيل ما يلي:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># تثبيت WSL2 وأحدث إصدار من Ubuntu&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-install&lt;/span> &lt;span class="n">-d&lt;/span> &lt;span class="n">Ubuntu&lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="mf">24.04&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># تحديث النواة (Kernel)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-update&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>بعد التثبيت، قم بتشغيل &lt;code>nvidia-smi&lt;/code> داخل وحدة تحكم WSL2، وإذا تم التعرف على GPU بشكل صحيح، فقد نجحت العملية.&lt;/p>
&lt;hr>
&lt;h1 id="3-بنية-نموذج-llm-المحلي-وآلية-الاستدلال-inference">3. بنية نموذج LLM المحلي وآلية الاستدلال (Inference)
&lt;/h1>&lt;p>من المفيد جدًا في استكشاف الأخطاء وإصلاحها وتحسين الأداء فهم كيفية قيام النموذج بإنشاء النص في بيئة محلية، وهيكله الداخلي.&lt;/p>
&lt;p>يوضح مخطط Mermaid التالي خط أنابيب (Pipeline) الاستدلال النموذجي لـ LLM المحلي.&lt;/p>
&lt;div class="mermaid">graph TD
User["إدخال المستخدم (الموجه/Prompt)"] --> Tokenizer["أداة الترميز (Tokenizer)"]
Tokenizer --> Embedding["طبقة التضمين (Embedding)"]
subgraph "كتلة المحول (Transformer Block) (x طبقات)"
Embedding --> Attn["الانتباه الذاتي (Self-Attention)"]
Attn --> KVCache["ذاكرة التخزين المؤقت KV (الاحتفاظ بالمفتاح/القيمة)"]
Attn --> FFN["شبكة التغذية الأمامية (FFN)"]
end
FFN --> Logits["حساب اللوجيت (Logits)"]
Logits --> Sampler["أداة أخذ العينات (Temperature, Top-K, Top-P)"]
Sampler --> OutputToken["الرمز المميز المخرج (Output Token)"]
OutputToken --> |"التوليد التلقائي الانحداري"| Tokenizer
OutputToken --> Decoder["أداة فك الترميز (Detokenizer)"]
Decoder --> FinalOutput["النص النهائي المخرج"]&lt;/div>
&lt;h2 id="31-مرحلتان-التعبئة-المسبقة-prefill-وفك-التشفير-decode">3.1 مرحلتان: التعبئة المسبقة (Prefill) وفك التشفير (Decode)
&lt;/h2>&lt;p>ينقسم إنشاء النص بواسطة LLM إلى مرحلتين تختلفان في الخصائص الحسابية:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>مرحلة التعبئة المسبقة (معالجة الموجه - Prefill)&lt;/strong>: هي المرحلة التي يتم فيها معالجة وفهم موجه الإدخال (Prompt) بأكمله مرة واحدة. نظرًا لإمكانية الحوسبة المتوازية، ترتبط قدرة حساب GPU (FLOPS) بشكل مباشر بالسرعة. إذا كان الموجه طويلاً، فقد تستغرق هذه المرحلة بضع ثوانٍ.&lt;/li>
&lt;li>&lt;strong>مرحلة فك التشفير (توليد الرموز المميزة - Decode)&lt;/strong>: هي المرحلة التي يتم فيها التنبؤ برمز مميز واحد في كل مرة وتمريره إلى الإدخال التالي (التوليد التلقائي الانحداري - Autoregressive). نظرًا لأن الحوسبة المتوازية مقيدة في هذه المرحلة، فإن عرض النطاق الترددي لـ VRAM في GPU يصبح عنق الزجاجة الحاسم.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="4-حساب-استهلاك-vram-والفهم-الرياضي-لحجم-النموذج">4. حساب استهلاك VRAM والفهم الرياضي لحجم النموذج
&lt;/h1>&lt;p>لتحكم بشكل صحيح على &amp;ldquo;ما هو النموذج الذي سيعمل على جهاز الكمبيوتر الخاص بي؟&amp;quot;، تحتاج إلى فهم معادلة حساب VRAM. في حالة حدوث تراجع (Fallback) إلى ذاكرة النظام (RAM) بسبب نقص VRAM، ستنخفض سرعة الاستدلال بمقدار 10 إلى 100 مرة.&lt;/p>
&lt;h2 id="41-vram-الأساسي-بناء-على-حجم-المعلمة-parameter">4.1 VRAM الأساسي بناءً على حجم المعلمة (Parameter)
&lt;/h2>&lt;p>هو مقدار الذاكرة المطلوب لتحميل أوزان (Weights) النموذج في VRAM.
يتم حسابه باستخدام حجم النموذج $P$ (عدد المعلمات، الوحدة: 1 مليار = 1B) وعدد البايتات لكل معلمة $B$.&lt;/p>
$$
V_{base} = P \times B \quad \text{(GB)}
$$
&lt;p>على سبيل المثال، عند تحميل نموذج بـ 8B (8 مليارات) معلمة بتنسيق FP16 (فاصلة عائمة نصف الدقة، 16 بت = 2 بايت):&lt;/p>
$$
V_{base} = 8 \times 2 = 16 \text{ GB}
$$
&lt;p>بمعنى آخر، حتى مع وحدة معالجة رسومات تحتوي على 16 جيجابايت من VRAM، ستصل إلى الحد الأقصى تقريبًا بمجرد تحميل النموذج.&lt;/p>
&lt;h2 id="42-سحر-التكميم-quantization">4.2 سحر التكميم (Quantization)
&lt;/h2>&lt;p>وهنا يأتي دور &amp;ldquo;التكميم&amp;rdquo;. من خلال تقليل دقة المعلمات، يتم تصغير حجم النموذج بشكل كبير. في حالة التكميم الأكثر شيوعًا 4 بت (مثل: Q4_K_M)، يبلغ المتوسط حوالي 0.55 بايت لكل معلمة.&lt;/p>
$$
V_{base\_4bit} = 8 \times 0.55 = 4.4 \text{ GB}
$$
&lt;p>وبالتالي، إذا كان لديك 16 جيجابايت من VRAM، فيمكنك بسهولة تشغيل نموذج 8B بوجود مساحة إضافية كافية.&lt;/p>
&lt;h2 id="43-حساب-ذاكرة-التخزين-المؤقت-kv-إصدار-يدعم-gqa">4.3 حساب ذاكرة التخزين المؤقت KV (إصدار يدعم GQA)
&lt;/h2>&lt;p>أثناء الاستدلال، تستهلك &amp;ldquo;ذاكرة التخزين المؤقت KV&amp;rdquo; التي تحتفظ بالسياق الماضي VRAM. في أحدث النماذج مثل Llama 3، يتم استخدام GQA (الانتباه الاستعلامي المجمع - Grouped Query Attention) لتوفير الذاكرة.&lt;/p>
&lt;p>يمكن التعبير عن استهلاك ذاكرة التخزين المؤقت KV $V_{kv}$ (بالجيجابايت) بالصيغة الرياضية التالية:&lt;/p>
$$
V_{kv} = 2 \times b \times s \times l \times \left( \frac{h_{kv}}{h_q} \right) \times h_q \times d \times B_{kv} \div 10^9
$$
&lt;p>عند التبسيط، يمكن حسابها ببساطة باستخدام عدد رؤوس المفاتيح والقيم $h_{kv}$:&lt;/p>
$$
V_{kv} = 2 \times b \times s \times l \times h_{kv} \times d \times B_{kv} \div 10^9
$$
&lt;p>حيث أن:&lt;/p>
&lt;ul>
&lt;li>$b$: حجم الدفعة (عادة 1 للاستخدام الشخصي المحلي)&lt;/li>
&lt;li>$s$: طول التسلسل (طول السياق، مثال: 8192)&lt;/li>
&lt;li>$l$: عدد الطبقات (مثال: 32)&lt;/li>
&lt;li>$h_{kv}$: عدد رؤوس KV (مثال: 8)&lt;/li>
&lt;li>$d$: عدد الأبعاد لكل رأس (مثال: 128)&lt;/li>
&lt;li>$B_{kv}$: عدد البايتات لذاكرة التخزين المؤقت KV (2 إذا كان FP16)&lt;/li>
&lt;/ul>
&lt;p>مثال للحساب (Llama 3 8B، سياق 8192، ذاكرة تخزين مؤقت FP16):
$V_{kv} = 2 \times 1 \times 8192 \times 32 \times 8 \times 128 \times 2 \div 10^9 \approx 1.07 \text{ GB}$&lt;/p>
&lt;p>يرجى ملاحظة أنه كلما زاد طول السياق $s$، زادت الحاجة إلى VRAM بشكل خطي.&lt;/p>
&lt;hr>
&lt;h1 id="5-الممارسة-1-إعداد-أسرع-وأقصر-باستخدام-ollama">5. الممارسة 1: إعداد أسرع وأقصر باستخدام Ollama
&lt;/h1>&lt;p>بمجرد فهم النظرية، دعنا نقم بتشغيل LLM فعليًا على بيئة ويندوز.
اعتبارًا من عام 2026، فإن الأداة الأكثر سهولة في الاستخدام هي &amp;ldquo;Ollama&amp;rdquo;. فهي توفر واجهة سطر أوامر (CLI) بديهية تشبه Docker.&lt;/p>
&lt;h2 id="51-التثبيت-والتشغيل">5.1 التثبيت والتشغيل
&lt;/h2>&lt;ol>
&lt;li>قم بتنزيل مثبت ويندوز من &lt;a class="link" href="https://ollama.com/" target="_blank" rel="noopener"
>موقع Ollama الرسمي&lt;/a> وقم بتشغيله.&lt;/li>
&lt;li>افتح PowerShell وأدخل الأمر التالي. هنا، سنستخدم &lt;code>llama3:8b&lt;/code> الذي يدعم اللغة اليابانية.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="n">llama3&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="n">8b&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>في أول تشغيل، سيتم تنزيل النموذج. بمجرد الانتهاء، يمكنك التفاعل معه مباشرة في الجهاز الطرفي (Terminal).&lt;/p>
&lt;h2 id="52-إنشاء-ذكاء-اصطناعي-مخصص-باستخدام-modelfile">5.2 إنشاء ذكاء اصطناعي مخصص باستخدام Modelfile
&lt;/h2>&lt;p>يمكنك بسهولة إنشاء ذكاء اصطناعي بشخصية (Persona) محددة. قم بإنشاء &lt;code>Modelfile&lt;/code> في أي مكان تريده.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">FROM llama3:8b
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">SYSTEM &amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">أنت مهندس برمجيات أول ممتاز جدًا.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">يرجى الإجابة على أسئلة المستخدم بشكل منطقي وموجز، مع تقديم أمثلة التعليمات البرمجية دائمًا.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER temperature 0.3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER num_ctx 8192
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>قم ببناء النموذج المخصص الخاص بك وتشغيله بالأوامر التالية:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">create&lt;/span> &lt;span class="n">SeniorDev&lt;/span> &lt;span class="o">-f&lt;/span> &lt;span class="p">./&lt;/span>&lt;span class="n">Modelfile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="n">SeniorDev&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="53-الاستخدام-من-التطبيقات-الخارجية-محرر-الذكاء-الاصطناعي">5.3 الاستخدام من التطبيقات الخارجية (محرر الذكاء الاصطناعي)
&lt;/h2>&lt;p>تكشف Ollama عن نقطة نهاية API متوافقة مع OpenAI على &lt;code>http://localhost:11434&lt;/code>.
من خلال تحديد عنوان URL هذا في إعدادات الخلفية (Backend) لإضافات VS Code مثل Cursor و Continue.dev، وتحديد اسم النموذج كـ &lt;code>SeniorDev&lt;/code> أو ما شابه، ستحصل على مساعد تشفير (Coding) محلي قوي ومجاني.&lt;/p>
&lt;hr>
&lt;h1 id="6-الممارسة-2-ضبط-الأداء-الأقصى-باستخدام-llamacpp">6. الممارسة 2: ضبط الأداء الأقصى باستخدام llama.cpp
&lt;/h1>&lt;p>إذا كنت ترغب في إجراء إدارة دقيقة للذاكرة أو تجربة أحدث التنسيقات (مثل EXL2 وتكميم IQ) بسرعة، فسوف تتفاعل مباشرة مع المحرك الأساسي &lt;code>llama.cpp&lt;/code>.&lt;/p>
&lt;h2 id="61-خطوات-بناء-llamacpp">6.1 خطوات بناء llama.cpp
&lt;/h2>&lt;p>في بيئة ويندوز، من الأفضل بناءه من المصدر باستخدام CUDA Toolkit و CMake.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">clone&lt;/span> &lt;span class="n">https&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="p">//&lt;/span>&lt;span class="n">github&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">com&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">ggerganov&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">llama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cpp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">llama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cpp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">&lt;/span>&lt;span class="n">mkdir&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># التهيئة والتجميع ليكون متوافقًا مع CUDA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">..&lt;/span> &lt;span class="n">-DLLAMA_CUBLAS&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="n">ON&lt;/span> &lt;span class="n">-DBUILD_SHARED_LIBS&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="n">OFF&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-build&lt;/span> &lt;span class="p">.&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">Release&lt;/span> &lt;span class="n">-j&lt;/span> &lt;span class="mf">16&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="62-التشغيل-المتقدم-في-وضع-الخادم">6.2 التشغيل المتقدم في وضع الخادم
&lt;/h2>&lt;p>استخدم &lt;code>llama-server.exe&lt;/code> الذي تم بناؤه لاستضافة النموذج.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="p">.\&lt;/span>&lt;span class="n">bin&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Release&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="nb">llama-server&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">exe&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-model&lt;/span> &lt;span class="s2">&amp;#34;C:\models\Llama-3-8B-Instruct.Q4_K_M.gguf&amp;#34;&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-ctx-size&lt;/span> &lt;span class="mf">8192&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-n-gpu-layers&lt;/span> &lt;span class="mf">99&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-threads&lt;/span> &lt;span class="mf">8&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-flash-attn&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-port&lt;/span> &lt;span class="mf">8080&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>&lt;code>--n-gpu-layers 99&lt;/code>: نقل كل الطبقات الممكنة إلى VRAM الخاص بـ GPU.&lt;/li>
&lt;li>&lt;code>--flash-attn&lt;/code>: تمكين FlashAttention 3 لتحسين سرعة الاستدلال وتقليل استهلاك VRAM لذاكرة التخزين المؤقت KV.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="7-واجهة-المستخدم-الرسومية-gui-بناء-lm-studio-و-rag-المحلي">7. واجهة المستخدم الرسومية (GUI): بناء LM Studio و RAG المحلي
&lt;/h1>&lt;p>إذا كنت لا تفضل استخدام سطر الأوامر، أو إذا كنت ترغب في إجراء التوليد المعزز بالاسترجاع (RAG) بشكل بديهي، فاستخدم واجهة مستخدم رسومية (GUI).&lt;/p>
&lt;h2 id="71-lm-studio">7.1 LM Studio
&lt;/h2>&lt;p>يعد LM Studio تطبيقًا رائعًا يجمع بين البحث عن النماذج، والتنزيل، والتحقق المسبق من متطلبات النظام، وواجهة مستخدم (UI) للدردشة في مكان واحد. بضغطة زر &amp;ldquo;Local Server&amp;rdquo; داخل التطبيق، سيتم تشغيل واجهة برمجة تطبيقات (API) متوافقة مع OpenAI.&lt;/p>
&lt;h2 id="72-بنية-rag-باستخدام-anythingllm">7.2 بنية RAG باستخدام AnythingLLM
&lt;/h2>&lt;p>هذا هو المخطط المعماري لبيئة RAG التي تسمح بقراءة المستندات الداخلية للشركة والمذكرات الشخصية.&lt;/p>
&lt;div class="mermaid">graph LR
Document["المستند (PDF, MD)"] --> Chunking["تقسيم إلى كتل (Chunking)"]
Chunking --> EmbedModel["نموذج التضمين (Embedding Model)"]
EmbedModel --> VectorDB["قاعدة بيانات المتجهات (Vector Database)"]
UserQuery["سؤال المستخدم"] --> EmbedQuery["تضمين السؤال"]
EmbedQuery --> VectorDB
VectorDB --> |"بحث عن التشابه"| RetrievedDocs["استخراج المستندات ذات الصلة"]
UserQuery --> PromptBuilder["توليد الموجه (Prompt)"]
RetrievedDocs --> PromptBuilder
PromptBuilder --> LocalLLM["نموذج LLM محلي"]
LocalLLM --> Answer["الإجابة النهائية"]&lt;/div>
&lt;p>باستخدام إصدار سطح المكتب من AnythingLLM (لويندوز)، يمكنك تحديد Ollama (لـ LLM والتضمين) من شاشة الإعدادات، وإعداده لاستخدام VectorDB محلي (LanceDB)، وستكتمل هذه البنية في غضون بضع دقائق. هذه هي ولادة الذكاء الاصطناعي الخاص الذي لا يرسل البيانات إلى الخارج على الإطلاق.&lt;/p>
&lt;hr>
&lt;h1 id="8-الضبط-الدقيق-lora-على-windows-wsl2">8. الضبط الدقيق (LoRA) على Windows WSL2
&lt;/h1>&lt;p>لا يقتصر الأمر على التشغيل المحلي فحسب، بل إذا كنت ترغب في جعل النموذج أكثر ذكاءً باستخدام بياناتك الخاصة، فيمكنك إجراء الضبط الدقيق (Fine-tuning) باستخدام LoRA (التكيف منخفض الرتبة - Low-Rank Adaptation). اعتبارًا من عام 2026، وبفضل مكتبة تسمى &amp;ldquo;Unsloth&amp;rdquo;، يمكنك إكمال تدريب نموذج 8B في بضع ساعات حتى مع 16 جيجابايت من VRAM في بيئة Windows WSL2.&lt;/p>
&lt;p>قم بتشغيل الأوامر التالية داخل Ubuntu في WSL2 لإعداد البيئة:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">conda create --name unsloth_env &lt;span class="nv">python&lt;/span>&lt;span class="o">=&lt;/span>3.11
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">conda activate unsloth_env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install &lt;span class="s2">&amp;#34;unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install --no-deps trl peft accelerate bitsandbytes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>تعمل Unsloth على تحسين أنوية CUDA (CUDA kernels) إلى أقصى حد، وبالمقارنة مع مكتبة Hugging Face القياسية، فإن سرعة التدريب تزيد بحوالي الضعف، وينخفض استهلاك VRAM إلى النصف تقريبًا. بمجرد فتح Jupyter Notebook وتحميل مجموعة البيانات (بتنسيق JSONL)، يمكن إجراء التدريب لعدة عصور (Epochs) باستخدام أجهزة مثل RTX 4060 Ti مع 12 جيجابايت إلى 16 جيجابايت من VRAM.&lt;/p>
&lt;hr>
&lt;h1 id="9-استكشاف-أخطاء-الأداء-وإصلاحها">9. استكشاف أخطاء الأداء وإصلاحها
&lt;/h1>&lt;p>فيما يلي المشكلات الشائعة والحلول الخاصة بها.&lt;/p>
&lt;h3 id="1-سرعة-الاستدلال-بطيئة-للغاية-1-إلى-2-رمز--ثانية">1. سرعة الاستدلال بطيئة للغاية (1 إلى 2 رمز / ثانية)
&lt;/h3>&lt;p>&lt;strong>السبب&lt;/strong>: النموذج لا يتناسب مع VRAM وتم تحميله على ذاكرة النظام (RAM).
&lt;strong>الحل&lt;/strong>: تحقق من &amp;ldquo;ذاكرة GPU المخصصة&amp;rdquo; في إدارة المهام. إذا وصلت إلى الحد الأقصى، فقم بتقليل حجم السياق (&lt;code>-c&lt;/code>)، أو استخدم نموذج تكميم بعدد بتات أقل (مثل Q4_K_M).&lt;/p>
&lt;h3 id="2-خطأ-cuda-out-of-memory">2. خطأ &amp;ldquo;CUDA out of memory&amp;rdquo;
&lt;/h3>&lt;p>&lt;strong>السبب&lt;/strong>: تم استنفاد VRAM بالكامل. يحدث هذا بشكل خاص عندما تطول المحادثة وتتضخم ذاكرة التخزين المؤقت KV.
&lt;strong>الحل&lt;/strong>: قم بتقييد قيمة &lt;code>num_ctx&lt;/code> بشكل مقصود في حالة Ollama، أو قيمة &lt;code>-c&lt;/code> في حالة llama.cpp.&lt;/p>
&lt;h3 id="3-توليد-اللغة-مثل-اليابانية-أو-العربية-غريب">3. توليد اللغة (مثل اليابانية أو العربية) غريب
&lt;/h3>&lt;p>&lt;strong>السبب&lt;/strong>: عدم تطابق قالب الموجه (Prompt template)، أو النموذج غير مدعوم.
&lt;strong>الحل&lt;/strong>: استخدم نموذجًا يحتوي اسمه على &lt;code>Instruct&lt;/code>، وتأكد من تحديد القالب الصحيح (مثل تنسيق ChatML أو Llama3) الذي حدده منشئ النموذج في الأداة.&lt;/p>
&lt;hr>
&lt;h1 id="10-الخلاصة-والآفاق-المستقبلية">10. الخلاصة والآفاق المستقبلية
&lt;/h1>&lt;p>في عام 2026، لم يعد بناء نماذج LLM المحلية في بيئة ويندوز حكرًا على عدد قليل من المهندسين فقط. بفضل تحول تنسيق GGUF إلى معيار أساسي، وظهور أنظمة بيئية محسّنة مثل Ollama و LM Studio، والتحسينات على مستوى الأجهزة (Hardware) مثل FlashAttention، يمكن لأي شخص الآن بسهولة الحصول على بيئة ذكاء اصطناعي بمستوى الشركات (Enterprise-grade).&lt;/p>
&lt;p>يرجى الاستفادة من النقاط التالية المشروحة في هذا المقال:&lt;/p>
&lt;ol>
&lt;li>استخدم &lt;strong>الحساب الرياضي لـ VRAM&lt;/strong> لاختيار حجم النموذج ومستوى التكميم المناسبين لمنطق مواصفات جهاز الكمبيوتر الخاص بك.&lt;/li>
&lt;li>استخدم &lt;strong>Ollama&lt;/strong> لإعداد بيئة بأسرع وقت، وربطها مع محرر الذكاء الاصطناعي لتحسين الإنتاجية بشكل كبير.&lt;/li>
&lt;li>استخدم التحكم المتقدم في المعلمات من خلال &lt;strong>llama.cpp&lt;/strong> لاستخراج أقصى أداء ممكن للأجهزة.&lt;/li>
&lt;li>قم ببناء نظام RAG محلي آمن للتعامل مع البيانات السرية باستخدام &lt;strong>AnythingLLM&lt;/strong>.&lt;/li>
&lt;li>استفد من &lt;strong>Unsloth (WSL2)&lt;/strong> لتطوير وتدريب ذكاء اصطناعي مخصص يمتلك معرفتك المتخصصة الخاصة.&lt;/li>
&lt;/ol>
&lt;p>لم يعد مصطلح &amp;ldquo;إضفاء الطابع الديمقراطي&amp;rdquo; على الذكاء الاصطناعي مجرد كلمة طنانة (Buzzword)، بل أصبح نظامًا واقعيًا يعمل على سطح مكتب ويندوز الخاص بك. تحرر من تكاليف استخدام واجهات برمجة التطبيقات السحابية وخطر تسرب المعلومات، وادخل الآن إلى عالم الذكاء الاصطناعي الخاص القوي والحر.&lt;/p></description></item></channel></rss>