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.

bash
pip install libreyolo

Eine Ausnahme ist das Adapter-Fine-Tuning mit lora=True. Dafür ist das Zusatzpaket lora erforderlich.

bash
pip install "libreyolo[lora]"

Vorhersage

Die Gewichte werden bei der ersten Verwendung von Hugging Face heruntergeladen und lokal zwischengespeichert.

Python
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)
CLI
libreyolo predict model=LibreECs.pt source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg save=True
Pose
from 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)
Instanzsegmentierung
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.

CheckpointEingabe (px)mAP 50-95Parameter (M)
LibreECl64060.132.97
LibreECm64058.419.43
LibreECs64054.39.88
LibreECx64061.149.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.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreECs.pt")model.train(    data="my-dataset.yaml",    epochs=50,    imgsz=640,    batch=8,    lr0=5e-4,)
CLI
libreyolo train model=LibreECs.pt data=my-dataset.yaml epochs=50 imgsz=640 batch=8 lr0=5e-4
Pose
from 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,)
Instanzsegmentierung
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,)
LoRA
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.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreECs.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])
CLI
libreyolo val model=LibreECs.pt data=my-dataset.yaml
Pose
from 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"])
Instanzsegmentierung
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)"])   # Boxen

Pose 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

AufgabeONNXTorchScriptExecuTorchTensorRTOpenVINOPaddleMNNRKNNncnnTFLiteCoreMLCore AI
DetectionDetection to ONNX: unterstütztDetection to TorchScript: unterstütztDetection to ExecuTorch: unterstütztDetection to TensorRT: unterstütztDetection to OpenVINO: unterstütztDetection to Paddle: unterstütztDetection to MNN: unterstütztDetection to RKNN: nicht unterstütztDetection to ncnn: nicht unterstütztDetection to TFLite: nicht unterstütztDetection to CoreML: nicht unterstütztDetection to Core AI: unterstützt
PosePose to ONNX: unterstütztPose to TorchScript: unterstütztPose to ExecuTorch: unterstütztPose to TensorRT: unterstütztPose to OpenVINO: unterstütztPose to Paddle: unterstütztPose to MNN: nicht unterstütztPose to RKNN: nicht unterstütztPose to ncnn: nicht unterstütztPose to TFLite: nicht unterstütztPose to CoreML: nicht unterstütztPose to Core AI: nicht unterstützt
Instance segmentationInstance segmentation to ONNX: unterstütztInstance segmentation to TorchScript: unterstütztInstance segmentation to ExecuTorch: unterstütztInstance segmentation to TensorRT: unterstütztInstance segmentation to OpenVINO: unterstütztInstance segmentation to Paddle: unterstütztInstance segmentation to MNN: nicht unterstütztInstance segmentation to RKNN: nicht unterstütztInstance segmentation to ncnn: nicht unterstütztInstance segmentation to TFLite: nicht unterstütztInstance segmentation to CoreML: nicht unterstütztInstance 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.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreECs.pt")model.export(format="onnx", imgsz=640)model.export(format="tensorrt", imgsz=640, half=True)
CLI
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=640
Exportierte Datei verwenden
from 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

Tensorimages float32 [batch, 3, height, width]
FarbeRGB
SkalierungPixel / 255
NormalisierungMittelwert [0.485,0.456,0.406], Standardabweichung [0.229,0.224,0.225]
Größenanpassungauf 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
AusgabeFormBedeutung
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

  1. Apply sigmoid to pred_logits.
  2. 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.
  3. Keep the entries whose score is strictly above the confidence threshold (0.25 by default). There is no NMS.
  4. 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.
  5. 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.
  6. nms=True is not available for this family: export raises NotImplementedError.
Instance segmentation, Standardexport
AusgabeFormBedeutung
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

  1. 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.
  2. 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.
  3. 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.
  4. The mask is the pixels whose resized logit is above 0. Masks are not cropped to the box.
  5. nms=True is not available for this family: export raises NotImplementedError.
Pose, Standardexport
AusgabeFormBedeutung
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

  1. Apply sigmoid to the last logit of each query. That is the person score.
  2. 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.
  3. 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.
  4. 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).
  5. LibreYOLO reports visibility 1 for every keypoint, since the graph predicts xy only.
  6. 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.

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
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.

Mit LibreYOLO v1.6.0 verifiziert. Supporttabellen, Checkpoints und Benchmarkwerte auf dieser Seite werden aus der veröffentlichten Bibliothek und den publizierten Gewichten generiert und nicht von Hand geschrieben.