Intermédiaire 12 minVision

LLM multimodal vision en local : analyser des images avec Ollama

Décrire une photo, extraire un tableau d'un screenshot, lire le total d'une facture scannée : depuis 2024 les LLM vision open-weight tiennent la comparaison avec GPT-4o sur ces tâches, et Ollama les expose avec la même simplicité que les modèles texte. Ce guide montre comment installer un LLM vision local avec Ollama, l'appeler depuis Python avec une image base64, et tirer parti de Qwen2.5-VL, Llama 3.2-Vision ou Llama 4 Scout selon votre VRAM.

Par Mohamed Meguedmi·Màj 2026-05-23·Testé sur Windows, macOS, Linux

#Pourquoi un LLM vision en local ?

Envoyer une facture client, un screenshot médical ou un document RH chez OpenAI pose un problème de confidentialité que les directions juridiques refusent de plus en plus. Un LLM vision local répond à ces cas concrets : OCR de pièces comptables, description automatique d'un catalogue produit, modération d'images, accessibilité (alt-text), extraction de données depuis des PDF scannés.

La différence avec un OCR classique (Tesseract, PaddleOCR) : un LLM vision comprend la sémantique. Il sait dire "le numéro de TVA est FR12345678901" alors qu'un OCR vous rend une soupe de caractères que vous devez ensuite parser. Sur des documents structurés, la fiabilité dépasse 95 % en mode "extraction JSON".

i
Ce que vision veut dire ici
Un LLM "multimodal vision" accepte des images en entrée en plus du texte. Il ne génère pas d'images (pour ça, voir Stable Diffusion). Vous lui donnez une image + une question, il répond en texte.

#Les modèles vision disponibles dans Ollama

Ollama supporte nativement plusieurs familles vision depuis la version 0.4 (octobre 2024). Voici les options pertinentes en 2026, classées par taille et qualité d'OCR français.

qwen2.5vl:7b
Le meilleur compromis qualité/VRAM. Excellente OCR FR, comprend les tableaux et formulaires. ~6 Go VRAM en Q4.
qwen2.5vl:3b
Version légère pour 8 Go de VRAM ou Mac M1/M2 16 Go. OCR FR correcte, descriptions un peu moins riches.
qwen2.5vl:32b
Pour RTX 3090/4090/5090 : qualité proche de GPT-4o sur l'analyse de documents complexes. ~19 Go VRAM en Q4.
llama3.2-vision:11b
Modèle Meta sorti en septembre 2024. Très bon en description générale, moins précis en OCR pure. ~8 Go VRAM.
llama3.2-vision:90b
Le palier serveur. Demande 64+ Go de VRAM (multi-GPU ou Mac Studio Ultra). Pour usage pro intensif.
llama4:scout
Llama 4 Scout (avril 2025), MoE 17B actifs, 109B total. Architecture mixed expert, contexte 10M tokens. ~64 Go VRAM en Q4.
llava:7b / llava:13b
L'ancêtre, encore utile en dépannage. Qualité dépassée par Qwen2.5-VL en 2026.
moondream:1.8b
Modèle minuscule (~1,5 Go VRAM) pour Raspberry Pi 5 ou descriptions rapides en masse. Pas d'OCR sérieuse.
Recommandation par défaut
Si vous avez 8 Go de VRAM ou plus, commencez par qwen2.5vl:7b. C'est le meilleur rapport qualité/poids pour du français en 2026, et la communauté Ollama documente bien ses cas d'usage.

#Prérequis matériels

La VRAM nécessaire pour un LLM vision est légèrement supérieure à son équivalent texte, à cause du vision encoder (souvent un ViT) qui reste chargé en mémoire en plus du modèle de langage.

8 Go VRAM (RTX 3060 12GB, 4060, M1/M2 16GB)
qwen2.5vl:3b en Q4, ou llama3.2-vision:11b en quantization Q3.
12 Go VRAM (RTX 3060 12GB, 4070, 5070)
qwen2.5vl:7b confortable, llama3.2-vision:11b en Q4_K_M.
16 Go VRAM (RTX 4070 Ti Super, 4080, 5070 Ti)
Tout ce qui précède + contexte 32k tokens.
24 Go VRAM (RTX 3090, 4090, 5090)
qwen2.5vl:32b en Q4, qualité proche cloud.
Mac M-series 24-48 Go unifié
qwen2.5vl:7b ou 32b grâce à la mémoire unifiée. Préférez M3/M4 pour la bande passante.

Ollama doit être en version 0.4 minimum pour les modèles vision modernes. Vérifiez avec ollama --version. Si vous êtes en dessous, mettez à jour avant d'aller plus loin.

#1. Installer un modèle vision

L'installation est identique à un modèle texte : ollama pull télécharge les poids et le vision encoder en une seule commande.

Terminal — installer Qwen2.5-VL 7B
ollama pull qwen2.5vl:7b

Le téléchargement fait environ 5,5 Go (poids LM en Q4 + encoder ViT). Comptez 2-3 minutes sur fibre. Vérifiez ensuite que le modèle est listé :

Terminal
ollama list

# NAME              ID            SIZE      MODIFIED
# qwen2.5vl:7b      abc123...     5.5 GB    2 minutes ago
!
Tags vision spécifiques
Attention au tag : qwen2.5:7b (sans vl) est le modèle texte uniquement, qwen2.5vl:7b est la version multimodale. Beaucoup de débutants téléchargent le mauvais et se demandent pourquoi les images ne marchent pas.

#2. Premier test en CLI

Ollama accepte les images directement dans la CLI depuis la version 0.4 : passez le chemin du fichier après votre prompt.

Décrire une image en français
ollama run qwen2.5vl:7b "Décris cette image en 3 phrases en français." ./photo.jpg

Le modèle charge l'image, l'encode via ViT, et répond en streaming. Sur une RTX 4070, comptez 2-4 secondes pour une description courte, 8-12 secondes pour une analyse détaillée.

Sortie typique
L'image montre un chat tigré assis sur un rebord de fenêtre en bois clair.
Le pelage présente des rayures grises et noires caractéristiques d'un tabby.
À l'arrière-plan, on devine un jardin flou avec de la végétation verte.
Plusieurs images d'un coup
Vous pouvez passer plusieurs chemins : ollama run qwen2.5vl:7b "Compare ces deux images" photo1.jpg photo2.jpg. Utile pour du diff visuel ou de la dédup.

#3. API Python avec image base64

Pour intégrer un LLM vision dans une app, Ollama expose son endpoint REST sur http://localhost:11434. L'image se passe soit en chemin (binding Python), soit en base64 (HTTP brut).

Méthode recommandée : la bibliothèque officielle ollama-python. Elle gère l'encodage base64 pour vous et accepte un chemin directement.

Installation
pip install ollama pillow
vision_local.py — appel simple
import ollama

response = ollama.chat(
    model='qwen2.5vl:7b',
    messages=[{
        'role': 'user',
        'content': 'Quel est le texte visible sur cette image ? Réponds en français.',
        'images': ['./screenshot.png'],
    }],
)

print(response['message']['content'])

Si vous préférez gérer le base64 vous-même (image en mémoire, blob S3, upload via FastAPI), voici la version explicite :

Avec base64 explicite
import base64
import requests

with open('facture.png', 'rb') as f:
    img_b64 = base64.b64encode(f.read()).decode('utf-8')

response = requests.post(
    'http://localhost:11434/api/chat',
    json={
        'model': 'qwen2.5vl:7b',
        'messages': [{
            'role': 'user',
            'content': 'Décris cette image.',
            'images': [img_b64],
        }],
        'stream': False,
    },
    timeout=120,
)

print(response.json()['message']['content'])
i
Format base64 attendu
Ollama accepte le base64 brut, sans préfixe data:image/png;base64,. Si vous récupérez l'image depuis un navigateur, pensez à stripper ce préfixe avant l'appel.

#4. Cas pratique : OCR d'une facture FR

L'extraction structurée depuis un document scanné est le cas d'usage business le plus demandé. Le pattern qui marche le mieux : demander une sortie JSON avec un schéma explicite dans le prompt.

ocr_facture.py
import ollama
import json

SYSTEM = '''Tu es un assistant d'extraction de données comptables.
Tu réponds UNIQUEMENT en JSON valide, sans markdown, sans commentaire.'''

PROMPT = '''Extrais les informations de cette facture française au format JSON :
{
  "fournisseur": str,
  "siret": str ou null,
  "numero_facture": str,
  "date": "YYYY-MM-DD",
  "montant_ht": float,
  "tva": float,
  "montant_ttc": float,
  "lignes": [{"description": str, "quantite": float, "prix_unitaire": float}]
}'''

response = ollama.chat(
    model='qwen2.5vl:7b',
    messages=[
        {'role': 'system', 'content': SYSTEM},
        {'role': 'user', 'content': PROMPT, 'images': ['./facture.png']},
    ],
    format='json',
    options={'temperature': 0.1},
)

data = json.loads(response['message']['content'])
print(f"Fournisseur : {data['fournisseur']}")
print(f"Montant TTC : {data['montant_ttc']} €")

Deux astuces qui changent la fiabilité du tout au tout : passer format='json' (Ollama force alors un JSON valide en sortie) et baisser la température à 0.1 pour limiter les hallucinations sur les montants. Sur 100 factures FR variées, Qwen2.5-VL 7B obtient typiquement 92-96 % d'extraction correcte montant TTC + date + fournisseur.

!
Toujours valider les montants
Même à 96 %, vous aurez 4 erreurs sur 100 factures. En production, validez systématiquement que montant_ht + tva ≈ montant_ttc et flaggez les écarts pour revue humaine. Un LLM n'est pas un comptable agréé.

#Qwen2.5-VL vs Llama 3.2 Vision : que choisir ?

Les deux modèles dominent la scène open-weight vision en 2026. Notre comparatif terrain sur des cas francophones :

OCR français (factures, contrats)
Qwen2.5-VL gagne clairement. Llama 3.2-Vision a tendance à "inventer" des chiffres sur les documents flous. Avantage Qwen +15 % de précision.
Description générale d'image
Match nul. Llama 3.2-Vision donne des descriptions plus narratives, Qwen2.5-VL plus factuelles. Question de goût.
Compréhension de tableaux
Qwen2.5-VL excelle. C'est l'un des seuls modèles 7B qui sait lire un tableau croisé Excel sans le mélanger.
Captioning multilingue (FR/EN/ES)
Qwen2.5-VL a été entraîné sur plus de langues. Llama 3.2-Vision est meilleur en anglais pur.
Latence sur RTX 4070
Comparables : 2-4 s pour une réponse courte. Llama 3.2-Vision est 10-15 % plus rapide en première inférence (vision encoder plus petit).
Licence
Qwen2.5-VL en Apache 2.0 (usage commercial libre). Llama 3.2-Vision en Llama Community License (restrictions au-delà de 700M MAU).
Verdict pratique
Pour 90 % des cas d'usage francophones (OCR, extraction, description), Qwen2.5-VL est le choix par défaut. Llama 3.2-Vision reste pertinent si vous êtes déjà sur l'écosystème Meta (fine-tuning, déploiement Llama Stack) ou pour du captioning anglais grand public.

#Dépannage

"Error: model does not support images"
Vous appelez un modèle texte. Vérifiez que le tag contient bien vl, vision, llava ou moondream. ollama list doit afficher le bon modèle.
Le modèle décrit autre chose que l'image
Le base64 est probablement corrompu ou contient le préfixe data:image. Strippez data:image/png;base64, avant l'appel. Testez d'abord en CLI pour isoler le problème.
VRAM saturée au chargement
Le vision encoder s'ajoute aux poids LM. Passez à une quantization plus agressive (q3_K_M) ou réduisez OLLAMA_NUM_CTX à 4096 dans l'env.
OCR rate les accents français
Précisez explicitement "Réponds en français en préservant les accents" dans le system prompt. Sinon le modèle latinise parfois (e à la place de é).
Temps de réponse > 30 s
Une image 4000x3000 explose le nombre de tokens visuels. Redimensionnez à 1024x1024 max avant envoi : 90 % de la qualité OCR pour 10 % du compute.
Redimensionner avant inférence
from PIL import Image

img = Image.open('facture_4k.png')
img.thumbnail((1024, 1024), Image.LANCZOS)
img.save('facture_resized.png', optimize=True)

#Pour aller plus loin

Vous avez un LLM vision local fonctionnel. Trois directions naturelles pour aller plus loin :

Intégrer dans une app Python complète
Le guide Intégrer Ollama dans une application Python via l'API REST détaille FastAPI, streaming, function calling — applicable tel quel aux modèles vision.
Construire un pipeline d'extraction documentaire
Le guide Compta : extraction de factures montre l'industrialisation complète (queue de jobs, validation, export ERP) à partir d'un LLM vision local.
Choisir le GPU adapté à votre charge
Le guide Choisir son GPU pour l'IA locale couvre les paliers VRAM 12/16/24 Go et leur impact sur les modèles vision 7B/32B.
Ce guide vous a aidé ?

Un retour, une erreur, une précision ? Faites-nous signe, ça améliore le guide pour tout le monde.