لماذا تستضيف LocalAI ذاتيًا على خادم VPS
حيث يركّز Ollama على النص، يستهدف LocalAI توافقًا واسعًا مع واجهة OpenAI API: فهو يكشف /v1/chat/completions و/v1/embeddings و/v1/images/generations وحتى نسخ الصوت، على واجهة واحدة. بالنسبة إلى فريق لديه بالفعل شيفرة مكتوبة مقابل OpenAI SDK، يُعدّ LocalAI بديلاً شبه شفاف: تغيّر عنوان URL الأساسي والمفتاح، والباقي يعمل. على خادم VPS، تحصل على هذا التنوّع دون اعتماد خارجي أو تكلفة لكل استدعاء. وهذا وثيق الصلة بشكل خاص عندما تحتاج في آنٍ واحد إلى توليد النصوص، والمتجهات لأغراض RAG، وأحيانًا الصور، دون تكثير المزوّدين والمفاتيح.
الفوائد الملموسة لاستضافة LocalAI ذاتيًا
- بديل مباشر لواجهة OpenAI API: لا إعادة كتابة لشيفرة العميل.
- واجهة واحدة للمحادثة والتضمينات والصور والصوت.
- دعم واجهات خلفية متعدّدة (llama.cpp وdiffusers وwhisper) ضمن واجهة موحّدة.
- صيغ نماذج مفتوحة (GGUF) قابلة للتنزيل والتبادل.
- لا فاتورة حسب الاستخدام: تكلفة VPS ثابتة لجميع أنواع التوليد.
- بيانات ومخرجات محفوظة بالكامل على خادمك.
المتطلبات العتادية والبرمجية
بما أن LocalAI متعدّد الاستخدامات، فإن احتياجاته تعتمد على الوظائف المُفعَّلة. الأرقام أدناه هي حدود دنيا مقيسة — خادم VPS أقوى يقلل أوقات الاستجابة دون أن يغير الجدوى.
نص فقط، CPU، نموذج 7B (مثل Mistral-7B-GGUF): 8 GB من RAM، 4 vCPU، 30 GB من القرص. بهذا الحجم، يستغرق استدعاء /v1/chat/completions من 5 إلى 15 ثانية حسب التكميم (Q4 هو التوازن المعياري). يناسب نموذج 3B ذاكرة بسعة 4 GB.
نص + صور (7B + Stable Diffusion): 16 GB من RAM، يُوصى بـGPU، 50 GB من القرص. بدون GPU، يستغرق توليد صورة واحدة عدة دقائق على CPU — فضّل خادم VPS بـGPU للاستخدام المنتظم وخيار SINGLE_ACTIVE_BACKEND=true لتفادي التشبع عند مزج المحادثة والصور على نفس المضيف بـCPU.
البرمجيات المطلوبة: Docker 24+ وDocker Compose v2 (docker compose بدون شرطة)، نطاق فرعي مخصص (مثل ia.your-domain.com)، المنفذ 443 مفتوح، سجل DNS يشير إلى عنوان IP الخادم.
نشر LocalAI باستخدام Docker Compose وHTTPS
إعداد هيكل المجلدات
عبر SSH:
mkdir -p /opt/localai/{models,config} && cd /opt/localai. سيستقبل مجلد models ملفات GGUF؛ أما config فسيستقبل ملفات YAML التي تصف كل نموذج لـLocalAI.إنشاء ملف docker-compose.yaml
أنشئ
/opt/localai/docker-compose.yaml بالمحتوى التالي:services: localai: image: localai/localai:latest-cpu restart: unless-stopped ports: - "127.0.0.1:8080:8080" volumes: - ./models:/build/models - ./config:/build/models environment: - MODELS_PATH=/build/models - SINGLE_ACTIVE_BACKEND=true - API_KEY=your-secret-key healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/readyz"] interval: 30s retries: 3استبدل
latest-cpu بـlatest-gpu-nvidia-cuda-12 إذا كان خادم VPS لديك يحتوي على GPU NVIDIA. تُفعّل API_KEY حماية الرمز على جميع نقاط النهاية — بدون هذا المتغير، تكون الـAPI متاحة بدون مصادقة.تشغيل الحاوية
شغّل
docker compose up -d، ثم تابع سجلات الإقلاع: docker compose logs -f localai. انتظر الرسالة LocalAI API is listening on [::]:8080 قبل المتابعة.تنزيل أول نموذج عبر المعرض
يضم معرض LocalAI أكثر من 200 نموذج مُهيّأ مسبقًا. لتثبيت Mistral-7B-Instruct مكمَّمًا بـQ4:
curl http://127.0.0.1:8080/models/apply \ -H 'Authorization: Bearer your-secret-key' \ -d '{"id": "huggingface@thebloke__mistral-7b-instruct-v0.2-gguf/mistral-7b-instruct-v0.2.Q4_K_M.gguf"}'تابع التقدم:
curl http://127.0.0.1:8080/models/jobs/<job-id>. يُنزَّل GGUF في ./models/ ويُنشأ ملف YAML الخاص به تلقائيًا في ./config/.إضافة نموذج تضمينات
لـRAG، ثبّت
all-MiniLM-L6-v2 (84 MB، 256 MB من RAM):# config/all-minilm.yaml name: all-minilm backend: bert-embeddings parameters: model: all-MiniLM-L6-v2.ggufنزّل GGUF يدويًا في
./models/ من HuggingFace، ثم أعد التشغيل: docker compose restart localai. تحقق بـcurl http://127.0.0.1:8080/v1/models.تفعيل Whisper لنسخ الصوت
أضف
config/whisper.yaml:name: whisper-1 backend: whisper parameters: model: whisper-base.enيُنزَّل نموذج whisper-base (~142 MB) تلقائيًا عند أول استدعاء. اختبر بـ:
curl http://127.0.0.1:8080/v1/audio/transcriptions \ -H 'Authorization: Bearer your-secret-key' \ -F [email protected] -F model=whisper-1تهيئة الوكيل العكسي Nginx وSSL
أنشئ
/etc/nginx/sites-available/localai:server { listen 443 ssl; server_name ia.your-domain.com; ssl_certificate /etc/letsencrypt/live/ia.your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ia.your-domain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:8080; proxy_read_timeout 300s; proxy_send_timeout 300s; } }aحصل على الشهادة بـ
certbot certonly --nginx -d ia.your-domain.com، ثم nginx -s reload. المهلة العالية ضرورية للاستنتاجات الطويلة على CPU.اختبار الـAPI عبر HTTPS
تحقق من النشر الكامل:
curl https://ia.your-domain.com/v1/chat/completions \ -H 'Authorization: Bearer your-secret-key' \ -H 'Content-Type: application/json' \ -d '{"model": "mistral-7b-instruct-v0.2.Q4_K_M", "messages": [{"role": "user", "content": "Hello"}]}'استجابة JSON تحتوي على حقل
choices تؤكد أن النشر يعمل بشكل صحيح.
فعّل فقط الواجهات الخلفية التي تحتاجها. تحميل نموذج محادثة ونموذج تضمين وStable Diffusion في آنٍ واحد على خادم VPS يعمل بالمعالج يُشبع ذاكرة RAM ويُنهار الأداء. عيّن SINGLE_ACTIVE_BACKEND=true للإبقاء على واجهة خلفية واحدة مقيمة في كل مرة، واحجز توليد الصور لخادم VPS مزوّد بوحدة معالجة رسومات إذا أصبح استخدامًا منتظمًا.
اختيار النماذج وتحميلها
يدعم LocalAI صيغًا عدة، لكن صيغة GGUF (التي ينتجها llama.cpp) هي المعيار الموصى به لـCPU: إنها مكمَّمة (تقلل استخدام RAM)، ومحمولة، ومدعومة جيدًا من قِبل المعرض.
GGUF مقابل صيغ أخرى: صيغ GGUF هي الوحيدة القابلة للتحميل مباشرةً عبر llama.cpp دون تحويل مسبق. نماذج Diffusers (الصور) وONNX (التضمينات الخفيفة) لها واجهاتها الخلفية الخاصة وليست قابلة للتبادل مع GGUF.
المعرض مقابل التنزيل اليدوي: المعرض هو الخيار الأبسط — فهو ينزّل GGUF ويولّد YAML الإعداد تلقائيًا. بالنسبة لنموذج غير مدرج في المعرض (نموذج مضبوط الدقة، أو GGUF مخصص)، ضع الملف في ./models/ وأنشئ YAML يدويًا:
name: my-model
backend: llama
parameters:
model: my-model.Q4_K_M.gguf
context_size: 4096سرد النماذج المحمّلة:
curl https://ia.your-domain.com/v1/models \
-H 'Authorization: Bearer your-secret-key'تظهر في القائمة النماذج التي يوجد لها YAML في ./config/، حتى لو لم يُنزَّل GGUF بعد — في هذه الحالة يُطلق الاستدعاء الأول التنزيل.
توصيل تطبيقاتك بـLocalAI
بما أن LocalAI متوافق مع OpenAI API، فإن ترحيل تطبيق قائم يتلخص في تغييرين: عنوان URL الأساسي والمفتاح.
Python (openai SDK):
import openai
client = openai.OpenAI(
base_url="https://ia.your-domain.com/v1",
api_key="your-secret-key"
)
response = client.chat.completions.create(
model="mistral-7b-instruct-v0.2.Q4_K_M",
messages=[{"role": "user", "content": "Summarize this text: ..."}]
)
print(response.choices[0].message.content)Node.js (openai SDK):
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://ia.your-domain.com/v1',
apiKey: 'your-secret-key'
});
const completion = await client.chat.completions.create({
model: 'mistral-7b-instruct-v0.2.Q4_K_M',
messages: [{ role: 'user', content: 'Hello' }]
});
console.log(completion.choices[0].message.content);curl مباشر:
curl https://ia.your-domain.com/v1/embeddings \
-H 'Authorization: Bearer your-secret-key' \
-H 'Content-Type: application/json' \
-d '{"model": "all-minilm", "input": "Text to vectorize"}'تقبل مكتبات LangChain وLlamaIndex ومعظم أطر RAG معاملًا openai_api_base أو base_url — التغيير مطابق.
حل المشكلات: الأخطاء الشائعة
404 model not found أو model not loaded: اسم النموذج الممرَّر في model: لا يطابق أي ملف YAML في ./config/. تحقق بـGET /v1/models: الاسم المعروض يجب استخدامه كما هو بالضبط. إذا لم يظهر النموذج، تحقق من وجود YAML في المجلد المثبَّت وأعد تشغيل الحاوية.
استنتاج بطيء جدًا أو killed (OOM): النموذج يتجاوز RAM المتاحة. يتطلب نموذج 7B Q4 تقريبًا 6 GB من RAM الحرة وقت التحميل. تحقق بـdocker stats localai خلال استنتاج. الحلول: الانتقال إلى تكميم أخف (Q3_K_S أو Q2_K)، تقليل context_size في YAML، أو ترقية خادم VPS.
SINGLE_ACTIVE_BACKEND error: LocalAI مُهيَّأ بـSINGLE_ACTIVE_BACKEND=true وطلب يحاول تحميل نموذج ثانٍ بينما الأول نشط. هذا هو السلوك المتوقع على CPU. انتظر انتهاء الاستنتاج الأول، أو عطّل الخيار إذا كان خادم VPS لديك يمتلك RAM كافية لنماذج متعددة في آنٍ واحد.
GPU غير مكتشف (CUDA device not found): تحقق من استخدام صورة latest-gpu-nvidia-cuda-12، ومن تثبيت برنامج تشغيل NVIDIA على المضيف (nvidia-smi)، ومن حصول الحاوية على وصول GPU (gpus: all في docker-compose.yaml تحت مفتاح deploy:). بدون هذه الشروط الثلاثة، يعود LocalAI بصمت إلى CPU.
401 Unauthorized: المتغير API_KEY مُعيَّن في docker-compose.yaml لكن ترويسة Authorization: Bearer <key> غائبة أو خاطئة في الاستدعاء. تتطلب جميع نقاط النهاية، بما فيها /v1/models، الترويسة فور تعيين API_KEY.
LocalAI مقابل Ollama مقابل vLLM: أيّ خادم LLM تختار؟
مرّر الجدول أفقيًا
| LocalAI | Ollama | vLLM | |
|---|---|---|---|
| يتطلّب GPU | لا (CPU افتراضيًا) | لا (CPU افتراضيًا) | نعم (GPU إلزامي) |
| واجهة API متوافقة مع OpenAI | نعم (كاملة) | نعم (جزئيًا) | نعم (كاملة) |
| توليد الصور | نعم (Stable Diffusion) | لا | لا |
| نسخ الصوت | نعم (Whisper) | لا | لا |
| تضمينات أصلية | نعم | نعم | نعم |
| مكتبة النماذج | أكثر من 200 نموذج GGUF | قائمة نماذج منتقاة | نماذج HuggingFace |
| معدل الإنتاج (رمز/ث، 7B) | ~10-20 CPU / ~80+ GPU | ~15-25 CPU / ~80+ GPU | ~150+ GPU فقط |
| RAM (نموذج 7B Q4) | ~6 GB | ~6 GB | ~14 GB (FP16) |
| حالة الاستخدام الرئيسية | API موحدة متعددة الوسائط | استنتاج نص بسيط | إنتاج عالي الأداء |