YOLOv9

Um detector convolucional de estágio único: uma passada pontua uma grade densa de caixas e o NMS descarta as duplicadas. O LibreYOLO traz três variantes dele, uma delas sem etapa de NMS.

Tarefas
detection
Tamanhos
yolo9: t, s, m, c at 640 px; yolo9_p2: t, s at 640 px
Instalação
pip install libreyolo
Nível de suporte
Carro-chefe, desde a v1.0.0. Os recursos são projetados e validados por completo em GPU aqui primeiro.
Origem
YOLOv9 por MultimediaTechLab, MIT. Artigo, código-fonte
Licenças
Código MIT, pesos MIT. Uso comercial

Instalação

O YOLOv9 não precisa de nenhum extra além do pacote base.

bash
pip install libreyolo

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("LibreYOLO9s.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes:    print(box.cls, box.conf, box.xyxy)
CLI
libreyolo predict model=LibreYOLO9s.pt save=True \  source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg
Sem NMS
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Mesma chamada, checkpoint diferente. A cabeça end-to-end devolve suas# próprias predições de maior pontuação, então nenhum NMS roda e iou é ignorado.model = LibreYOLO("LibreYOLO9E2Es.pt")result = model(SAMPLE_IMAGE, conf=0.25, max_det=300) print(len(result.boxes))

O objeto Results retornado é o mesmo que todas as famílias retornam, então trocar por outro detector é uma mudança de uma linha. Nos modelos base e de stride 4, conf define o limiar de confiança e iou o limiar do NMS. O modelo end-to-end não roda NMS e ignora iou, então conf e max_det são o que dá forma à saída dele. Veja predição para fontes, streaming e tratamento de resultados.

Variantes

Três variantes compartilham um backbone. As três só detectam, e aceitam os mesmos argumentos.

O modelo base prediz em três escalas de características e elimina as caixas duplicadas com NMS.

O modelo end-to-end mantém essa cabeça e acrescenta ao lado dela um ramo de correspondência um-para-um. A inferência lê só o ramo um-para-um e pega as predições de maior pontuação dele, então nenhum NMS roda. Escolha esse quando o runtime em que você faz deploy não tiver operador de NMS.

O modelo de stride 4 puxa mais um nível acima no backbone, estende o neck até ele e prediz em quatro escalas em vez de três. A escala extra é para objetos que cobrem poucos pixels; o único checkpoint publicado para ele é treinado com imagens aéreas. Checkpoints de detecção base se transferem para ele: o backbone e o neck carregam sem alterações, as três torres de cabeça pré-treinadas sobem uma posição e a torre de stride 4 parte de inicialização aleatória.

CheckpointEntrada (px)mAP 50-95Parâmetros (M)
LibreYOLO9c64056.425.5
LibreYOLO9m64055.320.12
LibreYOLO9s64055.97.2
LibreYOLO9t64041.82.04

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.

Treinamento

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")model.train(data="my-dataset.yaml", epochs=100, imgsz=640, batch=16)
CLI
libreyolo train model=LibreYOLO9s.pt data=my-dataset.yaml \  epochs=100 imgsz=640 batch=16
Objetos pequenos
from libreyolo import LibreYOLO9P2 # A variante de stride 4 não tem checkpoint COCO próprio, então indique# um de detecção base: o backbone e o neck dele carregam sem alterações# e a torre da cabeça de stride 4 parte de inicialização aleatória.model = LibreYOLO9P2(None, size="s")model.train(data="my-dataset.yaml", epochs=100, pretrained="LibreYOLO9s.pt")

pretrained decide de onde a execução parte. Passe True para carregar o checkpoint publicado do mesmo modelo e tamanho, ou um nome ou caminho para qualquer outra coisa. Tensores cuja forma não bate são pulados em vez de recusados, e a execução registra quantos foram carregados, então um checkpoint treinado com um número diferente de classes ainda é um ponto de partida utilizável.

O modelo de stride 4 não tem checkpoint COCO publicado próprio, então True resolve ali para um arquivo que não existe e o download falha. Indique um checkpoint de detecção base no lugar.

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

O modelo base pode treinar um ramo auxiliar PGI ao lado da cabeça principal. O ramo é exclusivo do treinamento: predição e exportação usam a cabeça principal. Uma execução o anexa quando os pesos iniciais trazem tensores PGI ou quando treina do zero. Os checkpoints base publicados não trazem nenhum, então um fine-tuning a partir deles treina só a cabeça principal e registra isso no log. aux_weight=0.25 anexa um ramo novo com esse peso de loss mesmo assim, e aux_weight=0 o mantém desligado. Uma execução retomada mantém a configuração PGI do seu checkpoint. Nos tamanhos m e c o ramo é o do upstream: um segundo backbone sobre a imagem de entrada, cujos estágios o CBFuse soma com taps CBLinear do backbone principal, e sua própria cabeça, com 12.8M e 25.7M de parâmetros exclusivos do treinamento com 80 classes. Os modelos end-to-end e de stride 4 não têm ramo PGI.

As três variantes limitam a norma L2 do gradiente a 10 antes de cada passo do otimizador; clip_max_norm=0 desliga o clipping. A atribuição de labels pontua as âncoras em fp32, também sob autocast float16. max_labels=300 limita as caixas mantidas por imagem de treinamento, e as caixas além disso são descartadas com um aviso único; a memória da atribuição acompanha as caixas reais de cada imagem, não o limite. O momentum do SGD aumenta de 0.8 a 0.937 durante três épocas. letterbox_pad=None herda o registro do checkpoint: pesos sem registro usam topleft, enquanto novas conversões oficiais registram center.

O mosaic de YOLO9 e YOLOX prefere imagens parceiras anotadas, com no máximo 20 sorteios; o MixUp de YOLO9 usa a mesma política. O MixUp vem desligado por padrão (mixup_prob=0). Quando ligado, a razão de mistura é sorteada de Beta(1, 1), uniforme em [0, 1], como no MultimediaTechLab/YOLO. Veja histogramas de eventos para perfis de entrada não RGB.

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("LibreYOLO9s.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])
CLI
libreyolo val model=LibreYOLO9s.pt data=my-dataset.yaml
Contra o COCO
# O yaml de COCO que vem junto carrega um script de download embutido,# então ele precisa de permissão explícita a menos que o dataset já esteja local.libreyolo val model=LibreYOLO9c.pt data=coco.yaml imgsz=640 \  allow_download_scripts=True

Exportação

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

Uma marca vale para as três variantes: onde elas diferem, a matriz traz a mais fraca das três.

Um artefato exportado é recarregado pelo LibreYOLO() a partir do sufixo do arquivo, então um arquivo .onnx ou .engine se comporta como um checkpoint e devolve o mesmo Results. Rodar o grafo em um runtime puro, sem o LibreYOLO instalado, também é suportado, mas aí o pré-processamento e o pós-processamento ficam por sua conta.

Para o modelo de detecção base, a metade de pós-processamento disso pode ir para dentro do grafo. nms=True em uma exportação para ONNX coloca a supressão dentro do modelo, e a primeira saída passa a ser um tensor fixo (1, max_det, 6) cujas linhas são x1, y1, x2, y2, score, class, preenchidas com zeros além da contagem de detecções. Esse grafo é de batch 1 e não carrega eixos dinâmicos. Os modelos end-to-end e de stride 4 não aceitam a flag.

Cada formato instala um extra diferente e aceita alguns argumentos próprios. As duas coisas estão na página daquele formato.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")model.export(format="onnx", imgsz=640)
CLI
libreyolo export model=LibreYOLO9s.pt format=onnx imgsz=640
Com NMS no grafo
libreyolo export model=LibreYOLO9s.pt format=onnx nms=True \  conf=0.25 iou=0.45 max_det=300
Usar o arquivo exportado
from libreyolo import LibreYOLO, SAMPLE_IMAGE # A factory decide pelo sufixo do arquivo, então um artefato exportado# carrega como qualquer checkpoint e devolve o mesmo objeto Results.model = LibreYOLO("LibreYOLO9s.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)

TFLite INT8 usa int8=True com dados de calibração.

Entradas e saídas ONNX

LibreYOLO9

Tensorimages float32 [batch, 3, height, width]
CorRGB
Escalapixel / 255
Normalizaçãonenhuma
Redimensionamentoletterbox, bilinear, valor de preenchimento 114, posição do preenchimento vinda da chave de metadados letterbox_pad

Scale by r = min(height / h, width / w), resize to (int(w * r), int(h * r)) and paste onto a canvas filled with 114.

Paste position comes from the letterbox_pad metadata key: topleft puts the image in the top-left corner, center splits the padding on both sides. A missing key means topleft.

Detection, exportação padrão
SaídaFormaSignificado
output[batch, 4 + nc, anchors]Rows 0 to 3 are x1, y1, x2, y2 in input-canvas pixels. Rows 4 onward are per-class scores, sigmoid already applied. anchors is the cell count over strides 8, 16 and 32, 8400 at 640 x 640.

Pós-processamento

  1. Transpose to [anchors, 4 + nc].
  2. Keep every (anchor, class) pair whose score is above the confidence threshold (0.25 by default). One anchor can yield several classes.
  3. Run NMS per class with IoU 0.45 and keep at most 300 detections.
  4. Map boxes back to the original image: subtract the pad offset, divide by r, clip to the image.
  5. Drop boxes whose width or height is 0 after clipping.
Detection, nms=True
SaídaFormaSignificado
output[1, max_det, 6]Rows are x1, y1, x2, y2, score, class in input-canvas pixels, zero-padded past the detection count. Confidence, IoU and max_det are baked in and recorded as nms_conf, nms_iou and max_det metadata.
raw[1, 4 + nc, anchors]The same tensor as the default export's output, before suppression.

Pós-processamento

  1. Drop rows whose score is 0 or below your threshold.
  2. Map boxes back to the original image: subtract the pad offset, divide by r, clip to the image.

LibreYOLO9E2E

Tensorimages float32 [batch, 3, height, width]
CorRGB
Escalapixel / 255
Normalizaçãonenhuma
Redimensionamentoletterbox, bilinear, valor de preenchimento 114, posição do preenchimento vinda da chave de metadados letterbox_pad

Scale by r = min(height / h, width / w), resize to (int(w * r), int(h * r)) and paste onto a canvas filled with 114.

Paste position comes from the letterbox_pad metadata key: topleft puts the image in the top-left corner, center splits the padding on both sides. A missing key means topleft.

This model has no nms=True export. The exporter raises NotImplementedError, so only the default export below exists.

Detection, exportação padrão
SaídaFormaSignificado
output[batch, 4 + nc, anchors]Predictions of the one-to-one head only. Rows 0 to 3 are x1, y1, x2, y2 in input-canvas pixels. Rows 4 onward are per-class scores, sigmoid already applied. anchors is the cell count over strides 8, 16 and 32, 8400 at 640 x 640.

Pós-processamento

  1. Transpose to [anchors, 4 + nc].
  2. Flatten the [anchors, nc] scores into one list of anchors x nc (anchor, class) pairs. Pair i belongs to anchor i / nc (integer division) and class i % nc.
  3. Keep the 300 highest-scoring pairs (max_det), highest first. One anchor can yield several classes.
  4. Of those, keep the pairs whose score is above the confidence threshold (0.25 by default).
  5. Do not run NMS. The one-to-one head is trained to fire once per object, and LibreYOLO ignores the iou setting for this model.
  6. Map boxes back to the original image: subtract the pad offset, divide by r, clip to the image.
  7. Drop boxes whose width or height is 0 after clipping.

LibreYOLO9P2

Tensorimages float32 [batch, 3, height, width]
CorRGB
Escalapixel / 255
Normalizaçãonenhuma
Redimensionamentoletterbox, bilinear, valor de preenchimento 114, posição do preenchimento vinda da chave de metadados letterbox_pad

Scale by r = min(height / h, width / w), resize to (int(w * r), int(h * r)) and paste onto a canvas filled with 114.

Paste position comes from the letterbox_pad metadata key: topleft puts the image in the top-left corner, center splits the padding on both sides. A missing key means topleft.

This model has no nms=True export. The exporter raises NotImplementedError, so only the default export below exists.

Detection, exportação padrão
SaídaFormaSignificado
output[batch, 4 + nc, anchors]Rows 0 to 3 are x1, y1, x2, y2 in input-canvas pixels. Rows 4 onward are per-class scores, sigmoid already applied. anchors is the cell count over strides 4, 8, 16 and 32, 34000 at 640 x 640. nc is 10 for LibreYOLO9P2s-visdrone.

Pós-processamento

  1. Transpose to [anchors, 4 + nc].
  2. Keep every (anchor, class) pair whose score is above the confidence threshold (0.25 by default). One anchor can yield several classes.
  3. Run NMS per class with IoU 0.45 and keep at most 300 detections.
  4. Map boxes back to the original image: subtract the pad offset, divide by r, clip to the image.
  5. Drop boxes whose width or height is 0 after clipping.

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

Todos os arquivos de pesos publicados desta família.

ArquivoEntrada (px)Licença dos pesos
Detection
LibreYOLO9t.pt640mit
LibreYOLO9s.pt640mit
LibreYOLO9m.pt640mit
LibreYOLO9c.pt640mit
LibreYOLO9E2Et.pt640mit
LibreYOLO9E2Es.pt640mit
LibreYOLO9E2Em.pt640mit
LibreYOLO9E2Ec.pt640mit
LibreYOLO9P2s-visdrone.ptcc-by-nc-sa-3.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
YOLOv9, MultimediaTechLab
Licença original
MIT
Código-fonte original
github.com/MultimediaTechLab/YOLO
Código do LibreYOLO
MIT
Pesos
MIT, republicado em huggingface.co/LibreYOLO
Interpretação
MIT is a permissive license, so these weights can be used in commercial and closed-source products. The one standing obligation is to keep the license text and the copyright notice, Kin-Yiu Wong and Hao-Tang Tsui, with any copy you redistribute. It places no condition on your own application code, and a model you train yourself on your own data is yours. Two things are worth knowing beyond that. The code is ported from the authors' MIT re-release of YOLOv9, MultimediaTechLab/YOLO at commit c4cb5f6f, not the GPL-3.0 repository that carries the same model, so the permissive terms come from the source LibreYOLO actually derives from. And one checkpoint in this family is not MIT: the weight repository of the stride-4 VisDrone model, LibreYOLO9P2s-visdrone.pt, declares CC BY-NC-SA 3.0, which rules out commercial use and requires share-alike on derivatives.

O código das três variantes é portado de MultimediaTechLab/YOLO no commit c4cb5f6f (MIT). O preditor one-to-one do modelo end-to-end segue o design do DATE, de Yiqun Chen (Apache-2.0), implementado para o LibreYOLO sem nenhum código do DATE copiado. O nível de stride 4 é código do LibreYOLO.

O checkpoint aéreo com stride 4 prevê as classes VisDrone. Use a licença declarada pelo publicador no repositório dos pesos.

Citação

@inproceedings{wang2024yolov9,
      title={{YOLOv9}: Learning What You Want to Learn Using Programmable Gradient Information},
      author={Wang, Chien-Yao and Yeh, I-Hau and Liao, Hong-Yuan Mark},
      year={2024},
      booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},
}

Copiado do bloco de citação dos autores em github.com/MultimediaTechLab/YOLO#citations.

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.

Arquitetura de YOLOv9

Escolha uma variante ou a visão da família e selecione um bloco para ver os detalhes. Abra o diagrama completo para ampliar ou baixar SVG e PNG. Os diagramas estão em inglês.