Esta seção por enquanto está disponível só em inglês.
Documentação principal
Nível experimental

LibreVLM

Aponte um modelo de linguagem e visão para uma imagem, forneça uma lista de palavras e receba bounding boxes. O LibreVLM transforma Qwen3-VL, Florence-2 e modelos semelhantes em detectores de objetos de vocabulário aberto que usam exatamente a mesma API Results de todos os outros modelos do LibreYOLO.

Introdução

Um detector clássico vem com uma lista fixa de classes incorporada à sua cabeça. O LibreVLM elimina essa restrição. Ele encapsula modelos modernos de linguagem e visão ajustados por instruções, pede que emitam bounding boxes, analisa o texto gerado e retorna o mesmo objeto Results que você já usa com YOLO9 e RF-DETR. A lista de classes é apenas uma lista de palavras fornecida em runtime, portanto adicionar uma nova categoria não custa nada e funciona em zero-shot.

  • Vocabulário aberto. Detecte "pink car", "license plate" ou "the small island" sem jamais treinar uma cabeça para essas classes.
  • Uma fábrica, um contrato. LibreVLM(...) retorna o Results padrão com boxes.xyxy, boxes.cls, boxes.conf, além de .plot() e .save().
  • Backends intercambiáveis. Seis famílias de modelos por trás de uma única string de alias, de um Florence-2 com 230M a um Qwen3-VL com 8B.
  • Uma saída de emergência bruta. chat() oferece respostas livres a perguntas sobre imagens quando você precisa de mais do que bounding boxes.

Por que um nível separado (e uma página separada)

O LibreVLM é mantido intencionalmente fora da fábrica LibreYOLO(...) de vocabulário fechado e de seu registro .pt. Esses modelos são orientados por prompts, têm vocabulário aberto e informam confiança sintética, portanto seguem um contrato diferente. Tratá-los como um nível próprio mantém a documentação principal de detecção limpa e transparente sobre o que está sendo medido.

Na branch dev

Atualmente, o LibreVLM está na branch dev e tem lançamento previsto para a v1.3. Ele não faz parte da v1.2.0. É um nível de inferência exclusivo para Python: ainda não há caminhos de treinamento, validação, exportação ou CLI, e as pontuações de confiança são provisórias. Leia a seção Limitações antes de criar algo sobre ele.

Instalação

O LibreVLM fica disponível por meio do extra opcional vlm. Ele instala uma versão recente de transformers e os auxiliares exigidos por alguns processadores. Sem o extra, importar uma família VLM gera um ImportError que aponta para esta página.

bash
1pip install 'libreyolo[vlm]'

Os pesos são baixados do Hugging Face Hub no primeiro uso para uma pasta local weights/. Algumas famílias são distribuídas sob licenças que não são da OSI e registram um aviso único antes do download. Recomenda-se uma GPU para os backends maiores, mas todos os modelos também rodam em CPU com device="cpu".

Início rápido

Crie um modelo, declare as palavras que interessam e faça a predição. O backend padrão é Qwen3-VL-4B, o detector mais forte do nível, com licença 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")

Esse é o ciclo completo. Tudo depois de predict() se comporta como um detector normal, então o código existente de visualização, recorte e rastreamento continua funcionando.

Modelos compatíveis

Escolha um backend pelo alias passado a LibreVLM(...). O nome da família sem tamanho usa o tamanho padrão. O backend padrão geral é qwen3-vl-4b. Na prática, os detectores mais fortes são Qwen3-VL, LFM2-VL e Florence-2.

FamíliaNome alternativoTamanhos (parâmetros)LicençaObservações
Qwen3-VLqwen3-vl-2b / -4b / -8b2B / 4B / 8BApache-2.0Padrão e mais forte. Ponto de partida recomendado.
LFM2-VLlfm2-vl-450m / -1.6b450M / 1.6BLFM Open LicenseDimensionado para edge, um detector pequeno surpreendentemente forte. Exige aviso.
InternVL3internvl3-1b / -2b / -8b1B / 2B / 8BQwen LicenseBom grounding com 8B. Os tamanhos menores são fracos. Exige aviso.
Florence-2florence-2-base / -large0.23B / 0.77BMITModelo criado especificamente para grounding. Bounding boxes precisos, sem chat().
SmolVLM2smolvlm2-500m / -2.2b500M / 2.2BApache-2.0Minúsculo e rápido. Detector mais fraco, bom para testes rápidos.
Kosmos-2kosmos-2~1.6BMITModelo de grounding de 2023. Bounding boxes menos precisos, sem chat().

Escolha de um backend

  • Melhor qualidade: qwen3-vl-8b ou qwen3-vl-4b (o padrão).
  • Bounding boxes precisos e tamanho reduzido: florence-2-large.
  • Edge / CPU: lfm2-vl-450m ou smolvlm2-500m.
  • Licença totalmente permissiva: qualquer tamanho de Qwen3-VL, SmolVLM2, Florence-2 ou Kosmos-2.

Licenciamento

Qwen3-VL e SmolVLM2 usam Apache-2.0. Florence-2 e Kosmos-2 usam MIT. LFM2-VL e InternVL3 têm licenças que não são da OSI e emitem um aviso único antes do primeiro download, para que você possa tomar uma decisão informada sobre o uso comercial.

Definição do vocabulário

O vocabulário é o centro da detecção de vocabulário aberto. Chame set_classes() com uma lista de strings de labels. A configuração é persistente: ela permanece em todas as chamadas posteriores de predict() e track() até você defini-la novamente. O método retorna self, portanto pode ser encadeado.

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"])

As labels podem ser qualquer frase. Elas precisam ser únicas sem diferenciar maiúsculas de minúsculas, e você deve passar uma lista, não uma string isolada. Se você nunca chamar set_classes(), o modelo usará o vocabulário COCO-80, para que um predict() isolado ainda produza um resultado razoável.

Predição

predict() (e a chamada equivalente model(...)) aceita os mesmos tipos de fonte que qualquer detector do LibreYOLO: um caminho, uma imagem PIL, um array numpy, uma URL, uma pasta ou um vídeo. stream=True e track() também funcionam.

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)

Formato do retorno

Você recebe o objeto Results padrão, idêntico ao de um detector de vocabulário fechado:

CampoFormato / tipoSignificado
result.boxes.xyxyN x 4Bounding boxes em pixels [x1, y1, x2, y2], redimensionados para a imagem original.
result.boxes.clsNIDs de classe que indexam o vocabulário de set_classes().
result.boxes.confNConfiança sintética: 1.0 para cada bounding box (consulte Limitações).
result.plot() / .save()-Os auxiliares usuais de desenho e salvamento.

Nos bastidores, o LibreVLM analisa a saída do modelo de forma tolerante (lidando com blocos de markdown, texto solto, bounding boxes duplicados e arrays truncados), mapeia labels de texto livre de volta aos IDs das suas classes e descarta qualquer label que não esteja no seu vocabulário. Essa última etapa faz um gerador de formato livre se comportar como um detector de conjunto fechado.

Exemplos

Detectar um objeto de uma cor específica

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")

Bounding boxes precisos com 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()

Filtrar para uma única classe durante a execução

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])

Executar na CPU com uma imagem de amostra integrada

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"

Batches, pastas e vídeo

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 bruto

Às vezes, você quer o modelo, não o detector. As famílias com template de chat expõem chat(), que recebe uma imagem e um prompt de formato livre e retorna o texto decodificado sem alterações. Use-o para contagem, criação de legendas ou perguntas visuais rápidas.

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

chat() está disponível nas famílias com template de chat (Qwen3-VL, LFM2-VL, SmolVLM2, InternVL3). Florence-2 e Kosmos-2 são modelos de grounding por token de tarefa e geram NotImplementedError. Use predict() com eles.

Como os backends diferem

Todas as famílias retornam o mesmo Results, mas chegam a ele de maneiras diferentes. Você raramente precisa se preocupar com isso, porém conhecer essas diferenças ajuda a entender por que alguns backends se comportam como se comportam. As famílias de chat recebem a instrução de gerar um array JSON de bounding boxes. Os modelos de grounding usam tokens de tarefa dedicados.

FamíliaPromptEspaço de coordenadaschat()
Qwen3-VLPrompt JSON de bounding boxes0 a 1000, redimensionadoSim
LFM2-VLPrompt JSON de bounding boxesNormalizado de 0 a 1Sim
SmolVLM2Prompt JSON de bounding boxesNormalizado de 0 a 1Sim
InternVL3Prompt JSON de bounding boxes0 a 1000, redimensionadoSim
Florence-2Token de tarefaPixels nativosNão
Kosmos-2Prompt de groundingNormalizado, redimensionadoNão

Nas famílias de chat, você pode substituir o prompt de detecção com o argumento prompt= do construtor e limitar o comprimento da geração com max_new_tokens=. O dispositivo e o dtype são definidos automaticamente: bf16 ou fp16 no CUDA, fp32 na CPU.

Limitações

O LibreVLM é poderoso, mas ainda é recente. Conhecer os limites de antemão evita surpresas depois.

  • Confiança sintética. Todo bounding box recebe pontuação 1.0. Portanto, o filtro conf= se comporta como tudo ou nada, em vez de usar um limiar real.
  • Sem mAP / validação. val() gera um erro porque as pontuações sintéticas tornariam o mAP do COCO enganoso.
  • Sem treinamento nem exportação. train() e export() geram erros. Faça fine-tuning do VLM na origem e carregue os pesos resultantes.
  • Rastreamento degradado. track() funciona, mas as pontuações uniformes tornam inativa a etapa de recuperação de baixa confiança do rastreador.
  • Uma imagem por vez. A geração é sequencial na v1, então valores maiores de batch= não aceleram o processamento.
  • Somente API Python. A CLI libreyolo ainda não reconhece aliases de VLM.

Onde ele se destaca

Use o LibreVLM quando o conjunto de classes for aberto, mudar com frequência ou for difícil de rotular de antemão: prototipagem rápida, categorias raras ou de cauda longa e fluxos de trabalho para "encontrar o objeto que descrevo em palavras". Quando você precisar de confiança calibrada, throughput ou um artefato pronto para deploy, treine um YOLO9 ou RF-DETR de vocabulário fechado seguindo a documentação principal.

Somente inferênciabranch dev / previsto para a v1.3Código-fonte no GitHub