# Llama 3.2 Vision

Exécutez les modèles multimodaux Llama 3.2 Vision de Meta pour la compréhension d'images sur les GPU CLORE.AI.

{% hint style="success" %}
Tous les exemples peuvent être exécutés sur des serveurs GPU loués via [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

## Pourquoi Llama 3.2 Vision ?

* **Multimodal** - Comprend à la fois le texte et les images
* **Tailles multiples** - Versions de 11B et 90B de paramètres
* **Polyvalent** - OCR, questions/réponses visuelles, légendes d'images, analyse de documents
* **Poids ouverts** - Entièrement open source de Meta
* **Écosystème Llama** - Compatible avec Ollama, vLLM, transformers

## Variantes de modèle

| Modèle                        | Paramètres | VRAM (FP16) | Contexte | Idéal pour                |
| ----------------------------- | ---------- | ----------- | -------- | ------------------------- |
| Llama-3.2-11B-Vision          | 11B        | 24 Go       | 128K     | Usage général, GPU unique |
| Llama-3.2-90B-Vision          | 90B        | 180 Go      | 128K     | Qualité maximale          |
| Llama-3.2-11B-Vision-Instruct | 11B        | 24 Go       | 128K     | Chat/assistant            |
| Llama-3.2-90B-Vision-Instruct | 90B        | 180 Go      | 128K     | Production                |

## Déploiement rapide sur CLORE.AI

**Image Docker :**

```
vllm/vllm-openai:latest
```

**Ports :**

```
22/tcp
8000/http
```

**Commande :**

```bash
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.2-11B-Vision-Instruct \
    --host 0.0.0.0 \
    --port 8000 \
    --max-model-len 8192
```

## Accéder à votre service

Après le déploiement, trouvez votre `http_pub` URL dans **Mes commandes**:

1. Aller à la **Mes commandes** page
2. Cliquez sur votre commande
3. Trouvez l' `http_pub` URL (par ex., `abc123.clorecloud.net`)

Utilisez `https://VOTRE_HTTP_PUB_URL` au lieu de `localhost` dans les exemples ci-dessous.

## Exigences matérielles

| Modèle     | GPU minimum   | Recommandé   | Optimal   |
| ---------- | ------------- | ------------ | --------- |
| Vision 11B | RTX 4090 24GB | A100 40GB    | A100 80GB |
| Vision 90B | 4x A100 40Go  | 4x A100 80GB | 8x H100   |

## Installation

### Utilisation d'Ollama (le plus simple)

```bash
# Récupérer le modèle
ollama pull llama3.2-vision:11b

# Exécuter en interactif
ollama run llama3.2-vision:11b
```

### Utilisation de vLLM

```bash
pip install vllm

python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.2-11B-Vision-Instruct \
    --host 0.0.0.0 \
    --port 8000
```

### Utilisation de Transformers

```python
import torch
from transformers import MllamaForConditionalGeneration, AutoProcessor

model_id = "meta-llama/Llama-3.2-11B-Vision-Instruct"

model = MllamaForConditionalGeneration.from_pretrained(
    model_id,
    torch_dtype=torch.bfloat16,
    device_map="auto"
)
processor = AutoProcessor.from_pretrained(model_id)
```

## Utilisation de base

### Compréhension d'image

```python
import torch
from transformers import MllamaForConditionalGeneration, AutoProcessor
from PIL import Image
import requests

model_id = "meta-llama/Llama-3.2-11B-Vision-Instruct"

model = MllamaForConditionalGeneration.from_pretrained(
    model_id,
    torch_dtype=torch.bfloat16,
    device_map="auto"
)
processor = AutoProcessor.from_pretrained(model_id)

# Charger l'image
url = "https://example.com/image.jpg"
image = Image.open(requests.get(url, stream=True).raw)

# Créer l'invite
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image"},
            {"type": "text", "text": "Qu'y a-t-il dans cette image ? Décrivez en détail."}
        ]
    }
]

input_text = processor.apply_chat_template(messages, add_generation_prompt=True)
inputs = processor(image, input_text, return_tensors="pt").to(model.device)

output = model.generate(**inputs, max_new_tokens=500)
print(processor.decode(output[0], skip_special_tokens=True))
```

### Avec Ollama

```bash
# Décrire une image
ollama run llama3.2-vision:11b "Décrivez cette image : /path/to/image.jpg"

# Ou utiliser l'API
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.2-vision:11b",
  "prompt": "Qu'est-ce qu'il y a dans cette image ?",
  "images": ["image_encodée_en_base64_ici"]
}'
```

### Avec l'API vLLM

```python
from openai import OpenAI
import base64

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="non-nécessaire"
)

# Encoder l'image en base64
with open("image.jpg", "rb") as f:
    image_base64 = base64.b64encode(f.read()).decode()

response = client.chat.completions.create(
    model="meta-llama/Llama-3.2-11B-Vision-Instruct",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Qu'y a-t-il dans cette image ?"},
                {
                    "type": "image_url",
                    "image_url": {"url": f"data:image/jpeg;base64,{image_base64}"}
                }
            ]
        }
    ],
    max_tokens=500
)

print(response.choices[0].message.content)
```

## Cas d'utilisation

### OCR / Extraction de texte

```python
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image"},
            {"type": "text", "text": "Extraire tout le texte de cette image. Formater en markdown."}
        ]
    }
]
```

### Analyse de documents

```python
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image"},
            {"type": "text", "text": "Analysez ce document. Résumez les points clés."}
        ]
    }
]
```

### Questions-réponses visuelles

```python
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image"},
            {"type": "text", "text": "Combien de personnes y a-t-il sur cette photo ? Que font-elles ?"}
        ]
    }
]
```

### Génération de légendes d'images

```python
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image"},
            {"type": "text", "text": "Écrivez une légende détaillée pour cette image adaptée aux réseaux sociaux."}
        ]
    }
]
```

### Code à partir de captures d'écran

```python
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image"},
            {"type": "text", "text": "Convertissez cette capture d'écran d'interface en code HTML/CSS."}
        ]
    }
]
```

## Images multiples

```python
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image"},
            {"type": "image"},
            {"type": "text", "text": "Comparez ces deux images. Quelles sont les différences ?"}
        ]
    }
]

# Traiter avec plusieurs images
inputs = processor(
    images=[image1, image2],
    text=input_text,
    return_tensors="pt"
).to(model.device)
```

## Traitement par lots

```python
import os
from PIL import Image

def process_images(image_paths, prompt):
    results = []

    for path in image_paths:
        image = Image.open(path)

        messages = [
            {
                "role": "user",
                "content": [
                    {"type": "image"},
                    {"type": "text", "text": prompt}
                ]
            }
        ]

        input_text = processor.apply_chat_template(messages, add_generation_prompt=True)
        inputs = processor(image, input_text, return_tensors="pt").to(model.device)

        output = model.generate(**inputs, max_new_tokens=300)
        result = processor.decode(output[0], skip_special_tokens=True)

        results.append({"file": path, "description": result})

        # Vider le cache entre les images
        torch.cuda.empty_cache()

    return results

# Traiter un dossier
images = [f"./images/{f}" for f in os.listdir("./images") if f.endswith(('.jpg', '.png'))]
results = process_images(images, "Décrivez cette image en un paragraphe.")
```

## Interface Gradio

```python
import gradio as gr
import torch
from transformers import MllamaForConditionalGeneration, AutoProcessor
from PIL import Image

model_id = "meta-llama/Llama-3.2-11B-Vision-Instruct"
model = MllamaForConditionalGeneration.from_pretrained(
    model_id, torch_dtype=torch.bfloat16, device_map="auto"
)
processor = AutoProcessor.from_pretrained(model_id)

def analyze_image(image, question):
    messages = [
        {
            "role": "user",
            "content": [
                {"type": "image"},
                {"type": "text", "text": question}
            ]
        }
    ]

    input_text = processor.apply_chat_template(messages, add_generation_prompt=True)
    inputs = processor(image, input_text, return_tensors="pt").to(model.device)

    output = model.generate(**inputs, max_new_tokens=500)
    return processor.decode(output[0], skip_special_tokens=True)

demo = gr.Interface(
    fn=analyze_image,
    inputs=[
        gr.Image(type="pil", label="Téléverser l'image"),
        gr.Textbox(label="Question", placeholder="Qu'y a-t-il dans cette image ?")
    ],
    outputs=gr.Textbox(label="Réponse"),
    title="Llama 3.2 Vision - Analyse d'image",
    description="Téléversez une image et posez-lui des questions. Exécuté sur CLORE.AI."
)

demo.launch(server_name="0.0.0.0", server_port=7860)
```

## Performances

| Tâche                          | Modèle | GPU       | Temps |
| ------------------------------ | ------ | --------- | ----- |
| Description d'une seule image  | 11B    | RTX 4090  | \~3s  |
| Description d'une seule image  | 11B    | A100 40GB | \~2s  |
| OCR (1 page)                   | 11B    | RTX 4090  | \~5s  |
| Analyse de document            | 11B    | A100 40GB | \~8s  |
| Traitement par lot (10 images) | 11B    | A100 40GB | \~25s |

## Quantification

### 4-bit avec bitsandbytes

```python
from transformers import BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.bfloat16
)

model = MllamaForConditionalGeneration.from_pretrained(
    model_id,
    quantization_config=quantization_config,
    device_map="auto"
)
```

### GGUF avec Ollama

```bash
# Quantifié en 4 bits (tient dans 8 Go de VRAM)
ollama pull llama3.2-vision:11b-q4_K_M

# Quantifié en 8 bits
ollama pull llama3.2-vision:11b-q8_0
```

## Estimation des coûts

Tarifs typiques du marketplace CLORE.AI :

| GPU           | Tarif horaire | Idéal pour             |
| ------------- | ------------- | ---------------------- |
| RTX 4090 24GB | \~$0.10       | Modèle 11B             |
| A100 40GB     | \~$0.17       | 11B avec contexte long |
| A100 80GB     | \~$0.25       | 11B optimal            |
| 4x A100 80GB  | \~$1.00       | Modèle 90B             |

*Les prix varient. Vérifiez* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *pour les tarifs actuels.*

**Économisez de l'argent :**

* Utilisez **Spot** ordres pour le traitement par lot
* Payer avec **CLORE** jetons
* Utilisez des modèles quantifiés (4 bits) pour le développement

## Dépannage

### Mémoire insuffisante

```python
# Utiliser la quantification 4 bits
model = MllamaForConditionalGeneration.from_pretrained(
    model_id,
    load_in_4bit=True,
    device_map="auto"
)

# Ou réduire max_new_tokens
output = model.generate(**inputs, max_new_tokens=256)
```

### Génération lente

* Assurez-vous que le GPU est utilisé (vérifiez `nvidia-smi`)
* Utilisez bfloat16 au lieu de float32
* Réduisez la résolution de l'image avant le traitement
* Utilisez vLLM pour un meilleur débit

### Image ne se charge pas

```python
from PIL import Image
import requests
from io import BytesIO

# À partir d'une URL
response = requests.get(url)
image = Image.open(BytesIO(response.content)).convert("RGB")

# À partir d'un fichier
image = Image.open("path/to/image.jpg").convert("RGB")

# Redimensionner si trop grande
max_size = 1024
if max(image.size) > max_size:
    image.thumbnail((max_size, max_size))
```

### Jeton HuggingFace requis

```bash
# Définir le jeton pour les modèles restreints
export HUGGING_FACE_HUB_TOKEN=hf_xxxxx

# Ou se connecter
huggingface-cli login
```

## Llama Vision vs Autres

| Fonction    | Llama 3.2 Vision | LLaVA 1.6  | GPT-4V       |
| ----------- | ---------------- | ---------- | ------------ |
| Paramètres  | 11B / 90B        | 7B / 34B   | Inconnu      |
| Open source | Oui              | Oui        | Non          |
| Qualité OCR | Excellent        | Bon        | Excellent    |
| Contexte    | 128K             | 32K        | 128K         |
| Multi-image | Oui              | Limité     | Oui          |
| Licence     | Llama 3.2        | Apache 2.0 | Propriétaire |

**Utilisez Llama 3.2 Vision lorsque :**

* Besoin d'un multimodal open source
* OCR et analyse de documents
* Intégration avec l'écosystème Llama
* Compréhension de contexte long

## Prochaines étapes

* [LLaVA](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-vision/llava-vision-language) - Modèle de vision alternatif
* [Florence-2](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-vision/florence2) - Le modèle de vision de Microsoft
* [composant Ollama](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-langage/ollama) - Déploiement facile
* [vLLM](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-langage/vllm) - Service en production
