- سحب
vllm/vllm-openai:latestوشغّله باستخدام--runtime nvidia --gpus all --ipc=hostللحصول على خادم استنتاج متوافق مع واجهة برمجة تطبيقات OpenAI ومدعوم ببطاقة رسوميات. - ربط مجلد
~/.cache/huggingfaceداخل الحاوية بحيث تبقى أوزان النموذج سليمة بعد إعادة تشغيل الحاوية. - يعرض الخادم واجهة برمجة تطبيقات متوافقة مع OpenAI على المنفذ 8000؛ يمكنك اختباره باستخدام الأمر
curl http://localhost:8000/v1/models. - أهم ثلاثة إعدادات ضبط هي
--tensor-parallel-size,--max-model-len، و--gpu-memory-utilization.
تنشر vLLM صورة رسمية جاهزة للحاويات (Docker image)، vllm/vllm-openaiالتي تتضمن خادم استنتاج جاهز للتشغيل ومتوافق مع واجهة برمجة تطبيقات OpenAI. وأسرع طريقة لذلك هي: تثبيت أداة حاويات NVIDIA على الجهاز المضيف، ثم تشغيل الصورة باستخدام --gpus all ومعرف النموذج على منصة Hugging Face. وبمجرد تنزيل النموذج، يصبح الخادم جاهزًا للعمل على المنفذ 8000، ويقبل نفس الطلبات التي تقبلها واجهة برمجة تطبيقات OpenAI.
المتطلبات الأساسية
- محرّك Docker الإصدار 20.10 أو أحدث — يعمل Docker Desktop على أنظمة Windows وmacOS عبر واجهة WSL2 الخلفية.
- وحدة معالجة رسوميات NVIDIA مع برنامج تشغيل يدعم CUDA 12.x. نفّذ الأمر التالي للتحقق:
nvidia-smiلعرض الإصدار الأقصى من CUDA الذي يدعمه برنامج التشغيل لديك، كما هو مذكور في حقل «إصدار CUDA». - أداة حاويات NVIDIA — الجسر الذي يسمح لـ Docker برؤية وحدة معالجة الرسومات (GPU). راجع القسم التالي لمزيد من التفاصيل.
- ما يكفي من ذاكرة VRAM لتشغيل النموذج المستهدف. استخدم حاسبة الذاكرة VRAM الأداة المُخصصة لذلك للتحقق قبل تنزيل النموذج.
تثبيت أداة حاويات NVIDIA
تجاهل هذا القسم إذا كان الأمر التالي docker run --gpus all nvidia/cuda:12.0-base nvidia-smi يعمل بالفعل على جهازك.
لينكس (Ubuntu/Debian):
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey |
sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list |
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' |
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart dockerRHEL/CentOS: استبدل deb بـ URL المستودع الخاص بـ rpm المقابل من وثائق NVIDIA واستخدم الأمر dnf بدلاً من apt-get.
ويندوز (WSL2): ثبّت برنامج تشغيل NVIDIA الخاص بنظام Windows على الجهاز المضيف — ولا حاجة لتثبيت أداة أدوات الحاويات (Container Toolkit) بشكل منفصل داخل بيئة WSL2. ويقوم Docker Desktop تلقائيًا بإدارة عملية تمرير وحدة معالجة الرسومات (GPU passthrough).
نظام التشغيل macOS: لا تدعم وحدات معالجة الرسومات من شركة NVIDIA نظام macOS. ولا يمكن تشغيل vLLM على معالجات Apple Silicon عبر Docker باستخدام تسريع وحدة معالجة الرسومات (GPU acceleration). وللاستنتاج المحلي على أجهزة Apple، يمكنك النظر في إنشاء نسخة تعمل على وحدة المعالجة المركزية فقط (CPU-only build)، أو استخدام بيئة تشغيل مختلفة.
أدنى أمر تشغيل مطلوب
docker run --runtime nvidia --gpus all
--ipc=host
-v ~/.cache/huggingface:/root/.cache/huggingface
-p 8000:8000
vllm/vllm-openai:latest
--model meta-llama/Meta-Llama-3-8B-Instruct| علامة | لماذا يهم هذا |
|---|---|
--runtime nvidia | يوجّه استدعاءات وحدة معالجة الرسومات عبر محرك تشغيل الحاويات الخاص بشركة NVIDIA. |
--gpus all | يعرّض جميع وحدات معالجة الرسومات المتاحة على الجهاز المضيف. ويمكنك استخدام "device=0,1" لتحديد وحدات معالجة الرسومات المُراد استخدامها تحديدًا. |
--ipc=host | يشترك في مساحة أسماء الاتصال بين العمليات (IPC namespace) الخاصة بالجهاز المضيف. وهذا شرطٌ ضروري لدعم الذاكرة المشتركة في إطار PyTorch؛ وإهمال هذا الخيار يؤدي إلى حدوث خطأ من نوع «Bus error» Bus error أو تعطل ناتج عن مشكلة في الذاكرة المشتركة. |
-v ~/.cache/huggingface:… | يُثبّت ذاكرة التخزين المؤقت لـ Hugging Face الموجودة على الجهاز المضيف، مما يضمن بقاء أوزان النموذج بعد إعادة تشغيل الحاوية. |
-p 8000:8000 | يعرّض خادم واجهة برمجة التطبيقات المتوافق مع OpenAI على الجهاز المضيف. |
--model | أي معرف نموذج من Hugging Face أو مسار محلي تم تثبيته داخل الحاوية. |
لتنزيل نموذج مقيد الوصول (مثل Llama 3 أو Mistral وما إلى ذلك)، يجب أيضًا تمرير المعلمة التالية: -e HUGGING_FACE_HUB_TOKEN=hf_yourtoken. ويوصى بتخزين الرمز المميز (Token) في ملف .env وتمريره باستخدام الخيار --env-file .env بدلًا من كتابته مباشرةً في سجل الأوامر (shell history).
تثبيت ذاكرة التخزين المؤقت لـ Hugging Face
يقوم vLLM بتنزيل أوزان النموذج إلى المسار /root/.cache/huggingface داخل الحاوية. وبغياب تثبيت مجلد (volume mount)، فإن كل أمر docker run سيؤدي إلى إعادة تنزيل النموذج بالكامل — والذي قد يتراوح حجمه عادةً بين 5 و80 غيغابايت. وسطر التثبيت المطلوب هو:
-v ~/.cache/huggingface:/root/.cache/huggingfaceإذا كانت نماذجك مخزنة في موقع غير افتراضي، فعيّن المتغير البيئي -e HF_HOME=/your/path وافتح تلك المسار بدلًا من ذلك. ولبيئات الانفصال التام عن الشبكة (air-gapped)، قم أولاً بتنزيل النموذج باستخدام huggingface-cli download ثم مرر المعلمة --model /path/in/container مع ربط مجلد أوزان النموذج كـ volume.
أبرز إعدادات خادم vLLM
تُمرَّر هذه العلمات بعد اسم الصورة — فهي وسائط تُرسل إلى عملية خادم vLLM، وليست إلى Docker.
| علامة | افتراضي | متى يجب تغييرها؟ |
|---|---|---|
--tensor-parallel-size N | 1 | عيّن القيمة إلى عدد وحدات معالجة الرسومات (GPUs) المستخدمة في الخدمة متعددة وحدات المعالجة. ويجب أن يكون عدد رؤوس الانتباه (attention heads) في النموذج قابلاً للقسمة على N. واجمعها مع المعلمة --gpus "device=0,1,..." مع سرد عددٍ دقيقٍ من الأجهزة يساوي N. |
--gpu-memory-utilization 0.X | 0.90 | قلل القيمة إلى 0.75–0.80 إذا ظهرت أخطاء استنفاد الذاكرة (OOM) أو كنت تشارك وحدة معالجة الرسومات مع عمليات أخرى. |
--max-model-len N | تكوين النموذج | تحدد الحد الأقصى لحجم ذاكرة التخزين المؤقت KV. وهي مفيدة عندما يؤدي السياق الافتراضي للنموذج (مثل 128 ألف رمز) إلى استنزاف ذاكرة VRAM. جرّب أولًا استخدام --max-model-len 8192 كأول تخفيض. |
--dtype auto | تلقائي | استبدلها يدويًّا بـ bfloat16 أو float16 إذا اختار الكشف التلقائي دقة غير متوقعة. |
--quantization awq / gptq | none | فعِّل هذه المعلمة عند استخدام إصدارات نماذج مُكمَّنة مسبقًا. وتقلل تقريبًا من استهلاك ذاكرة VRAM إلى النصف، مع بعض التأثير على الجودة. |
--port | 8000 | غيّر المنفذ إذا كان المنفذ 8000 مستخدمًا بالفعل على الجهاز المضيف. |
غير متأكد مما إذا كانت وحدة معالجة الرسومات لديك تحتوي على ما يكفي من ذاكرة VRAM لتشغيل نموذج معين؟ إن قائمة دليل متطلبات الذاكرة VRAM النماذج الشائعة حاسبة الذاكرة VRAM تتيح لك إدخال نوع التكمين وحجم الدفعة (batch size). أما بالنسبة لقرارات شراء الأجهزة، فراجع دليل التوصيات الخاصة بوحدات معالجة الرسومات (GPU).
إتاحة نقطة النهاية المتوافقة مع واجهة برمجة تطبيقات OpenAI واختبارها
وبمجرد أن تطبع الحاوية الرسالة INFO: Application startup completeيصبح واجهة برمجة التطبيقات (API) جاهزة للعمل.
# سرد النماذج المحملة
curl http://localhost:8000/v1/models
# إكمال النص
curl http://localhost:8000/v1/completions
-H "Content-Type: application/json"
-d '{"model": "meta-llama/Meta-Llama-3-8B-Instruct", "prompt": "عاصمة فرنسا هي", "max_tokens": 20}'
# إكمال المحادثة
curl http://localhost:8000/v1/chat/completions
-H "Content-Type: application/json"
-d '{"model": "meta-llama/Meta-Llama-3-8B-Instruct", "messages": [{"role": "user", "content": "مرحبًا"}]}'يمكن لأي عميل متوافق مع OpenAI — مثل مكتبة Python openai SDK، أو LangChain، أو LlamaIndex — العمل عبر تعيين base_url="http://localhost:8000/v1" وتوفير أي سلسلة نصية غير فارغة كقيمة لـ api_key.
مثال على ملف Docker Compose
لنشر دائم، فإن ملف Compose أسهل في الإدارة من أمر طويل من docker run command:
services:
vllm:
image: vllm/vllm-openai:latest
runtime: nvidia
environment:
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN}
volumes:
- ~/.cache/huggingface:/root/.cache/huggingface
ports:
- "8000:8000"
ipc: host
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
command: >
--model meta-llama/Meta-Llama-3-8B-Instruct
--gpu-memory-utilization 0.90
--max-model-len 8192ابدأ بـ docker compose up -d. وكتلة deploy.resources في ملف Compose تعادل ما تحققه المعلمة --gpus all.
الأخطاء الشائعة والحلول المُقترحة لها
| خطأ | السبب | إصلاح |
|---|---|---|
| Bus error أو /dev/shm صغيرة جدًا | القيمة الافتراضية لـ /dev/shm في Docker هي 64 ميغابايت — وهي صغيرة جدًا لبرنامج PyTorch. | أضف المعلمة --ipc=host --ipc=host --shm-size=8g إذا لم تتمكن من مشاركة مساحة أسماء IPC الخاصة بالمضيف. |
| خطأ CUDA: لا توجد صورة نواة متاحة | نسخة CUDA المدمجة في صورة vLLM تتجاوز الإصدار الذي يدعمه برنامج التشغيل الخاص بك. | تشغيل nvidia-smi استخدم الأمر لتحديد أقصى إصدار من CUDA المدعوم، ثم ثبّت إصدار الصورة المقابل (مثلًا، vllm/vllm-openai:v0.5.5). |
| torch.cuda.OutOfMemoryError | تتجاوز أوزان النموذج بالإضافة إلى ذاكرة التخزين المؤقت KV الذاكرة العشوائية المتوفرة (VRAM). | جرّب --max-model-len 4096 أولاً. ثم خفّضها --gpu-memory-utilization إلى 0.80. وإذا استمر حدوث خطأ نفاد الذاكرة (OOM)، فاستخدم نسخة مُكمَّنة من النموذج أو وحدة معالجة رسوميات أكبر. |
| ممنوع الوصول إلى دليل التخزين المؤقت (cache directory) | يتم تشغيل الحاوية بصلاحيات المستخدم الجذر (root)، بينما يملك مستخدم آخر الدليل المقابل على الجهاز المضيف. | تشغيل نفّذ الأمر `chmod -R a+rw ~/.cache/huggingface` على الجهاز المضيف، أو استخدم مجلدًا اسمياً في Docker (named Docker volume) بدلًا من ربط المجلد (bind mount). |
تبدأ الحاوية بالتشغيل ولكنها curl تردّ برسالة «تم رفض الاتصال» (connection refused) | ما زال النموذج قيد التحميل، أو أن -p 8000:8000 النموذج غير موجود. | انتظر ظهور سطر السجل Application startup complete ثم تأكّد من وجود تعيين المنفذ (port mapping) في أمر التشغيل الخاص بك. |
الأسئلة الشائعة
أي علامة (tag) لصورة Docker الخاصة بـ vLLM يجب أن أستخدم؟
vllm/vllm-openai:latest العلامة `latest` تتبع أحدث إصدار متاح وهي مناسبة للتجارب. أما بالنسبة للبيئات الإنتاجية، فيجب تثبيت الإصدار على علامة محددة (مثل v0.6.0) لضمان قابلية إعادة إنشاء البناء. وتُشير كل علامة إصدار على Docker Hub إلى إصدار CUDA الذي تم تجميع الصورة عليه، والذي يجب أن يكون أقل من أو يساوي إصدار CUDA المدعوم بواسطة برنامج التشغيل الخاص بك.
هل يمكنني تشغيل vLLM داخل حاوية Docker دون استخدام وحدة معالجة رسوميات؟
الصورة القياسية تتطلب وحدة معالجة رسوميات من شركة NVIDIA. أما الاستنتاج على وحدة المعالجة المركزية فقط (CPU-only inference) فهو ممكن عبر بناء vLLM من الكود المصدري باستخدام المتغير VLLM_TARGET_DEVICE=cpuولكن الأداء سيكون أبطأ بمقدار رتبة كبيرة، ولا يُوصى به عمليًا لخدمة الاستعلامات. أما بالنسبة للاستنتاج المحلي على وحدة المعالجة المركزية فقط، فتُعد أدوات مثل `llama.cpp` أو `Ollama` بدائل أكثر ملاءمة — راجع دليل Ollama المقارنة المقدمة في الوثائق
كيف أُشغّل نموذجًا مقيدًا (gated model) يتطلب رمزًا من Hugging Face؟
مرر الرمز كمتغير بيئة: -e HUGGING_FACE_HUB_TOKEN=hf_yourtoken. واحفظه في ملف .env وأشر إليه باستخدام --env-file .env لتفادي تسريبه في سجل الأوامر (shell history). ويستخدم الخادم هذا الرمز أثناء التنزيل الأولي للنموذج، ولا يلزم وجوده بعد تخزين أوزان النموذج محليًا.
ما وظيفة الخيار `--tensor-parallel-size` ولماذا قد أحتاجه؟
يُقسِّم التوازي التنسوري (Tensor parallelism) مصفوفات أوزان النموذج عبر عدة وحدات معالجة رسوميات، مما يسمح بتشغيل نماذج أكبر من سعة وحدة معالجة رسوميات واحدة. عيّنه على عدد وحدات معالجة الرسوميات التي ترغب في استخدامها (غالبًا ٢ أو ٤). ويجب أن يتطابق هذا العدد مع عدد وحدات معالجة الرسوميات المُمرَّر إلى الخيار --gpusكما يجب أن يكون عدد رؤوس الانتباه (attention heads) في النموذج قابلاً للقسمة على هذا العدد.
هل يُعد تشغيل vLLM داخل حاوية Docker فعّالًا من حيث التكلفة مقارنةً بواجهة برمجة التطبيقات المُدارة (managed API)؟
يعتمد ذلك تمامًا على حجم طلباتك. فالاستضافة الذاتية تتضمّن تكاليف ثابتة مرتفعة (مثل تأجير جهاز يحتوي على وحدة معالجة رسوميات أو شراء الأجهزة)، لكن التكلفة الهامشية لكل طلب تكون قريبة من الصفر. أما واجهات برمجة التطبيقات المُدارة فلا تتضمّن تكاليف ثابتة، لكنها تفرض رسومًا عن كل رمز (token). واستخدم حاسبة المقارنة بين الاستضافة الذاتية وواجهة برمجة التطبيقات (API) حاسبة نقطة التعادل (break-even calculator)
كيف أقدّم خدمة نماذج متعددة في وقت واحد؟
شغّل حاوية واحدة لكل نموذج، مع تعيين كل منها إلى منفذ مختلف على الجهاز المضيف (مثل 8000 و8001). ولا يدعم vLLM حاليًا خدمة نماذج متعددة من عملية واحدة. ولتوجيه الطلبات حسب اسم النموذج إلى المنفذ الصحيح، ضع وكيل عكسـي (reverse proxy) مثل `nginx` أو `Caddy` أمام الحاويات.

