Aller au contenu

LiteLLM — Passerelle IA

LiteLLM fournit une passerelle API compatible OpenAI qui unifie l'accès à tous les backends LLM dans AKKO. Au lieu d'appeler Ollama directement, les services et notebooks utilisent l'API standard de LiteLLM — ce qui permet de changer de backend (Ollama, vLLM, API cloud) sans modifier le code applicatif.

Architecture

Notebooks / Cockpit / Applications
            |
      +-----v------+
      |   LiteLLM   |  API compatible OpenAI (port 4000)
      | (Passerelle) |
      +-----+------+
            |
      +-----v------+
      |   Ollama    |  Runtime LLM local (port 11434)
      | qwen2.5-coder:7b, qwen2.5:3b, nomic-embed-text
      +------------+

Modèles configurés

Modèle Taille Cas d'usage
qwen2.5-coder:7b 4.7 Go Génération de code, text-to-SQL, appel d'outils MCP
qwen2.5:3b 2.0 Go Chat général, conversations jupyter-ai
nomic-embed-text 137 Mo Embeddings RAG (pgvector)

Utilisation

Depuis les notebooks (jupyter-ai)

jupyter-ai est pré-configuré pour utiliser LiteLLM comme backend :

# jupyter-ai utilise JUPYTER_AI_DEFAULT_PROVIDER et JUPYTER_AI_DEFAULT_MODEL
# Ces variables sont définies automatiquement par le spawner JupyterHub

Appels API directs

from openai import OpenAI

client = OpenAI(
    base_url="http://akko-akko-litellm:4000/v1",
    api_key="akko-dev-litellm-key"  # master_key depuis les values
)

response = client.chat.completions.create(
    model="qwen2.5-coder:7b",
    messages=[{"role": "user", "content": "Écris une requête SQL pour trouver les meilleurs clients"}]
)
print(response.choices[0].message.content)

URLs

Mode URL
Kubernetes (k3d) https://llm.akko.local

Configuration

Kubernetes (Helm)

akko-litellm:
  enabled: true
  ollamaHost: "akko-akko-ollama"
  config:
    general_settings:
      master_key: "votre-clé-secrète"
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 512Mi     # Surcharge dev : 1Gi (LiteLLM OOM en charge en dessous de 1Gi)

Exigence mémoire

LiteLLM nécessite au minimum 1 Gi de limite mémoire. Il sera tué (OOMKilled) à 512Mi.

Authentification

LiteLLM est protégé par OAuth2-Proxy (middleware ForwardAuth). Les utilisateurs doivent être authentifiés via Keycloak SSO pour accéder à l'API depuis l'ingress.

Pour les appels internes entre services (dans le cluster), utilisez la master_key pour l'authentification.

Dépannage

LiteLLM OOMKilled (CrashLoopBackOff)

Symptômes : Le pod LiteLLM entre en statut CrashLoopBackOff. kubectl describe pod affiche OOMKilled comme dernière raison de terminaison.

Cause : LiteLLM nécessite au moins 1 Gi de mémoire. Si la limite mémoire est en dessous de ce seuil (ex. 512Mi), le OOM-killer du noyau tue le processus.

Solution :

# Vérifier les limites mémoire actuelles
kubectl get pod -n akko -l app.kubernetes.io/name=akko-litellm -o jsonpath='{.items[0].spec.containers[0].resources}'

# S'assurer que la limite mémoire est d'au moins 1Gi dans votre fichier values
# akko-litellm.resources.limits.memory: 1Gi
helm upgrade akko helm/akko/ -n akko -f helm/examples/values-dev.yaml \
  --set akko-litellm.resources.limits.memory=1Gi

Backend Ollama injoignable

Symptômes : Les appels API à LiteLLM retournent Connection refused ou 502 Bad Gateway. Les logs affichent Connection error to ollama backend.

Cause : Le pod Ollama n'est pas en cours d'exécution, pas prêt, ou la valeur ollamaHost dans le chart Helm ne correspond pas au nom réel du service Ollama.

Solution :

# Vérifier que le pod Ollama tourne
kubectl get pods -n akko -l app.kubernetes.io/name=akko-ollama

# Vérifier l'endpoint du service Ollama
kubectl get svc -n akko | grep ollama

# Consulter les logs LiteLLM pour les erreurs de connexion
kubectl logs -n akko deploy/akko-akko-litellm --tail=50

# Vérifier que la valeur ollamaHost correspond au nom du service
kubectl get cm -n akko -l app.kubernetes.io/name=akko-litellm -o yaml | grep -i ollama

Échec de validation de la clé API

Symptômes : Les requêtes retournent 401 Unauthorized ou Authentication Error: Invalid API Key. Les services internes qui fonctionnaient cessent de répondre.

Cause : La master_key configurée dans LiteLLM ne correspond pas à la clé utilisée par le service appelant. Cela arrive souvent après un helm upgrade où la clé a été régénérée ou écrasée.

Solution :

# Vérifier la master_key actuelle dans la config LiteLLM
kubectl get secret -n akko -l app.kubernetes.io/name=akko-litellm -o yaml

# Vérifier que les variables d'environnement des notebooks/services correspondent
kubectl exec -n akko deploy/akko-jupyterhub -- env | grep LITELLM

# Redémarrer LiteLLM après correction de la clé
kubectl rollout restart -n akko deploy/akko-akko-litellm

Modèle introuvable

Symptômes : Les appels API retournent Model not found: <nom-du-modèle>. L'interface LiteLLM n'affiche aucun modèle disponible.

Cause : Le nom du modèle dans la requête ne correspond à aucun modèle configuré dans le routage LiteLLM, ou Ollama n'a pas encore terminé le téléchargement du modèle.

Solution :

# Lister les modèles disponibles dans Ollama
kubectl exec -n akko deploy/akko-akko-ollama -- ollama list

# Vérifier la config LiteLLM pour les modèles enregistrés
kubectl logs -n akko deploy/akko-akko-litellm --tail=100 | grep -i model

# Vérifier que le ConfigMap LiteLLM liste les modèles attendus
kubectl get cm -n akko -l app.kubernetes.io/name=akko-litellm -o yaml

Temps de réponse lents

Symptômes : Les appels API prennent plus de 30 secondes. Des timeouts surviennent sur les prompts volumineux. Les notebooks semblent bloqués pendant les tâches assistées par IA.

Cause : Le backend Ollama tourne sur CPU (normal en dev), le modèle est trop volumineux pour les ressources disponibles, ou plusieurs requêtes simultanées s'accumulent car Ollama les traite séquentiellement.

Solution :

# Vérifier l'utilisation des ressources Ollama
kubectl top pod -n akko -l app.kubernetes.io/name=akko-ollama

# Vérifier si Ollama est limité par le CPU (CPU élevé, pas de GPU)
kubectl describe pod -n akko -l app.kubernetes.io/name=akko-ollama | grep -A5 "Resources"

# Envisager un modèle plus petit (qwen2.5:3b au lieu de 7b) pour des réponses plus rapides
# Ou passer à vLLM avec GPU en production pour un débit élevé