Per ora questa sezione è disponibile solo in inglese.
Documentazione principale
Livello sperimentale

LibreVLM

Punta un modello visione-linguaggio su un'immagine, forniscigli un elenco di parole e ottieni dei box. LibreVLM trasforma Qwen3-VL, Florence-2 e modelli simili in rilevatori di oggetti a vocabolario aperto che usano esattamente la stessa API Results di ogni altro modello LibreYOLO.

Introduzione

Un rilevatore classico include nella propria testa un elenco fisso di classi. LibreVLM elimina questo vincolo. Racchiude moderni modelli visione-linguaggio ottimizzati per seguire istruzioni, chiede loro di generare bounding box, analizza il testo prodotto e restituisce lo stesso oggetto Results che usi già per YOLO9 e RF-DETR. L'elenco delle classi è semplicemente un elenco di parole fornito durante l'esecuzione, quindi aggiungere una nuova categoria non costa nulla e funziona in modalità zero-shot.

  • Vocabolario aperto. Rileva "pink car", "license plate" o "the small island" senza addestrare una testa specifica.
  • Una factory, un contratto. LibreVLM(...) restituisce l'oggetto Results standard con boxes.xyxy, boxes.cls, boxes.conf, oltre a .plot() e .save().
  • Backend intercambiabili. Sei famiglie di modelli dietro un'unica stringa alias, da Florence-2 con 230M parametri a Qwen3-VL con 8B.
  • Una via d'uscita diretta. chat() permette di fare domande libere sulle immagini quando ti serve qualcosa di più dei box.

Perché un livello separato e una pagina separata

LibreVLM viene deliberatamente tenuto fuori dalla factory a vocabolario chiuso LibreYOLO(...) e dal suo registro .pt. Questi modelli sono guidati da prompt, usano un vocabolario aperto e riportano una confidenza sintetica, quindi rispettano un contratto diverso. Trattarli come un livello indipendente mantiene chiara la documentazione principale sul rilevamento e descrive con trasparenza ciò che viene misurato.

Nel branch dev

LibreVLM si trova attualmente nel branch dev ed è previsto per la release v1.3; non fa parte della v1.2.0. È un livello di inferenza disponibile solo tramite Python: non esistono ancora percorsi per addestramento, validazione, esportazione o CLI e i punteggi di confidenza sono segnaposto. Leggi la sezione Limitazioni prima di costruirci sopra.

Installazione

LibreVLM è disponibile tramite il pacchetto extra opzionale vlm. Installa una versione recente di transformers e gli strumenti ausiliari richiesti da alcuni processori. Senza il pacchetto extra, l'importazione di una famiglia VLM genera un ImportError che rimanda a questa pagina.

bash
1pip install 'libreyolo[vlm]'

I pesi vengono scaricati da Hugging Face Hub al primo utilizzo in una cartella locale weights/. Alcune famiglie vengono distribuite con licenze non OSI e mostrano un avviso una sola volta prima del download. Per i backend più grandi è consigliata una GPU, ma ogni modello funziona anche su CPU con device="cpu".

Avvio rapido

Crea un modello, dichiara le parole che ti interessano ed esegui la predizione. Il backend predefinito è Qwen3-VL-4B, il rilevatore più potente del livello, con licenza Apache-2.0.

python
1from libreyolo import LibreVLM
2
3# Qwen3-VL-4B by default; weights autodownload on first use
4model = LibreVLM()
5
6# The vocabulary is just words. Any words.
7model.set_classes(["pink car", "wheel"])
8
9result = model.predict("street.jpg")
10
11print(result.boxes.xyxy) # pixel [x1, y1, x2, y2]
12print(result.boxes.cls) # ids into ["pink car", "wheel"]
13result.plot() # same drawing helpers as any LibreYOLO model
14result.save("out.jpg")

Questo è l'intero ciclo. Tutto ciò che segue predict() si comporta come un normale rilevatore, quindi il codice esistente per visualizzazione, ritaglio e tracking continua a funzionare.

Modelli supportati

Scegli un backend tramite l'alias che passi a LibreVLM(...). Il solo nome della famiglia seleziona la dimensione predefinita. Il backend predefinito complessivo è qwen3-vl-4b. In pratica, i rilevatori più potenti sono Qwen3-VL, LFM2-VL e Florence-2.

FamigliaAliasDimensioni (parametri)LicenzaNote
Qwen3-VLqwen3-vl-2b / -4b / -8b2B / 4B / 8BApache-2.0Predefinito e più potente. Punto di partenza consigliato.
LFM2-VLlfm2-vl-450m / -1.6b450M / 1.6BLFM Open LicenseDimensioni adatte all'edge, piccolo rilevatore sorprendentemente potente. Richiede la conferma di un avviso.
InternVL3internvl3-1b / -2b / -8b1B / 2B / 8BQwen LicenseBuon grounding nella versione 8B; le dimensioni piccole sono deboli. Richiede la conferma di un avviso.
Florence-2florence-2-base / -large0.23B / 0.77BMITModello creato appositamente per il grounding. Box precisi, senza chat().
SmolVLM2smolvlm2-500m / -2.2b500M / 2.2BApache-2.0Piccolo e veloce; rilevatore meno potente. Adatto per prove rapide.
Kosmos-2kosmos-2~1.6BMITModello di grounding del 2023. Box più approssimativi, senza chat().

Scegliere un backend

  • Qualità migliore: qwen3-vl-8b o qwen3-vl-4b (il predefinito).
  • Box precisi e ingombro ridotto: florence-2-large.
  • Edge / CPU: lfm2-vl-450m o smolvlm2-500m.
  • Licenza completamente permissiva: qualsiasi dimensione di Qwen3-VL, SmolVLM2, Florence-2 o Kosmos-2.

Licenze

Qwen3-VL e SmolVLM2 hanno licenza Apache-2.0; Florence-2 e Kosmos-2 hanno licenza MIT. LFM2-VL e InternVL3 usano licenze non OSI e mostrano un avviso una sola volta prima del primo download, così puoi fare una scelta informata per l'uso commerciale.

Impostare il vocabolario

Il vocabolario è il cuore del rilevamento a vocabolario aperto. Chiama set_classes() con un elenco di stringhe di etichette. L'impostazione è persistente: rimane valida per ogni successiva chiamata a predict() e track() finché non la modifichi. Il metodo restituisce self, quindi può essere concatenato.

python
1# Sticky and chainable
2model = LibreVLM("qwen3-vl-2b").set_classes(["person", "dog", "cat"])
3
4# Set it once at construction instead
5model = LibreVLM("lfm2-vl-450m", names=["boat"], device="cpu")
6
7# Re-set any time to change what you are looking for
8model.set_classes(["a red car", "a blue truck"])

Le etichette possono essere qualsiasi frase. Devono essere univoche senza distinzione tra maiuscole e minuscole e devi passare un elenco, non una singola stringa. Se non chiami mai set_classes(), il modello usa come fallback il vocabolario COCO-80, così anche un semplice predict() produce un risultato sensato.

Predizione

predict() e la chiamata equivalente model(...) accettano gli stessi tipi di sorgente di qualsiasi rilevatore LibreYOLO: un percorso, un'immagine PIL, un array numpy, un URL, una cartella o un video. Funzionano anche stream=True e track().

python
1result = 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)

Struttura restituita

Ottieni l'oggetto Results standard, identico a quello di un rilevatore a vocabolario chiuso:

CampoForma / tipoSignificato
result.boxes.xyxyN x 4Box in pixel [x1, y1, x2, y2], ridimensionati in base all'immagine originale.
result.boxes.clsNID delle classi che indicizzano il vocabolario di set_classes().
result.boxes.confNConfidenza sintetica: 1.0 per ogni box (vedi Limitazioni).
result.plot() / .save()-I consueti strumenti ausiliari per disegnare e salvare.

Dietro le quinte, LibreVLM analizza in modo tollerante l'output del modello, gestendo delimitatori markdown, testo estraneo, box duplicati e array troncati; associa le etichette in testo libero agli ID delle classi e scarta ogni etichetta che non appartiene al vocabolario. Quest'ultimo passaggio fa sì che un generatore a forma libera si comporti come un rilevatore a insieme chiuso.

Esempi

Rileva un oggetto di un colore specifico

python
1from libreyolo import LibreVLM
2
3model = LibreVLM("qwen3-vl-4b")
4model.set_classes(["red car"])
5
6result = model.predict("parking_lot.jpg")
7print(f"Found {len(result.boxes.cls)} red car(s)")
8result.save("red_cars.jpg")

Box precisi con Florence-2

python
1# Florence-2 is a purpose-built grounder: very tight pixel boxes.
2model = LibreVLM("florence-2-large")
3model.set_classes(["a red car", "license plate"])
4
5result = model.predict("car.jpg")
6result.plot()

Filtra al volo una singola classe

python
1model = LibreVLM("qwen3-vl-2b").set_classes(["person", "dog", "cat"])
2
3# classes= filters the configured vocabulary by id
4people_only = model.predict("street.jpg", classes=[0])

Esegui su CPU con un'immagine di esempio integrata

python
1from libreyolo import LibreVLM, SAMPLE_IMAGE
2
3model = LibreVLM("lfm2-vl-450m", device="cpu")
4# No set_classes() -> falls back to the COCO-80 vocabulary
5result = model.predict(SAMPLE_IMAGE)
6print(model.names[result.boxes.cls[0]]) # e.g. "person"

Batch, cartelle e video

python
1model = LibreVLM().set_classes(["forklift", "pallet"])
2
3# A whole folder
4for result in model.predict("warehouse_frames/", stream=True):
5 result.save()
6
7# A video file (frames are processed one at a time)
8model.predict("warehouse.mp4", save=True)

Chat diretta

A volte ti serve il modello, non il rilevatore. Le famiglie con template di chat espongono chat(), che riceve un'immagine e un prompt a forma libera e restituisce il testo decodificato senza modifiche. Usalo per il conteggio, la generazione di didascalie o domande visive rapide.

python
1model = LibreVLM("qwen3-vl-4b")
2
3answer = model.chat("harbor.jpg", "How many boats are docked? Answer with a number.")
4print(answer)

chat() è disponibile nelle famiglie con template di chat (Qwen3-VL, LFM2-VL, SmolVLM2, InternVL3). Florence-2 e Kosmos-2 sono modelli di grounding basati su token di task e generano NotImplementedError; con questi modelli usa predict().

Differenze tra i backend

Ogni famiglia restituisce lo stesso oggetto Results, ma lo ottiene in modo diverso. Raramente è necessario occuparsene, ma aiuta a capire perché alcuni backend si comportano in un determinato modo. Alle famiglie di chat viene richiesto un array JSON di box; i modelli di grounding usano token di task dedicati.

FamigliaPromptSpazio delle coordinatechat()
Qwen3-VLPrompt JSON per i boxDa 0 a 1000, ridimensionato
LFM2-VLPrompt JSON per i boxNormalizzato da 0 a 1
SmolVLM2Prompt JSON per i boxNormalizzato da 0 a 1
InternVL3Prompt JSON per i boxDa 0 a 1000, ridimensionato
Florence-2Token di taskPixel nativiNo
Kosmos-2Prompt di groundingNormalizzato e ridimensionatoNo

Per le famiglie di chat puoi sostituire il prompt di rilevamento con l'argomento prompt= del costruttore e limitare la lunghezza della generazione con max_new_tokens=. Il dispositivo e il dtype vengono determinati automaticamente: bf16 o fp16 su CUDA, fp32 su CPU.

Limitazioni

LibreVLM è potente ma ancora giovane. Conoscerne subito i limiti evita sorprese in seguito.

  • Confidenza sintetica. Ogni box riceve un punteggio di 1.0. Il filtro conf= si comporta quindi in modo tutto o niente, anziché come una vera soglia.
  • Niente mAP o validazione. val() genera un errore perché i punteggi sintetici renderebbero fuorviante la mAP COCO.
  • Niente addestramento o esportazione. train() ed export() generano un errore. Esegui invece il fine-tuning del VLM upstream e carica i pesi risultanti.
  • Tracking limitato. track() funziona, ma i punteggi uniformi rendono inattiva la fase di recupero a bassa confidenza del tracker.
  • Un'immagine alla volta. Nella v1 la generazione è sequenziale, quindi valori maggiori di batch= non aumentano la velocità.
  • Solo API Python. La CLI libreyolo non riconosce ancora gli alias VLM.

Dove dà il meglio

Usa LibreVLM quando l'insieme di classi è aperto, cambia spesso o è difficile da etichettare in anticipo: prototipazione rapida, categorie rare o a coda lunga e flussi di lavoro del tipo "trova la cosa che descrivo a parole". Quando ti servono confidenza calibrata, throughput o un artefatto pronto per il deployment, addestra un modello YOLO9 o RF-DETR a vocabolario chiuso seguendo la documentazione principale.

Solo inferenzabranch dev / previsto per la v1.3Sorgente su GitHub