Docker pour l'IA
Type: Build
Languages: Docker
Prerequisites: Phase 0, Lessons 01 and 03
Time: ~60 minutes
Objectifs d'apprentissage
- Construire une image Docker fonctionnant avec GPU avec des bibliothèques CUDA, PyTorch et IA à partir d'un fichier Docker
- Montez les annuaires hôtes en tant que volumes pour persister dans les modèles, les ensembles de données et le code à travers les reconstructions de conteneurs
- Configurer le kit d'outils NVIDIA Container pour exposer les GPU à l'intérieur des conteneurs
- Orchestration des applications d'IA multi-service (serveur d'inférence + base de données vectorielle) à l'aide de Docker Compose
Le problème
Vous avez formé un modèle sur votre ordinateur portable avec PyTorch 2.3, CUDA 12.4 et Python 3.12. Votre collègue a PyTorch 2.1, CUDA 11.8 et Python 3.10. Votre modèle s'écrase sur leur machine. Votre fichier Docker fonctionne sur les deux.
Les projets d'IA sont des cauchemars de dépendance. Une pile typique comprend Python, PyTorch, pilotes CUDA, cuDNN, bibliothèques C au niveau du système et des packages spécialisés comme flash-attn qui nécessitent des versions de compilateur exactes. Docker emballe tout cela en une seule image qui fonctionne de manière identique partout.
Le concept
Docker enveloppe votre code, votre temps d'exécution, vos bibliothèques et vos outils système dans une unité isolée appelée un conteneur.
graph TD
subgraph without["Without Docker"]
A1["Your machine<br/>Python 3.12<br/>CUDA 12.4<br/>PyTorch 2.3"] -->|crashes| X1["???"]
A2["Their machine<br/>Python 3.10<br/>CUDA 11.8<br/>PyTorch 2.1"] -->|crashes| X2["???"]
A3["Server<br/>Python 3.11<br/>CUDA 12.1<br/>PyTorch 2.2"] -->|crashes| X3["???"]
end
subgraph with_docker["With Docker — Same image everywhere"]
B1["Your machine<br/>Python 3.12 | CUDA 12.4<br/>PyTorch 2.3 | Your code"]
B2["Their machine<br/>Python 3.12 | CUDA 12.4<br/>PyTorch 2.3 | Your code"]
B3["Server<br/>Python 3.12 | CUDA 12.4<br/>PyTorch 2.3 | Your code"]
endPourquoi les projets d'IA ont plus besoin de Docker que la plupart
- GPU drivers are fragile.Le code CUDA 12.4 n'est pas exécuté sur CUDA 11.8. Docker isole le kit d'outils CUDA à l'intérieur du conteneur tout en partageant le pilote GPU hôte via le kit d'outils NVIDIA Container.
- Model weights are large.Un modèle de paramètre 7B est de 14 Go en fp16. Vous ne voulez pas le télécharger à chaque fois que vous le reconstruisez.
- Multi-service architectures are common.Une application d'IA réelle n'est pas seulement un script Python. C'est un serveur d'inférence, une base de données vectorielle pour RAG, peut-être un frontend Web. Docker Compose orchestre tout cela avec une seule commande.
Le vocabulaire clé
| Term | What it means |
|---|---|
| Image | A read-only template. Your recipe. Built from a Dockerfile. |
| Container | A running instance of an image. Your kitchen. |
| Dockerfile | Instructions to build an image. Layer by layer. |
| Volume | Persistent storage that survives container restarts. |
| docker-compose | A tool for defining multi-container applications in YAML. |
Modèles de conteneurs communs dans l'IA
Dev Container
Full toolkit. Editor support. Jupyter. Debugging tools.
Used during development and experimentation.
Training Container
Minimal. Just the training script and dependencies.
Runs on GPU clusters. No editor, no Jupyter.
Inference Container
Optimized for serving. Small image. Fast cold start.
Runs behind a load balancer in production.Faites-le
Étape 1: Installez Docker
bash# macOS
brew install --cask docker
open /Applications/Docker.app
# Ubuntu
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in for group change to take effectVérifiez:
bashdocker --version
docker run hello-worldÉtape 2: Installez le kit d'outils NVIDIA Container (Linux avec GPU NVIDIA)
Cela permet aux conteneurs Docker d'accéder à votre GPU. Les utilisateurs de macOS et Windows (WSL2) peuvent sauter cela; Docker Desktop gère les GPU différemment sur ces plateformes.
bashdistribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart dockerTestez l'accès GPU à l'intérieur d'un conteneur:
bashdocker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smiSi vous voyez vos informations sur le GPU, le kit d'outils fonctionne.
Étape 3: Comprendre les images de base
Choisir la bonne image de base permet d'économiser des heures de débogage.
nvidia/cuda:12.4.1-devel-ubuntu22.04
Full CUDA toolkit. Compilers included.
Use for: building packages that need nvcc (flash-attn, bitsandbytes)
Size: ~4 GB
nvidia/cuda:12.4.1-runtime-ubuntu22.04
CUDA runtime only. No compilers.
Use for: running pre-built code
Size: ~1.5 GB
pytorch/pytorch:2.6.0-cuda12.4-cudnn9-runtime
PyTorch pre-installed on top of CUDA.
Use for: skipping the PyTorch install step
Size: ~6 GB
python:3.12-slim
No CUDA. CPU only.
Use for: inference on CPU, lightweight tools
Size: ~150 MBÉtape 4: Écrire un fichier Docker pour le développement de l'IA
Voici le fichier Docker dans code/Dockerfile- Parcourez-le .
dockerfileFROM --platform=linux/amd64 nvidia/cuda:12.4.1-devel-ubuntu22.04
ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONUNBUFFERED=1
RUN apt-get update && apt-get install -y --no-install-recommends \
software-properties-common \
git \
curl \
build-essential \
&& add-apt-repository -y ppa:deadsnakes/ppa \
&& apt-get update && apt-get install -y --no-install-recommends \
python3.12 \
python3.12-venv \
python3.12-dev \
&& rm -rf /var/lib/apt/lists/*
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.12 1
RUN curl -sSL https://raw.githubusercontent.com/pypa/get-pip/3b73145063be545b649ad9ca83ea8da5fc915a4f/public/get-pip.py -o /tmp/get-pip.py \
&& echo "a341e1a43e38001c551a1508a73ff23636a11970b61d901d9a1cad2a18f57055 /tmp/get-pip.py" | sha256sum -c - \
&& python /tmp/get-pip.py \
&& rm /tmp/get-pip.py \
&& update-alternatives --install /usr/bin/pip pip /usr/local/bin/pip3.12 1
RUN python -m pip install --no-cache-dir --upgrade pip setuptools wheel
RUN python -m pip install --no-cache-dir \
torch==2.6.0+cu124 \
torchvision==0.21.0+cu124 \
torchaudio==2.6.0+cu124 \
--index-url https://download.pytorch.org/whl/cu124
RUN python -m pip install --no-cache-dir \
numpy \
pandas \
scikit-learn \
matplotlib \
jupyter \
transformers \
datasets \
accelerate \
safetensors
WORKDIR /workspace
VOLUME ["/workspace", "/models"]
EXPOSE 8888
CMD ["python"]- Faites-le !
bashdocker build -t ai-dev -f phases/00-setup-and-tooling/07-docker-for-ai/code/Dockerfile .Cela prend un certain temps la première fois (téléchargement de l'image de base CUDA + PyTorch).
macOS / Apple Silicon (M1/M2/M3/M4):Le --platform=linux/amd64sur le FROML'image de base CUDA envoie également une variante arm64 et Docker Desktop la choisit automatiquement sur Apple Silicon, mais PyTorch publie son cu124les roues pour x86_64 seulement, donc le pip install torch==2.6.0+cu124couche échoue avec No matching distribution found for torch==2.6.0+cu124. En branchant la plateforme, l'image x86_64 est tirée et exécutée sous émulation: la construction est plus lente et le conteneur n'a pas de GPU (il n'y a pas de CUDA sur un Mac).--gpus allde la docker runPour le travail de la GPU sur Apple Silicon, exécutez les leçons natively avec la construction MPS de la leçon 01 et gardez cette image pour les hôtes x86_64 Linux avec un GPU NVIDIA.
- Je vais le faire.
bashdocker run --rm -it --gpus all \
-v $(pwd):/workspace \
-v ~/models:/models \
ai-dev python -c "import torch; print(f'PyTorch {torch.__version__}, CUDA: {torch.cuda.is_available()}')"Exécuter Jupyter à l'intérieur du conteneur:
bashdocker run --rm -it --gpus all \
-v $(pwd):/workspace \
-v ~/models:/models \
-p 8888:8888 \
ai-dev jupyter notebook --ip=0.0.0.0 --port=8888 --no-browser --allow-rootÉtape 5: Montage de volume pour les données et les modèles
Les montage de volume sont essentiels pour le travail de l'IA. Sans eux, vos téléchargements de modèle de 14 Go disparaissent lorsque le conteneur s'arrête.
bash# Mount your code
-v $(pwd):/workspace
# Mount a shared models directory
-v ~/models:/models
# Mount datasets
-v ~/datasets:/dataDans votre script d'entraînement, chargez-vous du chemin monté:
pythonfrom transformers import AutoModel
model = AutoModel.from_pretrained("/models/llama-7b")Le modèle est installé sur votre système de fichiers hôte.
Étape 6: Docker Composer pour les applications d'IA multi-service
Une application RAG réelle a besoin d'un serveur d'inférence et d'une base de données vectorielle.
Regardez !code/docker-compose.yml- Le numéro de la liste:
yamlservices:
ai-dev:
build:
context: .
dockerfile: Dockerfile
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
volumes:
- ../../../:/workspace
- ~/models:/models
- ~/datasets:/data
ports:
- "8888:8888"
stdin_open: true
tty: true
command: jupyter notebook --ip=0.0.0.0 --port=8888 --no-browser --allow-root
qdrant:
image: qdrant/qdrant:v1.12.5
ports:
- "6333:6333"
- "6334:6334"
volumes:
- qdrant_data:/qdrant/storage
volumes:
qdrant_data:Commencez tout:
bashcd phases/00-setup-and-tooling/07-docker-for-ai/code
docker compose up -dMaintenant votre conteneur de développement d' IA peut atteindre la base de données vectorielle à http://qdrant:6333Docker Compose crée automatiquement un réseau partagé.
Testez la connexion à l'intérieur du conteneur d'IA:
pythonfrom qdrant_client import QdrantClient
client = QdrantClient(host="qdrant", port=6333)
print(client.get_collections())Arrêtez tout !
bashdocker compose downAjouter -vpour supprimer également le volume de qdrant:
bashdocker compose down -vÉtape 7: Commandes Docker utiles pour le travail d'IA
bash# List running containers
docker ps
# List all images and their sizes
docker images
# Remove unused images (reclaim disk space)
docker system prune -a
# Check GPU usage inside a running container
docker exec -it <container_id> nvidia-smi
# Copy a file from container to host
docker cp <container_id>:/workspace/results.csv ./results.csv
# View container logs
docker logs -f <container_id>Utilisez-le
Vous avez maintenant un environnement de développement d'IA reproduisable.
- Utilisation
docker compose uppour démarrer votre environnement de développement et vecteur de base de données ensemble - Montez votre code, vos modèles et vos données en volumes afin que rien ne soit perdu entre les reconstructions
- Lorsque la leçon nécessite un nouveau paquet Python, ajoutez-le au fichier Docker et reconstruisez
- Partagez votre dossier avec vos coéquipiers.
Pas de GPU ?
Retirez le --gpus allLe contenant fonctionne toujours pour les leçons basées sur le processeur PyTorch détecte l'absence de CUDA et revient automatiquement sur le processeur.
Exercices
- Construisez le fichier Docker et courez
python -c "import torch; print(torch.__version__)"à l'intérieur du conteneur - Démarrez la pile composée de docker et vérifiez que Qdrant est accessible depuis le conteneur d' IA à
http://qdrant:6333/collections - Ajouter
flaskPour le fichier Docker, reconstruire et exécuter un serveur API simple sur le port 5000.-p 5000:5000 - Mesurer la taille de l' image avec
docker imagesEssayez de changer l' image de base dedevelàruntimeet comparer les tailles
Les termes clés
| Term | What people say | What it actually means |
|---|---|---|
| Container | "Lightweight VM" | An isolated process using the host kernel, with its own filesystem and network |
| Image layer | "Cached step" | Each Dockerfile instruction creates a layer. Unchanged layers are cached, so rebuilds are fast. |
| NVIDIA Container Toolkit | "GPU in Docker" | A runtime hook that exposes host GPUs to containers via --gpus flag |
| Volume mount | "Shared folder" | A directory on the host mapped into the container. Changes persist after the container stops. |
| Base image | "Starting point" | The FROM image your Dockerfile builds on top of. Determines what is pre-installed. |
This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.
Browse the complete course catalog or open this lesson on GitHub.