EdgeCrafter
Un vision transformer compatto per la predizione densa su hardware edge, pubblicato dall'upstream come tre modelli fratelli: ECDet, ECPose ed ECSeg. LibreYOLO li carica tutti e tre come un'unica famiglia, con il task portato dal checkpoint.
- Task
- detection, pose, instance segmentation
- Dimensioni
- s, m, l, x at 640 px
- Installa
pip install libreyolo- Livello di supporto
- Principale, dalla v1.2.0. Rilevatori addestrabili principali: le funzionalità seguono i modelli di punta nella stessa ondata di release.
- Origine
- EdgeCrafter di Intellindust AI Lab, Apache-2.0 original COCO weights; restricted obj2coco weights. Articolo, sorgente
- Licenze
- Codice Apache-2.0, pesi Apache-2.0 original COCO weights; restricted obj2coco weights. Uso commerciale
Installazione
EdgeCrafter non richiede nessun extra opzionale. Tutto ciò che importa è già nell'installazione di base.
pip install libreyoloIl fine-tuning con adattatori tramite lora=True è l'eccezione, e richiede
l'extra lora.
pip install "libreyolo[lora]"Predizione
I pesi vengono scaricati da Hugging Face al primo utilizzo e restano nella cache locale.
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreECs.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes: print(box.cls, box.conf, box.xyxy)libreyolo predict model=LibreECs.pt source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg save=Truefrom libreyolo import LibreYOLO, SAMPLE_IMAGE # Il suffisso -pose nel nome del file seleziona la testa dei keypoint,# quindi qui non serve l'argomento task.model = LibreYOLO("LibreECs-pose.pt")result = model(SAMPLE_IMAGE, save=True) print(result.keypoints.xy)print(result.boxes.conf)from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreECs-seg.pt")result = model(SAMPLE_IMAGE, save=True) print(result.masks.data.shape)Il task viene dal nome del file, quindi un checkpoint -pose o -seg seleziona
da solo la propria testa e non richiede nessun argomento task. Tutti e tre
restituiscono l'oggetto Results che restituisce ogni famiglia, con
result.keypoints in più per la posa e result.masks per la segmentazione. La
posa copre una sola classe, person, con i 17 keypoint COCO, e il conteggio è
fissato quando il modello viene costruito. Non ha una testa per i box, quindi
ogni box della posa è l'estensione che racchiude i suoi stessi keypoint, e il
terzo canale del keypoint è una costante invece che un punteggio per punto.
conf e max_det filtrano la selezione delle query; iou è accettato per
parità di API ma non ha effetto, perché tutte e tre le teste decodificano un
insieme di query senza passaggio di NMS. Vedi predizione per
sorgenti, streaming e gestione dei risultati.
La predizione di rilevamento accetta imgsz=(height, width) rettangolare; addestramento ed esportazione mantengono i propri vincoli sulle dimensioni.
Varianti
Quattro dimensioni. Girano tutte alla stessa risoluzione di input, quindi la tabella le separa per numero di parametri e accuratezza.
| Checkpoint | Ingresso (px) | mAP 50-95 | Parametri (M) |
|---|---|---|---|
| LibreECl | 640 | 60.1 | 32.97 |
| LibreECm | 640 | 58.4 | 19.43 |
| LibreECs | 640 | 54.3 | 9.88 |
| LibreECx | 640 | 61.1 | 49.94 |
COCO val2017, 500 images. Misurato con il sistema di benchmark di LibreYOLO e pubblicato su Vision Analysis, dove vengono confrontate le latenze tra hardware e runtime e sono disponibili i record completi delle esecuzioni.
L'upstream pubblica ECDet, ECPose ed ECSeg come tre modelli separati invece che un solo modello con tre teste. Condividono il backbone ECViT e l'encoder ibrido e differiscono solo nella testa, quindi LibreYOLO li riunisce in un'unica famiglia e lascia che sia il nome del file del checkpoint a portare il task. Una lettera di dimensione significa quindi lo stesso backbone e lo stesso encoder per tutti e tre, e predizione, validazione ed esportazione accettano gli stessi argomenti qualunque sia quello che carichi.
Addestramento
Tutti e tre i task si addestrano tramite train(), che legge il task dal
checkpoint caricato e sceglie il trainer corrispondente.
from libreyolo import LibreYOLO model = LibreYOLO("LibreECs.pt")model.train( data="my-dataset.yaml", epochs=50, imgsz=640, batch=8, lr0=5e-4,)libreyolo train model=LibreECs.pt data=my-dataset.yaml epochs=50 imgsz=640 batch=8 lr0=5e-4from libreyolo import LibreYOLO # Richiede un dataset di keypoint a classe singola il cui data.yaml# dichiari kpt_shape, e imgsz alla dimensione nativa del checkpoint.model = LibreYOLO("LibreECs-pose.pt")model.train( data="my-pose-dataset.yaml", epochs=50, imgsz=640,)from libreyolo import LibreYOLO # Richiede etichette poligonali, e imgsz alla dimensione nativa del checkpoint.model = LibreYOLO("LibreECs-seg.pt")model.train( data="my-dataset.yaml", epochs=50, imgsz=640,)from libreyolo import LibreYOLO model = LibreYOLO("LibreECs.pt")model.train( data="my-dataset.yaml", epochs=50, lora=True,)Cosa è stato verificato per il rilevamento e la segmentazione: la parità di
inferenza con l'upstream a 1e-5, layer per layer e per ogni dimensione, e che la
loss e un singolo passo di addestramento girino su input sintetici. Cosa no,
stando alla docstring di train() stessa: la convergenza di un fine-tuning
completo, l'addestramento multi-GPU, il passaggio di ricarica del migliore allo
stop della data augmentation, e il rimappaggio delle classi da Objects365 a
COCO. La via della posa segue la ricetta pubblicata di DETRPose, un matcher
ungherese su costi di classe, L1 sui keypoint e OKS con denoising contrastivo
dei keypoint, e nemmeno la sua convergenza è stata verificata end to end.
Se non tocchi niente, il trainer esegue 74 epoche con lr0=5e-4 e la precisione
mista attiva, seguendo la ricetta dell'upstream: AdamW, una schedule cosine
piatta, EMA a 0.9999 e input normalizzati su ImageNet. Posa e segmentazione
richiedono entrambe imgsz alla dimensione nativa del checkpoint, perché la
loro griglia di anchor per la valutazione viene costruita quando il modello
viene costruito; un valore diverso solleva un errore prima che l'esecuzione
parta. La posa richiede inoltre un dataset a classe singola il cui data.yaml
dichiari kpt_shape, con un numero di keypoint che corrisponde alla testa.
lora=True si applica solo al rilevamento; posa e segmentazione sollevano un
ValueError se lo ricevono. Su Apple silicon il trainer tiene l'esecuzione
sulla GPU e manda una sola operazione su CPU, il backward del grid-sample dentro
l'attenzione deformabile, che PyTorch non implementa in Metal.
Vedi addestramento per dataset, data augmentation, multi-GPU e logger.
Validazione
val() restituisce un dizionario indicizzato per nome della metrica, e stampa i
risultati per classe se verbose resta attivo.
from libreyolo import LibreYOLO model = LibreYOLO("LibreECs.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])libreyolo val model=LibreECs.pt data=my-dataset.yamlfrom libreyolo import LibreYOLO model = LibreYOLO("LibreECs-pose.pt")metrics = model.val(data="my-pose-dataset.yaml") print(metrics["metrics/keypoints_mAP50-95"])print(metrics["metrics/keypoints_mAP50"])from libreyolo import LibreYOLO model = LibreYOLO("LibreECs-seg.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/mAP50-95(M)"]) # maschereprint(metrics["metrics/mAP50-95(B)"]) # boxLa posa riporta le metriche OKS sui keypoint sotto metrics/keypoints_*. La
segmentazione riporta le maschere sotto la chiave semplice metrics/mAP50-95 e
ripete entrambe le viste in una sola passata, i box sotto (B) e le maschere
sotto (M).
Esportazione
| Task | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX: supportato | Detection to TorchScript: supportato | Detection to ExecuTorch: supportato | Detection to TensorRT: supportato | Detection to OpenVINO: supportato | Detection to Paddle: supportato | Detection to MNN: supportato | Detection to RKNN: non supportato | Detection to ncnn: non supportato | Detection to TFLite: non supportato | Detection to CoreML: non supportato | Detection to Core AI: supportato |
| Pose | Pose to ONNX: supportato | Pose to TorchScript: supportato | Pose to ExecuTorch: supportato | Pose to TensorRT: supportato | Pose to OpenVINO: supportato | Pose to Paddle: supportato | Pose to MNN: non supportato | Pose to RKNN: non supportato | Pose to ncnn: non supportato | Pose to TFLite: non supportato | Pose to CoreML: non supportato | Pose to Core AI: non supportato |
| Instance segmentation | Instance segmentation to ONNX: supportato | Instance segmentation to TorchScript: supportato | Instance segmentation to ExecuTorch: supportato | Instance segmentation to TensorRT: supportato | Instance segmentation to OpenVINO: supportato | Instance segmentation to Paddle: supportato | Instance segmentation to MNN: non supportato | Instance segmentation to RKNN: non supportato | Instance segmentation to ncnn: non supportato | Instance segmentation to TFLite: non supportato | Instance segmentation to CoreML: non supportato | Instance segmentation to Core AI: non supportato |
Un artefatto esportato si ricarica con LibreYOLO() in base al suffisso del
file, quindi un file .onnx o .engine si comporta come un checkpoint e
restituisce lo stesso Results. Posa e segmentazione esportano con un input
fisso di 640 per 640 invece che con forme dinamiche, e anche diversi target di
rilevamento sono a canvas fisso, tra cui OpenVINO, Paddle, MNN, ExecuTorch e
Core AI. Esportazione elenca gli argomenti che ogni formato
accetta e gli extra che qualcuno di essi aggiunge.
from libreyolo import LibreYOLO model = LibreYOLO("LibreECs.pt")model.export(format="onnx", imgsz=640)model.export(format="tensorrt", imgsz=640, half=True)libreyolo export model=LibreECs.pt format=onnx imgsz=640libreyolo export model=LibreECs-pose.pt format=onnx imgsz=640libreyolo export model=LibreECs-seg.pt format=onnx imgsz=640from libreyolo import LibreYOLO, SAMPLE_IMAGE # La factory smista in base al suffisso del file, quindi un artefatto# esportato si carica come qualsiasi checkpoint e restituisce lo stesso# oggetto Results.model = LibreYOLO("LibreECs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)Input e output ONNX
| Tensore | images float32 [batch, 3, height, width] |
|---|---|
| Colore | RGB |
| Scala | pixel / 255 |
| Normalizzazione | media [0.485,0.456,0.406], deviazione standard [0.229,0.224,0.225] |
| Ridimensionamento | allungare a larghezza x altezza (senza riempimento, il rapporto d'aspetto non viene mantenuto), Pillow bilinear |
Come riprodurre il ridimensionamento bilineare di Pillow
LibreYOLO ridimensiona con il filtro BILINEAR di Pillow (Image.resize). Non è OpenCV INTER_LINEAR né INTER_AREA: in riduzione, Pillow allarga il filtro del fattore di riduzione, e i ridimensionamenti di OpenCV cambiano le rilevazioni e spostano i riquadri di diversi pixel. Per riprodurlo senza Pillow, ridimensiona un asse, arrotonda a 8 bit, poi ridimensiona l'altro asse e arrotonda di nuovo. Per ogni asse, siano s = in_size / out_size e f = max(s, 1). Il pixel di uscita i ha centro c = (i + 0.5) * s e legge i pixel sorgente j da int(c - f + 0.5) a int(c + f + 0.5) - 1, limitati all'immagine, ciascuno con peso max(0, 1 - |j + 0.5 - c| / f), diviso per la somma dei pesi. Pillow lavora in virgola fissa e sceglie l'ordine degli assi dalla forma dell'immagine, quindi i pesi in virgola mobile possono differire di un livello su pochi pixel. Questo non cambia i risultati nei nostri controlli.
Square input only. Export rejects a non-square imgsz, and height and width are 640 by default.
Detect and segment: batch size 1 only. The graph declares a dynamic batch axis, but batches of 2 or more fail in 1.7.0. Pose runs with any batch size.
For a bit-exact match, use Pillow's integer math: multiply each weight by 2^22 and round half away from zero, sum weight x pixel in integers, add 2^21, shift right by 22 and clip to 0 to 255.
Divide by 255 after the resize, then subtract the ImageNet mean and divide by the ImageNet std per channel.
Detection, esportazione predefinita
| Output | Forma | Significato |
|---|---|---|
pred_logits | [batch, queries, nc] | Raw class logits per query, sigmoid not applied. 300 queries and 80 classes for the COCO checkpoints. |
pred_boxes | [batch, queries, 4] | Boxes as cx, cy, w, h, normalized 0 to 1 of the input. |
Post-elaborazione
- Apply sigmoid to pred_logits.
- Flatten the scores to queries x nc and take the top max_det (300 by default) over all queries x classes. For flat index k, the query is k // nc and the class is k % nc. One query can yield several classes.
- Keep the entries whose score is strictly above the confidence threshold (0.25 by default). There is no NMS.
- Convert the query's box to x1, y1, x2, y2 with x1 = cx - w / 2, y1 = cy - h / 2, x2 = cx + w / 2, y2 = cy + h / 2.
- Map boxes back to the original image: multiply x by the original width and y by the original height. The input was stretched, so no pad offset applies. LibreYOLO does not clip these boxes to the image.
- nms=True is not available for this family: export raises NotImplementedError.
Instance segmentation, esportazione predefinita
| Output | Forma | Significato |
|---|---|---|
pred_logits | [batch, queries, nc] | Raw class logits per query, sigmoid not applied. 300 queries and 80 classes for the COCO checkpoints. |
pred_boxes | [batch, queries, 4] | Boxes as cx, cy, w, h, normalized 0 to 1 of the input. |
pred_masks | [batch, queries, mask_h, mask_w] | Raw mask logits per query over the whole input canvas, sigmoid not applied. mask_h and mask_w are a quarter of the input, 160 x 160 at 640 x 640. |
Post-elaborazione
- Select detections exactly as for detect: sigmoid on pred_logits, top max_det (300 by default) over all queries x classes, keep scores strictly above the confidence threshold (0.25 by default). There is no NMS.
- Convert and map the boxes as for detect: cx, cy, w, h to x1, y1, x2, y2, then multiply x by the original width and y by the original height. LibreYOLO does not clip these boxes to the image.
- For each kept detection, take the mask logits of its query and resize them straight to the original image size with bilinear interpolation, half-pixel centers (align_corners=False) and no antialiasing. cv2.resize with INTER_LINEAR on float32 does this.
- The mask is the pixels whose resized logit is above 0. Masks are not cropped to the box.
- nms=True is not available for this family: export raises NotImplementedError.
Pose, esportazione predefinita
| Output | Forma | Significato |
|---|---|---|
pred_logits | [batch, queries, 2] | Raw logits per query, sigmoid not applied. 60 queries. Index 1, the last one, is the person class. Index 0 is an unused slot. |
pred_keypoints | [batch, queries, num_keypoints * 2] | Keypoints as x0, y0, x1, y1 and so on, normalized 0 to 1 of the input. num_keypoints is 17 (COCO order) and is recorded in the num_keypoints metadata key. There is no box output and no keypoint visibility or confidence. |
Post-elaborazione
- Apply sigmoid to the last logit of each query. That is the person score.
- Sort the queries by score, highest first, and keep at most max_det (300 by default, so all 60 queries). Keep the queries whose score is at or above the confidence threshold (0.25 by default). Note at or above here, strictly above for detect and segment. There is no NMS.
- Reshape each kept query's keypoints to [num_keypoints, 2]. Map them back to the original image: multiply x by the original width and y by the original height.
- The box is the extent of the mapped keypoints: x1, y1 are the minimum x and y, x2, y2 the maximum. The class is always 0 (person).
- LibreYOLO reports visibility 1 for every keypoint, since the graph predicts xy only.
- nms=True is not available for this family: export raises NotImplementedError.
Per verificare la tua implementazione, passa lo stesso file a LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") restituisce i risultati di riferimento. Verificato con LibreYOLO 1.7.0.
Checkpoint
Tutti i file di pesi pubblicati per questa famiglia.
| File | Ingresso (px) | Licenza dei pesi |
|---|---|---|
| Detection | ||
| LibreECs.pt | 640 | apache-2.0 |
| LibreECm.pt | 640 | apache-2.0 |
| LibreECl.pt | 640 | apache-2.0 |
| LibreECx.pt | 640 | apache-2.0 |
| LibreECl-obj2coco.pt | other | |
| LibreECm-obj2coco.pt | other | |
| LibreECs-obj2coco.pt | other | |
| LibreECx-obj2coco.pt | other | |
| Pose | ||
| LibreECs-pose.pt | 640 | apache-2.0 |
| LibreECm-pose.pt | 640 | apache-2.0 |
| LibreECl-pose.pt | 640 | apache-2.0 |
| LibreECx-pose.pt | 640 | apache-2.0 |
| LibreECl-pose-obj2coco.pt | other | |
| LibreECm-pose-obj2coco.pt | other | |
| LibreECs-pose-obj2coco.pt | other | |
| LibreECx-pose-obj2coco.pt | other | |
| Instance segmentation | ||
| LibreECs-seg.pt | 640 | apache-2.0 |
| LibreECm-seg.pt | 640 | apache-2.0 |
| LibreECl-seg.pt | 640 | apache-2.0 |
| LibreECx-seg.pt | 640 | apache-2.0 |
| LibreECm-seg-obj2coco.pt | other | |
| LibreECs-seg-obj2coco.pt | other | |
| LibreECl-seg-obj2coco.pt | other | |
| LibreECx-seg-obj2coco.pt | other | |
Oggi tutti i file elencati sopra sono presenti nell<link>organizzazione LibreYOLO</link> e vengono scaricati al primo utilizzo.
Le varianti obj2coco coprono rilevamento, segmentazione e posa. Il download richiede un consenso esplicito e i termini upstream limitano l'uso commerciale. I checkpoint COCO originali mantengono la licenza Apache-2.0 registrata.
Licenze
Controlla la licenza nel repository Hugging Face degli specifici pesi che scarichi. Ogni checkpoint nell<link>organizzazione LibreYOLO</link> ne include una e non è sempre la stessa per tutta la famiglia. Quel repository è la fonte autorevole; il riepilogo seguente descrive le condizioni applicabili al momento dellultima verifica di questa pagina.
Questa è una descrizione delle licenze coinvolte, non una consulenza legale. Se la risposta è importante a fini commerciali, leggi personalmente le licenze e chiedi una consulenza indipendente.
- Lavoro originale
- EdgeCrafter, Intellindust AI Lab
- Licenza upstream
- Apache-2.0 original COCO weights; restricted obj2coco weights
- Sorgente upstream
- github.com/Intellindust-AI-Lab/EdgeCrafter
- Codice LibreYOLO
- MIT
- Pesi
- Apache-2.0 original COCO weights; restricted obj2coco weights, ripubblicati su huggingface.co/LibreYOLO
- Interpretazione
- Original COCO checkpoints retain their recorded Apache-2.0 grant. The obj2coco detection, segmentation and pose variants require explicit opt-in and retain non-commercial upstream terms. The library code license does not replace those weight terms.
Citazione
@article{liu2026edgecrafter,
title={EdgeCrafter: Compact ViTs for Edge Dense Prediction via Task-Specialized Distillation},
author={Liu, Longfei and Hou, Yongjie and Li, Yang and Wang, Qirui and Sha, Youyang and Yu, Yongjun and Wang, Yinzhi and Ru, Peizhe and Yu, Xuanlong and Shen, Xi},
journal={arXiv},
year={2026}
}Copiato dal blocco di citazione degli autori disponibile su github.com/Intellindust-AI-Lab/EdgeCrafter#-citation.