MNN
MNN adalah engine inferensi ringan buatan Alibaba. LibreYOLO mengekspor graph ONNX statis, mengonversinya dengan tool mnnconvert yang dibawa paket MNN, lalu menulis sidecar JSON yang mencatat nama input dan output, bentuk input yang tetap serta nama kelasnya.
- Flag
export(format="mnn")- Menulis
- Satu berkas .mnn plus sidecar metadata .mnn.json
- Extra
pip install "libreyolo[mnn]"- Dimuat kembali
LibreYOLO("weights/LibreYOLO9t.mnn")- Bentuk
- NCHW tetap. dynamic=True ditolak.
- Presisi
- Hanya FP32, hanya CPU.
- Task
- Hanya deteksi di versi ini
Instalasi
# Extra ini sudah mencakup libreyolo[onnx]: MNN mengonversi dari perantara ONNX.pip install "libreyolo[mnn]"mnnconvert --versionExtra ini sudah mencakup libreyolo[onnx], karena konversinya berjalan lewat
perantara ONNX. Extra ini juga membawa executable mnnconvert, yang dicari
exporter pertama-tama di sebelah interpreter Python yang aktif, lalu di PATH.
Converter yang tidak ditemukan memunculkan ImportError yang menyebutkan
perintah instalasinya, bukan gagal di tengah konversi.
Ekspor
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt") # Menulis weights/LibreYOLO9t.mnn dan weights/LibreYOLO9t.mnn.jsonpath = model.export(format="mnn", imgsz=640)print(path)libreyolo export --model LibreYOLO9t.pt --format mnn --imgsz 640model.export( format="mnn", imgsz=640, # int, atau (tinggi, lebar) batch=1, # ditanam ke dalam artefak simplify=True, # onnxsim atas perantara ONNX output_path=None, # None menulis weights/<stem>.mnn verbose=False, # True menyalurkan log mnnconvert) # dynamic=True memunculkan ValueError. half=True dan int8=True ditolak.Sebelum menyerahkan graph, exporter membaca kontrak input ONNX dan menolak apa
pun yang tidak bisa diungkapkannya: input gambar lebih dari satu, atau bentuk
input dengan dimensi simbolik. MNN pada versi ini menuntut bentuk NCHW yang
sepenuhnya tetap, dan batch ditanam ke dalam artefak, bukan dinegosiasikan
saat pemuatan.
Sidecar itu bukan catatan tambahan yang opsional. weights/LibreYOLO9t.mnn.json
mencatat nama input dan output, bentuk input yang tetap, batch, nama kelas,
versi MNN yang dipakai, dan backend yang menjadi target artefaknya, dan runtime
memvalidasi setiap field tersebut saat pemuatan.
Di Windows, MNN 3.6.1 kadang menyelesaikan konversi lalu berhenti saat proses ditutup dengan access violation atau status fail-fast. Exporter mengenali exit code spesifik itu dan menganggap konversinya berhasil bila berkas keluarannya ada.
Menjalankan artefak
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("weights/LibreYOLO9t.mnn")result = model.predict(SAMPLE_IMAGE)print(result.boxes.xyxy[:3])import json import MNNimport numpy as np meta = json.load(open("weights/LibreYOLO9t.mnn.json"))print(meta["mnn_input_names"], meta["mnn_output_names"], meta["mnn_input_shape"]) runtime = MNN.nn.create_runtime_manager( ({"backend": 0, "precision": 1, "numThread": 4},))module = MNN.nn.load_module_from_file( "weights/LibreYOLO9t.mnn", meta["mnn_input_names"], meta["mnn_output_names"], runtime_manager=runtime, dynamic=False, shape_mutable=False,) blob = np.zeros(meta["mnn_input_shape"], dtype=np.float32)input_var = MNN.expr.const( blob, list(blob.shape), MNN.expr.NCHW, MNN.expr.float)outputs = module.forward([input_var])for out in outputs: print(np.array(MNN.expr.convert(out, MNN.expr.NCHW).read()).shape) # Preprocessing dan postprocessing menjadi tanggung jawab Anda di jalur ini.LibreYOLO() melakukan dispatch berdasarkan sufiks .mnn dan mengembalikan
objek Results yang sama seperti checkpoint. Pemuatannya memang sengaja ketat:
sidecar harus menyatakan format=mnn, mnn_backend=cpu, dynamic=false,
precision=fp32, sebuah ukuran, task deteksi, bentuk NCHW tetap yang positif
dan cocok dengan ukuran gambar yang tercatat, serta nama kelas yang mencakup
setiap indeks dari 0 sampai nc - 1. Ketidakcocokan apa pun akan memunculkan
error, bukan menebak.
Prediksi dengan imgsz yang berbeda dari saat artefak dibangun juga memunculkan
error, dan device diabaikan disertai peringatan, karena hasil ekspor MNN di
sini berjalan di CPU.
Snippet kedua adalah jalur runtime langsung. Preprocessing, decoding, NMS dan penskalaan ulang koordinat menjadi tanggung jawab Anda di sana, dan nama input serta output diambil dari sidecar karena module loader MNN memintanya secara eksplisit.
Batasan
Hanya deteksi. Backend menolak task lain saat pemuatan, dan sisi ekspornya sejalan: di luar kombinasi yang tercatat, preflight memunculkan error "MNN v1 has no implemented runtime contract for this family and task."
FP32, CPU, bentuk tetap. dynamic=True memunculkan ValueError, dan
half=True serta int8=True ditolak saat validasi.
Family deteksi yang tervalidasi adalah YOLO9, YOLO9-E2E, YOLO9-P2, RF-DETR, EC, RT-DETR, RT-DETRv2, RT-DETRv4, D-FINE, DEIM dan YOLO-NAS, masing-masing dicakup oleh konversi, pemuatan ulang artefak yang baru, eksekusi MNN di CPU, pemeriksaan metadata dan kesetaraan deteksi pasca-NMS terhadap model PyTorch. DEIMv2 berhasil dikonversi, dimuat ulang, dijalankan dan mempertahankan deteksi pasca-NMS, tetapi jalur perantara ONNX-nya belum sepenuhnya setara pada skor di tingkat query, sehingga statusnya dicatat sebagai tersedia, bukan tervalidasi.
Untuk grid family dan task selengkapnya, lihat matriks ekspor. Untuk satu kombinasi:
libreyolo formats --family yolo9 --task detect