EdgeCrafter
Ein kompakter Vision Transformer für dichte Vorhersagen auf Edge-Hardware, der upstream als drei verwandte Modelle veröffentlicht wurde: ECDet, ECPose und ECSeg. LibreYOLO lädt alle drei als eine Familie, wobei der Checkpoint die Aufgabe festlegt.
- Aufgaben
- detection, pose, instance segmentation
- Größen
- s, m, l, x at 640 px
- Installation
pip install libreyolo- Supportstufe
- Kern, seit v1.2.0. Trainierbare Kerndetektoren: Funktionen folgen den Flaggschiffen in derselben Release-Welle.
- Upstream
- EdgeCrafter von Intellindust AI Lab, Apache-2.0 original COCO weights; restricted obj2coco weights. Publikation, Quelle
- Lizenzen
- Code Apache-2.0, Gewichte Apache-2.0 original COCO weights; restricted obj2coco weights. Kommerzielle Nutzung
Installation
EdgeCrafter benötigt kein optionales Zusatzpaket. Alle Importe sind in der Basisinstallation enthalten.
pip install libreyoloEine Ausnahme ist das Adapter-Fine-Tuning mit lora=True. Dafür ist das
Zusatzpaket lora erforderlich.
pip install "libreyolo[lora]"Vorhersage
Die Gewichte werden bei der ersten Verwendung von Hugging Face heruntergeladen und lokal zwischengespeichert.
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 # Das Suffix -pose im Dateinamen wählt den Keypoint-Head aus,# daher ist hier kein task-Argument erforderlich.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)Die Aufgabe stammt aus dem Dateinamen. Ein -pose- oder -seg-Checkpoint
wählt somit seinen eigenen Head aus und benötigt kein Aufgabenargument. Alle
drei geben das Results-Objekt aller Familien zurück, ergänzt um
result.keypoints für Pose und result.masks für Segmentierung. Die
Pose-Schätzung umfasst eine Klasse, Person, mit den 17 COCO-Keypoints. Ihre
Anzahl wird beim Erstellen des Modells festgelegt. Das Modell besitzt keinen
Box-Head. Jede Pose-Box entspricht daher der Bounding Box ihrer eigenen
Keypoints, und der dritte Keypoint-Kanal ist eine Konstante statt eines
punktbezogenen Scores.
conf und max_det filtern die Auswahl der Queries. iou wird aus Gründen
der API-Parität akzeptiert, hat aber keine Wirkung, weil alle drei Heads eine
Menge von Queries ohne NMS-Schritt dekodieren. Unter
Vorhersage findest du Quellen, Streaming und die Verarbeitung
von Ergebnissen.
Die Erkennungsvorhersage akzeptiert rechteckiges imgsz=(height, width); Training und Export behalten ihre eigenen Formbeschränkungen bei.
Varianten
Es gibt vier Größen. Alle laufen mit derselben Eingabeauflösung, daher unterscheidet die Tabelle sie anhand der Parameteranzahl und Accuracy.
| Checkpoint | Eingabe (px) | mAP 50-95 | Parameter (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. Gemessen mit dem LibreYOLO-Benchmarksystem und auf Vision Analysis veröffentlicht. Dort werden Latenzen verschiedener Hardware und Runtimes verglichen und die vollständigen Laufprotokolle bereitgestellt.
Upstream veröffentlicht ECDet, ECPose und ECSeg als drei separate Modelle und nicht als ein Modell mit drei Heads. Sie verwenden dasselbe ECViT-Backbone und denselben hybriden Encoder und unterscheiden sich nur im Head. LibreYOLO fasst sie deshalb in einer Familie zusammen und lässt den Checkpoint-Dateinamen die Aufgabe tragen. Ein Größenbuchstabe bezeichnet somit bei allen drei Modellen dasselbe Backbone und denselben Encoder. Vorhersage, Validierung und Export akzeptieren unabhängig vom geladenen Modell dieselben Argumente.
Training
Alle drei Aufgaben werden über train() trainiert. Die Methode liest die
Aufgabe aus dem geladenen Checkpoint und wählt den passenden Trainer.
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 # Benötigt einen einklassigen Keypoint-Datensatz, dessen data.yaml# kpt_shape deklariert, und imgsz in der nativen Größe des Checkpoints.model = LibreYOLO("LibreECs-pose.pt")model.train( data="my-pose-dataset.yaml", epochs=50, imgsz=640,)from libreyolo import LibreYOLO # Benötigt Polygon-Labels und imgsz in der nativen Größe des Checkpoints.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,)Für Erkennung und Segmentierung wurde Folgendes geprüft: Inferenzparität mit
dem Upstream auf 1e-5, Schicht für Schicht und für jede Größe, sowie die
Ausführung des Losses und eines einzelnen Trainingsschritts auf synthetischer
Eingabe. Laut dem eigenen Docstring von train() wurde Folgendes nicht geprüft:
die Konvergenz eines vollständigen Fine-Tunings, Multi-GPU-Training, der Schritt
zum Neuladen des besten Modells nach dem Stopp der Augmentierung und die
Klassenumordnung von Objects365 zu COCO. Der Pose-Pfad folgt dem veröffentlichten
Rezept von DETRPose: einem ungarischen Matcher über Klassen-, Keypoint-L1- und
OKS-Kosten mit kontrastivem Keypoint-Denoising. Auch seine Konvergenz wurde
nicht vollständig geprüft.
Ohne Änderungen läuft der Trainer 74 Epochen mit lr0=5e-4 und aktivierter
Mixed Precision gemäß dem Upstream-Rezept: AdamW, ein Flat-Cosine-Zeitplan,
EMA mit 0.9999 und nach ImageNet normalisierte Eingaben. Pose und Segmentierung
benötigen beide imgsz in der nativen Größe des Checkpoints, weil ihr
Auswertungs-Anchor-Raster beim Erstellen des Modells aufgebaut wird. Ein anderer
Wert löst vor Beginn des Laufs einen Fehler aus. Pose benötigt außerdem einen
einklassigen Datensatz, dessen data.yaml den Wert kpt_shape deklariert. Die
Keypoint-Anzahl muss zum Head passen.
lora=True gilt nur für die Objekterkennung. Pose und Segmentierung lösen dafür
einen ValueError aus. Auf Apple-Silicon verbleibt der Lauf auf der GPU, der
Trainer verlagert aber eine Operation auf die CPU: den Grid-Sample-Backward-Pass
innerhalb der Deformable Attention, den PyTorch nicht in Metal implementiert.
Unter Training findest du Datensätze, Datenaugmentierung, Multi-GPU und Logger.
Validierung
val() gibt ein Dictionary mit den Metriknamen als Schlüsseln zurück und
druckt klassenspezifische Ergebnisse, solange verbose aktiviert bleibt.
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)"]) # Maskenprint(metrics["metrics/mAP50-95(B)"]) # BoxenPose meldet Keypoint-OKS-Metriken unter metrics/keypoints_*. Die Segmentierung
meldet Masken unter dem einfachen Schlüssel metrics/mAP50-95 und wiederholt
beide Ansichten in einem Durchlauf: Boxen unter (B) und Masken unter (M).
Export
| Aufgabe | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX: unterstützt | Detection to TorchScript: unterstützt | Detection to ExecuTorch: unterstützt | Detection to TensorRT: unterstützt | Detection to OpenVINO: unterstützt | Detection to Paddle: unterstützt | Detection to MNN: unterstützt | Detection to RKNN: nicht unterstützt | Detection to ncnn: nicht unterstützt | Detection to TFLite: nicht unterstützt | Detection to CoreML: nicht unterstützt | Detection to Core AI: unterstützt |
| Pose | Pose to ONNX: unterstützt | Pose to TorchScript: unterstützt | Pose to ExecuTorch: unterstützt | Pose to TensorRT: unterstützt | Pose to OpenVINO: unterstützt | Pose to Paddle: unterstützt | Pose to MNN: nicht unterstützt | Pose to RKNN: nicht unterstützt | Pose to ncnn: nicht unterstützt | Pose to TFLite: nicht unterstützt | Pose to CoreML: nicht unterstützt | Pose to Core AI: nicht unterstützt |
| Instance segmentation | Instance segmentation to ONNX: unterstützt | Instance segmentation to TorchScript: unterstützt | Instance segmentation to ExecuTorch: unterstützt | Instance segmentation to TensorRT: unterstützt | Instance segmentation to OpenVINO: unterstützt | Instance segmentation to Paddle: unterstützt | Instance segmentation to MNN: nicht unterstützt | Instance segmentation to RKNN: nicht unterstützt | Instance segmentation to ncnn: nicht unterstützt | Instance segmentation to TFLite: nicht unterstützt | Instance segmentation to CoreML: nicht unterstützt | Instance segmentation to Core AI: nicht unterstützt |
Ein exportiertes Artefakt wird anhand seiner Dateiendung wieder über LibreYOLO()
geladen. Eine .onnx- oder .engine-Datei verhält sich daher wie ein Checkpoint
und gibt dasselbe Results-Objekt zurück. Pose und Segmentierung werden mit
einer festen Eingabe von 640 mal 640 statt mit dynamischen Formen exportiert.
Auch mehrere Erkennungsziele verwenden eine feste Arbeitsfläche, darunter
OpenVINO, Paddle, MNN, ExecuTorch und Core AI. Export führt die
Argumente auf, die jedes Format akzeptiert, sowie die Zusatzpakete, die einige
davon benötigen.
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 # Die Factory entscheidet anhand der Dateiendung, daher wird ein Exportartefakt# wie jeder Checkpoint geladen und gibt dasselbe Results-Objekt zurück.model = LibreYOLO("LibreECs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)ONNX-Ein- und Ausgaben
| Tensor | images float32 [batch, 3, height, width] |
|---|---|
| Farbe | RGB |
| Skalierung | Pixel / 255 |
| Normalisierung | Mittelwert [0.485,0.456,0.406], Standardabweichung [0.229,0.224,0.225] |
| Größenanpassung | auf Breite x Höhe strecken (ohne Auffüllen, Seitenverhältnis wird nicht beibehalten), Pillow bilinear |
So reproduzierst du die bilineare Skalierung von Pillow
LibreYOLO skaliert mit dem BILINEAR-Filter von Pillow (Image.resize). Das ist weder OpenCV INTER_LINEAR noch INTER_AREA: Beim Verkleinern weitet Pillow den Filter um den Verkleinerungsfaktor, und die Skalierungen von OpenCV verändern Detektionen und verschieben Boxen um mehrere Pixel. Um es ohne Pillow nachzubauen, skaliere eine Achse, runde auf 8 Bit, skaliere dann die andere Achse und runde erneut. Pro Achse gilt s = in_size / out_size und f = max(s, 1). Ausgabepixel i hat das Zentrum c = (i + 0.5) * s und liest Quellpixel j von int(c - f + 0.5) bis int(c + f + 0.5) - 1, auf das Bild begrenzt, jeweils mit dem Gewicht max(0, 1 - |j + 0.5 - c| / f), geteilt durch die Summe der Gewichte. Pillow rechnet in Festkomma und wählt die Achsenreihenfolge anhand der Bildform, daher können Gleitkomma-Gewichte bei einigen Pixeln um eine Stufe abweichen. Das ändert die Ergebnisse in unseren Prüfungen nicht.
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, Standardexport
| Ausgabe | Form | Bedeutung |
|---|---|---|
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. |
Nachbearbeitung
- 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, Standardexport
| Ausgabe | Form | Bedeutung |
|---|---|---|
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. |
Nachbearbeitung
- 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, Standardexport
| Ausgabe | Form | Bedeutung |
|---|---|---|
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. |
Nachbearbeitung
- 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.
Um deine eigene Implementierung zu prüfen, lade dieselbe Datei mit LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") liefert die Referenzergebnisse. Geprüft mit LibreYOLO 1.7.0.
Checkpoints
Alle veröffentlichten Gewichtsdateien dieser Familie.
| Datei | Eingabe (px) | Lizenz der Gewichte |
|---|---|---|
| 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 | |
Jede oben aufgeführte Datei ist heute in der LibreYOLO-Organisation verfügbar und wird bei der ersten Verwendung heruntergeladen.
Die obj2coco-Varianten decken Erkennung, Segmentierung und Pose ab. Ihr Download erfordert eine ausdrückliche Zustimmung, und ihre Upstream-Bedingungen beschränken die kommerzielle Nutzung. Die ursprünglichen COCO-Checkpoints behalten ihre gespeicherte Apache-2.0-Lizenz.
Lizenzierung
Prüfe die Lizenz im Hugging-Face-Repository der konkreten Gewichte, die du herunterlädst. Jeder Checkpoint in der LibreYOLO-Organisation hat eine Lizenz, und sie ist innerhalb einer Familie nicht immer gleich. Dieses Repository ist die maßgebliche Quelle. Die Zusammenfassung unten beschreibt den Stand bei der letzten Verifizierung dieser Seite.
Dies ist eine Beschreibung der beteiligten Lizenzen und keine Rechtsberatung. Wenn die Antwort kommerziell relevant ist, lies die Lizenzen selbst und hole eigenen Rechtsrat ein.
- Originalarbeit
- EdgeCrafter, Intellindust AI Lab
- Upstream-Lizenz
- Apache-2.0 original COCO weights; restricted obj2coco weights
- Upstream-Quelle
- github.com/Intellindust-AI-Lab/EdgeCrafter
- LibreYOLO-Code
- MIT
- Gewichte
- Apache-2.0 original COCO weights; restricted obj2coco weights, erneut unter huggingface.co/LibreYOLO veröffentlicht
- Einordnung
- 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.
Zitieren
@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}
}Aus dem Zitierblock der Autoren unter github.com/Intellindust-AI-Lab/EdgeCrafter#-citation kopiert.