EdgeCrafter
エッジハードウェア上の密な予測に適した小型Vision Transformerです。アップストリームではECDet、ECPose、ECSegという3つの姉妹モデルとして公開されています。LibreYOLOは3つすべてを1つのファミリーとして読み込み、チェックポイントによってタスクを決定します。
- タスク
- detection, pose, instance segmentation
- サイズ
- s, m, l, x at 640 px
- インストール
pip install libreyolo- サポートティア
- コア、v1.2.0以降。学習可能なコア検出器:機能は同じリリースサイクルでフラッグシップに続いて実装されます。
- アップストリーム
- Intellindust AI LabのEdgeCrafter、Apache-2.0 original COCO weights; restricted obj2coco weights。論文、ソース
- ライセンス
- コード:Apache-2.0、重み:Apache-2.0 original COCO weights; restricted obj2coco weights。商用利用
インストール
EdgeCrafterにオプションの追加パッケージは不要です。インポートするものはすべて基本インストールに含まれています。
pip install libreyololora=Trueによるアダプターのファインチューニングは例外で、lora追加パッケージが必要です。
pip install "libreyolo[lora]"推論
重みは初回使用時にHugging Faceからダウンロードされ、ローカルにキャッシュされます。
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 # ファイル名の -pose サフィックスでキーポイントヘッドを選択するため# 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)タスクはファイル名で決まるため、-poseまたは-segチェックポイントは固有のヘッドを選択し、タスク引数を必要としません。3つすべてが各ファミリー共通のResultsオブジェクトを返し、姿勢推定ではresult.keypoints、セグメンテーションではresult.masksが追加されます。姿勢推定はpersonの1クラスとCOCOの17キーポイントを対象とし、モデル構築時にその数が固定されます。ボックスヘッドを持たないため、各姿勢ボックスは自身のキーポイントを囲む範囲となり、キーポイントの3番目のチャンネルは点ごとのスコアではなく定数です。
confとmax_detはクエリ選択をフィルタリングします。3つのヘッドはすべてNMSステップなしでクエリ集合をデコードするため、iouはAPIの互換性のため受け付けられますが効果はありません。ソース、ストリーミング、結果の処理については推論を参照してください。
物体検出の推論は長方形のimgsz=(height, width)を受け付けます。学習とエクスポートには、それぞれの形状制約が引き続き適用されます。
バリアント
4つのサイズがあります。すべて同じ入力解像度で動作するため、表ではパラメータ数と精度で区別しています。
| チェックポイント | 入力(px) | mAP 50-95 | パラメータ(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。LibreYOLOベンチマークハーネスで測定し、Vision Analysisで公開しています。そこではハードウェアおよびランタイム別のレイテンシを比較でき、完全な実行記録も確認できます。
アップストリームは、3つのヘッドを持つ1つのモデルではなく、ECDet、ECPose、ECSegを3つの別個のモデルとして公開しています。これらはECViTバックボーンとハイブリッドエンコーダーを共有し、ヘッドだけが異なります。そのため、LibreYOLOは3つを1つのファミリーにまとめ、チェックポイントのファイル名でタスクを表します。したがって、サイズ文字は3つすべてで同じバックボーンとエンコーダーを意味し、どれを読み込んでも推論、検証、エクスポートは同じ引数を受け取ります。
学習
3つのタスクはすべてtrain()で学習します。読み込んだチェックポイントからタスクを読み取り、対応するトレーナーを選択します。
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 # data.yaml で kpt_shape を宣言した単一クラスのキーポイントデータセットと# チェックポイントのネイティブサイズに合わせた imgsz が必要model = LibreYOLO("LibreECs-pose.pt")model.train( data="my-pose-dataset.yaml", epochs=50, imgsz=640,)from libreyolo import LibreYOLO # ポリゴンラベルとチェックポイントのネイティブサイズに合わせた imgsz が必要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,)検出とセグメンテーションで確認済みなのは、サイズごとに層単位で行ったアップストリームとの1e-5以内の推論一致と、合成入力で損失および1回の学習ステップが動作することです。train()自体のdocstringによると、完全なファインチューニングの収束、マルチGPU学習、データ拡張停止後の最良モデル再読み込みステップ、Objects365からCOCOへのクラス再マッピングは未検証です。姿勢推定の処理はDETRPoseの公開レシピに従います。クラス、キーポイントのL1、OKSコストを使うHungarian matcherと、対照的キーポイントノイズ除去を採用していますが、そのエンドツーエンドの収束も未検証です。
設定を変更しなければ、トレーナーはアップストリームのレシピに従い、混合精度を有効にしてlr0=5e-4で74エポック実行します。AdamW、フラットコサインスケジュール、0.9999のEMA、ImageNetで正規化した入力を使います。姿勢推定とセグメンテーションでは、どちらもチェックポイントのネイティブサイズに合わせたimgszが必要です。評価用アンカーグリッドはモデルの構築時に作成されるため、異なる値を指定すると実行開始前に例外が発生します。姿勢推定には、data.yamlでkpt_shapeを宣言し、キーポイント数がヘッドと一致する単一クラスのデータセットも必要です。
lora=Trueは検出だけに適用されます。姿勢推定とセグメンテーションではValueErrorが発生します。Apple siliconでは実行をGPU上に維持しつつ、変形可能アテンション内部のgrid-sampleの逆伝播という1つの演算をCPUに送ります。PyTorchがMetal上でこの演算を実装していないためです。
データセット、データ拡張、マルチGPU、ロガーについては学習を参照してください。
検証
val()はメトリクス名をキーとする辞書を返し、verboseを有効のままにするとクラス別の結果を表示します。
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)"]) # マスクprint(metrics["metrics/mAP50-95(B)"]) # ボックス姿勢推定はmetrics/keypoints_*にキーポイントのOKSメトリクスを報告します。セグメンテーションは通常のmetrics/mAP50-95キーにマスクを報告し、1回の処理で両方のビューも繰り返します。ボックスは(B)、マスクは(M)に格納されます。
エクスポート
| タスク | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX:対応 | Detection to TorchScript:対応 | Detection to ExecuTorch:対応 | Detection to TensorRT:対応 | Detection to OpenVINO:対応 | Detection to Paddle:対応 | Detection to MNN:対応 | Detection to RKNN:非対応 | Detection to ncnn:非対応 | Detection to TFLite:非対応 | Detection to CoreML:非対応 | Detection to Core AI:対応 |
| Pose | Pose to ONNX:対応 | Pose to TorchScript:対応 | Pose to ExecuTorch:対応 | Pose to TensorRT:対応 | Pose to OpenVINO:対応 | Pose to Paddle:対応 | Pose to MNN:非対応 | Pose to RKNN:非対応 | Pose to ncnn:非対応 | Pose to TFLite:非対応 | Pose to CoreML:非対応 | Pose to Core AI:非対応 |
| Instance segmentation | Instance segmentation to ONNX:対応 | Instance segmentation to TorchScript:対応 | Instance segmentation to ExecuTorch:対応 | Instance segmentation to TensorRT:対応 | Instance segmentation to OpenVINO:対応 | Instance segmentation to Paddle:対応 | Instance segmentation to MNN:非対応 | Instance segmentation to RKNN:非対応 | Instance segmentation to ncnn:非対応 | Instance segmentation to TFLite:非対応 | Instance segmentation to CoreML:非対応 | Instance segmentation to Core AI:非対応 |
エクスポートした成果物は、ファイルサフィックスに基づいてLibreYOLO()から再度読み込めます。そのため、.onnxまたは.engineファイルはチェックポイントと同様に動作し、同じResultsを返します。姿勢推定とセグメンテーションは、動的形状ではなく固定の640 x 640入力でエクスポートされます。OpenVINO、Paddle、MNN、ExecuTorch、Core AIを含む複数の検出ターゲットも固定キャンバスです。各形式が受け付ける引数と、一部の形式に追加される引数についてはエクスポートを参照してください。
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 # ファクトリーはファイルサフィックスで振り分けるためエクスポート成果物も# 任意のチェックポイントと同様に読み込まれ同じ Results オブジェクトを返すmodel = LibreYOLO("LibreECs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)ONNX の入力と出力
| テンソル | images float32 [batch, 3, height, width] |
|---|---|
| 色 | RGB |
| スケーリング | ピクセル値 / 255 |
| 正規化 | 平均 [0.485,0.456,0.406], 標準偏差 [0.229,0.224,0.225] |
| リサイズ | 幅 x 高さに引き伸ばす(パディングなし、アスペクト比は保持しない), Pillow bilinear |
Pillow のバイリニアリサイズを再現する方法
LibreYOLO は Pillow の BILINEAR フィルタ(Image.resize)でリサイズします。これは OpenCV の INTER_LINEAR や INTER_AREA ではありません。縮小時、Pillow は縮小率の分だけフィルタを広げます。OpenCV のリサイズでは検出結果が変わり、ボックスが数ピクセルずれます。Pillow なしで再現するには、片方の軸をリサイズして 8 ビットに丸め、もう片方の軸をリサイズして再び丸めます。軸ごとに s = in_size / out_size、f = max(s, 1) とします。出力ピクセル i の中心は c = (i + 0.5) * s で、元画像のピクセル j を int(c - f + 0.5) から int(c + f + 0.5) - 1 まで(画像内に制限して)読み取り、それぞれの重みは max(0, 1 - |j + 0.5 - c| / f) で、重みの合計で割ります。Pillow は固定小数点で計算し、画像の形状から軸の順序を選ぶため、浮動小数点の重みでは一部のピクセルで 1 レベル異なることがあります。これは私たちの検証の結果を変えません。
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、デフォルトのエクスポート
| 出力 | 形状 | 意味 |
|---|---|---|
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. |
後処理
- 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、デフォルトのエクスポート
| 出力 | 形状 | 意味 |
|---|---|---|
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. |
後処理
- 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、デフォルトのエクスポート
| 出力 | 形状 | 意味 |
|---|---|---|
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. |
後処理
- 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.
自分の実装を確認するには、同じファイルを LibreYOLO で実行します。LibreYOLO("model.onnx").predict("image.jpg") が基準となる結果を返します。 LibreYOLO 1.7.0 で検証済み。
チェックポイント
このファミリーで公開されているすべての重みファイルです。
| ファイル | 入力(px) | 重みのライセンス |
|---|---|---|
| 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 | |
上記のすべてのファイルは現在LibreYOLO orgにあり、初回使用時にダウンロードされます。
obj2cocoバリアントは、物体検出、セグメンテーション、姿勢推定に対応します。ダウンロードには明示的な同意が必要で、アップストリームの条件により商用利用が制限されます。元のCOCOチェックポイントは、記録済みのApache-2.0の許諾を維持します。
ライセンス
ダウンロードする特定の重みについて、Hugging Faceリポジトリのライセンスを確認してください。LibreYOLO orgの各チェックポイントにはライセンスが付与されており、同じファミリー内でも常に同一とは限りません。そのリポジトリが正式な情報源です。以下の概要は、このページを最後に検証した時点で適用されていた内容を示します。
これは関連するライセンスの説明であり、法的助言ではありません。商用上重要な場合は、自分でライセンスを読み、専門家の助言を受けてください。
- 原著作物
- EdgeCrafter, Intellindust AI Lab
- アップストリームのライセンス
- Apache-2.0 original COCO weights; restricted obj2coco weights
- アップストリームのソース
- github.com/Intellindust-AI-Lab/EdgeCrafter
- LibreYOLOのコード
- MIT
- 重み
- Apache-2.0 original COCO weights; restricted obj2coco weights、huggingface.co/LibreYOLOで再公開
- 解釈
- 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.
引用
@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}
}著者によるgithub.com/Intellindust-AI-Lab/EdgeCrafter#-citationの引用ブロックからコピーしています。