Exécuter des LLMs avec llama.cpp

Introduction

llama.cpp est une implémentation légère et performante en C/C++ pour exécuter des LLMs. Elle permet une inférence LLM efficace sur du matériel grand public, y compris les appareils ARM64 comme NVIDIA Jetson. Elle est devenue la norme par défaut pour l'inférence LLM locale grâce à son efficacité et sa large prise en charge des formats.

Alors qu'Ollama fournit une interface conviviale autour de llama.cpp, comprendre llama.cpp directement vous offre :

  • Un contrôle maximal sur les paramètres d'inférence
  • Une meilleure compréhension du fonctionnement interne des LLMs
  • La capacité d'optimiser pour des cas d'utilisation spécifiques
  • Le support des formats de quantification personnalisés

llama-cpp

Pourquoi llama.cpp ?

FonctionnalitéDescription
C/C++ purPas de dépendances lourdes, empreinte minimale
Multiples backendsSupport CPU, CUDA, Metal, OpenCL, Vulkan
Format GGUFSupport natif des modèles quantifiés
IntégrableFacile à intégrer dans les applications
Fallback CPUFonctionne même sans GPU
StreamingStreaming de tokens en temps réel

Installation sur Jetson

Prérequis

Assurez-vous d'avoir les outils de construction installés :

bash
# Mettre à jour la liste des paquets
sudo apt-get update

# Installer les essentiels de construction
sudo apt-get install -y build-essential git cmake

# Ajouter les variables d'environnement CUDA à .bashrc
echo '
# CUDA Environment
export CUDA_HOME=/usr/local/cuda
export PATH=$CUDA_HOME/bin:$PATH
export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH
export CUDACXX=$CUDA_HOME/bin/nvcc
' >> ~/.bashrc

# Recharger la configuration du shell
source ~/.bashrc

# Vérifier l'installation de CUDA
nvcc --version

Cloner et construire llama.cpp

bash
# Cloner le dépôt
cd ~
git clone https://github.com/ggerganov/llama.cpp.git
cd llama.cpp

# Construire avec support CUDA pour Jetson
#make -j$(nproc) GGML_CUDA=1

# Alternative : Utiliser CMake
mkdir build && cd build
cmake .. -DGGML_CUDA=ON
cmake --build . --config Release -j$(nproc)

builded_llamacpp

Vérifier l'installation

bash
# Vérifier si les binaires ont été construits
ls ~/llama.cpp/build/bin/llama-cli

# Tester la version
~/llama.cpp/build/bin/llama-cli --version

llama_v

Obtenir votre premier modèle

llama.cpp utilise le format GGUF (GGML Universal Format) — un format binaire efficace pour stocker des modèles quantifiés.

Télécharger un modèle

bash
# Créer un répertoire models
mkdir -p ~/llama.cpp/models
cd ~/llama.cpp/models

# Télécharger Llama 3.2 3B (quantification Q4_K_M - 4-bit)
wget https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF/resolve/main/Llama-3.2-3B-Instruct-Q4_K_M.gguf

# Ou télécharger depuis Hugging Face avec curl
huggingface-cli download bartowski/Llama-3.2-3B-Instruct-GGUF Llama-3.2-3B-Instruct-Q4_K_M.gguf --local-dir ./models

Comprendre la quantification GGUF

QuantificationBitsTaille du fichierQualitéVitesse
Q2_K2-bitTrès petitInférieurePlus rapide
Q3_K_M3-bitPetitAcceptableTrès rapide
Q4_K_M4-bitMoyenBonRapide
Q5_K_M5-bitMoyen-grandTrès bonModéré
Q6_K6-bitGrandExcellentPlus lent
Q8_08-bitTrès grandPresque originalPlus lent

Pour les appareils Jetson :

  • Orin Nano 4GB : Utiliser Q2_K ou Q3_K_M
  • Orin Nano 8GB : Utiliser Q3_K_M ou Q4_K_M
  • Orin NX 16GB+ : Utiliser Q4_K_M ou Q5_K_M

Modèles recommandés pour Jetson

bash
# Télécharger Qwen3 4B (excellent support multilingue)
wget https://huggingface.co/bartowski/Qwen3-4B-Instruct-GGUF/resolve/main/Qwen3-4B-Instruct-Q4_K_M.gguf

# Télécharger DeepSeek-R1 1.5B (modèle de raisonnement distillé)
wget https://huggingface.co/bartowski/DeepSeek-R1-Distill-Qwen-1.5B-GGUF/resolve/main/DeepSeek-R1-Distill-Qwen-1.5B-Q4_K_M.gguf

# Télécharger Gemma3 4B
wget https://huggingface.co/bartowski/gemma-3-4b-it-GGUF/resolve/main/gemma-3-4b-it-Q4_K_M.gguf

Utilisation de base

Génération de texte simple

bash
cd ~/llama.cpp

# Inférence basique
./build/bin/llama-cli \
  -m models/Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  -p "The future of edge AI is"

Mode chat (conversationnel)

bash
# Démarrer une session de chat interactive
./build/bin/llama-cli \
  -m models/Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  -cnv \
  --chat-template llama3

Note : Le flag -cnv active le mode conversationnel, et --chat-template spécifie comment formater la conversation.

Flags communs de llama-cli

FlagDescriptionExemple
-m, --modelChemin du fichier modèle-m models/model.gguf
-p, --promptPrompt initial-p "Hello world"
-cnvMode conversation-cnv
-n, --n-predictNombre de tokens à générer-n 256
-c, --ctx-sizeTaille du contexte (en tokens)-c 4096
--tempTempérature (créativité)--temp 0.7
--top-pÉchantillonnage nucleus--top-p 0.9
-ngl, --n-gpu-layersCouches GPU à décharger-ngl 35
-t, --threadsNombre de threads CPU-t 4

Optimisation pour GPU Jetson

Déchargement GPU

Décharger les couches du modèle vers le GPU améliore considérablement les performances :

bash
# Déterminer les couches GPU optimales
# Commencer avec -ngl 999 (décharger toutes les couches)
./build/bin/llama-cli \
  -m models/Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  -p "Explain quantum computing" \
  -ngl 35 \
  -n 256

Astuce : Utilisez -ngl 999 pour décharger automatiquement toutes les couches possibles vers le GPU.

Mesurer les performances

bash
# Exécuter avec statistiques de performance
./build/bin/llama-cli \
  -m models/Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  -p "What is the capital of France?" \
  -n 50 \
  -ngl 35 \
  --perf

llamacpp_test

Métrique clé : eval time per token doit être inférieur à 100ms pour de bonnes performances en temps réel.

Fonctionnalités avancées

Exécuter le serveur API

llama.cpp inclut un mode serveur pour l'accès REST API :

bash
# Démarrer le serveur
./llama-server \
  -m models/Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  --host 0.0.0.0 \
  --port 8000 \
  -ngl 35 \
  -c 4096

Accéder au serveur :

bash
# Requête simple
curl -X POST http://localhost:8000/completion \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Once upon a time",
    "n_predict": 100
  }'

# Complétion de chat
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "user", "content": "What is machine learning?"}
    ],
    "max_tokens": 256
  }'

Prompts système

Définir le comportement du modèle avec des prompts système :

bash
./llama-cli \
  -m models/Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  -p "You are a helpful coding assistant. Explain Python list comprehensions." \
  --system "You are an expert Python programmer. Provide concise, practical code examples."

Traitement par lots

Traiter efficacement plusieurs prompts :

python
# batch_inference.py
import subprocess
import json

prompts = [
    "Explain neural networks",
    "What is GPU acceleration?",
    "Describe edge computing"
]

model_path = "~/llama.cpp/models/Llama-3.2-3B-Instruct-Q4_K_M.gguf"

for prompt in prompts:
    result = subprocess.run(
        ["./llama-cli", "-m", model_path, "-p", prompt, "-n", "100", "--temp", "0.7"],
        capture_output=True,
        text=True
    )
    print(f"Prompt: {prompt}")
    print(f"Response: {result.stdout}\n")

Convertir des modèles en GGUF

Si vous avez un modèle au format Hugging Face (PyTorch/SafeTensors), convertissez-le en GGUF :

bash
cd ~/llama.cpp

# Installer les dépendances Python
pip install -r requirements.txt

# Convertir un modèle Hugging Face en GGUF
python convert_hf_to_gguf.py \
  /path/to/model \
  --outfile output-model.gguf \
  --outtype q4_k_m

Types de sortie disponibles :

  • f16 : 16-bit float (sans quantification)
  • q8_0 : quantification 8-bit
  • q6_k : quantification 6-bit
  • q5_k_m : quantification 5-bit
  • q4_k_m : quantification 4-bit (équilibre recommandé)
  • q3_k_m : quantification 3-bit
  • q2_k : quantification 2-bit (plus compressé)

Exemples d'intégration

Liaison Python

bash
# Installer les liaisons Python
pip install llama-cpp-python

# Pour support CUDA (Jetson)
CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python --upgrade --force-reinstall --no-cache-dir
python
from llama_cpp import Llama

# Charger le modèle
llm = Llama(
    model_path="/path/to/model-Q4_K_M.gguf",
    n_gpu_layers=35,
    n_ctx=4096
)

# Générer du texte
output = llm(
    "Q: What is the capital of France?\nA:",
    max_tokens=50,
    temperature=0.7
)
print(output["choices"][0]["text"])

# Complétion de chat
output = llm.create_chat_completion(
    messages=[
        {"role": "user", "content": "Tell me a joke"}
    ],
    max_tokens=100
)
print(output["choices"][0]["message"]["content"])

Benchmark de performance

Optimisations spécifiques pour Jetson

bash
# Paramètres optimaux pour Jetson Orin Nano 8GB
./llama-cli \
  -m models/Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  -p "Explain transformers in machine learning" \
  -ngl 35 \
  -t 6 \
  -c 4096 \
  -n 200 \
  --temp 0.7

Script de benchmark

bash
#!/bin/bash
# benchmark.sh

MODEL="models/Llama-3.2-3B-Instruct-Q4_K_M.gguf"
PROMPT="Explain the concept of artificial intelligence and its applications."

echo "Benchmarking llama.cpp on Jetson"
echo "Model: $MODEL"
echo "Prompt: $PROMPT"
echo ""

for gpu_layers in 0 10 20 30 35; do
    echo "Testing with $gpu_layers GPU layers..."
    timeout 120 ./llama-cli \
        -m $MODEL \
        -p "$PROMPT" \
        -ngl $gpu_layers \
        -n 100 \
        --per-test 2>&1 | grep "eval time"
done

Problèmes courants et solutions

Problème 1 : CUDA non détecté

Problème : Le déchargement GPU ne fonctionne pas

Solution :

bash
# Reconstruire avec CUDA
make clean
make -j$(nproc) GGML_CUDA=1

# Vérifier l'installation de CUDA
nvidia-smi
nvcc --version

Problème 2 : Mémoire insuffisante

Problème : Le chargement du modèle échoue avec OOM

Solution :

bash
# Réduire les couches GPU
./llama-cli -m model.gguf -ngl 10  # Au lieu de -ngl 35

# Utiliser un contexte plus petit
./llama-cli -m model.gguf -c 2048  # Au lieu de 4096 par défaut

# Utiliser une quantification plus agressive
# Passer de Q5_K_M à Q4_K_M ou Q3_K_M

Problème 3 : Performance lente en CPU uniquement

Problème : La génération est trop lente sans GPU

Solution :

bash
# Activer plus de threads
./llama-cli -m model.gguf -t 8  # Utiliser 8 threads CPU

# Utiliser un modèle plus petit ou une quantification plus agressive

# S'assurer que le régulateur CPU est en mode performance
sudo apt-get install cpufrequtils
sudo cpufreq-set -g performance

Exercice pratique

Accomplissez ces tâches :

  1. Construire llama.cpp avec support CUDA
  2. Télécharger 3 modèles différents et comparer leurs tailles
  3. Exécuter l'inférence sur chaque modèle avec -ngl 35
  4. Mesurer les performances en utilisant le flag --perf
  5. Démarrer le serveur et tester les requêtes API
  6. Créer un script Python qui traite 5 prompts différents en lot

Références


Suivant : Continuez vers Module 5.4 : Inférence haute performance avec vLLM pour du LLM serving de qualité production !