New article: cloud-init for localai

This commit is contained in:
nemunaire 2024-08-31 11:46:30 +02:00
parent 612b6084f5
commit 66e9ea1578
2 changed files with 372 additions and 0 deletions

View File

@ -0,0 +1,186 @@
---
title: "Cloud-init to deploy LocalAI in the cloud in 5 minutes"
date: !!timestamp '2024-08-27 13:12:00'
tags:
- ai
- container
- hosting
- privacy
---
It's possible to use generative AI without sharing your data with companies or states that raid our data.
The world of free software is full of applications for evaluating and using generative AI. After extensive testing, I present here the cloud-init file for deploying your own LocalAI instance in under 5 minutes.
<!-- more -->
## Why LocalAI?
LocalAI is a free software application designed to offer a local, self-hosted alternative to AI service providers.
The application features an API compatible with that of OpenAI.
The idea is to be able to replace calls to OpenAI from any existing application in the blink of an eye: simply change the domain to which the API points.
All OpenAI functionalities are replicated: text completion, image generation (Dall-E), audio transcription (Whisper), chat with an AI assistant, including function calls, embeddings, ...
However, it's not OpenAI, Anthropic or Google templates that are used to perform these tasks: this is done via open templates, such as Meta's Mistral or Llama, but the catalog of templates is immense.
LocalAI also provides a web interface for managing templates and testing each feature.
But don't expect a ChatGPT-style interface - that's not the point here.
## Choosing your machine
LocalAI works on any machine, from the Raspberry Pi to a server with a €20,000 graphics card.
However, you shouldn't expect acceptable performance on small machines, and bear in mind that larger models, similar to those accessed through ChatGPT, Claude, ... require a lot of memory. To get an idea of the specifications required, [see this article](https://www.theregister.com/2024/08/25/ai_pc_buying_guide/).
When you don't have hardware to dedicate to AI, the cloud can be a good way to evaluate performance and use cases.
I was able to test OVH's various GPU machines, available from €0.70/hr to €2.75/hr, with :
- NVIDIA L4
- NVIDIA L40S
- NVIDIA A100
Depending on the graphics card, a different version of CUDA will be used.
The above cards are all compatible with CUDA 12, but for other cards it may be necessary to adapt the version in the cloud-init script.
I recommend that you have at least 100 GB of disk space on your machine, so that you can evaluate many models without having to sort them out regularly.
## The cloud-init script
`cloud-init` is a standard method for automatically configuring a new machine.
Almost all cloud providers support it.
It's usually a metadata passed to the machine when it starts up.
The script is given for a machine booted with Ubuntu 24.04.
All that remains to be done is to point the DNS record of the domain to the public IP of the machine created.
### Machine without graphics card
Configuring a machine without a graphics card doesn't present much of a challenge: simply launch the LocalAI Docker container:
```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 with graphics card
With a graphics card, the exercise is made more complex by the fact that you have to start by installing the kernel modules needed to drive the graphics card, as well as those required for Docker to assign the card to the container.
```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
```
### Script details
To keep things simple and make the service directly usable, I've used the [web server `caddy`](https://caddyserver.com/) to expose and protect the LocalAI service.
`caddy` will automatically request a certificate for the domain it is to serve, in this case `ia.example.com`, so remember to adapt this part of the configuration, and declare the server's IP in your domain.
#### TLS certificate
Cloud environments are quick to create and destroy machines, and as there is no persistence here, you need to be vigilant because if the machine is recreated, new certificates will be requested, which can quickly lead to [the number of certificates issued for the domain being exceeded](https://letsencrypt.org/docs/duplicate-certificate-limit/).
In order to ensure healthy behavior, the script I'm proposing simply requests certificates from the Let's Encrypt test instance.
When you've finished testing, simply delete or comment out the `acme_ca` line in Caddy's configuration.
#### Access restriction
Online services such as ChatGPT, Claude, ... require authentication using an API key. There's no such concept in LocalAI: any API key will be considered valid.
If your machine is exposed directly to the Internet, you need to protect access to LocalAI so that the API cannot be used by just anyone.
You need to adapt Caddy's configuration to authorize your IPs, in the `@my-ips` list, or if you don't have fixed IPs, [create users for Basic authentication](https://caddyserver.com/docs/caddyfile/directives/basic_auth).

View File

@ -0,0 +1,186 @@
---
title: "Cloud-init pour déployer LocalAI dans le cloud en 5 minutes"
date: !!timestamp '2024-08-27 13:12:00'
tags:
- ai
- container
- hosting
- privacy
---
Utiliser les IA génératives sans partager ses données avec des entreprises ou des états qui rafolent 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 existente : 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 n'est 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 fourni 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 garder en tête que les gros modèles, similaire à 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
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 sont compatibles.
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 complexifié 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 prompt à la création et à la destruction des machines rapidement, comme il n'y a pas de persistance ici, il convient d'être vigilient 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és 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 tel que ChatGPT, Claude, ... requiert 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.
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é 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).