تقرأ أن بإمكانك تشغيل نموذج لغة على جهازك فلا يخرج سؤالك ولا مستندات عملك إلى أي شركة، فتحمل Ollama وتكتب أمراً واحداً، ثم تواجه واحدة من نتيجتين: إما أن تظهر الإجابة كلمة كل ثانيتين فتغلق النافذة وأنت مقتنع أن جهازك لا يصلح، وإما أن تذهب لتشتري بطاقة رسومية غالية ثم تكتشف أن النموذج الذي تريده لا يدخل في ذاكرتها أصلاً. والسبب في الحالتين واحد: لم يحسب أحد قبل البدء كم ذاكرة يحتاج النموذج، ومن أي ذاكرة سوف يقرأ، وكم سرعتها.
وقد شرحنا في مقال كيف تعمل نماذج اللغة الكبيرة LLM ما يحدث داخل النموذج: التوكنز Tokens، والمعاملات Parameters، وذاكرة KV Cache، وفكرة التكميم Quantization، ولن نعيد شرح هذه المفاهيم هنا، وإنما نأخذها إلى سؤال عملي واحد: ماذا يعمل على جهازك أنت، سواء كان لابتوب أو كمبيوتراً مكتبياً أو جهاز Mac أو سيرفراً، وبأي سرعة، وماذا تشتري إذا قررت أن تشتري.
وسوف نناقش في هذا المقال ما يلي:
- متى يستحق تشغيل النموذج على جهازك، ومتى تكون الخدمة السحابية API أفضل.
- القاعدة الوحيدة: النموذج يجب أن يدخل في الذاكرة، ومعادلة بسيطة تحسب بها الذاكرة بأحجام ملفات حقيقية من 1B إلى 70B.
- الأجهزة واحداً واحداً: المعالج وحده، وبطاقات NVIDIA وAMD، وأجهزة Mac بذاكرتها الموحدة، والبطاقات المدمجة ووحدات NPU، والسيرفر بعدة بطاقات، وRaspberry Pi.
- تجربة حقيقية على جهاز بلا بطاقة رسومية: الذاكرة والسرعة لأربعة نماذج، وأثر نافذة السياق وعدد الخيوط.
- لماذا تحدد سرعة الذاكرة سرعة التوليد، وما معنى «سريع بما يكفي».
- اختيار التكميم، وكلفة نافذة السياق، والأدوات التي تبدأ بها ورخصها.
- اختيار النموذج على قدر ذاكرتك، ونصائح محايدة قبل شراء العتاد.
قبل كل شيء: هل تحتاج تشغيله على جهازك أصلاً؟
الحل البسيط أن تعتبر النموذج المحلي بديلاً مجانياً لخدمات مثل ChatGPT وClaude وGemini، والمشكلة أن هذا غير صحيح من جهتين: فالنماذج التي تعمل على جهاز عادي أصغر بكثير من النماذج الكبيرة التي تقدمها هذه الخدمات، فجودتها أقل خاصة في المهام الصعبة وفي اللغة العربية كما رأينا في قسم الأخطاء في المقال السابق، كما أنها ليست مجانية، فأنت تدفع ثمن العتاد والكهرباء والوقت الذي تصرفه في تشغيلها وتحديثها. لذلك فالسؤال الصحيح ليس «أيهما أرخص» وإنما «ما الذي أحتاجه فعلاً»، والصورة التالية تبين الأسئلة الأربعة التي تحسم القرار في أغلب الحالات:

والتشغيل المحلي يستحق في الحالات التالية:
- الخصوصية Privacy: عندما تمنعك سياسة مؤسستك أو العقد مع عميلك من إرسال البيانات إلى خدمة خارجية، وهذا أقوى الأسباب وأوضحها، لأن النص لا يغادر جهازك أبداً.
- العمل دون إنترنت Offline: في شبكة معزولة، أو في جهاز ميداني، أو ببساطة في طائرة.
- التكلفة مع الحجم الكبير: إذا كان لديك عمل ثابت يتكرر آلاف المرات كل يوم، مثل تصنيف الرسائل أو استخراج الحقول من المستندات، فقد يصبح جهاز تملكه أرخص من الدفع لكل توكن، ولكن احسب ذلك بأرقامك أنت، لأن الجهاز الذي يعمل ساعة في اليوم فقط نادراً ما يغطي ثمنه.
- التعلم والتحكم: أن تفهم كيف تعمل هذه النماذج، وأن تختار النسخة والإعدادات بنفسك، وألا يتغير النموذج تحتك لأن الشركة حدثته.
أما الخدمة السحابية API فهي الأنسب عندما تحتاج أعلى جودة ممكنة في مهام صعبة مثل كتابة الكود المعقد أو التحليل الطويل، أو عندما يكون استخدامك قليلاً أو متقطعاً، أو عندما لا يوجد في فريقك من يصون الجهاز ويحدثه ويراقبه. وكثير من الفرق تستخدم الاثنين معاً: نموذج محلي صغير للبيانات الحساسة والمهام المتكررة البسيطة، وخدمة سحابية لغيرها.
القاعدة الوحيدة: النموذج يجب أن يدخل في الذاكرة
كل ما في هذا المقال يرجع إلى قاعدة واحدة: النموذج كله يجب أن يكون في الذاكرة أثناء العمل، لأن كل توكن تولده يمر على كل طبقات النموذج كما شرحنا في قسم الذاكرة في المقال السابق. والذاكرة هنا هي الذاكرة التي يقرأ منها من يقوم بالحساب: ذاكرة البطاقة الرسومية VRAM إذا كانت البطاقة هي التي تحسب، أو الذاكرة الموحدة Unified Memory في أجهزة Mac، أو ذاكرة النظام RAM إذا كان المعالج CPU وحده هو الذي يحسب.
والحل البسيط الأول لحساب هذه الذاكرة أن تنظر إلى حجم ملف النموذج فقط، فتقول إن النموذج 4.7 GB والبطاقة 6 GB إذن يكفي، والمشكلة أن الملف هو الأوزان Weights فقط، وفوقها ذاكرة KV Cache التي تكبر مع طول المحادثة، ومخازن الحساب Compute Buffers التي يحجزها برنامج التشغيل، وما يحتاجه نظام التشغيل وبقية البرامج من نفس الذاكرة، وفي البطاقة الرسومية قد تكون الشاشة نفسها تأخذ جزءاً من VRAM. والحل البسيط الثاني أن تقول: إذا لم تكف الذاكرة فسوف يستخدم النظام ذاكرة التبديل Swap على القرص، والمشكلة أن القرص أبطأ من الذاكرة بمرات كثيرة كما شرحنا في مقال Hello World، والنموذج يقرأ أوزانه كلها مع كل توكن، فيصبح التوليد بطيئاً إلى حد لا يمكن استخدامه.
والطريقة الصحيحة أن تحسب الميزانية كاملة بهذه المعادلة:
الذاكرة المطلوبة ≈ الأوزان + KV Cache + مخازن الحساب + هامش لنظام التشغيل
الأوزان ≈ عدد المعاملات × البتات لكل معامل ÷ 8
KV Cache ≈ حجم KV لكل توكن × طول نافذة السياق × عدد الطلبات المتوازيةفي المعادلة أعلاه لاحظ التالي:
- البتات لكل معامل تأتي من نوع التكميم، وهي بحسب جدول أداة التكميم في llama.cpp قرابة 16 في F16، و8.5 في Q8_0، و6.56 في Q6_K، و5.70 في Q5_K_M، و4.89 في Q4_K_M.
- حجم KV لكل توكن يحسب من ملف إعدادات النموذج بالمعادلة التي شرحناها في قسم نافذة السياق، وهو مثلاً 56 KiB في Qwen2.5-7B، و128 KiB في Llama 3.1 8B، و192 KiB في Qwen2.5-14B، و320 KiB في Llama 3.1 70B.
- الطلبات المتوازية مهمة في السيرفر، فإذا خدمت أربعة مستخدمين في نفس الوقت فذاكرة KV أربعة أضعاف، كما سيأتي في قسم السياق.
الصورة التالية تبين هذه الميزانية لنموذج Qwen2.5-7B بتكميم Q4_K_M، والأرقام فيها من ملف النموذج ومن قياسنا في التجربة أدناه:

أحجام حقيقية من 1B إلى 70B
بدلاً من أن تحسب كل مرة، فهذه أحجام ملفات حقيقية من مكتبة Ollama لنماذج Qwen2.5 وLlama 3.1 وLlama 3.2 بثلاث دقات، والأرقام للأوزان وحدها كما تظهر في المكتبة:
| النموذج | Q4_K_M | Q8_0 | F16 |
|---|---|---|---|
| Llama 3.2 1B | 808 MB | 1.3 GB | 2.5 GB |
| Qwen2.5 3B | 1.9 GB | 3.3 GB | 6.2 GB |
| Qwen2.5 7B | 4.7 GB | 8.1 GB | 15 GB |
| Llama 3.1 8B | 4.9 GB | 8.5 GB | 16 GB |
| Qwen2.5 14B | 9.0 GB | 16 GB | 30 GB |
| Qwen2.5 32B | 20 GB | 35 GB | 66 GB |
| Llama 3.1 70B | 43 GB | 75 GB | 141 GB |
ولنطبق المعادلة على ثلاثة أمثلة بنافذة سياق 4096 توكناً ومستخدم واحد:
- Llama 3.1 8B بتكميم Q4_K_M: الأوزان 4.9 GB، وذاكرة KV قرابة 128 KiB × 4096 = 512 MiB، ثم مخازن الحساب، أي قرابة 6 GB، وبالتالي يدخل في بطاقة 8 GB، ولا يدخل في بطاقة 6 GB إلا بتقسيم الطبقات كما سيأتي.
- Qwen2.5 14B بتكميم Q4_K_M: الأوزان 9.0 GB وذاكرة KV قرابة 768 MiB، أي قرابة 10.5 GB، فيدخل في بطاقة 12 GB بهامش صغير، ويرتاح في 16 GB.
- Llama 3.1 70B بتكميم Q4_K_M: الأوزان 43 GB وحدها، وبالتالي لا تدخل في أي بطاقة منزلية واحدة، وتحتاج إما عدة بطاقات، أو جهاز Mac بذاكرة موحدة كبيرة، أو المعالج مع 64 GB من RAM وصبر طويل.
الأجهزة واحداً واحداً: ماذا تتوقع من جهازك؟
القاعدة واحدة في كل الأجهزة، والذي يختلف هو نوع الذاكرة وحجمها وسرعتها، والصورة التالية تجمع الأنواع الستة التي سوف نمر عليها:

اللابتوب والكمبيوتر بالمعالج فقط
أي جهاز حديث يستطيع تشغيل نموذج صغير على المعالج دون أي بطاقة، فبرنامج llama.cpp الذي يعمل داخل Ollama مكتوب ليعمل على المعالج، ويستخدم تعليمات المعالج السريعة مثل AVX2 وAVX-512 في أجهزة x86 وNEON في أجهزة ARM. والسؤال الحقيقي ليس «هل يعمل» وإنما «بأي سرعة»، وهنا يقع أكثر الناس في خطأ شائع: يظنون أن عدد الأنوية هو الذي يحدد السرعة، فيشترون معالجاً بعدد أنوية أكبر ثم لا يتغير شيء تقريباً.
والسبب أن توليد كل توكن يحتاج أن يقرأ المعالج أوزان النموذج كلها من الذاكرة RAM، فإذا كان النموذج 4.7 GB فهو يقرأ قرابة 4.7 GB لكل توكن، وبالتالي فالذي يحدد السرعة في الغالب هو عرض النطاق الترددي للذاكرة Memory Bandwidth، أي كم جيجابايت تنقل الذاكرة إلى المعالج في الثانية، وليس عدد الأنوية. ويمكنك حساب الحد النظري لذاكرة جهازك بضرب سرعتها في 8 بايت في عدد القنوات Channels:
- DDR4-2400 بقناتين Dual Channel، وهي ذاكرة جهاز التجربة: 2400 × 8 × 2 = 38.4 GB/s.
- DDR5-5600 بقناتين: 5600 × 8 × 2 = 89.6 GB/s.
لاحظ أن القناتين شرط، فإذا كانت في جهازك شريحة ذاكرة واحدة فأنت تعمل بنصف السرعة، وهذا من أرخص التحسينات إذا كان اللوح الأم يدعم قناتين. وسوف ترى في التجربة أدناه أن جهازنا بذاكرة 38.4 GB/s أعطى قرابة 3.7 توكن في الثانية لنموذج 7B، وهي سرعة تكفي لمهمة ليلية أو لتجربة الأفكار، وتبدو بطيئة في المحادثة. والنتيجة العملية للمعالج وحده:
- نماذج 1B إلى 3B بتكميم Q4 تعمل بسرعة مريحة في أغلب الأجهزة الحديثة، وهي مناسبة للتصنيف والتلخيص القصير واستخراج الحقول.
- نماذج 7B إلى 8B تعمل ببطء مقبول إذا كانت الذاكرة 16 GB أو أكثر.
- نماذج 14B فما فوق تعمل إذا كانت الذاكرة تكفي، ولكن السرعة تنزل إلى بضع توكنز في الثانية أو أقل، فلا تعتمد عليها في المحادثة.
بطاقات NVIDIA: الطريق الأسهل
بطاقات NVIDIA هي الأوسع دعماً في هذا المجال، والسبب أن أغلب أدوات التعلم الآلي كتبت أولاً لمنصة CUDA الخاصة بها. ويتطلب Ollama بحسب صفحة دعم البطاقات بطاقة بقدرة حسابية Compute Capability من 5.0 فما فوق مع تعريف Driver إصدار 550 أو أحدث، أي من بطاقات GTX 750 Ti القديمة إلى أحدث البطاقات. والذي يهمك في البطاقة أولاً هو حجم VRAM، ثم سرعتها، والجدول التالي يبين ما تتوقعه من كل فئة بنافذة سياق 4096، والأحجام من جدول الأحجام أعلاه:
| VRAM | ما يدخل فيها كاملاً بتكميم Q4_K_M | ملاحظة |
|---|---|---|
| 8 GB | حتى 7B و8B | بهامش صغير، والنافذة الطويلة قد تخرج جزءاً إلى المعالج |
| 12 GB | 8B بتكميم Q8_0، أو 14B بتكميم Q4 | 14B بهامش صغير |
| 16 GB | 14B براحة | تستطيع رفع النافذة أكثر |
| 24 GB | 32B بتكميم Q4 | 20 GB للأوزان وحدها، فالنافذة محدودة |
وقد يتساءل البعض: ماذا لو كان النموذج أكبر من VRAM قليلاً؟ والإجابة أن llama.cpp يدعم كما يذكر توثيقه التشغيل الهجين CPU+GPU، أي أن يضع جزءاً من طبقات النموذج في البطاقة والباقي في RAM ليحسبه المعالج، وOllama يقوم بهذا التقسيم تلقائياً، ويظهر في الأمر ollama ps بنسبة مثل 48%/52% CPU/GPU كما في أسئلة Ollama الشائعة. والمشكلة أن السرعة لا تنزل بنسبة ما خرج من البطاقة، وإنما تنزل أكثر بكثير، والصورة التالية تبين السبب:

والسبب أن كل توكن يمر على كل الطبقات بالترتيب، فالطبقات التي في البطاقة تنتهي بسرعة، ثم ينتظر الجميع الطبقات التي في RAM، وهذه تقرأ من ذاكرة أبطأ بمرات كثيرة. لذلك فخروج ثلث الطبقات إلى المعالج قد يجعل السرعة أقرب إلى سرعة المعالج منها إلى سرعة البطاقة، والقاعدة: إذا رأيت في ollama ps نسبة CPU غير صفر فاختر تكميماً أصغر أو نموذجاً أصغر أو نافذة أقصر قبل أن تقبل بالتقسيم.
بطاقات AMD
دعم بطاقات AMD أصبح جيداً ولكنه أضيق من NVIDIA، فبحسب صفحة دعم البطاقات في Ollama يحتاج Ollama على Linux تعريف ROCm v7 ويدعم قائمة من بطاقات Radeon RX وRadeon PRO وInstinct ومعالجات Ryzen AI، وعلى Windows القائمة أقصر وتشمل بعض بطاقات RX 7000 وPRO فقط. ولبقية البطاقات يوجد طريق ثان هو Vulkan، وهو واجهة رسومية عامة يدعمها أغلب مصنعي البطاقات، ويستخدمها Ollama على Windows وLinux كطريق احتياطي للبطاقات التي لا يدعمها ROCm أو CUDA، ويمكن إيقافه بالمتغير OLLAMA_VULKAN=0. لذلك قبل أن تشتري بطاقة AMD لهذا الغرض، ابحث عن اسمها بالضبط في تلك القائمة.
أجهزة Mac بمعالجات Apple Silicon
في أجهزة Mac الحديثة لا توجد ذاكرة منفصلة للبطاقة الرسومية، وإنما ذاكرة موحدة Unified Memory يقرأ منها المعالج والبطاقة معاً، وهذا يعني أن جهاز Mac بذاكرة 64 GB يستطيع أن يضع في بطاقته نموذجاً لا يدخل في أي بطاقة منزلية من NVIDIA. وOllama يستخدم بطاقة Mac عبر واجهة Metal، وllama.cpp يعتبر Apple Silicon «مواطناً من الدرجة الأولى» بحسب توثيقه.
ولكن لاحظ نقطتين قبل أن تحسب: الأولى أن macOS لا يعطي البطاقة كل الذاكرة، وإنما يحدد لها حداً يسمى recommendedMaxWorkingSetSize، وهو بحسب ما قاسه المستخدمون في نقاش llama.cpp عن ذاكرة Mac قرابة الثلثين إلى ثلاثة أرباع الذاكرة، ويمكن رفعه بالأمر sudo sysctl iogpu.wired_limit_mb=<MB> على مسؤوليتك مع ترك ما يكفي للنظام. والثانية أن سرعة الذاكرة تختلف كثيراً بين الأجهزة، فهي في جدول قياسات llama.cpp على أجهزة Apple من 68 GB/s في M1 العادي إلى 800 GB/s في M2 Ultra، وسوف ترى في قسم السرعة أن هذا الفرق يظهر مباشرة في عدد التوكنز في الثانية. ولاحظ أن ذاكرة Mac لا يمكن زيادتها بعد الشراء، فاختر حجمها على قدر النماذج التي تنوي تشغيلها.
البطاقات المدمجة ووحدات NPU
أغلب أجهزة اللابتوب فيها بطاقة رسومية مدمجة Integrated GPU داخل المعالج، وأغلب الأجهزة الجديدة فيها أيضاً وحدة معالجة عصبية Neural Processing Unit واختصاراً NPU، فهل تساعد في تشغيل النماذج؟ والإجابة الصادقة: قليلاً، وفي حالات محدودة. فالبطاقة المدمجة تقرأ من نفس ذاكرة النظام، فلا تكسب سرعة ذاكرة، وتوثيق llama.cpp لبطاقات Intel عبر SYCL يذكر أن البطاقة المدمجة التي فيها أقل من 80 وحدة تنفيذ Execution Units سوف تكون على الأغلب أبطأ من أن تستخدم عملياً. وفي جهاز التجربة بطاقة مدمجة Intel HD Graphics 630 من 2017، ولم يجد Ollama أي بطاقة يستخدمها فعمل على المعالج كما سترى في سجله.
أما وحدات NPU فلا يذكرها توثيق Ollama في صفحة الأجهزة المدعومة، وجدول llama.cpp لا يذكر منها إلا وحدات Ascend من Huawei عبر CANN، والدعم الموجود اليوم لوحدات NPU في أجهزة الكمبيوتر يأتي من أدوات الشركات المصنعة نفسها، مثل OpenVINO GenAI من Intel الذي يشغل نماذج مجهزة خصيصاً على NPU في معالجات Core Ultra. لذلك لا تشتر جهازاً من أجل وحدة NPU إذا كانت خطتك أن تستخدم Ollama.
السيرفر بعدة بطاقات وعدة مستخدمين
عندما يكبر النموذج عن بطاقة واحدة يمكن لOllama وllama.cpp أن يوزعا الطبقات على عدة بطاقات في نفس الجهاز، فتصبح ذاكرة البطاقات مجتمعة هي الحد. ولكن السيرفر الذي يخدم فريقاً كاملاً له مشكلة ثانية غير حجم النموذج: كل مستخدم يعمل في نفس الوقت يحتاج ذاكرة KV خاصة به، فالمتغير OLLAMA_NUM_PARALLEL الذي يحدد عدد الطلبات المتوازية يضاعف الذاكرة المطلوبة للسياق بحسب أسئلة Ollama الشائعة. وOllama مصمم أولاً لجهاز واحد ومستخدمين قلائل، أما خدمة عشرات المستخدمين بكفاءة فلها محركات مخصصة مثل vLLM برخصة Apache-2.0، وقد خصصنا لها مقالاً قادماً في مرحلة الذكاء الاصطناعي على سيرفرك.
Raspberry Pi والأجهزة الصغيرة
أعلنت Raspberry Pi في يناير 2025 عن نسخة Raspberry Pi 5 بذاكرة 16 GB، وذكرت نماذج اللغة الكبيرة صراحة من الاستخدامات التي تستفيد من الذاكرة الأكبر. والنموذج هنا يعمل على المعالج ARM وحده، فتوقع ما تتوقعه من لابتوب ضعيف: نماذج 0.5B إلى 3B بتكميم Q4 تعمل، وتصلح لتعلم الأدوات ولمهام صغيرة ثابتة مثل تصنيف نص قصير أو استخراج حقل، ولا تصلح لمساعد محادثة تعتمد عليه. وهي على أي حال طريقة ممتعة لتفهم كل ما في هذا المقال على جهاز في حجم كف اليد.
تجربة حقيقية: جهاز بلا بطاقة رسومية
الآن نقيس بأنفسنا. جهاز التجربة كمبيوتر مكتبي بمعالج Intel Core i7-7700K من 2017 (أربع أنوية وثمانية خيوط) وذاكرة DDR4-2400 بقناتين، ويعمل Docker Desktop على Windows عبر WSL2 ويرى 8 معالجات افتراضية و31.3 GiB من الذاكرة، ولا توجد فيه بطاقة NVIDIA. والأرقام التالية توضيحية تخص هذا الجهاز وحده، والهدف منها أن ترى العلاقات بين الحجم والذاكرة والسرعة، وليس أن تقارن بها جهازك. وإذا لم يكن Docker مثبتاً لديك فقد شرحنا تثبيته في دليل تثبيت Docker على Ubuntu:
docker volume create lab-llm2-ollama
docker run -d --name lab-llm2-ollama -p 127.0.0.1:19180:11434 \
-v lab-llm2-ollama:/root/.ollama ollama/ollama:0.35.1
for m in qwen2.5:0.5b qwen2.5:1.5b qwen2.5:3b qwen2.5:7b; do
docker exec lab-llm2-ollama ollama pull $m
done
docker exec lab-llm2-ollama ollama listوالمخرج سوف يكون كما يلي:
NAME ID SIZE MODIFIED
qwen2.5:7b 845dbda0ea48 4.7 GB 13 minutes ago
qwen2.5:3b 357c53fb659c 1.9 GB 19 minutes ago
qwen2.5:1.5b 65ec06548149 986 MB 22 minutes ago
qwen2.5:0.5b a8b0c5157701 397 MB 23 minutes agoفي الإعداد أعلاه لاحظ التالي:
- منفذ Ollama منشور على
127.0.0.1فقط، والسبب أن واجهته لا تطلب أي مصادقة، فلا تنشرها على كل الواجهات أبداً. - التحميل كله قرابة 8 GB، والنماذج الأربعة من عائلة Qwen2.5 بتكميم Q4_K_M الافتراضي في Ollama، وأحجامها تطابق ما في المكتبة.
- لم نضف الخيار
--gpusلأن الجهاز لا توجد فيه بطاقة NVIDIA، وسوف نرى بعد قليل ماذا يحدث لو أضفناه.
وأول ما تفعله بعد التشغيل أن تتأكد من الجهاز الذي وجده Ollama، فهو يكتب ذلك في سجله عند البدء:
docker logs lab-llm2-ollama 2>&1 | grep "inference compute"time=2026-10-06T05:33:31.712Z level=INFO source=types.go:50 msg="inference compute" id=cpu library=cpu compute="" name=cpu description=cpu libdirs=ollama driver="" pci_id="" type="" total="31.3 GiB" available="29.2 GiB"والسطر واضح: library=cpu، أي أن Ollama لم يجد أي بطاقة يستخدمها، والذاكرة المتاحة له 29.2 GiB من أصل 31.3 GiB. وفي جهاز ببطاقة NVIDIA معرفة بشكل صحيح سوف ترى هنا library=CUDA مع اسم البطاقة وحجم VRAM، فإذا لم تره فالنموذج سيعمل على المعالج مهما كانت بطاقتك قوية.
السرعة والذاكرة لأربعة أحجام
البرنامج التالي speed.py يرسل نفس السؤال إلى كل نموذج بدرجة حرارة 0 ويطلب 128 توكناً، ويحسب سرعة قراءة النص وسرعة التوليد من الحقول التي ترجعها واجهة Ollama، وهي prompt_eval_count وprompt_eval_duration وeval_count وeval_duration والأزمنة فيها بالنانو ثانية، ثم يقرأ حجم النموذج في الذاكرة من ollama ps. وهو يعمل على جهازك مباشرة بمكتبات Python الأساسية:
import json, sys, subprocess, urllib.request
API = "http://127.0.0.1:19180/api/generate"
PROMPT = "Explain in one paragraph why a database index makes reads faster."
def run(model, **opts):
subprocess.run(["docker", "exec", "lab-llm2-ollama", "ollama", "stop", model], capture_output=True)
body = {"model": model, "prompt": PROMPT, "stream": False,
"options": {"temperature": 0, "num_predict": 128, "seed": 1, **opts}}
req = urllib.request.Request(API, json.dumps(body).encode(), {"Content-Type": "application/json"})
r = json.load(urllib.request.urlopen(req, timeout=900))
ps = subprocess.run(["docker", "exec", "lab-llm2-ollama", "ollama", "ps"], capture_output=True, text=True).stdout.splitlines()[1].split()
pp = r["prompt_eval_count"] / (r["prompt_eval_duration"] / 1e9)
tg = r["eval_count"] / (r["eval_duration"] / 1e9)
return pp, tg, f"{ps[2]} {ps[3]}", r["load_duration"] / 1e9
print(f"{'model':<14}{'in memory':>11}{'load s':>8}{'prompt tok/s':>14}{'gen tok/s':>11}")
for m in sys.argv[1:]:
pp, tg, mem, load = run(m)
print(f"{m:<14}{mem:>11}{load:>8.1f}{pp:>14.1f}{tg:>11.1f}")python3 speed.py qwen2.5:0.5b qwen2.5:1.5b qwen2.5:3b qwen2.5:7bوالمخرج سوف يكون كما يلي:
model in memory load s prompt tok/s gen tok/s
qwen2.5:0.5b 484 MB 3.1 53.0 32.3
qwen2.5:1.5b 1.2 GB 3.6 78.9 15.9
qwen2.5:3b 2.2 GB 5.6 33.3 5.4
qwen2.5:7b 5.1 GB 10.6 11.8 3.7في المخرج أعلاه لاحظ التالي:
- عمود
in memoryمنollama psأكبر من حجم الملف دائماً: 484 MB لملف 397 MB، و5.1 GB لملف 4.7 GB، والفرق هو ذاكرة KV للنافذة الافتراضية 4096 ومخازن الحساب، وهذا ما رسمناه في ميزانية الذاكرة أعلاه. - سرعة التوليد تنزل مع الحجم: 32.3 ثم 15.9 ثم 5.4 ثم 3.7 توكن في الثانية. واضرب السرعة في حجم الملف لترى كم جيجابايت قرأ المعالج في الثانية: 32.3 × 0.4 ≈ 13 GB/s، و15.9 × 0.99 ≈ 16 GB/s، و3.7 × 4.7 ≈ 17 GB/s، أي أن الرقم قريب في كل النماذج، وهو قرابة نصف الحد النظري 38.4 GB/s، وهذه علامة أن الذاكرة هي القيد وليس الحساب.
- نموذج 3B أعطى 5.4 في هذا التشغيل، ثم أعطى 9.5 في تجربة الخيوط بعد قليل بنفس الإعدادات (9.5 × 1.9 ≈ 18 GB/s)، والسبب أن جهاز التجربة مشترك وتعمل عليه برامج أخرى، لذلك قس على جهازك أكثر من مرة ولا تعتمد على تشغيل واحد.
- سرعة قراءة النص هنا لسؤال قصير من قرابة 40 توكناً، لذلك تتذبذب كثيراً بين التشغيلات، وقد رأيت في المقال السابق أن النص الطويل يأخذ ثوان قبل أول حرف حتى في نموذج 0.5B.
- نموذج 7B على هذا المعالج يعطي قرابة أربع توكنز في الثانية، أي أن إجابة من 300 توكن تأخذ أكثر من دقيقة، وهذا يكفي لعمل دفعي ولا يكفي لمحادثة مريحة.
هل تفيد أنوية أكثر؟
لنتأكد من فكرة أن الذاكرة وليس عدد الأنوية هو الذي يحدد سرعة التوليد، فالبرنامج التالي threads.py يشغل نموذج 3B بعدد خيوط مختلف عبر الخيار num_thread:
import json, sys, subprocess, urllib.request
model = sys.argv[1]
subprocess.run(["docker", "exec", "lab-llm2-ollama", "ollama", "stop", model], capture_output=True)
for n in (1, 2, 4, 8):
body = {"model": model, "prompt": f"Run {n}. Explain in one paragraph why a database index makes reads faster.", "stream": False,
"options": {"temperature": 0, "num_predict": 64, "num_thread": n, "seed": 1}}
r = json.load(urllib.request.urlopen(urllib.request.Request("http://127.0.0.1:19180/api/generate", json.dumps(body).encode(), {"Content-Type": "application/json"}), timeout=900))
print(f"num_thread={n} prompt {r['prompt_eval_count']/(r['prompt_eval_duration']/1e9):6.1f} tok/s generation {r['eval_count']/(r['eval_duration']/1e9):5.1f} tok/s")python3 threads.py qwen2.5:3bnum_thread=1 prompt 11.4 tok/s generation 4.6 tok/s
num_thread=2 prompt 16.5 tok/s generation 7.0 tok/s
num_thread=4 prompt 39.1 tok/s generation 9.5 tok/s
num_thread=8 prompt 20.1 tok/s generation 2.4 tok/sفي المخرج أعلاه لاحظ التالي:
- من خيط واحد إلى أربعة خيوط تضاعفت سرعة التوليد مرتين فقط (4.6 إلى 9.5) رغم أن الخيوط أربعة أضعاف، والسبب أن الأنوية الأربعة تتشارك نفس الذاكرة، فكلما زادت الأنوية اقتربت من سقف سرعة الذاكرة.
- ثمانية خيوط كانت أسوأ بكثير من أربعة (2.4 مقابل 9.5)، لأن المعالج فيه أربع أنوية حقيقية فقط، والخيوط الأربعة الإضافية خيوط افتراضية Hyper-Threading تتشارك نفس الأنوية، فتنتظر الخيوط بعضها بدلاً من أن تسرع. ولهذا السبب يختار Ollama بنفسه عدد الأنوية الحقيقية، وتجد ذلك في سجله:
n_threads = 4 (n_threads_batch = 4) / 8. - القاعدة: لا ترفع
num_threadفوق عدد الأنوية الحقيقية، وإذا اشتريت جهازاً للتشغيل على المعالج فسرعة الذاكرة وعدد قنواتها أهم من عدد الأنوية بعد حد معين. وهذه الأرقام من تشغيل واحد على جهاز مشترك، فالاتجاه هو المهم وليس الرقم نفسه.
ماذا لو طلبت بطاقة غير موجودة؟
لنكسر الإعداد عمداً، فنشغل Container بالخيار --gpus all على هذا الجهاز الذي لا توجد فيه بطاقة NVIDIA:
docker run --rm --name lab-llm2-gputest --gpus all ollama/ollama:0.35.1 --versiondocker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running prestart hook #0: exit status 1, stdout: , stderr: Auto-detected mode as 'legacy'
nvidia-container-cli: initialization error: WSL environment detected but no adapters were foundوالمهم في هذا الخطأ السطر الأخير: nvidia-container-cli هو جزء من NVIDIA Container Toolkit الذي يربط البطاقة بال Container، وقد بحث عن بطاقة في بيئة WSL فلم يجد. وهذا أفضل من أن يعمل ال Container بصمت على المعالج، لأنك تعرف المشكلة من أول سطر. وعلى سيرفر Linux ببطاقة NVIDIA فالخطوات بحسب توثيق Ollama مع Docker هي تثبيت NVIDIA Container Toolkit، ثم ربطه بDocker وإعادة تشغيله، ثم إضافة الخيار --gpus=all:
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
docker run -d --gpus=all --name ollama -p 127.0.0.1:11434:11434 \
-v ollama:/root/.ollama ollama/ollamaوقبل Ollama تأكد أن ال Container يرى البطاقة بالأمر الذي يذكره توثيق Docker وهو docker run --rm --gpus all ubuntu nvidia-smi، وعلى Windows يعمل الخيار --gpus في Docker Desktop مع WSL2 فقط وببطاقة NVIDIA بحسب صفحة GPU في Docker Desktop. ولبطاقات AMD يستخدم Ollama نسخة خاصة ollama/ollama:rocm مع تمرير الأجهزة /dev/kfd و/dev/dri كما في نفس التوثيق.
السرعة: لماذا تحدد الذاكرة سرعة التوليد؟
رأيت في التجربة رقمين للسرعة، وهما مختلفان في طبيعتهما:
- قراءة النص Prompt Processing: النموذج يقرأ توكنز سؤالك كلها معاً، فيقرأ الأوزان مرة واحدة ويستخدمها لمئات التوكنز، لذلك تحددها قوة الحساب، وهي التي تقرر كم تنتظر قبل أن يظهر أول حرف من الإجابة، خاصة إذا ألصقت مستنداً طويلاً.
- التوليد Generation: النموذج يولد توكناً واحداً في كل خطوة، ولكل توكن يقرأ الأوزان كلها من الذاكرة، لذلك تحددها في الغالب سرعة الذاكرة، وهي التي تقرر كم تنتظر حتى تكتمل الإجابة.
ومن هنا تأتي معادلة تقريبية مفيدة: الحد الأعلى لسرعة التوليد ≈ عرض نطاق الذاكرة ÷ حجم النموذج. ففي جهازنا 38.4 GB/s ÷ 4.7 GB ≈ 8 توكنز في الثانية كحد نظري لنموذج 7B، وقد قسنا 3.7، أي أقل من الحد كما هو متوقع، لأن الذاكرة لا تعمل أبداً بسرعتها النظرية الكاملة. والصورة التالية تبين هذه العلاقة بأرقام منشورة من مصدرين أوليين:

في الصورة أعلاه لاحظ التالي:
- في جدول قياسات llama.cpp على أجهزة Apple لنموذج LLaMA 7B بتكميم Q4_0، أعطى M1 بذاكرة 68 GB/s قرابة 14 توكناً في الثانية، وM1 Pro بذاكرة 200 GB/s قرابة 36، وM3 Max بذاكرة 400 GB/s قرابة 66، وM2 Ultra بذاكرة 800 GB/s قرابة 94، أي أن السرعة تكبر مع سرعة الذاكرة.
- في جدول أداة التكميم في llama.cpp لنموذج Llama 3.1 8B على نفس العتاد، كانت سرعة التوليد 29.17 توكن في الثانية بدقة F16 (14.96 GiB)، و50.93 بتكميم Q8_0 (7.95 GiB)، و71.93 بتكميم Q4_K_M (4.58 GiB)، بينما بقيت سرعة قراءة النص بين 820 و920 تقريباً في الثلاثة، أي أن الملف الأصغر يولد أسرع لأنه يقرأ بيانات أقل، أما القراءة فلا تتأثر كثيراً بالحجم لأنها مقيدة بالحساب.
وقد يتساءل البعض: ما هي السرعة الكافية؟ والإجابة تعتمد على نوع العمل. في المحادثة الإجابة تظهر أمامك وأنت تقرأها، فإذا كان النص يظهر أسرع من قراءتك فالسرعة كافية، وإذا كنت تنتظر كل كلمة فستمل بسرعة، لذلك جرب بنفسك بالأمر ollama run مع الخيار --verbose واحكم. أما العمل الدفعي Batch، مثل تلخيص ألف مستند في الليل، فالسرعة تحدد متى ينتهي العمل فقط: ألف مستند في 300 توكن لكل ملخص بسرعة 5 توكنز في الثانية تساوي 60,000 ثانية من التوليد، أي قرابة 17 ساعة، وهذا قد يكون مقبولاً لعمل ليلي يتكرر مرة في الأسبوع، وغير مقبول لعمل يومي.
اختيار التكميم في الواقع
شرحنا فكرة التكميم في المقال السابق: أن تحفظ كل معامل بعدد بتات أقل فيصغر الملف ويسرع التوليد مقابل انخفاض في الدقة. والسؤال العملي: أي نوع تختار؟ والقاعدة التي تبدأ بها:
- Q4_K_M هو الاختيار الافتراضي في مكتبة Ollama لأغلب النماذج، وهو نقطة التوازن الشائعة بين الحجم والجودة، فابدأ به.
- Q5_K_M وQ6_K أكبر قليلاً وأدق قليلاً، فإذا كانت ذاكرتك تتسع لها بعد حساب KV Cache فجربها على مهامك وقارن.
- Q8_0 أدق من Q4 وقرابة ضعف حجمه، وهو مناسب للنماذج الصغيرة التي تتسع لها الذاكرة بسهولة.
- F16 أو BF16 هي الدقة الأصلية، ونادراً ما تحتاجها للتشغيل، فهي أبطأ في التوليد وتأخذ ثلاثة أضعاف ذاكرة Q4 تقريباً كما رأيت في جدول llama.cpp.
- الأنواع الأصغر من Q4 مثل Q3 وQ2 تنخفض فيها الجودة بشكل أوضح، فلا تنزل إليها إلا إذا كان البديل ألا يعمل النموذج أبداً، واختبر النتائج بعناية.
وإذا كان الخيار بين نموذج أكبر بتكميم Q4 ونموذج أصغر بدقة أعلى بنفس الذاكرة، فلا تحكم بالأرقام وحدها، وإنما جرب الاثنين على عشرين سؤالاً حقيقياً من عملك وبلغتك، والسبب أن الفرق يظهر في مهامك أنت، وقد رأينا في المقال السابق كيف يجيب نفس النموذج بالإنجليزية ويخطئ بالعربية.
أما الصيغ فأشهرها للأجهزة الشخصية GGUF التي يستخدمها llama.cpp وOllama وLM Studio، وفيها الأوزان المكممة مع كل ما يحتاجه النموذج في ملف واحد. وفي Hugging Face سوف ترى أيضاً ملفات safetensors بالدقة الأصلية، وهي التي تستخدمها مكتبة transformers ومحركات السيرفرات مثل vLLM، وصيغاً مكممة خاصة بالبطاقات الرسومية مثل GPTQ وAWQ، وهذه تخص السيرفرات أكثر من الأجهزة الشخصية، وسوف نعود إليها في مقال vLLM.
نافذة السياق تكلف ذاكرة
شرحنا في المقال السابق أن ذاكرة KV Cache تحفظ قيماً لكل توكن في النافذة، وأن Ollama يحجزها للنافذة كلها عند تحميل النموذج. والقيمة الافتراضية للنافذة في Ollama بحسب توثيق طول السياق تعتمد على ذاكرة البطاقة: 4k إذا كانت أقل من 24 GiB، و32k من 24 إلى 48 GiB، و256k إذا كانت 48 GiB فأكثر، ويمكنك تغييرها لكل طلب بالخيار num_ctx، أو للخادم كله بالمتغير OLLAMA_CONTEXT_LENGTH. ولاحظ ما يعنيه هذا: إذا اشتريت بطاقة 24 GB فسوف يبدأ Ollama بنافذة 32k، فتأخذ ذاكرة KV منها أكثر مما تتوقع.
ولنقس ذلك على نموذج 7B، فالبرنامج التالي ctx.py يحمل النموذج بخمسة أطوال للنافذة ويطبع سطر ollama ps بعد كل مرة:
import json, sys, subprocess, urllib.request
model = sys.argv[1]
for ctx in (2048, 4096, 8192, 16384, 32768):
subprocess.run(["docker", "exec", "lab-llm2-ollama", "ollama", "stop", model], capture_output=True)
body = {"model": model, "prompt": "Hi", "stream": False, "options": {"num_ctx": ctx, "num_predict": 1}}
urllib.request.urlopen(urllib.request.Request("http://127.0.0.1:19180/api/generate", json.dumps(body).encode(), {"Content-Type": "application/json"}), timeout=900).read()
line = subprocess.run(["docker", "exec", "lab-llm2-ollama", "ollama", "ps"], capture_output=True, text=True).stdout.splitlines()[1]
print(f"num_ctx={ctx:<6} | {' '.join(line.split())}")python3 ctx.py qwen2.5:7bnum_ctx=2048 | qwen2.5:7b 845dbda0ea48 4.9 GB 100% CPU 2048 4 minutes from now
num_ctx=4096 | qwen2.5:7b 845dbda0ea48 5.1 GB 100% CPU 4096 4 minutes from now
num_ctx=8192 | qwen2.5:7b 845dbda0ea48 5.5 GB 100% CPU 8192 4 minutes from now
num_ctx=16384 | qwen2.5:7b 845dbda0ea48 5.9 GB 100% CPU 16384 4 minutes from now
num_ctx=32768 | qwen2.5:7b 845dbda0ea48 6.9 GB 100% CPU 32768 4 minutes from nowفي المخرج أعلاه لاحظ التالي:
- نفس النموذج ونفس السؤال، وتغيرت الذاكرة من 4.9 GB إلى 6.9 GB بسبب طول النافذة وحده، والسبب أن Ollama يحجز ذاكرة KV للنافذة كلها عند التحميل ولو لم تستخدمها.
- الزيادة من 4096 إلى 32768 كانت 1.8 GB، والحساب من ملف إعدادات Qwen2.5-7B يعطي 56 KiB × 28,672 توكناً إضافياً ≈ 1.53 GiB، أي قرابة 1.64 GB، والباقي مخازن حساب تكبر مع النافذة أيضاً.
- العمود
100% CPUيؤكد أن النموذج كله في RAM، وفي جهاز ببطاقة رسومية هذا هو العمود الذي تراقبه: إذا رفعت النافذة فخرج جزء من النموذج من VRAM فسوف ترى نسبة مثل20%/80% CPU/GPU، وتنزل السرعة كما شرحنا في قسم NVIDIA. - في بطاقة 8 GB تأخذ الأوزان والنافذة 32768 قرابة 6.9 GB، فلا يبقى إلا هامش صغير للشاشة وغيرها، وهذا ما تراه في الصورة الثانية من هذا المقال.
وإذا احتجت نافذة طويلة على ذاكرة محدودة، فهناك خياران في أسئلة Ollama الشائعة: تكميم ذاكرة KV نفسها بالمتغير OLLAMA_KV_CACHE_TYPE=q8_0، وهو يوفر قرابة النصف مقارنة بالقيمة الافتراضية f16، ويتطلب تفعيل Flash Attention، والنوع q4_0 يوفر قرابة ثلاثة أرباع مع خسارة دقة ملحوظة في النوافذ الطويلة. والخيار الثاني أبسط: لا تضع في النافذة إلا ما تحتاجه، وهذا ما تقوم به أنظمة RAG.
الأدوات التي تبدأ بها
كل الأدوات التالية تشغل نماذج GGUF على جهازك، والفرق بينها في الواجهة والرخصة، وسوف نخصص لأهمها مقالات تثبيت واستخدام مفصلة في مرحلة الذكاء الاصطناعي على سيرفرك، لذلك نكتفي هنا بما يساعدك على الاختيار:
| الأداة | ما هي | الرخصة |
|---|---|---|
| Ollama | خادم بواجهة برمجية وسطر أوامر، ومكتبة نماذج جاهزة، ويعمل على Linux وWindows وmacOS وفي Docker | MIT |
| llama.cpp | المحرك الذي تقوم عليه أغلب هذه الأدوات، بأدوات سطر أوامر وخادم، ويعطيك التحكم الكامل | MIT |
| LM Studio | تطبيق مكتبي بواجهة رسومية للبحث عن النماذج وتشغيلها | برنامج مغلق المصدر Proprietary، ورخصته تسمح بالاستخدام الشخصي والاستخدام الداخلي في العمل |
| Jan | تطبيق مكتبي للمحادثة مع النماذج المحلية | Apache-2.0 |
| GPT4All | تطبيق مكتبي للمحادثة مع النماذج المحلية والمستندات | MIT |
| Open WebUI | واجهة ويب للمحادثة تعمل فوق Ollama أو أي خادم متوافق، وتناسب الفرق | رخصة Open WebUI الخاصة، انظر الملاحظة أدناه |
والاختيار باختصار: إذا أردت أن تجرب على جهازك الشخصي بواجهة رسومية فابدأ بتطبيق مكتبي، وإذا أردت خادماً يستخدمه برنامجك أو فريقك فابدأ بOllama في Docker كما في التجربة أعلاه، ثم أضف فوقه واجهة ويب، وإذا أردت أن تتحكم في كل خيار فانزل إلى llama.cpp مباشرة.
اختيار النموذج على قدر ذاكرتك
الآن نجمع كل ما سبق في قرار واحد: كم ذاكرة تستطيع أن تعطي النموذج، وما هو أكبر نموذج يدخل فيها مع هامش للسياق؟ والذاكرة هنا هي VRAM في البطاقة، أو قرابة الثلثين إلى ثلاثة أرباع الذاكرة الموحدة في Mac، أو RAM بعد ما يحتاجه النظام وبرامجك في حالة المعالج وحده. والصورة التالية تضع أحجام الملفات الحقيقية أمام أحجام الذاكرة الشائعة:

والجدول التالي يحول الصورة إلى نقطة بداية عملية بتكميم Q4_K_M ونافذة 4096:
| الذاكرة المتاحة للنموذج | الأحجام الواقعية | ماذا تتوقع |
|---|---|---|
| 8 GB RAM بالمعالج فقط | 1B إلى 3B | مهام صغيرة ثابتة، وجودة محدودة بالعربية |
| 16 GB RAM بالمعالج فقط | حتى 7B و8B | بطيء في المحادثة، ومقبول للعمل الدفعي |
| 8 GB VRAM | 7B و8B | محادثة مريحة بنافذة قصيرة |
| 12 إلى 16 GB VRAM | 14B | جودة أفضل بوضوح من 7B في أغلب المهام |
| 24 GB VRAM | 32B بنافذة محدودة | أعلى ما تصل إليه بطاقة منزلية واحدة |
| 48 GB فأكثر (عدة بطاقات أو Mac بذاكرة كبيرة) | 70B | أقرب ما تصل إليه محلياً من النماذج الكبيرة |
أما العائلات نفسها فأشهر النماذج المفتوحة Open Weights التي تجدها بهذه الأحجام: Qwen2.5 من Alibaba وأغلب أحجامها برخصة Apache-2.0 مع استثناءات، وLlama من Meta برخصتها الخاصة، وMistral 7B برخصة Apache-2.0، وPhi-4 من Microsoft بحجم 14B برخصة MIT، وGemma من Google بشروط استخدام Gemma الخاصة. وقد شرحنا في قسم النماذج المفتوحة ورخصها لماذا يجب أن تقرأ رخصة كل نموذج بل كل حجم قبل الاستخدام التجاري، والمقارنة بين العائلات للعربية لها مقال قادم في نفس المرحلة.
قبل أن تشتري عتاداً
لن نرشح لك منتجاً بعينه، لأن الأسعار والإصدارات تتغير كل بضعة أشهر، ولكن هذه هي الأسئلة بالترتيب الذي يوفر عليك المال:
- جرب أولاً على ما تملكه: شغل نموذجاً صغيراً على المعالج في جهازك الحالي كما في التجربة أعلاه، واختبره على مهامك الحقيقية، فقد تكتشف أن نموذج 3B يكفي لعملك، أو أن 14B نفسه لا يكفي فتعرف أن الخدمة السحابية أنسب.
- حدد النموذج قبل العتاد: اختر أصغر نموذج يعطيك جودة مقبولة على أسئلتك، ثم احسب له الذاكرة بالمعادلة مع النافذة وعدد المستخدمين الذي تحتاجه.
- الذاكرة قبل كل شيء: في البطاقة الرسومية حجم VRAM أهم من قوة الحساب لهذا العمل، وبطاقة أبطأ بذاكرة أكبر تشغل نماذج لا تستطيع تشغيلها بطاقة أسرع بذاكرة أصغر.
- ثم سرعة الذاكرة: بين جهازين بنفس حجم الذاكرة، الأسرع ذاكرة هو الأسرع توليداً، وهذا يصدق على المعالج وMac والبطاقات.
- تأكد من الدعم بالاسم: ابحث عن اسم البطاقة بالضبط في قائمة البطاقات المدعومة قبل الشراء، خاصة في بطاقات AMD.
- لا تنس الكهرباء والحرارة والضجيج: بطاقة تعمل طوال اليوم في مكتبك أو في غرفة السيرفر لها كلفة مستمرة، فاحسبها مع ثمن الشراء.
أخطاء شائعة
- شراء العتاد قبل تجربة النموذج على مهامك، ثم اكتشاف أن النموذج الذي يدخل فيه لا يكفي جودة.
- حساب حجم الملف فقط ونسيان ذاكرة KV ومخازن الحساب والنظام، فيخرج جزء من النموذج إلى المعالج دون أن تنتبه، وتنهار السرعة.
- عدم النظر في عمود
PROCESSORفيollama ps، فتظن أن البطاقة تعمل والنموذج يعمل على المعالج. - رفع نافذة السياق إلى الحد الأقصى احتياطاً، فتحجز جيجابايتات لا تستخدمها.
- رفع
OLLAMA_NUM_PARALLELلخدمة عدة مستخدمين دون حساب أن الذاكرة تتضاعف معه. - شريحة ذاكرة واحدة في جهاز يدعم قناتين، فتعمل بنصف سرعة الذاكرة.
- نشر منفذ Ollama على كل الواجهات
0.0.0.0وهو لا يطلب أي مصادقة. - استخدام نموذج أو أداة في عمل تجاري دون قراءة رخصتها.
قائمة التحقق
- هل يمنع عليك إرسال البيانات للخارج، أم أن الخدمة السحابية تكفي؟
- ما أصغر نموذج يعطيك جودة مقبولة على عشرين سؤالاً حقيقياً من عملك وبلغتك؟
- كم الذاكرة المطلوبة: الأوزان + KV للنافذة وعدد المستخدمين + المخازن + هامش النظام؟
- أي ذاكرة سوف يقرأ منها: VRAM أم الذاكرة الموحدة أم RAM، وكم سرعتها؟
- هل يظهر في سجل Ollama الجهاز الصحيح (
library=CUDAأو غيره)، وهل يظهر فيollama psالنسبة100% GPU؟ - هل قست سرعة القراءة والتوليد على عتادك بالأمر
ollama run --verboseأو بالواجهة البرمجية؟ - هل المنفذ مقصور على
127.0.0.1أو خلف Reverse Proxy بمصادقة؟ - هل قرأت رخصة النموذج والأداة؟
تدريب عملي
- شغل
speed.pyعلى جهازك بنفس النماذج، واحسب الحد النظري لسرعة ذاكرتك، وقارن سرعة التوليد في نموذج 7B بالحد. - اختر نموذجاً واحداً وشغله بتكميمين مختلفين، مثل
qwen2.5:3bوqwen2.5:3b-instruct-q8_0، وقارن الحجم فيollama psوسرعة التوليد وجودة الإجابة على خمسة أسئلة من عملك.
وعند الانتهاء احذف ما أنشأته في التجربة:
docker rm -f lab-llm2-ollama
docker volume rm lab-llm2-ollama
docker image rm ollama/ollama:0.35.1الخلاصة
وصلنا لنهاية الموضوع، وأهم ما فيه:
- ابدأ بالسؤال: هل تحتاج التشغيل المحلي فعلاً؟ الخصوصية والعمل دون إنترنت والحجم الكبير الثابت والتعلم أسباب قوية، أما أعلى جودة والاستخدام القليل فالخدمة السحابية أنسب لهما.
- القاعدة الوحيدة: النموذج يجب أن يدخل في الذاكرة التي يقرأ منها، والميزانية هي الأوزان وذاكرة KV ومخازن الحساب وهامش النظام، وليست حجم الملف وحده.
- بتكميم Q4_K_M يأخذ نموذج 7B إلى 8B قرابة 5 GB، و14B قرابة 9 GB، و32B قرابة 20 GB، و70B قرابة 43 GB.
- سرعة التوليد تحددها سرعة الذاكرة وحجم النموذج أكثر من عدد الأنوية، وتقسيم الطبقات بين البطاقة والمعالج يجعل الجزء البطيء يحدد السرعة.
- NVIDIA الأوسع دعماً، وAMD مدعومة بقائمة محددة عبر ROCm ثم Vulkan، وMac يعطيك ذاكرة موحدة كبيرة تأخذ منها البطاقة قرابة الثلثين إلى ثلاثة أرباع، والبطاقات المدمجة ووحدات NPU دعمها محدود اليوم.
- نافذة السياق وعدد الطلبات المتوازية يكلفان ذاكرة، فاجعلهما على قدر حاجتك، وقس كل شيء على عتادك بأدوات Ollama نفسها.
وفي المقالات القادمة من مرحلة الذكاء الاصطناعي على سيرفرك بإذن الله سوف نتحدث عن النماذج المفتوحة ومقارنتها للعربية، وتشغيل Ollama مع Open WebUI لفريقك، وخدمة النماذج لفريق كامل مع vLLM.
دليلكيف تعمل نماذج اللغة الكبيرة LLM من الداخل؟كيف يحول النموذج سؤالك إلى أرقام ويختار الكلمة التالية حتى تكتمل الإجابة، ولماذا يخطئ بنفس الثقة.
دليلالتزامن Concurrency والخيوط: ماذا يعني لسيرفرك وتطبيقاتكلماذا يكون المعالج عند 100% والتطبيق بطيئاً، ولا تسرع الخيوط كود Python، وكيف تضبط عدد العمال وحدود ال Containers.
دليلماذا يحدث عندما تشغل برنامج Hello World؟نتتبع برنامج C صغيراً من المحرر إلى الشاشة، فترى كل طبقة يمر بها في الجهاز حتى تظهر الجملة أمامك.
دليلتثبيت Docker Engine وCompose على Ubuntuكيف تثبت Docker على Ubuntu من المستودع الرسمي، وتضبطه من البداية حتى لا يمتلئ القرص أو تنكشف منافذك للإنترنت.
دليلتحليل أداء سيرفر Linux في 60 ثانية: ماذا تكتب أولاً؟ماذا تكتب أول ما تدخل إلى سيرفر بطيء، وكيف تعرف خلال دقيقة هل المشكلة في المعالج أم الذاكرة أم القرص أم الشبكة.سجل التحديثات
- أكتوبر 2026: كتابة المقال، واختبار التجارب على Docker Engine 29.8.0 (Docker Desktop مع WSL2، معالج Intel Core i7-7700K وذاكرة DDR4-2400 بقناتين، دون بطاقة رسومية) مع Ollama 0.35.1 والنماذج qwen2.5:0.5b وqwen2.5:1.5b وqwen2.5:3b وqwen2.5:7b بتكميم Q4_K_M.