---
title: "Cloud-init pour déployer LocalAI dans le cloud en 5 minutes"
date: !!timestamp '2024-08-27 13:12:00'
image: /post/cloud-init-to-deploy-localai-in-5-minutes/og.webp
tags:
- ai
- container
- hosting
- privacy
---

Utiliser les IA génératives sans partager ses données avec des entreprises ou des États qui raffolent de nos données, c'est possible et accessible.

Le monde des logiciels libres regorge d'applications pour évaluer et utiliser les IA génératives.
Après de nombreux tests, je vous présente ici le fichier cloud-init pour déployer votre propre instance de LocalAI en moins de 5 minutes.

<!-- more -->

## Pourquoi LocalAI ?

LocalAI est un logiciel libre qui a pour vocation d'offrir une alternative locale, auto-hébergée, aux prestataires de services d'IA.
Cette application expose une API compatible avec celle d'OpenAI.
L'idée est de pouvoir remplacer en un clin d'œil les appels à OpenAI de n'importe quelle application existante : il suffit de changer le domaine où pointe l'API.

Toutes les fonctionnalités d'OpenAI sont répliquées : complétion de texte, génération d'image (Dall-E), transcription d'audio (Whisper), chat avec un assistant AI, y compris avec les appels de fonction, les embeddings, ...

Cependant, ce ne sont pas les modèles d'OpenAI, Anthropic ou Google qui sont utilisés pour faire ces tâches : cela passe par des modèles ouverts, tels que Mistral ou Llama de Meta, mais le catalogue de modèles est immense.

Notons que LocalAI fournit aussi une interface web pour gérer les modèles et tester chaque fonctionnalité.
Il ne faut pas s'attendre à avoir une interface à la ChatGPT, ce n'est pas le but ici.


## Choisir sa machine

LocalAI fonctionne sur n'importe quelle machine, du Raspberry Pi au serveur avec une carte graphique à 20000 €.

Néanmoins, il ne faudra pas s'attendre à des performances acceptables sur les petites machines, et il faudra garder en tête que les gros modèles, similaires à ceux auxquels on accède au travers de ChatGPT, Claude, ... nécessitent beaucoup de mémoire. Pour avoir une idée des spécifications nécessaires, [voyez cet article](https://www.theregister.com/2024/08/25/ai_pc_buying_guide/).

Lorsque l'on a pas de matériel à dédier à l'IA, le cloud peut être un bon moyen d'évaluer les performances et les cas d'usages.

J'ai pu tester les différentes machines GPU d'OVH, disponibles entre 0,70 €/h et 2,75 €/h, avec des cartes :

  - NVIDIA L4
  - NVIDIA L40S
  - NVIDIA A100
  - NVIDIA H100

Selon la carte graphique, la version de CUDA utilisée sera différente.
Les cartes ci-dessus sont toutes compatibles avec CUDA 12, mais pour d'autres cartes, il pourra être nécessaire d'adapter la version dans le script `cloud-init`.

Je recommande d'avoir au moins 100 GB d'espace disque sur la machine, afin de pouvoir évaluer de nombreux modèles sans devoir faire le tri régulièrement.


## Le script cloud-init

`cloud-init` est une méthode standard pour configurer automatiquement une nouvelle machine.
La quasi-totalité des fournisseurs de cloud est compatible.

Il s'agit généralement d'une métadonnée transmise à la machine lors de son démarrage.

Le script est donné pour une machine démarrée avec Ubuntu 24.04.


Il restera simplement à faire pointer l'enregistrement DNS du domaine sur l'IP publique de la machine créée.


### Machine sans carte graphique

La configuration d'une machine sans carte graphique ne présente pas beaucoup de défi, il s'agit de lancer le conteneur Docker de LocalAI tout simplement :

```yaml
#cloud-config
users:
  - default

packages:
  - docker.io

write_files:
  - content: |
      {
        acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
      }

      ia.example.com {
        @my-ips not remote_ip 127.0.0.1/8
        basicauth @my-ips {
          localai "$2a$14$hfEBPQMe9dV9VaoZbHbOaOoseMaqrFC9nST/7n7oeNWkhEKmyaxNi"
        }

        reverse_proxy localai:8080 {
          flush_interval -1
        }
      }
    path: /etc/caddy/Caddyfile

runcmd:
  # Allow traffic in IPv4
  - sed -i '/-A INPUT -j REJECT/i-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT\n-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT' /etc/iptables/rules.v4
  - iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
  - iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

  # Create docker network
  - docker network create local

  # Launch web server
  - docker run -d --restart unless-stopped --network local -v /etc/caddy:/etc/caddy -p 80:80 -p 443:443 --name caddy caddy:latest

  # Launch container
  - docker run -d --restart unless-stopped --network local -v "/var/lib/localai/models:/build/models:cached" --name localai localai/localai:latest-aio-cpu
```


### Machine avec carte graphique

Avec une carte graphique, l'exercice est rendu plus complexe par le fait qu'il faut commencer par installer les modules du noyau pour piloter la carte graphique, ainsi que le nécessaire pour que Docker puisse attribuer la carte au conteneur.

```yaml
#cloud-config
users:
  - default

packages:
  - docker.io
  - nvidia-dkms-535-server
  - nvidia-utils-535-server

write_files:
  - content: |
      {
        acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
      }

      ia.example.com {
        @my-ips not remote_ip 127.0.0.1/8
        basicauth @my-ips {
          localai "$2a$14$hfEBPQMe9dV9VaoZbHbOaOoseMaqrFC9nST/7n7oeNWkhEKmyaxNi"
        }

        reverse_proxy localai:8080 {
          flush_interval -1
        }
      }
    path: /etc/caddy/Caddyfile

runcmd:
  # Download and install GPU controller for Docker
  - curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | 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' > /etc/apt/sources.list.d/nvidia-container-toolkit.list
  - apt update && apt install -y nvidia-container-toolkit
  - nvidia-ctk runtime configure --runtime=docker
  - systemctl restart docker
  - sleep 5

  # Allow traffic in IPv4
  - sed -i '/-A INPUT -j REJECT/i-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT\n-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT' /etc/iptables/rules.v4
  - iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
  - iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

  # Create docker network
  - docker network create local

  # Launch web server
  - docker run -d --restart unless-stopped --network local -v /etc/caddy:/etc/caddy -p 80:80 -p 443:443 --name caddy caddy:latest

  # Launch container
  - docker run -d --restart unless-stopped --gpus all --network local -e DEBUG=true -v "/var/lib/localai/models:/build/models:cached" -p "8080:8080" --name localai --pull always localai/localai:latest-aio-gpu-nvidia-cuda-12
```

### Détails du script

Pour aller au plus simple et rendre le service utilisable directement, j'ai utilisé le [serveur web `caddy`](https://caddyserver.com/) pour exposer et protéger le service LocalAI.
`caddy` demandera automatiquement un certificat pour le domaine qu'il doit servir, ici `ia.example.com`, pensez à adapter cette partie de la configuration, et à déclarer l'IP du serveur dans votre domaine.


#### Certificat TLS

Les environnements cloud étant prompts à la création et à la destruction des machines rapidement, comme il n'y a pas de persistance ici, il convient d'être vigilant car si la machine est recréée, de nouveaux certificats vont être demandés, ce qui peut rapidement conduire [au dépassement du nombre de certificats émis pour le domaine](https://letsencrypt.org/docs/duplicate-certificate-limit/).

Afin d'avoir un comportement sain, le script que je vous propose se contente de demander des certificats à l'instance de test de Let's Encrypt.
Lorsque vous aurez terminé vos tests, vous pourrez simplement effacer ou commenter la ligne `acme_ca` dans la configuration de Caddy.


#### Restriction d'accès

Les services en ligne tels que ChatGPT, Claude, ... requièrent de s'authentifier au moyen d'une clef d'API.
Il n'y a pas de tel concept dans LocalAI : n'importe quelle clef d'API sera considérée valide.
Il faut donc protéger l'accès autrement.

Si votre machine est exposée directement sur Internet, il convient de protéger l'accès à LocalAI afin que l'API ne soit pas utilisée par n'importe qui.

Il faut adapter la configuration de Caddy pour autoriser vos IP, dans la liste `@my-ips`, ou à défaut d'IP fixes, [créer des utilisateurs pour l'authentification Basic](https://caddyserver.com/docs/caddyfile/directives/basic_auth).
