Paddle
PaddlePaddle推論モデルはmodel.pdmodelグラフとmodel.pdiparams重みファイルから構成されます。LibreYOLOは静的なopset 15のONNXグラフをエクスポートし、X2Paddleで変換します。結果をmetadata.yamlとともにパッケージ化するため、ほかのランタイムと同じファクトリから読み込めます。
- フラグ
export(format="paddle")- 出力
- model.pdmodel、model.pdiparams、metadata.yamlを含むディレクトリ
- 追加パッケージ
pip install "libreyolo[paddle]"- 再読み込み
LibreYOLO("weights/LibreYOLO9t_paddle", device="cpu")- バックエンド
libreyolo.backends.paddle.PaddleBackend- 形状
- 静的、バッチ1、opset 15。3項目すべてを強制
- 精度
- FP32のみ、CPUのみ
- ツールチェーン
- PaddlePaddle 2.6.2、X2Paddle 1.6.0、ONNX 1.17以前を厳密に確認
インストール
# Python 3.10〜3.12。WindowsではUbuntu 22.04のWSL2経路を検証済みpip install "libreyolo[paddle]"python -c "from importlib.metadata import version; print(version('paddlepaddle'), version('x2paddle'), version('onnx'))"追加パッケージは、同等性の検証で測定した正確なスタックに固定されます。PaddlePaddle 2.6.2、
X2Paddle 1.6.0、ONNX 1.17以前です。この固定条件はインストール時だけでなくエクスポート時にも
確認され、異なるバージョンでは期待するバージョンを示すImportErrorが発生します。新しい
PaddleリリースはX2Paddle 1.6.0が生成する静的コードの一部を拒否します。そのため、未検証の
成果物を生成するより早期に失敗する方が適切です。
エクスポート
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt") # ディレクトリweights/LibreYOLO9t_paddleを書き出しpath = model.export(format="paddle")print(path)libreyolo export --model LibreYOLO9t.pt --format paddlemodel.export( format="paddle", imgsz=640, # int。このファミリーの正方形キャンバス batch=1, # ほかの値ではValueError dynamic=False, # TrueではValueError simplify=True, # FalseではValueError opset=15, # ほかの値ではValueError output_path=None, # Noneはweights/<stem>_paddleに書き出し)4個の引数はデフォルト値ではなく固定値です。dynamicはFalse、batchは1、完全に静的な
変換グラフにするためsimplifyはTrueでなければなりません。opsetはX2Paddle 1.6.0が
受け付ける上限の15でなければなりません。ほかの値を渡すとトレース前に例外が発生します。
中間グラフには1つの正規化処理を行います。ONNXでは省略されたMaxPool dilationを1と定義し、 PyTorchはすべて1の属性を明示的に書き込みますが、X2Paddle 1.6.0はこれを拒否します。そのため、 エクスポーターは冗長なデフォルトを削除し、指定された演算自体は変更しません。
成果物はmodel.pdmodel、model.pdiparams、metadata.yamlを含むディレクトリです。
X2Paddleが変換中に生成するPythonコードは成果物に含まれません。
成果物を実行
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("weights/LibreYOLO9t_paddle", device="cpu")result = model.predict(SAMPLE_IMAGE)print(result.boxes.xyxy[:3])libreyolo predict --model weights/LibreYOLO9t_paddle \ --source https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg --device cpu --savefrom libreyolo.backends.paddle import PaddleBackend # LibreYOLO()がPaddleディレクトリ用に構築するもの。同じResults# オブジェクトを返し、ファクトリの振り分けを経由しないbackend = PaddleBackend("weights/LibreYOLO9t_paddle", device="cpu")result = backend.predict("parkour.jpg")print(result.boxes.xyxy[:3])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"]) # この経路では前処理と後処理を自分で実装LibreYOLO()はmodel.pdmodelとmodel.pdiparamsの両方を含むディレクトリを認識し、
metadata.yamlを読み込んで、チェックポイントと同じResultsオブジェクトを返します。
autoまたはcpu以外のデバイスでは例外が発生します。このバックエンドはCPU専用です。
ファクトリが構築するのはPaddleBackendです。これはlibreyoloからエクスポートされ、
libreyolo.backends.paddle.PaddleBackendとしてインポートできます。ファクトリの接尾辞による
振り分けなしでバックエンドを使う場合は直接構築してください。たとえば、自分で
metadata.yamlを書いていないディレクトリにtask=を明示的に渡す場合です。そのpredict()は
同じ入力ソースを受け取り、同じ結果を返します。
ランタイムを直接使うスニペットはバックエンドの設定を再現しており、3個のオプションを無効に しているのは意図的です。Paddle 2.6のCPU融合パイプラインは、deformable attention用に生成された 大規模なgather・scatterグラフの最適化中に異常終了する可能性があります。そのため、移植可能な 融合なしの静的グラフを同等性の測定対象にしています。この経路では前処理、デコード、NMS、 座標の再スケーリングを自分で実装します。
制約
動的形状、FP16、INT8、組み込みNMS、GPUランタイムには対応しません。
検証済みの組み合わせは、YOLO9物体検出、YOLO9-E2EとYOLO9-P2の物体検出、ECの物体検出・ 姿勢推定・セグメンテーション、RT-DETRv4、D-FINE、DEIM、DEIMv2の物体検出、YOLO-NASの 物体検出と姿勢推定です。それぞれで変換、CPUランタイムでの再読み込み、生出力の同等性、 公開結果との一致を確認しています。
拒否対象と、組み合わせごとに記録された理由は次のとおりです。
| 組み合わせ | 理由 |
|---|---|
| RF-DETR、全タスク | ONNX opset 17とGridSampleが必要。X2Paddle 1.6.0が受け付けるのはopset 15以下で、GridSampleのマッパーもない |
| RT-DETRとRT-DETRv2の物体検出 | 学習済みグラフにはopset 16以降のGridSampleが必要 |
| D-FINEセグメンテーション | 変換と再読み込みはできるが、マスクlogitの相対RMS誤差が3.52%、対応マスクの最小IoUが0.582 |
| YOLO9セグメンテーション | LibreYOLOのYOLO9は物体検出のみ |
| RTMDet-Insセグメンテーション | 動的カーネルによるマスクのデコードにエクスポート先ランタイムの契約がない |
検証済みまたは拒否対象として記載されていないものは、ONNXからPaddleへの変換経路で未検証で あることを示して拒否されます。
ファミリーとタスクの完全な対応表は エクスポート対応表を参照してください。1つの組み合わせを調べるには次を実行します。
libreyolo formats --family yolo9 --task detect