YOLO-NAS
Un detector convolucional cuyo backbone y cuello salieron de la búsqueda de arquitecturas de Deci.AI, construido con bloques RepVGG preparados para la cuantización. Sus pesos son de Deci.AI, con licencia solo para uso no comercial, y LibreYOLO no publica ninguno.
- Tareas
- detection, pose, oriented boxes
- Tamaños
- s, m, l at 640 px
- Instalación
pip install libreyolo- Nivel de compatibilidad
- Núcleo, desde v1.1.0. Detectores entrenables del núcleo: las funciones siguen a los modelos emblemáticos en la misma oleada de versiones.
- Licencias
- Código Apache-2.0, pesos Deci.AI proprietary, non-commercial. Uso comercial
Instalación
YOLO-NAS no necesita nada más allá del paquete base.
pip install libreyoloPredicción
Un nombre de checkpoint que no esté ya en disco se descarga de la CDN pública de Deci, no de la organización de LibreYOLO, que no aloja ninguno de estos pesos. Antes de que empiece la transferencia, la biblioteca imprime los términos de licencia de Deci una vez por proceso, y antes de abrir el archivo descargado comprueba su SHA-256 contra un valor fijado. Lo que esos términos permiten está en licencia.
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Un nombre que no esté ya en disco se descarga de la CDN de Deci. La# descarga imprime antes los términos de licencia de Deci; quedarte con# el archivo implica aceptarlos.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 # El sufijo -pose selecciona la cabeza de pose y su propio juego de pesos.model = LibreYOLO("LibreYOLONASs-pose.pt")result = model(SAMPLE_IMAGE) print(result.keypoints.xy)El objeto Results devuelto es el mismo que devuelven todas las familias, así
que cambiar a otro detector es un cambio de una línea. conf fija el umbral de
confianza e iou el umbral de NMS. Consulta predicción para
fuentes, streaming y manejo de resultados.
La tarea de cajas orientadas devuelve result.obb. El grafo OBB publicado usa un lienzo de 1024 píxeles y su conjunto registrado de 18 clases.
Variantes
Detección y pose son la misma arquitectura bajo cabezas distintas, y aceptan los mismos argumentos. Los tamaños de la tabla de abajo son los de detección; pose se publica en esos y en un tamaño más pequeño. La cabeza de pose predice el conjunto de keypoints de 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 con el sistema de benchmarks de LibreYOLO y publicado en Vision Analysis, donde se comparan la latencia entre distintos hardwares y runtimes y se conservan los registros completos de las ejecuciones.
Entrenamiento
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 # No se toca ningún checkpoint de Deci: el modelo parte de pesos# aleatorios, así que lo que salga de la ejecución deriva solo de tus datos.model = LibreYOLONAS(None, size="s")model.train(data="my-dataset.yaml", imgsz=640, batch=16)epochs, lr0 y amp se resuelven por tarea cuando los omites, así que una
ejecución de pose parte de valores por defecto distintos que una de detección.
El optimizador es AdamW por defecto. El número de clases sale del YAML del
dataset y la cabeza se reconstruye para él antes de la primera época; en la
cabeza de pose el número de keypoints se maneja igual, así que a un checkpoint
de pose de COCO se le puede hacer fine-tuning sobre un esqueleto de otro tamaño.
El fine-tuning parte de los pesos de Deci, que es lo que cubre la licencia de Deci. Entrenar desde un modelo inicializado al azar no involucra ningún checkpoint de Deci, y eso es el tercer snippet de arriba.
Consulta entrenamiento para datasets, aumento de datos (data augmentation), multi-GPU y loggers.
La detección usa por defecto amp=True con amp_dtype="float16"; el entrenamiento de cajas orientadas conserva amp=False. La cabeza OBB soporta entrenamiento, predicción y validación, usa aumentos con volteos y HSV, y selecciona checkpoints con metrics/mAP50-95(OBB). load_detect_weights_for_obb() la inicializa a partir de pesos de detección.
Validación
val() devuelve un diccionario de claves metrics/ que cubren precisión,
recall, mAP 50 y mAP 50-95, medidos contra cualquier dataset en el formato con
el que entrenaste.
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# El yaml de COCO incluido lleva un script de descarga embebido, así que# necesita permiso explícito salvo que el dataset ya esté en local.libreyolo val model=LibreYOLONASl.pt data=coco.yaml imgsz=640 \ allow_download_scripts=TrueExportación
| Tarea | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX: compatible | Detection to TorchScript: compatible | Detection to ExecuTorch: compatible | Detection to TensorRT: compatible | Detection to OpenVINO: compatible | Detection to Paddle: compatible | Detection to MNN: compatible | Detection to RKNN: compatible | Detection to ncnn: compatible | Detection to TFLite: compatible | Detection to CoreML: no compatible | Detection to Core AI: compatible |
| Pose | Pose to ONNX: compatible | Pose to TorchScript: compatible | Pose to ExecuTorch: compatible | Pose to TensorRT: compatible | Pose to OpenVINO: compatible | Pose to Paddle: compatible | Pose to MNN: no compatible | Pose to RKNN: no compatible | Pose to ncnn: compatible | Pose to TFLite: no compatible | Pose to CoreML: no compatible | Pose to Core AI: no compatible |
| Oriented boxes | Oriented boxes to ONNX: compatible | Oriented boxes to TorchScript: compatible | Oriented boxes to ExecuTorch: compatible | Oriented boxes to TensorRT: compatible | Oriented boxes to OpenVINO: compatible | Oriented boxes to Paddle: no compatible | Oriented boxes to MNN: no compatible | Oriented boxes to RKNN: no compatible | Oriented boxes to ncnn: compatible | Oriented boxes to TFLite: no compatible | Oriented boxes to CoreML: no compatible | Oriented boxes to Core AI: no compatible |
Un artefacto exportado se vuelve a cargar con LibreYOLO() según su sufijo de
archivo, así que un archivo .onnx o .engine se comporta como un checkpoint y
devuelve el mismo Results. Ejecutar el grafo en un runtime pelado, sin
LibreYOLO instalado, también está soportado, pero entonces el preprocesado y el
postprocesado corren de tu cuenta. Cada formato instala un extra distinto y
acepta unos cuantos argumentos propios. Ambas cosas están en la página de ese
formato.
Una exportación es otra copia de los mismos pesos en un contenedor distinto. Exportar un checkpoint de Deci no cambia ni de dónde vienen los pesos ni la licencia que los cubre.
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 # La factoría resuelve según el sufijo del archivo, así que un artefacto# exportado se carga como cualquier checkpoint y devuelve el mismo objeto Results.model = LibreYOLO("LibreYOLONASs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)Entradas y salidas ONNX
LibreYOLONAS detect
| Tensor | images float32 [batch, 3, height, width] |
|---|---|
| Color | RGB |
| Escalado | píxel / 255 |
| Normalización | ninguna |
| Redimensionado | custom, Pillow bilinear |
Cómo reproducir el redimensionado bilineal de Pillow
LibreYOLO redimensiona con el filtro BILINEAR de Pillow (Image.resize). No es OpenCV INTER_LINEAR ni INTER_AREA: al reducir, Pillow ensancha el filtro según el factor de reducción, y los redimensionados de OpenCV cambian las detecciones y desplazan las cajas varios píxeles. Para reproducirlo sin Pillow, redimensiona un eje, redondea a 8 bits, luego redimensiona el otro eje y vuelve a redondear. Por eje, sea s = in_size / out_size y f = max(s, 1). El píxel de salida i tiene centro c = (i + 0.5) * s y lee los píxeles de origen j desde int(c - f + 0.5) hasta int(c + f + 0.5) - 1, recortados a la imagen, cada uno con peso max(0, 1 - |j + 0.5 - c| / f), dividido por la suma de los pesos. Pillow trabaja en coma fija y elige el orden de los ejes según la forma de la imagen, así que los pesos en coma flotante pueden diferir en un nivel en unos pocos píxeles. Eso no cambia los resultados en nuestras comprobaciones.
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, exportación por defecto
| Salida | 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. |
Posprocesado
- 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] |
|---|---|
| Color | BGR |
| Escalado | píxel / 255 |
| Normalización | ninguna |
| Redimensionado | custom, Pillow bilinear |
Cómo reproducir el redimensionado bilineal de Pillow
LibreYOLO redimensiona con el filtro BILINEAR de Pillow (Image.resize). No es OpenCV INTER_LINEAR ni INTER_AREA: al reducir, Pillow ensancha el filtro según el factor de reducción, y los redimensionados de OpenCV cambian las detecciones y desplazan las cajas varios píxeles. Para reproducirlo sin Pillow, redimensiona un eje, redondea a 8 bits, luego redimensiona el otro eje y vuelve a redondear. Por eje, sea s = in_size / out_size y f = max(s, 1). El píxel de salida i tiene centro c = (i + 0.5) * s y lee los píxeles de origen j desde int(c - f + 0.5) hasta int(c + f + 0.5) - 1, recortados a la imagen, cada uno con peso max(0, 1 - |j + 0.5 - c| / f), dividido por la suma de los pesos. Pillow trabaja en coma fija y elige el orden de los ejes según la forma de la imagen, así que los pesos en coma flotante pueden diferir en un nivel en unos pocos píxeles. Eso no cambia los resultados en nuestras comprobaciones.
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, exportación por defecto
| Salida | 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. |
Posprocesado
- 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] |
|---|---|
| Color | BGR |
| Escalado | píxel / 255 |
| Normalización | ninguna |
| Redimensionado | 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, exportación por defecto
| Salida | 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. |
Posprocesado
- 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 comprobar tu propia implementación, pasa el mismo archivo por LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") devuelve los resultados de referencia. Verificado con LibreYOLO 1.7.0.
Checkpoints
No hay ninguno que listar. La licencia de Deci prohíbe la redistribución, así
que la organización de LibreYOLO no publica pesos de YOLO-NAS y la descarga se
resuelve en otro sitio: un nombre de la forma LibreYOLONAS<size>.pt,
LibreYOLONAS<size>-pose.pt para pose, o LibreYOLONAS<size>-obb.pt (s, m, l)
para cajas orientadas, se corresponde con el objeto equivalente en la CDN pública
de Deci.
Solo se pueden descargar así los checkpoints cuyo SHA-256 tiene fijado la
biblioteca. Cualquier otra cosa falla en cerrado en lugar de abrir un pickle de
terceros sin verificar, y hay que descargarla a mano y pasarla como ruta. Un
archivo que ya esté en disco se carga desde su ruta, sin descarga y sin control
de checksum. Eso incluye un .pth de Deci con su nombre original, que el
cargador reconoce.
Licencia
Comprueba la licencia en el repositorio de Hugging Face de los pesos concretos que descargues. Cada checkpoint de la organización de LibreYOLO incluye una, y no siempre es la misma en toda una familia. Ese repositorio es la fuente autorizada; el resumen siguiente describe qué se aplicaba cuando se verificó esta página por última vez.
Esta es una descripción de las licencias implicadas, no asesoramiento legal. Si la respuesta es importante a nivel comercial, lee las licencias y busca tu propio asesoramiento.
- Trabajo original
- YOLO-NAS, Deci.AI
- Licencia del proyecto original
- Deci.AI proprietary, non-commercial
- Fuente del proyecto original
- github.com/Deci-AI/super-gradients
- Código de LibreYOLO
- MIT
- Pesos
- Deci.AI proprietary, non-commercial, distribuidos por sus autores. LibreYOLO no los aloja ni los replica.
- Interpretación
- 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.
LibreYOLO ni aloja ni replica estos pesos: no existe nada de esta familia en la organización de LibreYOLO en Hugging Face. En su lugar, cada descarga automática va a la CDN pública de Deci, imprime los términos de Deci una vez por proceso antes de empezar, y se comprueba contra un SHA-256 fijado antes de abrir el archivo.
Entrenar desde un modelo inicializado al azar es la alternativa. La arquitectura es Apache-2.0 upstream y MIT aquí, así que un modelo entrenado de esa forma con tus propios datos no deriva de ningún checkpoint de Deci.
Cita
YOLO-NAS se publicó sin paper. La entrada de abajo es la que piden sus autores, y cubre SuperGradients, la biblioteca en la que se distribuyó.
@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 del bloque de cita de los autores en github.com/Deci-AI/super-gradients#citing.