LibreVLM
Pointez un modèle de vision-langage vers une image, fournissez-lui une liste de mots et récupérez des boîtes. LibreVLM transforme Qwen3-VL, Florence-2 et les modèles similaires en détecteurs d'objets à vocabulaire ouvert qui utilisent exactement la même API Results que tous les autres modèles LibreYOLO.
Introduction
Un détecteur classique est fourni avec une liste fixe de classes intégrée à sa tête. LibreVLM supprime cette contrainte. Il encapsule des modèles de vision-langage modernes affinés par instructions, leur demande d'émettre des bounding boxes, analyse le texte généré et renvoie le même objet Results que celui que vous utilisez déjà avec YOLO9 et RF-DETR. La liste de classes n'est qu'une liste de mots que vous fournissez au runtime : ajouter une catégorie ne coûte donc rien et fonctionne en zero-shot.
- Vocabulaire ouvert. Détectez
"pink car","license plate"ou"the small island"sans jamais entraîner de tête pour ces classes. - Une factory, un contrat.
LibreVLM(...)renvoie l'objetResultsstandard avecboxes.xyxy,boxes.clsetboxes.conf, ainsi que.plot()et.save(). - Backends interchangeables. Six familles de modèles derrière une seule chaîne d'alias, de Florence-2 230M à Qwen3-VL 8B.
- Un accès brut.
chat()vous permet de poser des questions libres sur une image lorsque les boîtes ne suffisent pas.
Pourquoi un niveau distinct (et une page distincte)
LibreVLM est délibérément tenu à l'écart de la factory LibreYOLO(...) à vocabulaire fermé et de son registre .pt. Ces modèles sont pilotés par prompt, à vocabulaire ouvert et indiquent une confiance synthétique : ils respectent donc un contrat différent. Les traiter comme un niveau distinct permet de conserver une documentation de détection principale claire et fidèle aux mesures effectuées.
Sur la branche dev
LibreVLM se trouve actuellement sur la branche dev et vise la version v1.3 ; il ne fait pas partie de v1.2.0. C'est un niveau d'inférence réservé à Python : l'entraînement, la validation, l'export et le chemin CLI ne sont pas encore disponibles, et les scores de confiance sont des valeurs temporaires. Lisez la section Limitations avant de vous appuyer dessus.
Installation
LibreVLM est disponible via l'extra facultatif vlm. Celui-ci installe une version récente de transformers et les utilitaires requis par certains processeurs. Sans cet extra, l'import d'une famille VLM déclenche une ImportError qui vous renvoie ici.
1 pip install 'libreyolo[vlm]'
Les poids sont téléchargés depuis le Hub Hugging Face lors de la première utilisation, dans un dossier local weights/. Quelques familles sont fournies sous des licences non OSI et affichent un avertissement unique avant le téléchargement. Un GPU est recommandé pour les backends les plus volumineux, mais chaque modèle fonctionne aussi sur CPU avec device="cpu".
Démarrage rapide
Construisez un modèle, définissez les mots qui vous intéressent et lancez une prédiction. Le backend par défaut est Qwen3-VL-4B, le détecteur le plus performant du niveau, sous licence Apache-2.0.
1 from libreyolo import LibreVLM 2 3 # Qwen3-VL-4B by default; weights autodownload on first use 4 model = LibreVLM() 5 6 # The vocabulary is just words. Any words. 7 model.set_classes(["pink car", "wheel"]) 8 9 result = model.predict("street.jpg") 10 11 print(result.boxes.xyxy) # pixel [x1, y1, x2, y2] 12 print(result.boxes.cls) # ids into ["pink car", "wheel"] 13 result.plot() # same drawing helpers as any LibreYOLO model 14 result.save("out.jpg")
La boucle complète se résume à cela. Tout ce qui suit predict() se comporte comme avec un détecteur normal : le code existant de visualisation, de recadrage et de suivi continue donc de fonctionner.
Modèles pris en charge
Choisissez un backend avec l'alias que vous transmettez à LibreVLM(...). Un nom de famille seul correspond à sa taille par défaut. Le backend global par défaut est qwen3-vl-4b. En pratique, les détecteurs les plus performants sont Qwen3-VL, LFM2-VL et Florence-2.
| Famille | Alias | Tailles (paramètres) | Licence | Notes |
|---|---|---|---|---|
| Qwen3-VL | qwen3-vl-2b / -4b / -8b | 2B / 4B / 8B | Apache-2.0 | Modèle par défaut et le plus performant. Point de départ recommandé. |
| LFM2-VL | lfm2-vl-450m / -1.6b | 450M / 1.6B | LFM Open License | Conçu pour l'edge, petit détecteur étonnamment performant. Soumis à un avertissement. |
| InternVL3 | internvl3-1b / -2b / -8b | 1B / 2B / 8B | Qwen License | Bon grounding à 8B ; les petites tailles sont peu performantes. Soumis à un avertissement. |
| Florence-2 | florence-2-base / -large | 0.23B / 0.77B | MIT | Modèle de grounding dédié. Boîtes ajustées, pas de chat(). |
| SmolVLM2 | smolvlm2-500m / -2.2b | 500M / 2.2B | Apache-2.0 | Minuscule et rapide ; détecteur moins performant. Adapté aux essais rapides. |
| Kosmos-2 | kosmos-2 | ~1.6B | MIT | Modèle de grounding de 2023. Boîtes plus approximatives, pas de chat(). |
Choisir un backend
- Meilleure qualité :
qwen3-vl-8bouqwen3-vl-4b(modèle par défaut). - Boîtes ajustées, faible encombrement :
florence-2-large. - Edge / CPU :
lfm2-vl-450mousmolvlm2-500m. - Licence entièrement permissive : toutes les tailles de Qwen3-VL, SmolVLM2, Florence-2 ou Kosmos-2.
Licences
Qwen3-VL et SmolVLM2 sont sous licence Apache-2.0 ; Florence-2 et Kosmos-2 sont sous licence MIT. LFM2-VL et InternVL3 utilisent des licences non OSI et affichent un avertissement unique avant leur premier téléchargement, afin que vous puissiez faire un choix éclairé pour un usage commercial.
Définir le vocabulaire
Le vocabulaire est au cœur de la détection à vocabulaire ouvert. Appelez set_classes() avec une liste de chaînes d'étiquettes. Ce réglage est persistant : il s'applique à tous les appels ultérieurs à predict() et track() jusqu'à ce que vous le redéfinissiez. La méthode renvoie self, ce qui permet de chaîner les appels.
1 # Sticky and chainable 2 model = LibreVLM("qwen3-vl-2b").set_classes(["person", "dog", "cat"]) 3 4 # Set it once at construction instead 5 model = LibreVLM("lfm2-vl-450m", names=["boat"], device="cpu") 6 7 # Re-set any time to change what you are looking for 8 model.set_classes(["a red car", "a blue truck"])
Les étiquettes peuvent être n'importe quelle expression. Elles doivent être uniques sans tenir compte de la casse, et vous devez transmettre une liste, pas une simple chaîne. Si vous n'appelez jamais set_classes(), le modèle utilise le vocabulaire COCO-80 par défaut afin qu'un simple predict() produise tout de même un résultat pertinent.
Prédiction
predict() (et l'appel équivalent à model(...)) accepte les mêmes types de sources que tous les détecteurs LibreYOLO : un chemin, une image PIL, un tableau numpy, une URL, un dossier ou une vidéo. stream=True et track() fonctionnent aussi.
1 result = model.predict( 2 source="image.jpg", # path | PIL | ndarray | URL | folder | video 3 conf=0.25, # see note below: scoring is synthetic 4 classes=[0], # optional: keep only these vocabulary ids 5 max_det=300, 6 )
Structure du retour
Vous récupérez l'objet Results standard, identique à celui d'un détecteur à vocabulaire fermé :
| Champ | Forme / type | Signification |
|---|---|---|
result.boxes.xyxy | N x 4 | Boîtes en pixels [x1, y1, x2, y2], redimensionnées aux dimensions de l'image d'origine. |
result.boxes.cls | N | Identifiants de classe indexant votre vocabulaire set_classes(). |
result.boxes.conf | N | Confiance synthétique : 1.0 pour chaque boîte (voir Limitations). |
result.plot() / .save() | - | Utilitaires habituels de dessin et d'enregistrement. |
En interne, LibreVLM analyse avec tolérance la sortie du modèle (blocs délimités en Markdown, texte parasite, boîtes dupliquées et tableaux tronqués), remappe les étiquettes de texte libre vers vos identifiants de classe et ignore toute étiquette absente de votre vocabulaire. Cette dernière étape permet à un générateur libre de se comporter comme un détecteur à ensemble fermé.
Exemples
Détecter un objet d'une couleur précise
1 from libreyolo import LibreVLM 2 3 model = LibreVLM("qwen3-vl-4b") 4 model.set_classes(["red car"]) 5 6 result = model.predict("parking_lot.jpg") 7 print(f"Found {len(result.boxes.cls)} red car(s)") 8 result.save("red_cars.jpg")
Boîtes ajustées avec Florence-2
1 # Florence-2 is a purpose-built grounder: very tight pixel boxes. 2 model = LibreVLM("florence-2-large") 3 model.set_classes(["a red car", "license plate"]) 4 5 result = model.predict("car.jpg") 6 result.plot()
Filtrer à la volée sur une seule classe
1 model = LibreVLM("qwen3-vl-2b").set_classes(["person", "dog", "cat"]) 2 3 # classes= filters the configured vocabulary by id 4 people_only = model.predict("street.jpg", classes=[0])
Exécuter sur CPU avec une image d'exemple intégrée
1 from libreyolo import LibreVLM, SAMPLE_IMAGE 2 3 model = LibreVLM("lfm2-vl-450m", device="cpu") 4 # No set_classes() -> falls back to the COCO-80 vocabulary 5 result = model.predict(SAMPLE_IMAGE) 6 print(model.names[result.boxes.cls[0]]) # e.g. "person"
Batchs, dossiers et vidéo
1 model = LibreVLM().set_classes(["forklift", "pallet"]) 2 3 # A whole folder 4 for result in model.predict("warehouse_frames/", stream=True): 5 result.save() 6 7 # A video file (frames are processed one at a time) 8 model.predict("warehouse.mp4", save=True)
Chat brut
Vous avez parfois besoin du modèle, pas du détecteur. Les familles à template de chat exposent chat(), qui reçoit une image et un prompt libre, puis renvoie le texte décodé tel quel. Utilisez-la pour compter, générer des légendes ou répondre à des questions visuelles rapides.
1 model = LibreVLM("qwen3-vl-4b") 2 3 answer = model.chat("harbor.jpg", "How many boats are docked? Answer with a number.") 4 print(answer)
chat() est disponible pour les familles à template de chat (Qwen3-VL, LFM2-VL, SmolVLM2, InternVL3). Florence-2 et Kosmos-2 sont des modèles de grounding à token de tâche et déclenchent une NotImplementedError ; utilisez predict() avec eux.
Différences entre les backends
Chaque famille renvoie le même Results, mais y parvient différemment. Vous avez rarement besoin de vous en préoccuper, mais ces détails expliquent le comportement de certains backends. Les familles de chat reçoivent un prompt demandant un tableau JSON de boîtes ; les modèles de grounding utilisent des tokens de tâche dédiés.
| Famille | Méthode de prompting | Espace de coordonnées | chat() |
|---|---|---|---|
| Qwen3-VL | Prompt JSON de boîtes | 0 à 1000, remis à l'échelle | Oui |
| LFM2-VL | Prompt JSON de boîtes | Normalisé de 0 à 1 | Oui |
| SmolVLM2 | Prompt JSON de boîtes | Normalisé de 0 à 1 | Oui |
| InternVL3 | Prompt JSON de boîtes | 0 à 1000, remis à l'échelle | Oui |
| Florence-2 | Token de tâche | Pixels natifs | Non |
| Kosmos-2 | Prompt de grounding | Normalisé, remis à l'échelle | Non |
Pour les familles de chat, vous pouvez remplacer le prompt de détection avec l'argument de constructeur prompt= et limiter la longueur de génération avec max_new_tokens=. Le device et le dtype sont déterminés automatiquement : bf16 ou fp16 sur CUDA, fp32 sur CPU.
Limitations
LibreVLM est puissant mais encore jeune. Connaître ses limites dès le départ évite les surprises.
- Confiance synthétique. Chaque boîte reçoit un score de 1.0. Le filtre
conf=fonctionne donc en tout ou rien, plutôt que comme un véritable seuil. - Pas de mAP ni de validation.
val()déclenche une erreur, car des scores synthétiques rendraient la mAP COCO trompeuse. - Pas d'entraînement ni d'export.
train()etexport()déclenchent une erreur. Faites le fine-tuning du VLM en amont et chargez plutôt les poids obtenus. - Suivi dégradé.
track()s'exécute, mais les scores uniformes rendent inopérante l'étape de récupération à faible confiance du tracker. - Une seule image à la fois. La génération est séquentielle dans la v1, donc augmenter la valeur de
batch=n'accélère pas le traitement. - API Python uniquement. La CLI
libreyolone résout pas encore les alias VLM.
Cas d'usage idéaux
Utilisez LibreVLM lorsque l'ensemble de classes est ouvert, change souvent ou est difficile à étiqueter en amont : prototypage rapide, catégories rares ou de longue traîne, et workflows « trouver l'objet que je décris avec des mots ». Quand vous avez besoin d'une confiance calibrée, de débit ou d'un artefact déployable, entraînez un YOLO9 ou RF-DETR à vocabulaire fermé à partir de la documentation principale.