Pourquoi self-héberger LocalAI sur un VPS
Là où Ollama se concentre sur le texte, LocalAI vise la compatibilité large avec l'API OpenAI : il expose /v1/chat/completions, /v1/embeddings, /v1/images/generations et même la transcription audio, sur une seule API. Pour une équipe qui a déjà du code écrit contre le SDK OpenAI, LocalAI est un remplacement quasi transparent : vous changez l'URL de base et la clé, le reste fonctionne. Sur un VPS, vous obtenez cette polyvalence sans dépendance externe ni coût par appel. C'est particulièrement pertinent quand vous avez besoin à la fois de génération de texte, de vecteurs pour du RAG et, ponctuellement, d'images, sans multiplier les fournisseurs et les clés.
Les bénéfices concrets d'un LocalAI auto-hébergé
- Remplacement drop-in de l'API OpenAI : aucune réécriture du code client.
- Une seule API pour le chat, les embeddings, les images et l'audio.
- Support de multiples backends (llama.cpp, diffusers, whisper) sous une interface unifiée.
- Formats de modèles ouverts (GGUF) téléchargeables et interchangeables.
- Pas de facturation à l'usage : un coût VPS fixe pour tous les types de génération.
- Données et générations conservées intégralement sur votre serveur.
Prérequis matériels et logiciels
LocalAI étant polyvalent, ses besoins dépendent des fonctions activées. Les chiffres ci-dessous sont des minimums mesurés — un VPS plus généreux réduit les temps de réponse, il ne change pas la faisabilité.
Texte seul, CPU, modèle 7B (ex. Mistral-7B-GGUF) : 8 Go de RAM, 4 vCPU, 30 Go de disque. À ce gabarit, un appel /v1/chat/completions prend 5 à 15 secondes selon la quantization (Q4 est le compromis standard). Un modèle 3B tient dans 4 Go de RAM.
Texte + images (7B + Stable Diffusion) : 16 Go de RAM, GPU recommandé, 50 Go de disque. Sans GPU, la génération d'une image prend plusieurs minutes sur un CPU — préférez un VPS GPU pour un usage régulier et l'option SINGLE_ACTIVE_BACKEND=true pour éviter la saturation si vous mixez chat et images sur le même hôte CPU.
Logiciels requis : Docker 24+ et Docker Compose v2 (docker compose sans tiret), un sous-domaine dédié (ex. ia.votre-domaine.com), le port 443 ouvert, une entrée DNS pointant sur l'IP du VPS.
Déployer LocalAI avec Docker Compose et HTTPS
Préparer l'arborescence
En SSH :
mkdir -p /opt/localai/{models,config} && cd /opt/localai. Le dossiermodelsrecevra les fichiers GGUF ;configrecevra les manifests YAML qui décrivent chaque modèle à LocalAI.Créer le fichier docker-compose.yaml
Créez
/opt/localai/docker-compose.yamlavec le contenu suivant :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=votre-cle-secrete healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/readyz"] interval: 30s retries: 3Remplacez
latest-cpuparlatest-gpu-nvidia-cuda-12si votre VPS dispose d'un GPU NVIDIA.API_KEYactive la protection par jeton sur tous les endpoints — sans cette variable, l'API est accessible sans authentification.Démarrer le conteneur
Lancez
docker compose up -d, puis suivez les logs d'amorçage :docker compose logs -f localai. Attendez le messageLocalAI API is listening on [::]:8080avant de continuer.Télécharger un premier modèle via la galerie
La galerie LocalAI regroupe plus de 200 modèles pré-configurés. Pour installer Mistral-7B-Instruct quantifié Q4 :
curl http://127.0.0.1:8080/models/apply \ -H 'Authorization: Bearer votre-cle-secrete' \ -d '{"id": "huggingface@thebloke__mistral-7b-instruct-v0.2-gguf/mistral-7b-instruct-v0.2.Q4_K_M.gguf"}'Suivez la progression :
curl http://127.0.0.1:8080/models/jobs/<job-id>. Le GGUF est téléchargé dans./models/et son manifest YAML créé automatiquement dans./config/.Ajouter un modèle d'embeddings
Pour le RAG, installez
all-MiniLM-L6-v2(84 Mo, 256 Mo de RAM) :# config/all-minilm.yaml name: all-minilm backend: bert-embeddings parameters: model: all-MiniLM-L6-v2.ggufTéléchargez le GGUF manuellement dans
./models/depuis HuggingFace, puis redémarrez :docker compose restart localai. Vérifiez aveccurl http://127.0.0.1:8080/v1/models.Activer Whisper pour la transcription audio
Ajoutez
config/whisper.yaml:name: whisper-1 backend: whisper parameters: model: whisper-base.enLe modèle whisper-base (~142 Mo) est téléchargé automatiquement au premier appel. Testez avec :
curl http://127.0.0.1:8080/v1/audio/transcriptions \ -H 'Authorization: Bearer votre-cle-secrete' \ -F [email protected] -F model=whisper-1Configurer le reverse proxy Nginx et le SSL
Créez
/etc/nginx/sites-available/localai:server { listen 443 ssl; server_name ia.votre-domaine.com; ssl_certificate /etc/letsencrypt/live/ia.votre-domaine.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ia.votre-domaine.com/privkey.pem; location / { proxy_pass http://127.0.0.1:8080; proxy_read_timeout 300s; proxy_send_timeout 300s; } }Obtenez le certificat avec
certbot certonly --nginx -d ia.votre-domaine.com, puisnginx -s reload. Le timeout élevé est nécessaire pour les inférences longues sur CPU.Tester l'API via HTTPS
Validez le déploiement complet :
curl https://ia.votre-domaine.com/v1/chat/completions \ -H 'Authorization: Bearer votre-cle-secrete' \ -H 'Content-Type: application/json' \ -d '{"model": "mistral-7b-instruct-v0.2.Q4_K_M", "messages": [{"role": "user", "content": "Bonjour"}]}'Une réponse JSON avec un champ
choicesconfirme que le déploiement fonctionne correctement.
N'activez que les backends dont vous avez besoin. Charger simultanément un modèle de chat, un modèle d'embedding et Stable Diffusion sur un VPS CPU sature la RAM et effondre les performances. Définissez SINGLE_ACTIVE_BACKEND=true pour ne garder qu'un backend résident à la fois, et réservez la génération d'images à un VPS GPU si elle devient un usage régulier.
Choisir et charger ses modèles
LocalAI supporte plusieurs formats, mais le format GGUF (produit par llama.cpp) est le standard recommandé pour le CPU : il est quantifié (réduit la RAM utilisée), portable et bien supporté par la galerie.
GGUF vs autres formats : les formats GGUF sont les seuls directement chargeables via llama.cpp sans conversion préalable. Les modèles Diffusers (images) et ONNX (embeddings légers) ont leurs propres backends et ne sont pas interchangeables avec les GGUF.
Galerie vs téléchargement manuel : la galerie est l'option la plus simple — elle télécharge le GGUF et génère le YAML de configuration automatiquement. Pour un modèle non référencé (un modèle fine-tuné, un GGUF personnalisé), déposez le fichier dans ./models/ et créez le YAML manuellement :
name: mon-modele
backend: llama
parameters:
model: mon-modele.Q4_K_M.gguf
context_size: 4096Lister les modèles chargés :
curl https://ia.votre-domaine.com/v1/models \
-H 'Authorization: Bearer votre-cle-secrete'Les modèles dont le YAML est présent dans ./config/ apparaissent dans la liste, même si leur GGUF n'a pas encore été téléchargé — dans ce cas, le premier appel déclenche le téléchargement.
Connecter ses applications à LocalAI
LocalAI étant compatible avec l'API OpenAI, la migration d'une application existante se résume à deux changements : l'URL de base et la clé.
Python (openai SDK) :
import openai
client = openai.OpenAI(
base_url="https://ia.votre-domaine.com/v1",
api_key="votre-cle-secrete"
)
response = client.chat.completions.create(
model="mistral-7b-instruct-v0.2.Q4_K_M",
messages=[{"role": "user", "content": "Résume ce texte : ..."}]
)
print(response.choices[0].message.content)Node.js (openai SDK) :
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://ia.votre-domaine.com/v1',
apiKey: 'votre-cle-secrete'
});
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 direct :
curl https://ia.votre-domaine.com/v1/embeddings \
-H 'Authorization: Bearer votre-cle-secrete' \
-H 'Content-Type: application/json' \
-d '{"model": "all-minilm", "input": "Texte à vectoriser"}'Les bibliothèques LangChain, LlamaIndex et la plupart des frameworks RAG acceptent un paramètre openai_api_base ou base_url — le changement reste identique.
Dépannage : erreurs courantes
404 model not found ou model not loaded : le nom de modèle passé dans model: ne correspond à aucun manifest YAML dans ./config/. Vérifiez avec GET /v1/models : le nom affiché doit être utilisé tel quel. Si le modèle n'apparaît pas, vérifiez que le YAML est bien dans le dossier monté et redémarrez le conteneur.
Inférence très lente ou killed (OOM) : le modèle dépasse la RAM disponible. Un modèle 7B Q4 nécessite environ 6 Go de RAM libre au moment du chargement. Vérifiez avec docker stats localai pendant une inférence. Solutions : passer à une quantization plus légère (Q3_K_S ou Q2_K), réduire le context_size dans le YAML, ou upgrader le VPS.
SINGLE_ACTIVE_BACKEND error : LocalAI est configuré avec SINGLE_ACTIVE_BACKEND=true et une requête tente de charger un second modèle pendant qu'un autre est actif. C'est le comportement attendu sur CPU. Attendez que la première inférence se termine, ou désactivez l'option si votre VPS a suffisamment de RAM pour plusieurs modèles simultanés.
GPU non détecté (CUDA device not found) : vérifiez que vous utilisez l'image latest-gpu-nvidia-cuda-12, que le driver NVIDIA est installé sur l'hôte (nvidia-smi), et que le conteneur a accès au GPU (gpus: all dans docker-compose.yaml sous la clé deploy:). Sans ces trois conditions, LocalAI bascule silencieusement sur le CPU.
401 Unauthorized : la variable API_KEY est définie dans le docker-compose.yaml mais le header Authorization: Bearer <clé> est absent ou incorrect dans l'appel. Tous les endpoints, y compris /v1/models, requièrent le header dès que API_KEY est positionné.
LocalAI vs Ollama vs vLLM : quel serveur LLM choisir ?
Faites défiler le tableau
| LocalAI | Ollama | vLLM | |
|---|---|---|---|
| GPU requis | Non (CPU par défaut) | Non (CPU par défaut) | Oui (GPU obligatoire) |
| API compatible OpenAI | Oui (complète) | Oui (partielle) | Oui (complète) |
| Génération d'images | Oui (Stable Diffusion) | Non | Non |
| Transcription audio | Oui (Whisper) | Non | Non |
| Embeddings natifs | Oui | Oui | Oui |
| Bibliothèque de modèles | 200+ modèles GGUF | Liste de modèles sélectionnés | Modèles HuggingFace |
| Débit (tokens/s, 7B) | ~10-20 CPU / ~80+ GPU | ~15-25 CPU / ~80+ GPU | ~150+ GPU uniquement |
| RAM (modèle 7B Q4) | ~6 Go | ~6 Go | ~14 Go (FP16) |
| Cas d'usage principal | API unifiée multi-modalités | Inférence texte simple | Production haute performance |