DEIM

Um transformer de detecção treinado com correspondência densa um-para-um, que converge em muito menos épocas que as receitas DETR sobre as quais é construído. O LibreYOLO inclui duas versões dele, distinguidas pelo checkpoint que você carrega.

Tarefas
detection
Tamanhos
deim: n, s, m, l, x at 640 px
Instalação
pip install libreyolo
Nível de suporte
Núcleo, desde a v1.2.0. Detectores treináveis do núcleo: os recursos chegam depois dos carros-chefe na mesma leva de versões.
Origem
DEIM and DEIMv2 por Intellindust AI Lab, Apache-2.0; the DEIMv2 DINOv3 backbone adds Meta's DINOv3 License. Artigo, código-fonte
Licenças
Código Apache-2.0, pesos Apache-2.0; the DEIMv2 DINOv3 backbone adds Meta's DINOv3 License. Uso comercial

Instalação

Nenhuma das duas versões precisa de um extra opcional. Tudo o que elas importam está na instalação base.

bash
pip install libreyolo

O fine-tuning por adaptadores com lora=True é a exceção, e precisa do extra lora.

bash
pip install "libreyolo[lora]"

Predição

Os pesos são baixados do Hugging Face no primeiro uso e ficam em cache localmente.

Python
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreDEIMn.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes:    print(box.cls, box.conf, box.xyxy)
CLI
libreyolo predict model=LibreDEIMn.pt save=True \  source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg
Vídeo
from libreyolo import LibreYOLO # A versão faz parte do nome do arquivo, e a fábrica roteia com base# no checkpoint, então as duas carregam do mesmo jeito.model = LibreYOLO("LibreDEIMv2pico.pt") # Qualquer fonte que a biblioteca aceita: arquivo, pasta, URL, índice# de webcam, stream RTSP ou uma lista .streamsfor result in model.predict("clip.mp4", stream=True, save=True):    print(len(result.boxes))

O objeto Results retornado é o mesmo que toda família retorna, então trocar por outro detector é uma mudança de uma linha. conf e max_det filtram uma decodificação top-k sobre queries e classes; não há um passo de NMS para ajustar, e iou é aceito mas não usado. Veja predição para fontes, streaming e tratamento de resultados.

DEIM aceita imgsz=(height, width) retangular para predição. DEIMv2 rejeita explicitamente solicitações de predição/validação retangulares. Isso não implica suporte a treinamento ou exportação retangulares.

Variantes

A versão 1 traz cinco tamanhos, todos no mesmo tamanho de entrada. A versão 2 mantém esses cinco nomes e acrescenta três menores, atto, femto e pico, os dois primeiros nativos em um tamanho de entrada menor que o resto. Cinco códigos de tamanho existem, portanto, nas duas versões e nomeiam modelos diferentes; a versão está escrita no nome do arquivo do checkpoint.

CheckpointEntrada (px)mAP 50-95Parâmetros (M)
LibreDEIMl64057.831.24
LibreDEIMm64055.419.59
LibreDEIMn64046.83.78
LibreDEIMs64052.110.32
LibreDEIMx64059.662.62
LibreDEIMv2atto32027.50.51
LibreDEIMv2femto41634.50.98
LibreDEIMv2l64058.632.55
LibreDEIMv2m64056.018.36
LibreDEIMv2n64046.73.6
LibreDEIMv2pico64042.21.54
LibreDEIMv2s64053.09.78
LibreDEIMv2x64061.351.21

COCO val2017, 500 images. Medido pelo conjunto de testes de benchmark do LibreYOLO e publicado no Vision Analysis, onde a latência entre hardwares e runtimes é comparada e os registros completos das execuções ficam disponíveis.

A versão 1 mantém a arquitetura do D-FINE e troca seu objetivo de classificação pela loss ciente de matchability da receita densa um-para-um, então as duas famílias compartilham quase todas as chaves do state dict e são distinguidas pelos metadados do checkpoint. A versão 2 mantém esse contrato de treinamento e mistura backbones: HGNetv2 abaixo de s, e um vision transformer DINOv3 com um adaptador de tuning espacial em s e acima. Esse backbone é o que coloca uma segunda licença nesses quatro checkpoints, então leia licenciamento antes de colocar um deles em produção.

Treinamento

O treinamento parte de um checkpoint publicado. pretrained nunca chega ao treinador: a versão 1 avisa que a chave é desconhecida e a ignora, a versão 2 a remove. Nenhuma das duas entrega um modelo inicializado aleatoriamente.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreDEIMn.pt") # coco128.yaml baixa uma amostra de 128 imagens no primeiro uso.# Aponte `data` para o YAML do seu próprio dataset em uma execução real.model.train(data="coco128.yaml", epochs=50, batch=8, lr0=1e-4)
CLI
libreyolo train model=LibreDEIMn.pt data=coco128.yaml \  epochs=50 batch=8 lr0=1e-4
DEIMv2
from libreyolo import LibreYOLO # Se não forem definidos, epochs, batch, imgsz e lr0 vêm da receita# publicada para o tamanho que foi carregado.model = LibreYOLO("LibreDEIMv2pico.pt")model.train(data="coco128.yaml", epochs=50)
LoRA
# Precisa do extra lora: pip install "libreyolo[lora]"from libreyolo import LibreYOLO model = LibreYOLO("LibreDEIMn.pt")model.train(data="coco128.yaml", epochs=50, lora=True)
Multi-GPU
libreyolo train model=LibreDEIMn.pt data=coco128.yaml \  epochs=50 device=0,1

Passe lr0 você mesmo na versão 1. A assinatura Python do train() dela usa 4e-4 como padrão, a taxa da receita COCO publicada, enquanto a configuração de treinamento da família carrega 1e-4 como seu padrão de fine-tune, e é esse valor menor que a CLI resolve quando o argumento está ausente. A configuração registra a medição por trás disso: nos tamanhos de batch que um fine-tune de fato usa, em datasets pequenos, a taxa do COCO degradou a transferência de forma mensurável.

A versão 2 resolve esses padrões sozinha. Deixar epochs, batch, imgsz e lr0 sem definir faz com que ela leia cada um da receita publicada para o tamanho que foi carregado, então os tamanhos pequenos treinam na própria resolução de entrada sem que ninguém precise dizer, e um valor que você passa sobrescreve a receita. imgsz é o argumento que ela restringe: precisa ser um múltiplo positivo de 32, e a versão 2 lança um erro antes de a execução começar caso contrário.

Veja treinamento para datasets, data augmentation, multi-GPU e loggers.

DEIM ativa AMP por padrão com amp_dtype="float16". Passe amp=False para treinamento em FP32.

Validação

val() retorna um dicionário de chaves metrics/ cobrindo precisão, recall, mAP 50 e mAP 50-95, medidos contra qualquer dataset no formato em que você treinou.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreDEIMn.pt") # val() retorna um dict simples, não um objetometrics = model.val(data="coco128.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])print(metrics["metrics/precision"], metrics["metrics/recall"])
CLI
libreyolo val model=LibreDEIMn.pt data=coco128.yaml
Contra o COCO
# coco-val-only.yaml busca as 5000 imagens de val2017 e pula o# conjunto de treinamento. Ele traz um script de download embutido,# então precisa de permissão explícita a menos que o dataset já esteja# local.libreyolo val model=LibreDEIMn.pt data=coco-val-only.yaml \  allow_download_scripts=True

As linhas da tabela de benchmark acima vêm do harness de benchmark do LibreYOLO; a nota abaixo dessa tabela registra qual dataset as produziu e liga os registros das execuções.

Exportação

TarefaONNXTorchScriptExecuTorchTensorRTOpenVINOPaddleMNNRKNNncnnTFLiteCoreMLCore AI
DetectionDetection to ONNX: compatívelDetection to TorchScript: compatívelDetection to ExecuTorch: incompatívelDetection to TensorRT: compatívelDetection to OpenVINO: compatívelDetection to Paddle: compatívelDetection to MNN: compatívelDetection to RKNN: incompatívelDetection to ncnn: incompatívelDetection to TFLite: incompatívelDetection to CoreML: incompatívelDetection to Core AI: compatível

A matriz cobre as duas versões em uma única página: onde elas discordam sobre um formato, a célula mostra a mais fraca das duas, então nada aqui fica supervalorizado para a versão que você carregar.

Um artefato exportado volta a carregar por LibreYOLO() pelo sufixo do arquivo, então um arquivo .onnx ou .engine se comporta como um checkpoint e retorna o mesmo Results.

Python
# Precisa do extra onnx: pip install "libreyolo[onnx]"from libreyolo import LibreYOLO model = LibreYOLO("LibreDEIMn.pt")path = model.export(format="onnx")print(path)
CLI
libreyolo export model=LibreDEIMn.pt format=onnx
Usar o arquivo exportado
from libreyolo import LibreYOLO, SAMPLE_IMAGE # A fábrica roteia pelo sufixo do arquivo, então um artefato exportado# carrega como qualquer checkpoint e retorna o mesmo objeto Results.model = LibreYOLO("LibreDEIMn.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)

Entradas e saídas ONNX

LibreDEIM, and LibreDEIMv2 atto, femto, pico and n

Tensorimages float32 [batch, 3, height, width]
CorRGB
Escalapixel / 255
Normalizaçãonenhuma
Redimensionamentoesticar para largura x altura (sem preenchimento, a proporção não é mantida), Pillow bilinear
Como reproduzir o redimensionamento bilinear do Pillow

O LibreYOLO redimensiona com o filtro BILINEAR do Pillow (Image.resize). Não é OpenCV INTER_LINEAR nem INTER_AREA: ao reduzir, o Pillow alarga o filtro pelo fator de redução, e os redimensionamentos do OpenCV mudam as detecções e deslocam as caixas em vários pixels. Para reproduzi-lo sem o Pillow, redimensione um eixo, arredonde para 8 bits, depois redimensione o outro eixo e arredonde de novo. Por eixo, seja s = in_size / out_size e f = max(s, 1). O pixel de saída i tem centro c = (i + 0.5) * s e lê os pixels de origem j de int(c - f + 0.5) até int(c + f + 0.5) - 1, limitados à imagem, cada um com peso max(0, 1 - |j + 0.5 - c| / f), dividido pela soma dos pesos. O Pillow calcula em ponto fixo e escolhe a ordem dos eixos pela forma da imagem, então pesos em ponto flutuante podem diferir em um nível em alguns pixels. Isso não muda os resultados nas nossas verificações.

Square input only. Export rejects a non-square imgsz. height and width equal the imgsz metadata key: 640 by default, 320 for DEIMv2 atto and 416 for DEIMv2 femto.

Batch size 1 only. The graph declares a dynamic batch axis, but batches of 2 or more fail in 1.7.0.

To run several images per call, export with batch=2. That graph takes any batch size and gives the same results per image.

Divide by 255 after the resize. There is no mean or std normalization for these sizes.

Only the default export exists. nms=True raises NotImplementedError for this family.

Detection, exportação padrão
SaídaFormaSignificado
pred_logits[batch, queries, nc]One logit per query and class. Sigmoid is not applied, and there is no background class. 300 queries, except DEIMv2 atto with 100 queries, femto with 150 queries and pico with 200 queries.
pred_boxes[batch, queries, 4]cx, cy, w, h of each query, normalized 0 to 1 of the input. The input is the whole image stretched, so these are also fractions of the original image.

Pós-processamento

  1. Apply sigmoid to pred_logits.
  2. Flatten the [queries, nc] scores and take the top 300 (max_det, 300 by default). For flat index k, the query is k // nc and the class is k % nc. One query can yield several classes.
  3. Keep the pairs whose score is above the confidence threshold (0.25 by default).
  4. Convert the query's box to x1 = cx - w / 2, y1 = cy - h / 2, x2 = cx + w / 2, y2 = cy + h / 2. Multiply x by the original image width and y by the original image height.
  5. There is no NMS and the iou threshold is not used. DEIM predicts a set of boxes.
  6. LibreYOLO does not clip these boxes, so an edge can sit slightly outside the image.

LibreDEIMv2 s, m, l and x

Tensorimages float32 [batch, 3, height, width]
CorRGB
Escalapixel / 255
Normalizaçãomédia [0.485,0.456,0.406], desvio padrão [0.229,0.224,0.225]
Redimensionamentoesticar para largura x altura (sem preenchimento, a proporção não é mantida), Pillow bilinear
Como reproduzir o redimensionamento bilinear do Pillow

O LibreYOLO redimensiona com o filtro BILINEAR do Pillow (Image.resize). Não é OpenCV INTER_LINEAR nem INTER_AREA: ao reduzir, o Pillow alarga o filtro pelo fator de redução, e os redimensionamentos do OpenCV mudam as detecções e deslocam as caixas em vários pixels. Para reproduzi-lo sem o Pillow, redimensione um eixo, arredonde para 8 bits, depois redimensione o outro eixo e arredonde de novo. Por eixo, seja s = in_size / out_size e f = max(s, 1). O pixel de saída i tem centro c = (i + 0.5) * s e lê os pixels de origem j de int(c - f + 0.5) até int(c + f + 0.5) - 1, limitados à imagem, cada um com peso max(0, 1 - |j + 0.5 - c| / f), dividido pela soma dos pesos. O Pillow calcula em ponto fixo e escolhe a ordem dos eixos pela forma da imagem, então pesos em ponto flutuante podem diferir em um nível em alguns pixels. Isso não muda os resultados nas nossas verificações.

These sizes use a DINOv3 backbone, so they take ImageNet mean and std. The atto, femto, pico and n sizes do not.

Square input only. Export rejects a non-square imgsz. height and width equal the imgsz metadata key, 640 by default.

Batch size 1 only. The graph declares a dynamic batch axis, but batches of 2 or more fail in 1.7.0.

To run several images per call, export with batch=2. That graph takes any batch size and gives the same results per image.

After the resize, divide by 255, then subtract the ImageNet mean and divide by the ImageNet std, per channel in RGB order.

Only the default export exists. nms=True raises NotImplementedError for this family.

Detection, exportação padrão
SaídaFormaSignificado
pred_logits[batch, queries, nc]One logit per query and class. Sigmoid is not applied, and there is no background class. 300 queries.
pred_boxes[batch, queries, 4]cx, cy, w, h of each query, normalized 0 to 1 of the input. The input is the whole image stretched, so these are also fractions of the original image.

Pós-processamento

  1. Apply sigmoid to pred_logits.
  2. Flatten the [queries, nc] scores and take the top 300 (max_det, 300 by default). For flat index k, the query is k // nc and the class is k % nc. One query can yield several classes.
  3. Keep the pairs whose score is above the confidence threshold (0.25 by default).
  4. Convert the query's box to x1 = cx - w / 2, y1 = cy - h / 2, x2 = cx + w / 2, y2 = cy + h / 2. Multiply x by the original image width and y by the original image height.
  5. There is no NMS and the iou threshold is not used. DEIM predicts a set of boxes.
  6. LibreYOLO does not clip these boxes, so an edge can sit slightly outside the image.

Para conferir a sua própria implementação, passe o mesmo arquivo pelo LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") devolve os resultados de referência. Verificado com o LibreYOLO 1.7.0.

Checkpoints

Todo arquivo de pesos publicado desta família.

ArquivoEntrada (px)Licença dos pesos
Detection
LibreDEIMn.pt640apache-2.0
LibreDEIMs.pt640apache-2.0
LibreDEIMm.pt640apache-2.0
LibreDEIMl.pt640apache-2.0
LibreDEIMx.pt640apache-2.0
LibreDEIMv2n.pt640apache-2.0
LibreDEIMv2s.pt640other
LibreDEIMv2m.pt640other
LibreDEIMv2l.pt640other
LibreDEIMv2x.pt640other
LibreDEIMv2atto.ptapache-2.0
LibreDEIMv2femto.ptapache-2.0
LibreDEIMv2pico.ptapache-2.0

Todos os arquivos acima existem hoje na organização LibreYOLO e são baixados no primeiro uso.

Licenciamento

Confira a licença no repositório do Hugging Face correspondente aos pesos que você baixar. Cada checkpoint na organização LibreYOLO tem uma licença, e ela nem sempre é a mesma em toda a família. Esse repositório é a fonte oficial. O resumo abaixo descreve o que se aplicava na última verificação desta página.

Esta é uma descrição das licenças envolvidas, não uma orientação jurídica. Se a resposta tiver importância comercial, leia as licenças e procure sua própria assessoria.

Trabalho original
DEIM and DEIMv2, Intellindust AI Lab
Licença original
Apache-2.0; the DEIMv2 DINOv3 backbone adds Meta's DINOv3 License
Código do LibreYOLO
MIT
Pesos
Apache-2.0; the DEIMv2 DINOv3 backbone adds Meta's DINOv3 License, republicado em huggingface.co/LibreYOLO
Interpretação
Apache-2.0 is a permissive license, so these weights can be used in commercial and closed-source products. It asks you to keep its license text and attribution notices with any copy of the weights you redistribute, and it grants a patent license. It places no obligation on your own application code, and weights you train yourself on your own data are yours. DEIM is Apache-2.0 throughout, and so are the DEIMv2 sizes below S, which use an HGNetv2 backbone. The DEIMv2 S, M, L and X sizes take their backbone from DINOv3, so both their weights and the backbone source vendored in LibreYOLO are additionally governed by Meta's DINOv3 License Agreement, which is not an OSI license: redistribution has to carry the agreement with it, and it forbids use for military or warfare purposes, weapons development, espionage, nuclear industries and anything subject to ITAR. Their Hugging Face repositories declare both licenses, and DEIMv2 is also cited separately (arXiv 2509.20787).
Os quatro tamanhos do DEIMv2 de S para cima pegam seu backbone do DINOv3, então seus repositórios de pesos carregam tanto a Apache-2.0 quanto a DINOv3 License da Meta, e o LibreYOLO distribui o código do backbone DINOv3 sob esse mesmo acordo. O resto desta família, incluindo todo tamanho do DEIMv2 abaixo de S, é Apache-2.0 apenas.

Citação

@misc{huang2024deim,
      title={DEIM: DETR with Improved Matching for Fast Convergence},
      author={Shihua, Huang and Zhichao, Lu and Xiaodong, Cun and Yongjun, Yu and Xiao, Zhou and Xi, Shen},
      booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
      year={2025},
}

Copiado do bloco de citação dos autores em github.com/Intellindust-AI-Lab/DEIM#5-citation.

O DEIMv2 é um artigo separado e tem seu próprio bloco de citação em github.com/Intellindust-AI-Lab/DEIMv2; cite esse se você usou um checkpoint da versão 2.

Verificado com o LibreYOLO v1.6.0. As tabelas de suporte, os checkpoints e os números de benchmark desta página são gerados a partir da biblioteca lançada e dos pesos publicados, não escritos à mão.