vLLM لتشغيل النماذج اللغوية على الإنتاج: متى يتفوق على Ollama

يتفوق vLLM حين يتوفر GPU ويتجاوز التزامن 5 إلى 10 طلبات، بفضل PagedAttention والدفعات المستمرة وواجهة متوافقة مع OpenAI، أما Ollama على سيرفر CPU فيكفي فريقاً صغيراً بكلفة ثابتة وإعداد بأمر واحد.
يتفوق vLLM على Ollama حين يكون عندك بطاقة رسومية GPU وعدد مستخدمين متزامنين يتجاوز 5 إلى 10 طلبات في نفس اللحظة، لأن vLLM مبني كخادم استدلال للإنتاج: يدير ذاكرة الـKV cache بتقنية PagedAttention فلا يهدر الذاكرة، ويجمع الطلبات بـالدفعات المستمرة (continuous batching) فيخدم عشرات المستخدمين على نفس البطاقة بإنتاجية أعلى بعدة أضعاف من التشغيل طلباً بطلب، ويقدّم واجهة متوافقة مع OpenAI مباشرة. أما Ollama فهو الخيار الأصح لفريق صغير من 3 إلى 15 شخصاً، أو حين لا يوجد GPU أصلاً، لأنه يشغّل نماذج مضغوطة بصيغة GGUF على المعالج بسهولة، بأمر واحد، وبذاكرة أقل. القاعدة المختصرة: Ollama للتجربة والفرق الصغيرة وسيرفرات CPU، وvLLM حين يصير النموذج خدمة يعتمد عليها منتج أو مئات المستخدمين.
الفرق بين أداة تجريبية وخادم استدلال
الاثنان يشغّلان نموذجاً لغوياً ويعطيانك واجهة HTTP، لكن الهدف مختلف. Ollama صُمّم لتجربة مطوّر واحد: تنزّل النموذج بـollama pull، وتشغّله، ويحمّل ويفرّغ النماذج من الذاكرة حسب الطلب. هذا ممتاز على جهاز مطوّر أو سيرفر داخلي لفريق، لكنه لم يُبنَ ليخدم مئات الطلبات المتزامنة بكفاءة.
vLLM بالعكس، يفترض أن النموذج سيبقى محمّلاً على GPU طوال الوقت، وأن هدفه الوحيد أن يخرج أكبر عدد ممكن من الـtokens في الثانية لأكبر عدد من المستخدمين. لهذا يحجز من البداية نسبة من ذاكرة البطاقة (افتراضياً 90%) ويديرها بنفسه.
| المعيار | Ollama | vLLM |
|---|---|---|
| العتاد المثالي | CPU أو GPU واحد | GPU واحد أو أكثر (NVIDIA غالباً) |
| صيغة النماذج | GGUF مضغوطة (Q4، Q8) | أوزان Hugging Face، وAWQ وGPTQ وFP8 |
| التزامن | بضعة طلبات متوازية ثم طابور | عشرات إلى مئات الطلبات بالدفعات المستمرة |
| واجهة OpenAI | متوفرة على /v1 | متوفرة على /v1 وهي الواجهة الأساسية |
| سهولة البدء | دقائق | من نصف ساعة إلى ساعة مع التعريفات وCUDA |
| أنسب استخدام | فريق داخلي، نماذج أولية، سيرفر CPU | منتج حي، API لعملاء، حمل متواصل |
PagedAttention والدفعات المستمرة بلغة بسيطة
مشكلة الذاكرة
عند توليد النص، يحتفظ النموذج لكل محادثة بذاكرة اسمها KV cache تنمو مع كل token. الخوادم التقليدية تحجز لكل طلب مساحة تكفي أطول رد ممكن، فلو كان الحد 4,096 token والرد الفعلي 300 فقط، ضاع أغلب المحجوز. ورقة vLLM البحثية قاست أن هذا الأسلوب يهدر في أنظمة سابقة من 60% إلى 80% من ذاكرة الـKV cache.
PagedAttention يستعير فكرة الذاكرة الافتراضية في أنظمة التشغيل: يقسّم الذاكرة إلى صفحات صغيرة بحجم ثابت ويعطي كل طلب صفحات حسب حاجته الفعلية لحظة بلحظة، فينخفض الهدر لأقل من 4%. النتيجة المباشرة أن نفس البطاقة تتسع لعدد أكبر بكثير من المحادثات في نفس الوقت.
الدفعات المستمرة
الأسلوب القديم يجمع 8 طلبات في دفعة وينتظر حتى ينتهي أطولها قبل أن يقبل طلباً جديداً، فيبقى المستخدم التاسع ينتظر حتى لو انتهت سبعة ردود. vLLM يدخل الطلبات الجديدة ويخرج المنتهية في كل خطوة توليد، فلا تقف البطاقة فارغة. الورقة الأصلية سجّلت إنتاجية أعلى حتى 24 ضعفاً مقارنة بالتشغيل عبر مكتبة Transformers المعتادة، والفرق العملي في بيئات الإنتاج غالباً بين 2 و4 أضعاف مقارنة بالخوادم الأبسط.
تشغيل vLLM بواجهة متوافقة مع OpenAI
التشغيل الأساسي أمر واحد بعد تثبيت تعريفات NVIDIA وCUDA:
pip install vllm
vllm serve Qwen/Qwen2.5-7B-Instruct \
--host 127.0.0.1 --port 8000 \
--gpu-memory-utilization 0.90 \
--max-model-len 8192 \
--max-num-seqs 64 \
--api-key "$VLLM_API_KEY"
أهم الخيارات: --max-model-len يحدد أطول سياق، وتقليله يرفع عدد المستخدمين المتزامنين لأن كل محادثة تحتاج ذاكرة أقل. --max-num-seqs يضع سقفاً للطلبات في الدفعة الواحدة، أما إن كان عندك أكثر من بطاقة فـ--tensor-parallel-size 2 يوزّع النموذج عليهما.
بعدها أي تطبيق مكتوب لواجهة OpenAI يعمل بتغيير العنوان فقط:
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="...")
r = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[{"role": "user", "content": "لخّص هذا العقد في 5 نقاط"}],
)
لا تعرض المنفذ 8000 للإنترنت مباشرة. ضع Nginx أمامه مع TLS وحد للطلبات، ويُعرض مقياس الأداء على /metrics بصيغة Prometheus لمتابعة طول الطابور وزمن أول token.
متطلبات الذاكرة لكل حجم نموذج
القاعدة التقريبية: كل مليار معامل يحتاج 2GB بدقة FP16، ونحو 0.5 إلى 0.6GB بضغط 4-bit، ثم تضيف فوق ذلك مساحة للـKV cache تحدد عدد المستخدمين المتزامنين.
| حجم النموذج | FP16 (أوزان فقط) | 4-bit AWQ/GPTQ | بطاقة مناسبة لـvLLM |
|---|---|---|---|
| 3B | نحو 6GB | نحو 2GB | 16GB تكفي مع هامش كبير |
| 7B إلى 8B | من 14 إلى 16GB | من 4 إلى 5GB | 24GB لـFP16، و16GB للمضغوط |
| 14B | نحو 28GB | نحو 9GB | 48GB لـFP16، و24GB للمضغوط |
| 32B | نحو 64GB | نحو 18 إلى 20GB | 80GB، أو بطاقتان 48GB |
| 70B | نحو 140GB | نحو 40GB | بطاقتان 80GB لـFP16، أو 48GB واحدة للمضغوط بسياق قصير |
مثال عملي: نموذج 8B بدقة FP16 على بطاقة 24GB، يأخذ 16GB للأوزان، ويبقى نحو 5GB للـKV cache بعد حجز 90%. بسياق 8,192 token هذا يكفي قرابة 10 إلى 15 محادثة طويلة في نفس اللحظة، أو أكثر بكثير إن كانت الرسائل قصيرة.
قائمة فحص قبل وضع vLLM على الإنتاج
تشغيل الأمر شيء، وتشغيل خدمة يعتمد عليها عملاؤك شيء آخر. هذه النقاط تفصل بين التجربة والإنتاج:
- شغّله كخدمة systemd بإعادة تشغيل تلقائية، لأن نفاد ذاكرة البطاقة مع طلب طويل غير متوقع قد يوقف العملية.
- ثبّت إصدار النموذج والمكتبة برقم محدد، فتحديث vLLM أو تغيّر أوزان النموذج على Hugging Face قد يغيّر سلوك الإجابات دون أن تنتبه.
- راقب ثلاثة أرقام: زمن أول token (الهدف أقل من ثانية للمحادثة)، وعدد الطلبات في الطابور، ونسبة استخدام الـKV cache، فإن تجاوزت 90% باستمرار فأنت بحاجة لسياق أقصر أو بطاقة إضافية.
- ضع حداً لطول الطلب والرد على مستوى التطبيق، حتى لا يحجز مستخدم واحد ذاكرة عشرة.
- اختبر الحمل قبل الإطلاق بأداة تحاكي 20 أو 50 مستخدماً متزامناً، وسجّل الإنتاجية بالـtokens في الثانية لتعرف سقفك الحقيقي.
هذه القائمة تأخذ يوم عمل واحداً، لكنها تحوّل أول عطل من مفاجأة في منتصف الليل إلى تنبيه تتعامل معه قبل أن يلاحظه أحد.
متى يكفي Ollama على سيرفر CPU
ليس كل فريق يحتاج GPU. إن كان الاستخدام داخلياً، مثل تلخيص مستندات أو مساعد للفريق القانوني أو تصنيف تذاكر، وعدد المستخدمين أقل من 15 ونادراً ما يسألون في نفس الثانية، فـOllama على سيرفر CPU يؤدي المهمة بكلفة ثابتة ومعروفة. الأرقام التقريبية على معالجات سيرفرات حديثة:
- نموذج 3B مضغوط Q4 على 4 vCPU و8GB: من 10 إلى 20 token في الثانية، كافٍ للتصنيف والتلخيص القصير.
- نموذج 7B إلى 8B مضغوط Q4 على 8 vCPU و16GB: من 4 إلى 8 tokens في الثانية، مقبول للمحادثة الداخلية.
- نماذج 14B وما فوق على CPU: بطيئة لأي استخدام تفاعلي، اجعلها للمهام الليلية في الخلفية.
باقة مؤسسة على الخادم السحابي بـ8 vCPU و16GB بـ18,000 ريال سنوياً تشغّل نموذج 8B مضغوطاً لفريق داخلي، وكل 2GB ذاكرة إضافية بـ600 ريال سنوياً، كما تأتي استضافة الذكاء الاصطناعي من كلاود بقالب Open WebUI مع Ollama مثبتاً مسبقاً بلا رسوم إضافية، فتبدأ بالتجربة الفعلية خلال دقائق، وبياناتك تبقى على سيرفر في الرياض بدل أن تُرسل لمزود خارجي.
اضبط Ollama للتزامن البسيط بمتغيرات البيئة:
OLLAMA_NUM_PARALLEL=4
OLLAMA_MAX_LOADED_MODELS=1
OLLAMA_KEEP_ALIVE=24h
الأخير يبقي النموذج محمّلاً فلا ينتظر أول مستخدم في الصباح 20 ثانية لتحميله.
كيف تقرر
- احسب ذروة التزامن الحقيقية: كم طلباً في نفس الثانية، لا كم مستخدماً مسجلاً. 50 موظفاً غالباً يعني من 2 إلى 5 طلبات متزامنة فقط.
- إن كانت الذروة أقل من 5 وزمن رد من 10 إلى 30 ثانية مقبولاً، ابدأ بـOllama على CPU وقِس.
- إن تجاوز طابور الانتظار 10 ثوانٍ باستمرار، أو صار النموذج جزءاً من منتج يستخدمه عملاؤك، انتقل لـvLLM على GPU.
- اكتب التطبيق من البداية لواجهة OpenAI، فيصير الانتقال من Ollama إلى vLLM تغيير عنوان واحد في ملف الإعدادات.
للاطلاع على الحجم المناسب وكلفة الموارد الإضافية راجع الأسعار والباقات.


