254 lines
6.7 KiB
Markdown
254 lines
6.7 KiB
Markdown
# Utilisation de Qwen3-VL dans le Système
|
|
|
|
## Vue d'ensemble
|
|
|
|
**Qwen3-VL:8b** est un modèle vision-langage utilisé via **Ollama** pour le raisonnement visuel et la prise de décision intelligente.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────┐
|
|
│ Screenshots │
|
|
│ + Détections │
|
|
└────────┬────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ LLM Manager │ ← Interface Python
|
|
└────────┬────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ Ollama │ ← Serveur local (localhost:11434)
|
|
└────────┬────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ Qwen3-VL:8b │ ← Modèle vision-langage
|
|
└─────────────────┘
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Dans `config.py` :
|
|
```python
|
|
"llm": "qwen3-vl:8b",
|
|
"ollama": {
|
|
"host": "localhost:11434",
|
|
"timeout": 30
|
|
}
|
|
```
|
|
|
|
## Trois Usages Principaux
|
|
|
|
### 1. Raisonnement sur les Détections
|
|
|
|
**Quand ?** Après que OWL-v2/DINO/YOLO ont détecté plusieurs éléments UI
|
|
|
|
**Pourquoi ?** Pour choisir intelligemment le bon élément parmi plusieurs candidats
|
|
|
|
**Comment ?**
|
|
```python
|
|
# Dans orchestrator.py, ligne 525
|
|
llm_result = self.llm.reason_about_detections(
|
|
detections_data, # Liste des éléments détectés
|
|
context, # Fenêtre active, historique
|
|
intent # Intention de l'utilisateur
|
|
)
|
|
```
|
|
|
|
**Exemple concret :**
|
|
```
|
|
Situation : 3 boutons détectés sur l'écran
|
|
- Bouton "Annuler" (confiance: 0.92)
|
|
- Bouton "Enregistrer" (confiance: 0.88)
|
|
- Bouton "Fermer" (confiance: 0.85)
|
|
|
|
Intention utilisateur : "Sauvegarder le document"
|
|
|
|
Qwen3-VL analyse les screenshots + le contexte et répond :
|
|
{
|
|
"element_index": 1,
|
|
"confidence": 0.95,
|
|
"reasoning": "Le bouton 'Enregistrer' correspond à l'intention de sauvegarder"
|
|
}
|
|
```
|
|
|
|
**Entrées envoyées à Qwen3-VL :**
|
|
- **Images** : Screenshots des ROI (régions d'intérêt) de chaque élément détecté, encodés en base64
|
|
- **Prompt** : Description textuelle avec l'intention et le contexte
|
|
- **Format** : Demande une réponse JSON structurée
|
|
|
|
**Sortie attendue :**
|
|
```json
|
|
{
|
|
"element_index": 1,
|
|
"confidence": 0.95,
|
|
"reasoning": "Explication du choix"
|
|
}
|
|
```
|
|
|
|
### 2. Génération avec Vision
|
|
|
|
**Quand ?** Pour analyser des screenshots et générer des descriptions
|
|
|
|
**Pourquoi ?** Pour comprendre ce qui se passe dans l'interface
|
|
|
|
**Comment ?**
|
|
```python
|
|
response = llm_manager.generate_with_vision(
|
|
prompt="Décris cette interface utilisateur",
|
|
images=[screenshot]
|
|
)
|
|
```
|
|
|
|
**Exemple :**
|
|
```
|
|
Input : Screenshot d'une fenêtre + prompt "Que vois-tu ?"
|
|
|
|
Qwen3-VL répond :
|
|
"Je vois une fenêtre de traitement de texte avec une barre d'outils en haut
|
|
contenant des boutons pour enregistrer, imprimer et formater le texte.
|
|
Le document actuel semble être vide."
|
|
```
|
|
|
|
### 3. Score de Pertinence d'Action
|
|
|
|
**Quand ?** Pour évaluer si une action proposée est pertinente
|
|
|
|
**Pourquoi ?** Pour éviter d'exécuter des actions incorrectes
|
|
|
|
**Comment ?**
|
|
```python
|
|
score = llm_manager.score_action_relevance(
|
|
action={"action_type": "click", "target_element": "button"},
|
|
intent="Fermer la fenêtre"
|
|
)
|
|
# Retourne : 0.85 (très pertinent)
|
|
```
|
|
|
|
## Flux de Données Complet
|
|
|
|
### Exemple : Détection d'un pattern de 3 clics
|
|
|
|
```
|
|
1. Utilisateur clique 3 fois sur un bouton
|
|
↓
|
|
2. EventCapture détecte le pattern répétitif
|
|
↓
|
|
3. Orchestrator récupère les 3 screenshots
|
|
↓
|
|
4. VisionAnalysis crée les signatures visuelles
|
|
↓
|
|
5. OWL-v2/DINO/YOLO détectent les éléments UI
|
|
↓
|
|
6. LLMManager envoie à Qwen3-VL :
|
|
- Screenshots des éléments (base64)
|
|
- Contexte : "Fenêtre Firefox, 3 clics répétés"
|
|
- Intention : "Rafraîchir la page"
|
|
↓
|
|
7. Qwen3-VL analyse et répond :
|
|
{
|
|
"element_index": 0,
|
|
"confidence": 0.92,
|
|
"reasoning": "C'est le bouton de rafraîchissement"
|
|
}
|
|
↓
|
|
8. Orchestrator crée une tâche apprise
|
|
↓
|
|
9. Prochaine fois, le système peut rejouer automatiquement
|
|
```
|
|
|
|
## Format des Images Envoyées
|
|
|
|
Les images sont converties en base64 PNG :
|
|
|
|
```python
|
|
def _image_to_base64(self, image: np.ndarray) -> str:
|
|
# 1. Convertir numpy array en PIL Image
|
|
pil_image = Image.fromarray(image.astype(np.uint8))
|
|
|
|
# 2. Encoder en PNG
|
|
buffered = BytesIO()
|
|
pil_image.save(buffered, format="PNG")
|
|
|
|
# 3. Convertir en base64
|
|
img_str = base64.b64encode(buffered.getvalue()).decode()
|
|
|
|
return img_str
|
|
```
|
|
|
|
## Fallback Automatique
|
|
|
|
Si Qwen3-VL n'est pas disponible (Ollama arrêté, modèle non téléchargé), le système utilise un **fallback** :
|
|
|
|
```python
|
|
def _fallback_to_vision_only(self, detections):
|
|
# Sélectionne simplement l'élément avec la confiance la plus élevée
|
|
best_detection = max(detections, key=lambda d: d['confidence'])
|
|
return {
|
|
"selected_element": best_detection,
|
|
"confidence": best_detection['confidence'],
|
|
"reasoning": "Sélection basée sur la confiance vision (fallback)"
|
|
}
|
|
```
|
|
|
|
## Vérifier que Qwen3-VL fonctionne
|
|
|
|
```bash
|
|
# 1. Vérifier qu'Ollama est lancé
|
|
curl http://localhost:11434/api/tags
|
|
|
|
# 2. Lister les modèles disponibles
|
|
ollama list
|
|
|
|
# 3. Si qwen3-vl:8b n'est pas là, le télécharger
|
|
ollama pull qwen3-vl:8b
|
|
|
|
# 4. Tester le modèle
|
|
ollama run qwen3-vl:8b "Bonjour"
|
|
```
|
|
|
|
## Logs et Debugging
|
|
|
|
Le LLMManager log toutes ses actions :
|
|
|
|
```python
|
|
self.logger.log_action({
|
|
"action": "llm_reasoning",
|
|
"intent": intent,
|
|
"num_detections": len(detections),
|
|
"selected_index": result.get("element_index"),
|
|
"confidence": result.get("confidence")
|
|
})
|
|
```
|
|
|
|
Cherche dans `data/logs/` pour voir l'historique des décisions de Qwen3-VL.
|
|
|
|
## Performance
|
|
|
|
- **Latence** : ~1-2 secondes par requête (dépend du GPU)
|
|
- **Mémoire** : ~8 GB VRAM pour le modèle 8b
|
|
- **Précision** : Excellente pour le raisonnement visuel UI
|
|
|
|
## Différence avec les Modèles de Détection
|
|
|
|
| Modèle | Rôle | Sortie |
|
|
|--------|------|--------|
|
|
| **OWL-v2/DINO/YOLO** | Détection d'objets | Bounding boxes + labels |
|
|
| **Qwen3-VL** | Raisonnement | Décision intelligente + explication |
|
|
|
|
**Exemple :**
|
|
- OWL-v2 dit : "J'ai trouvé 3 boutons"
|
|
- Qwen3-VL dit : "Le bouton du milieu est le bon car il correspond à l'intention de sauvegarder"
|
|
|
|
## Résumé
|
|
|
|
Qwen3-VL est le **cerveau** du système qui :
|
|
1. ✅ Comprend le contexte visuel
|
|
2. ✅ Raisonne sur les intentions
|
|
3. ✅ Prend des décisions intelligentes
|
|
4. ✅ Explique ses choix
|
|
|
|
Les modèles de détection (OWL-v2, DINO, YOLO) sont les **yeux** qui trouvent les éléments, mais Qwen3-VL est le **cerveau** qui décide quoi faire avec.
|