YOLO-NAS
Um detector convolucional cujo backbone e neck saíram da busca de arquiteturas da Deci.AI, construído com blocos RepVGG preparados para quantização. Seus pesos são da Deci.AI, licenciados apenas para uso não comercial, e o LibreYOLO não publica nenhum deles.
- Tarefas
- detection, pose, oriented boxes
- Tamanhos
- s, m, l at 640 px
- Instalação
pip install libreyolo- Nível de suporte
- Núcleo, desde a v1.1.0. Detectores treináveis do núcleo: os recursos chegam depois dos carros-chefe na mesma leva de versões.
- Origem
- YOLO-NAS por Deci.AI, Deci.AI proprietary, non-commercial. Artigo, código-fonte
- Licenças
- Código Apache-2.0, pesos Deci.AI proprietary, non-commercial. Uso comercial
Instalação
O YOLO-NAS não precisa de nada além do pacote base.
pip install libreyoloPredição
Um nome de checkpoint que ainda não esteja em disco é baixado da CDN pública da Deci, não da organização do LibreYOLO, que não hospeda nenhum desses pesos. Antes de a transferência começar, a biblioteca imprime os termos de licença da Deci uma vez por processo, e antes de o arquivo baixado ser aberto seu SHA-256 é conferido contra um valor fixado. O que esses termos permitem está em licenciamento.
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Um nome que ainda não esteja em disco é baixado da CDN da Deci. O# download imprime antes os termos de licença da Deci; ficar com o# arquivo significa aceitá-los.model = LibreYOLO("LibreYOLONASs.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes: print(box.cls, box.conf, box.xyxy)libreyolo predict model=LibreYOLONASs.pt save=True \ source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpgfrom libreyolo import LibreYOLO, SAMPLE_IMAGE # O sufixo -pose seleciona a cabeça de pose e seu próprio conjunto de pesos.model = LibreYOLO("LibreYOLONASs-pose.pt")result = model(SAMPLE_IMAGE) print(result.keypoints.xy)O objeto Results devolvido é o mesmo que toda família devolve, então trocar
por outro detector é uma mudança de uma linha. conf define o limiar de
confiança e iou o limiar do NMS. Veja predição para fontes,
streaming e tratamento de resultados.
A tarefa de caixas orientadas retorna result.obb. O grafo OBB publicado usa uma tela de 1024 pixels e seu conjunto registrado de 18 classes.
Variantes
Detecção e pose são a mesma arquitetura sob cabeças diferentes, e aceitam os mesmos argumentos. Os tamanhos da tabela abaixo são os de detecção; pose é publicado nesses e em um tamanho menor. A cabeça de pose prevê o conjunto de keypoints do COCO.
| Checkpoint | Entrada (px) | mAP 50-95 | Parâmetros (M) |
|---|---|---|---|
| LibreYOLONASl | 640 | 56.3 | 66.98 |
| LibreYOLONASm | 640 | 55.4 | 51.18 |
| LibreYOLONASs | 640 | 51.8 | 19.05 |
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
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLONASs.pt")model.train(data="my-dataset.yaml", epochs=100, imgsz=640, batch=16)libreyolo train model=LibreYOLONASs.pt data=my-dataset.yaml \ epochs=100 imgsz=640 batch=16from libreyolo import LibreYOLONAS # Nenhum checkpoint da Deci é tocado: o modelo parte de pesos aleatórios,# então o que sai da execução deriva apenas dos seus dados.model = LibreYOLONAS(None, size="s")model.train(data="my-dataset.yaml", imgsz=640, batch=16)epochs, lr0 e amp são resolvidos por tarefa quando você os omite, então
uma execução de pose parte de padrões diferentes dos de uma execução de
detecção. O otimizador é o AdamW por padrão. O número de classes vem do YAML do
dataset e a cabeça é reconstruída para ele antes da primeira época; na cabeça de
pose o número de keypoints é tratado do mesmo jeito, então um checkpoint de pose
do COCO pode receber fine-tuning sobre um esqueleto de outro tamanho.
O fine-tuning parte dos pesos da Deci, que é o que a licença da Deci cobre. Treinar a partir de um modelo inicializado aleatoriamente não envolve nenhum checkpoint da Deci, e é isso que o terceiro snippet acima faz.
Veja treinamento para datasets, data augmentation, multi-GPU e loggers.
Detecção usa amp=True com amp_dtype="float16" por padrão; o treinamento de caixas orientadas mantém amp=False. A cabeça OBB suporta treinamento, predição e validação, usa data augmentation com espelhamento/HSV e seleciona checkpoints com metrics/mAP50-95(OBB). load_detect_weights_for_obb() a inicializa a partir de pesos de detecção.
Validação
val() devolve 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.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLONASs.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])libreyolo val model=LibreYOLONASs.pt data=my-dataset.yaml# O yaml do COCO que vem junto carrega um script de download embutido,# então precisa de permissão explícita a menos que o dataset já esteja local.libreyolo val model=LibreYOLONASl.pt data=coco.yaml imgsz=640 \ allow_download_scripts=TrueExportação
| Tarefa | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX: compatível | Detection to TorchScript: compatível | Detection to ExecuTorch: compatível | Detection to TensorRT: compatível | Detection to OpenVINO: compatível | Detection to Paddle: compatível | Detection to MNN: compatível | Detection to RKNN: compatível | Detection to ncnn: compatível | Detection to TFLite: compatível | Detection to CoreML: incompatível | Detection to Core AI: compatível |
| Pose | Pose to ONNX: compatível | Pose to TorchScript: compatível | Pose to ExecuTorch: compatível | Pose to TensorRT: compatível | Pose to OpenVINO: compatível | Pose to Paddle: compatível | Pose to MNN: incompatível | Pose to RKNN: incompatível | Pose to ncnn: compatível | Pose to TFLite: incompatível | Pose to CoreML: incompatível | Pose to Core AI: incompatível |
| Oriented boxes | Oriented boxes to ONNX: compatível | Oriented boxes to TorchScript: compatível | Oriented boxes to ExecuTorch: compatível | Oriented boxes to TensorRT: compatível | Oriented boxes to OpenVINO: compatível | Oriented boxes to Paddle: incompatível | Oriented boxes to MNN: incompatível | Oriented boxes to RKNN: incompatível | Oriented boxes to ncnn: compatível | Oriented boxes to TFLite: incompatível | Oriented boxes to CoreML: incompatível | Oriented boxes to Core AI: incompatível |
Um artefato exportado é carregado de volta pelo LibreYOLO() conforme o 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. Cada formato instala um extra diferente e aceita alguns
argumentos próprios. Os dois estão na página daquele formato.
Uma exportação é outra cópia dos mesmos pesos em um contêiner diferente. Exportar um checkpoint da Deci não muda nem de onde os pesos vieram nem a licença que os cobre.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLONASs.pt")model.export(format="onnx", imgsz=640)libreyolo export model=LibreYOLONASs.pt format=onnx imgsz=640from libreyolo import LibreYOLO, SAMPLE_IMAGE # A fábrica resolve pelo sufixo do arquivo, então um artefato exportado# carrega como qualquer checkpoint e devolve o mesmo objeto Results.model = LibreYOLO("LibreYOLONASs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)Entradas e saídas ONNX
LibreYOLONAS detect
| Tensor | images float32 [batch, 3, height, width] |
|---|---|
| Cor | RGB |
| Escala | pixel / 255 |
| Normalização | nenhuma |
| Redimensionamento | custom, 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, and height equals width, 640 by default.
The image is not scaled to fill the canvas. The longest side goes to R = min(636, height, width), so 636 at 640 x 640.
Scale by r = min(R / h, R / w) and resize to (round(w * r), round(h * r)). The rounding is Python round, so an exact .5 goes to the even neighbor.
Paste the resized image onto a canvas filled with 114 at left = (width - new_w) // 2 and top = (height - new_h) // 2.
On the test image, cv2.resize with INTER_LINEAR loses two of the eight detections, and INTER_AREA moves boxes by up to 1.4 px.
Divide by 255 after the resize. There is no mean or std normalization.
Detection, exportação padrão
| Saída | Forma | Significado |
|---|---|---|
pred_logits | [batch, anchors, 4] | Boxes, despite the name. x1, y1, x2, y2 in input-canvas pixels. anchors is the cell count over strides 8, 16 and 32, 8400 at 640 x 640. |
pred_boxes | [batch, anchors, nc] | Class scores, despite the name. Sigmoid already applied. 80 classes for the COCO checkpoints. |
Pós-processamento
- The output names are swapped relative to their content. Read boxes from pred_logits and scores from pred_boxes, or tell them apart by the last dimension (4 for boxes).
- Take the best class per anchor: score = max over classes, class = argmax. One anchor yields at most one detection.
- Keep anchors whose score is strictly above the confidence threshold (0.25 by default).
- Keep the 1000 highest scoring candidates.
- Map boxes back to the original image: subtract left from x and top from y, divide by r, clip to the image. Drop boxes left with zero width or height.
- Run NMS per class with IoU 0.45 and keep at most 300 detections.
- nms=True is not available for this family: export raises NotImplementedError.
LibreYOLONAS pose
| Tensor | images float32 [batch, 3, height, width] |
|---|---|
| Cor | BGR |
| Escala | pixel / 255 |
| Normalização | nenhuma |
| Redimensionamento | custom, 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, and height equals width, 640 by default.
Channels are BGR, unlike detection. Pad value and position also differ from detection.
The longest side goes to R = min(640, height, width), so it fills the canvas.
Scale by r = min(R / h, R / w) and resize to (round(w * r), round(h * r)). The rounding is Python round, so an exact .5 goes to the even neighbor.
Paste the resized image in the top-left corner of a canvas filled with 127. All padding is on the bottom and the right.
On the test image, cv2.resize with INTER_LINEAR or INTER_AREA moves boxes by up to 5 px and keypoints by more than 10 px.
Divide by 255 after the resize. There is no mean or std normalization.
Pose, exportação padrão
| Saída | Forma | Significado |
|---|---|---|
boxes | [batch, anchors, 4] | Person boxes as x1, y1, x2, y2 in input-canvas pixels. anchors is the cell count over strides 8, 16 and 32, 8400 at 640 x 640. |
scores | [batch, anchors, nc] | Class scores, sigmoid already applied. nc is 1 (person) for the COCO pose checkpoints. |
keypoints_xy | [batch, anchors, num_keypoints, 2] | Keypoint x, y in input-canvas pixels. num_keypoints is 17 (COCO order) for the COCO pose checkpoints. |
keypoints_conf | [batch, anchors, num_keypoints] | Per-keypoint visibility score, sigmoid already applied. |
Pós-processamento
- Take the best class per anchor: score = max over classes, class = argmax. With one class this is just the person score.
- Keep anchors whose score is at or above the confidence threshold (0.25 by default). This is >=, not > as in detection.
- Keep the 1000 highest scoring candidates.
- Map boxes and keypoints back to the original image: divide x and y by r. The image sits in the top-left corner, so there is no pad offset to subtract.
- Clip boxes to the image and drop boxes left with zero width or height. Keypoints are not clipped and can fall outside the image.
- Run NMS per class with IoU 0.45 and keep at most 300 detections. Keep each survivor's keypoints as (x, y, keypoints_conf).
- nms=True is not available for this family: export raises NotImplementedError.
LibreYOLONAS obb
| Tensor | images float32 [batch, 3, height, width] |
|---|---|
| Cor | BGR |
| Escala | pixel / 255 |
| Normalização | nenhuma |
| Redimensionamento | custom, bilinear |
Square input only. Export rejects a non-square imgsz, and height equals width, 1024 by default.
Channels are BGR, unlike detection. The resize filter and the pad position also differ from detection.
The longest side goes to R = min(1024, height, width), so it fills the canvas.
Scale by r = min(R / h, R / w) and resize to (round(w * r), round(h * r)). The rounding is Python round, so an exact .5 goes to the even neighbor.
The resize is cv2.resize with INTER_LINEAR, not Pillow as in detection and pose. It is skipped when the image already has that size. On the test image, Pillow's filter here changes the detection count.
Paste the resized image in the top-left corner of a canvas filled with 114. All padding is on the bottom and the right.
Divide by 255 after the resize. There is no mean or std normalization.
Oriented boxes, exportação padrão
| Saída | Forma | Significado |
|---|---|---|
boxes | [batch, anchors, 5] | Rotated boxes as cx, cy, w, h, angle. cx, cy, w and h are in input-canvas pixels. The angle is in radians. The graph computes it as (sigmoid(logit) - 0.25) x pi, so it lies between -pi/4 and 3pi/4 and is not wrapped yet. The w side points along (cos angle, sin angle) in image coordinates, y down. anchors is the cell count over strides 8, 16 and 32, 21504 at 1024 x 1024. |
scores | [batch, anchors, nc] | Class scores, sigmoid already applied. 18 classes (DOTA 2.0) for the published checkpoints. |
Pós-processamento
- Take the best class per anchor: score = max over classes, class = argmax. One anchor yields at most one detection.
- Keep anchors whose score is at or above the confidence threshold (0.25 by default). This is >=, not > as in detection.
- Keep the 1000 highest scoring candidates.
- Map boxes back to the original image: divide cx, cy, w and h by r. The image sits in the top-left corner, so there is no pad offset, and the angle does not change.
- Clip cx to 0 to the image width and cy to 0 to the image height. w and h are not clipped. Drop boxes with w or h at or below 0.
- Put the long side first: if h > w, swap w and h and add pi/2 to the angle. Then wrap the angle to [-pi/2, pi/2) with angle = ((angle + pi/2) mod pi) - pi/2.
- Run greedy NMS per class on exact rotated-box IoU (polygon intersection area over union, for example cv2.rotatedRectangleIntersection) with IoU 0.45, and keep at most 300 detections. LibreYOLO does not use upstream's matrix soft-NMS.
- LibreYOLO also reports an axis-aligned box per detection. With ex = abs(cos angle) * w / 2 + abs(sin angle) * h / 2 and ey = abs(sin angle) * w / 2 + abs(cos angle) * h / 2, it is cx - ex, cy - ey, cx + ex, cy + ey, clipped to the image.
- nms=True is not available for this family: export raises NotImplementedError.
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
Não há nenhum para listar. A licença da Deci proíbe a redistribuição, então a
organização do LibreYOLO não publica pesos do YOLO-NAS e o download é resolvido
em outro lugar: um nome no formato LibreYOLONAS<size>.pt,
LibreYOLONAS<size>-pose.pt para pose, ou LibreYOLONAS<size>-obb.pt (s, m, l)
para caixas orientadas, corresponde ao objeto equivalente na CDN pública da Deci.
Só dá para baixar assim os checkpoints cujo SHA-256 a biblioteca fixa. Qualquer
outra coisa falha de forma fechada em vez de abrir um pickle de terceiros não
verificado, e precisa ser baixada à mão e passada como caminho. Um arquivo que
já esteja em disco carrega a partir do seu caminho, sem download e sem barreira
de checksum. Isso inclui um .pth da Deci com o nome original, que o carregador
reconhece.
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
- YOLO-NAS, Deci.AI
- Licença original
- Deci.AI proprietary, non-commercial
- Código-fonte original
- github.com/Deci-AI/super-gradients
- Código do LibreYOLO
- MIT
- Pesos
- Deci.AI proprietary, non-commercial, distribuído pelos autores. O LibreYOLO não hospeda nem espelha esses pesos.
- Interpretação
- Two licenses apply here and they are not the same. The SuperGradients source this port follows is Apache-2.0 and LibreYOLO's own implementation is MIT, so nothing restricts the architecture or the training code. Deci's published checkpoints are a different matter: the YOLO-NAS license grants a revocable, non-transferable right to use them and nothing more. It forbids redistribution and sublicensing, forbids offering them as a managed or remote service, restricts modification and reverse engineering, and rules out commercial use, including any model running in a production environment, unless you hold a separate agreement with Deci. LibreYOLO therefore does not mirror them, and prints those terms once before the download starts. Weights trained from a randomly initialized model on your own data derive from no Deci checkpoint.
O LibreYOLO não hospeda nem espelha esses pesos: não existe nada desta família na organização do LibreYOLO no Hugging Face. Em vez disso, todo download automático vai para a CDN pública da Deci, imprime os termos da Deci uma vez por processo antes de começar, e é conferido contra um SHA-256 fixado antes de o arquivo ser aberto.
Treinar a partir de um modelo inicializado aleatoriamente é a alternativa. A arquitetura é Apache-2.0 no upstream e MIT aqui, então um modelo treinado desse jeito com os seus próprios dados não deriva de nenhum checkpoint da Deci.
Citação
O YOLO-NAS foi lançado sem paper. A entrada abaixo é a que os autores pedem, e cobre o SuperGradients, a biblioteca em que ele foi distribuído.
@misc{supergradients,
doi = {10.5281/ZENODO.7789328},
url = {https://zenodo.org/record/7789328},
author = {Aharon, Shay and {Louis-Dupont} and {Ofri Masad} and Yurkova, Kate and {Lotem Fridman} and {Lkdci} and Khvedchenya, Eugene and Rubin, Ran and Bagrov, Natan and Tymchenko, Borys and Keren, Tomer and Zhilko, Alexander and {Eran-Deci}},
title = {Super-Gradients},
publisher = {GitHub},
journal = {GitHub repository},
year = {2021},
}Copiado do bloco de citação dos autores em github.com/Deci-AI/super-gradients#citing.