Paddle

PaddlePaddle-Inferenzmodelle bestehen aus einem model.pdmodel-Graphen neben einer model.pdiparams-Gewichtsdatei. LibreYOLO exportiert einen statischen ONNX-Graphen mit Opset 15, konvertiert ihn mit X2Paddle und packt das Ergebnis mit einer metadata.yaml zusammen, damit es über dieselbe Factory lädt wie jede andere Runtime.

Flag
export(format="paddle")
Schreibt
Ein Verzeichnis mit model.pdmodel, model.pdiparams und metadata.yaml
Extra
pip install "libreyolo[paddle]"
Lädt zurück
LibreYOLO("weights/LibreYOLO9t_paddle", device="cpu")
Backend
libreyolo.backends.paddle.PaddleBackend
Shapes
Statisch, Batch 1, Opset 15. Alle drei werden erzwungen.
Präzision
Nur FP32, nur CPU.
Toolchain
PaddlePaddle 2.6.2, X2Paddle 1.6.0, ONNX 1.17 oder älter, exakt geprüft

Installation

Installation
# Python 3.10 bis 3.12. Unter Windows ist WSL2 mit Ubuntu 22.04 validiert.pip install "libreyolo[paddle]"
Die gepinnten Versionen prüfen
python -c "from importlib.metadata import version; print(version('paddlepaddle'), version('x2paddle'), version('onnx'))"

Das Extra pinnt genau den Stack, den die Paritätsarbeit gemessen hat: PaddlePaddle 2.6.2, X2Paddle 1.6.0 und ONNX 1.17 oder älter. Diese Pins werden beim Export geprüft, nicht nur bei der Installation, und eine abweichende Version löst einen ImportError aus, der die erwartete nennt. Neuere Paddle-Releases lehnen Teile des statischen Codes ab, den X2Paddle 1.6.0 erzeugt, deshalb ist ein früher Fehlschlag besser als ein Artefakt, das niemand validiert hat.

Export

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt") # Schreibt das Verzeichnis weights/LibreYOLO9t_paddlepath = model.export(format="paddle")print(path)
CLI
libreyolo export --model LibreYOLO9t.pt --format paddle
Argumente
model.export(    format="paddle",    imgsz=640,        # int; quadratisches Canvas dieser Familie    batch=1,          # jeder andere Wert löst ValueError aus    dynamic=False,    # True löst ValueError aus    simplify=True,    # False löst ValueError aus    opset=15,         # jeder andere Wert löst ValueError aus    output_path=None, # None schreibt weights/<stem>_paddle)

Vier Argumente sind festgelegt und nicht bloß vorbelegt. dynamic muss False sein, batch muss 1 sein, simplify muss True sein, damit der Konvertierungsgraph vollständig statisch ist, und opset muss 15 sein, die Obergrenze, die X2Paddle 1.6.0 akzeptiert. Alles andere löst einen Fehler aus, bevor das Tracing beginnt.

Auf dem Zwischengraphen läuft eine Normalisierung. ONNX definiert eine weggelassene MaxPool-Dilation als eins, PyTorch schreibt das explizite Attribut aus lauter Einsen, und X2Paddle 1.6.0 lehnt es ab, deshalb entfernt der Exporter diesen redundanten Default und lässt die angegebene Operation unverändert.

Das Artefakt ist ein Verzeichnis: model.pdmodel, model.pdiparams und metadata.yaml. Der Python-Code, den X2Paddle während der Konvertierung erzeugt, gehört nicht dazu.

Ausführung des Artefakts

Über LibreYOLO
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("weights/LibreYOLO9t_paddle", device="cpu")result = model.predict(SAMPLE_IMAGE)print(result.boxes.xyxy[:3])
CLI
libreyolo predict --model weights/LibreYOLO9t_paddle \  --source https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg --device cpu --save
Das Backend direkt
from libreyolo.backends.paddle import PaddleBackend # Was LibreYOLO() für ein Paddle-Verzeichnis baut. Gleiches Results-# Objekt, kein Factory-Routing dazwischen.backend = PaddleBackend("weights/LibreYOLO9t_paddle", device="cpu")result = backend.predict("parkour.jpg")print(result.boxes.xyxy[:3])
Reines Paddle
import numpy as npimport paddle.inference as paddle_inferimport yaml directory = "weights/LibreYOLO9t_paddle"config = paddle_infer.Config(    f"{directory}/model.pdmodel", f"{directory}/model.pdiparams")config.disable_gpu()config.disable_mkldnn()config.switch_ir_optim(False) predictor = paddle_infer.create_predictor(config)handle = predictor.get_input_handle(predictor.get_input_names()[0])handle.reshape([1, 3, 640, 640])handle.copy_from_cpu(np.zeros((1, 3, 640, 640), dtype=np.float32))predictor.run()for name in predictor.get_output_names():    print(name, predictor.get_output_handle(name).copy_to_cpu().shape) meta = yaml.safe_load(open(f"{directory}/metadata.yaml"))print(meta["model_family"], meta["task"], meta["names"]) # Vor- und Nachverarbeitung liegen auf diesem Weg bei dir.

LibreYOLO() erkennt jedes Verzeichnis, das sowohl model.pdmodel als auch model.pdiparams enthält, liest metadata.yaml und liefert dasselbe Results-Objekt wie der Checkpoint. Ein anderes Device als auto oder cpu löst einen Fehler aus: Dieses Backend läuft nur auf der CPU.

Die Factory baut PaddleBackend, exportiert aus libreyolo und importierbar als libreyolo.backends.paddle.PaddleBackend. Baue es selbst, wenn du das Backend ohne das Suffix-Routing der Factory willst, etwa um task= explizit für ein Verzeichnis zu setzen, dessen metadata.yaml nicht von dir stammt. Sein predict() nimmt dieselben Quellen und liefert dieselben Ergebnisse.

Das Snippet mit der reinen Runtime spiegelt, was das Backend konfiguriert, und die drei abgeschalteten Optionen sind Absicht. Die CPU-Fusion-Pipeline von Paddle 2.6 kann abstürzen, während sie die großen Gather- und Scatter-Graphen optimiert, die für Deformable Attention entstehen, deshalb wurde die Parität gegen den portablen, unfusionierten statischen Graphen gemessen. Vorverarbeitung, Decoding, NMS und das Umrechnen der Koordinaten liegen auf diesem Weg bei dir.

Einschränkungen

Keine dynamischen Shapes, kein FP16, kein INT8, kein eingebettetes NMS, keine GPU-Runtime.

Validiert sind YOLO9-Erkennung, YOLO9-E2E- und YOLO9-P2-Erkennung, EC-Erkennung, -Pose und -Segmentierung, RT-DETRv4-, D-FINE-, DEIM- und DEIMv2-Erkennung sowie YOLO-NAS-Erkennung und -Pose. Jede Kombination ist durch Konvertierung, einen Reload in der CPU-Runtime, Parität der Rohausgaben und übereinstimmende öffentliche Ergebnisse abgedeckt.

Blockiert, mit dem Grund pro Kombination:

KombinationGrund
RF-DETR, alle AufgabenBraucht ONNX-Opset 17 und GridSample; X2Paddle 1.6.0 akzeptiert Opset 15 oder niedriger und hat keinen GridSample-Mapper
RT-DETR- und RT-DETRv2-ErkennungDie trainierten Graphen brauchen GridSample ab Opset 16
D-FINE-SegmentierungKonvertiert und lädt wieder, aber der relative RMS-Fehler der Mask-Logits liegt bei 3.52 % und die minimale IoU der zugeordneten Masken bei 0.582
YOLO9-SegmentierungYOLO9 ist in LibreYOLO reine Erkennung
RTMDet-Ins-SegmentierungDas Mask-Decoding mit dynamischen Kerneln hat keinen Vertrag für exportierte Runtimes

Alles, was weder als validiert noch als blockiert aufgeführt ist, wird mit dem Hinweis abgelehnt, dass es über den Konvertierungsweg von ONNX nach Paddle nicht validiert wurde.

Das vollständige Raster aus Familien und Aufgaben findest du in der Export-Matrix. Für eine einzelne Kombination:

Eine Familie und Aufgabe vor dem Export prüfen
libreyolo formats --family yolo9 --task detect

Gelesen aus libreyolo/export/paddle.py, libreyolo/export/exporter.py, libreyolo/export/support.py, libreyolo/backends/paddle.py, docs/paddle.md und pyproject.toml auf dem dev-Branch.