EdgeCrafter
Kompaktowy transformer wizji do gęstego przewidywania na sprzęcie edge, opublikowany jako trzy powiązane modele: ECDet, ECPose i ECSeg. LibreYOLO ładuje wszystkie trzy jako jedną rodzinę, przy czym zadanie jest realizowane przez checkpoint.
- Zadania
- detection, pose, instance segmentation
- Rozmiary
- s, m, l, x at 640 px
- Instalacja
pip install libreyolo- Poziom obsługi
- Główny, od wersji v1.2.0. Główne trenowalne detektory: otrzymują funkcje po modelach flagowych w tej samej fali wydań.
- Projekt źródłowy
- EdgeCrafter, autorzy: Intellindust AI Lab, licencja: Apache-2.0 original COCO weights; restricted obj2coco weights. Publikacja, kod źródłowy
- Licencje
- Kod: Apache-2.0, wagi: Apache-2.0 original COCO weights; restricted obj2coco weights. Użycie komercyjne
Instalacja
EdgeCrafter nie potrzebuje żadnych dodatkowych opcji. Wszystko, co importuje, znajduje się w instalacji bazowej.
pip install libreyoloDostrajanie adaptera z lora=True jest wyjątkiem i wymaga dodatkowego lora.
pip install "libreyolo[lora]"Predykcja
Wagi są pobierane z Hugging Face przy pierwszym użyciu i są przechowywane lokalnie w pamięci podręcznej.
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 # Sufiks -pose w nazwie pliku wybiera głowicę punktów kluczowych, więc nie# tutaj potrzebny jest argument zadania.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)Zadanie pochodzi z nazwy pliku, więc checkpoint -pose lub -seg wybiera swoją własną głowicę i nie przyjmuje argumentu zadania. Wszystkie trzy zwracają obiekt Results, który zwraca każda rodzina, z result.keypoints dodanym dla pozy i result.masks dla segmentacji. Poza obejmuje jedną klasę, osobę, z 17 punktami kluczowymi COCO, a ich liczba jest ustalona podczas tworzenia modelu. Nie ma głowicy do obwiedni, więc każda rama pozy zawiera obwiednię własnych punktów kluczowych, a trzeci kanał punktów kluczowych jest stały, zamiast być oceną dla każdego punktu.
Argumenty conf i max_det filtrują wybór zapytań. Argument iou jest
akceptowany dla zgodności API, ale nie ma wpływu na wynik, ponieważ wszystkie
trzy głowice dekodują zbiór zapytań bez etapu NMS. Zobacz stronę
predykcji, aby poznać źródła, streaming i obsługę wyników.
Predykcja detekcji przyjmuje prostokątny imgsz=(height, width); trenowanie i eksport zachowują własne ograniczenia kształtu.
Warianty
Cztery rozmiary. Wszystkie działają przy tej samej rozdzielczości wejściowej, więc tabela rozdziela je według liczby parametrów i dokładności.
| Checkpoint modelu | Wejście (px) | mAP 50-95 | Parametry (mln) |
|---|---|---|---|
| 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. Wyniki zmierzono za pomocą zestawu benchmarkowego LibreYOLO i opublikowano w Vision Analysis, gdzie porównywane są opóźnienia na różnych urządzeniach i w różnych środowiskach uruchomieniowych oraz znajdują się pełne zapisy przebiegów.
Projekt upstream publikuje ECDet, ECPose i ECSeg jako trzy osobne modele, a nie jeden model z trzema głowicami. Współdzielą ECViT, backbone i hybrydowy enkoder, a różni je tylko głowica. LibreYOLO łączy je więc w jedną rodzinę, w której nazwa pliku checkpointu wskazuje zadanie. Litera rozmiaru oznacza ten sam backbone i enkoder we wszystkich trzech modelach, a metody predykcji, walidacji i eksportu przyjmują te same argumenty niezależnie od wczytanego wariantu.
Trenowanie
Wszystkie trzy zadania trenują przez train(), który odczytuje zadanie z załadowanego checkpointu i wybiera odpowiedniego trenera.
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 # Wymaga jednoczesnego zestawu punktów kluczowych jednej klasy, którego plik data.yaml deklaruje# kpt_shape i imgsz w natywnej wielkości checkpointu.model = LibreYOLO("LibreECs-pose.pt")model.train( data="my-pose-dataset.yaml", epochs=50, imgsz=640,)from libreyolo import LibreYOLO # Wymaga etykiet wielokątów i rozmiaru obrazu (imgsz) w natywnym rozmiarze checkpointu.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,)Dla detekcji i segmentacji sprawdzono zgodność inferencji z projektem upstream
z tolerancją 1e-5, warstwa po warstwie i dla każdego rozmiaru, a także działanie
funkcji straty i pojedynczego kroku trenowania na danych syntetycznych. Zgodnie
z opisem metody train() nie sprawdzono zbieżności pełnego dostrajania,
trenowania na wielu GPU, ponownego wczytania najlepszego modelu po wyłączeniu
augmentacji ani mapowania klas Objects365 na COCO. Ścieżka estymacji pozy
korzysta z opublikowanego przepisu DETRPose: dopasowania węgierskiego względem
klas, kosztów L1 i OKS dla punktów kluczowych oraz kontrastowego odszumiania
punktów kluczowych. Jej zbieżności również nie zweryfikowano od początku do
końca.
Pozostawiony sam, trener wykonuje 74 epoki na lr0=5e-4 z włączoną mieszanką precyzji, zgodnie z recepturą upstream: AdamW, płaski harmonogram kosinusowy, EMA na 0,9999 i wejścia ImageNet-normalized. Poza i segmentacja wymagają imgsz w natywnej wielkości checkpointu, ponieważ ich siatka odniesienia do ewaluacji jest tworzona, gdy model jest konstruowany; inna wartość zwiększa się przed rozpoczęciem uruchamiania. Poza wymaga również jednoczęściowego zbioru danych, którego data.yaml deklaruje kpt_shape, z liczbą punktów kluczowych odpowiadającą głowie.
lora=True dotyczy wyłącznie detekcji; pozowanie i segmentacja powodują wywołanie ValueError na nim. Na Apple Silicon trener utrzymuje działanie na GPU i wysyła jedną operację do CPU, wsteczny grid-sample wewnątrz deformowalnej uwagi, której PyTorch nie implementuje w Metal.
Zobacz trenowanie dotyczące zbiorów danych, augmentacji, multi-GPU i loggerów.
Walidacja
val() zwraca słownik kluczowany nazwą metryki i drukuje wyniki dla każdej klasy, gdy verbose jest włączony.
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)"]) # maskiprint(metrics["metrics/mAP50-95(B)"]) # pudełkaRaporty pozycji kluczowych Pose zawierają metryki OKS pod metrics/keypoints_*. Raporty segmentacji zawierają maski pod zwykłym kluczem metrics/mAP50-95 i powtarzają oba widoki w jednym przebiegu, pudełka pod (B) i maski pod (M).
Eksport
| Zadanie | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX: obsługiwane | Detection to TorchScript: obsługiwane | Detection to ExecuTorch: obsługiwane | Detection to TensorRT: obsługiwane | Detection to OpenVINO: obsługiwane | Detection to Paddle: obsługiwane | Detection to MNN: obsługiwane | Detection to RKNN: brak obsługi | Detection to ncnn: brak obsługi | Detection to TFLite: brak obsługi | Detection to CoreML: brak obsługi | Detection to Core AI: obsługiwane |
| Pose | Pose to ONNX: obsługiwane | Pose to TorchScript: obsługiwane | Pose to ExecuTorch: obsługiwane | Pose to TensorRT: obsługiwane | Pose to OpenVINO: obsługiwane | Pose to Paddle: obsługiwane | Pose to MNN: brak obsługi | Pose to RKNN: brak obsługi | Pose to ncnn: brak obsługi | Pose to TFLite: brak obsługi | Pose to CoreML: brak obsługi | Pose to Core AI: brak obsługi |
| Instance segmentation | Instance segmentation to ONNX: obsługiwane | Instance segmentation to TorchScript: obsługiwane | Instance segmentation to ExecuTorch: obsługiwane | Instance segmentation to TensorRT: obsługiwane | Instance segmentation to OpenVINO: obsługiwane | Instance segmentation to Paddle: obsługiwane | Instance segmentation to MNN: brak obsługi | Instance segmentation to RKNN: brak obsługi | Instance segmentation to ncnn: brak obsługi | Instance segmentation to TFLite: brak obsługi | Instance segmentation to CoreML: brak obsługi | Instance segmentation to Core AI: brak obsługi |
Eksportowany artefakt ładuje się z powrotem przez LibreYOLO() na podstawie jego sufiksu pliku, więc plik .onnx lub .engine zachowuje się jak checkpoint i zwraca ten sam Results. Eksport pozycji i segmentacji odbywa się przy stałym wejściu 640 na 640 zamiast dynamicznych kształtów, a kilka celów detekcji jest również w stałym układzie, w tym OpenVINO, Paddle, MNN, ExecuTorch i Core AI. Eksport wymienia argumenty, które akceptuje każdy format, oraz dodatkowe, które dodaje kilka z nich.
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 # Fabryka kieruje na podstawie rozszerzenia pliku, więc eksportowany artefakt się ładuje# jak każdy checkpoint i zwraca ten sam obiekt Results.model = LibreYOLO("LibreECs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)Wejścia i wyjścia ONNX
| Tensor | images float32 [batch, 3, height, width] |
|---|---|
| Kolor | RGB |
| Skalowanie | piksel / 255 |
| Normalizacja | średnia [0.485,0.456,0.406], odchylenie standardowe [0.229,0.224,0.225] |
| Zmiana rozmiaru | rozciągnij do szerokości x wysokości (bez wypełnienia, proporcje nie są zachowane), Pillow bilinear |
Jak odtworzyć dwuliniowe skalowanie Pillow
LibreYOLO skaluje filtrem BILINEAR z Pillow (Image.resize). To nie jest OpenCV INTER_LINEAR ani INTER_AREA: przy zmniejszaniu Pillow poszerza filtr o współczynnik zmniejszenia, a skalowania OpenCV zmieniają detekcje i przesuwają ramki o kilka pikseli. Aby odtworzyć to bez Pillow, przeskaluj jedną oś, zaokrąglij do 8 bitów, potem przeskaluj drugą oś i zaokrąglij ponownie. Dla każdej osi niech s = in_size / out_size oraz f = max(s, 1). Piksel wyjściowy i ma środek c = (i + 0.5) * s i czyta piksele źródłowe j od int(c - f + 0.5) do int(c + f + 0.5) - 1, przycięte do obrazu, każdy z wagą max(0, 1 - |j + 0.5 - c| / f), podzieloną przez sumę wag. Pillow liczy w arytmetyce stałoprzecinkowej i wybiera kolejność osi na podstawie kształtu obrazu, więc wagi zmiennoprzecinkowe mogą się od niego różnić o jeden poziom na kilku pikselach. To nie zmienia wyników w naszych sprawdzeniach.
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, eksport domyślny
| Wyjście | Kształt | Znaczenie |
|---|---|---|
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. |
Przetwarzanie końcowe
- 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, eksport domyślny
| Wyjście | Kształt | Znaczenie |
|---|---|---|
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. |
Przetwarzanie końcowe
- 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, eksport domyślny
| Wyjście | Kształt | Znaczenie |
|---|---|---|
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. |
Przetwarzanie końcowe
- 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.
Aby sprawdzić własną implementację, uruchom ten sam plik w LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") zwraca wyniki wzorcowe. Zweryfikowano w LibreYOLO 1.7.0.
Checkpointy
Każdy opublikowany plik wag dla tej rodziny.
| Plik | Wejście (px) | Licencja wag |
|---|---|---|
| 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 | |
Każdy z powyższych plików jest obecnie dostępny w organizacji LibreYOLO i pobierany przy pierwszym użyciu.
Warianty obj2coco obejmują detekcję, segmentację i estymację pozy. Ich pobieranie wymaga jawnej zgody, a warunki projektu źródłowego ograniczają użytek komercyjny. Oryginalne checkpointy COCO zachowują zapisaną licencję Apache-2.0.
Licencjonowanie
Sprawdź licencję w repozytorium konkretnych pobieranych wag na Hugging Face. Każdy checkpoint w organizacji LibreYOLO ma licencję, która nie zawsze jest taka sama w całej rodzinie. To repozytorium jest źródłem rozstrzygającym, a poniższe podsumowanie opisuje stan z chwili ostatniej weryfikacji tej strony.
To opis obowiązujących licencji, a nie porada prawna. Jeśli odpowiedź ma znaczenie komercyjne, przeczytaj licencje i zasięgnij własnej porady prawnej.
- Oryginalna praca
- EdgeCrafter, Intellindust AI Lab
- Licencja projektu źródłowego
- Apache-2.0 original COCO weights; restricted obj2coco weights
- Kod źródłowy projektu
- github.com/Intellindust-AI-Lab/EdgeCrafter
- Kod LibreYOLO
- MIT
- Wagi
- Apache-2.0 original COCO weights; restricted obj2coco weights, ponownie opublikowane w huggingface.co/LibreYOLO
- Interpretacja
- 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.
Cytowanie
@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}
}Skopiowano z bloku cytowania autorów w github.com/Intellindust-AI-Lab/EdgeCrafter#-citation.