一、簡(jiǎn)介
飛槳(PaddlePaddle)以百度深度學(xué)習(xí)技術(shù)研究和業(yè)務(wù)應(yīng)用為基礎(chǔ),集深度學(xué)習(xí)核心訓(xùn)練和推理框架、基礎(chǔ)模型庫(kù)、端到端開(kāi)發(fā)套件和豐富的工具組件于一體的深度學(xué)習(xí)平臺(tái)。
1.訓(xùn)練模型庫(kù)
PaddleHub旨在為開(kāi)發(fā)者提供豐富的、高質(zhì)量的、直接可用的預(yù)訓(xùn)練模型。飛槳的產(chǎn)業(yè)級(jí)模型庫(kù)包含PaddleClas、PaddleDetection、PaddleSeg、PaddleOCR、PaddleGAN、PaddleVideo、PaddleNLP等方面。
1)PaddleDetection
PaddleDetection是一個(gè)基于PaddlePaddle的目標(biāo)檢測(cè)端到端開(kāi)發(fā)套件,在提供豐富的模型組件和測(cè)試基準(zhǔn)的同時(shí),注重端到端的產(chǎn)業(yè)落地應(yīng)用,幫助開(kāi)發(fā)者實(shí)現(xiàn)數(shù)據(jù)準(zhǔn)備、模型選型、模型訓(xùn)練、模型部署的全流程打通,快速進(jìn)行落地應(yīng)用。
不僅復(fù)現(xiàn)了常見(jiàn)的目標(biāo)檢測(cè)模型,還對(duì)模型的進(jìn)行了圖像增強(qiáng)、骨干網(wǎng)絡(luò)優(yōu)化、DropBlock,IoU Loss IoUAware等一系列深度優(yōu)化。同時(shí)內(nèi)置集成模型壓縮能力,提供了一鍵式剪裁,蒸餾,量化的腳本,大大提高模型精度和速度,并減小模型體積。
優(yōu)勢(shì):
模型豐富:PaddleDetection提供了豐富的模型,包含目標(biāo)檢測(cè)、實(shí)例分割、人臉檢測(cè)等100+個(gè)預(yù)訓(xùn)練模型,10+算法,持續(xù)推出針對(duì)服務(wù)器端和移動(dòng)端、嵌入式等的增強(qiáng)模型,涵蓋多種數(shù)據(jù)集競(jìng)賽冠軍方案,并提供適合云端/邊緣端設(shè)備部署的檢測(cè)方案。
高靈活度:PaddleDetection通過(guò)模塊化設(shè)計(jì)來(lái)解耦各個(gè)組件,模型網(wǎng)絡(luò)結(jié)構(gòu)和數(shù)據(jù)處理均可定制,基于配置文件可以輕松地搭建各種檢測(cè)模型。
-
易部署:PaddleDetection的模型中使用的核心算子均通過(guò)C++或CUDA實(shí)現(xiàn),提供跨平臺(tái)推理引擎,實(shí)現(xiàn)了模型訓(xùn)練到部署的無(wú)縫銜接,同時(shí)內(nèi)置集成了一鍵式壓縮和部署能力。
- 對(duì)于低算力的設(shè)備,推出SSDLite及其量化模型,通過(guò)模型增強(qiáng),SSDLite在驍龍845芯片上推理時(shí)延達(dá)到41ms。
- 對(duì)于需要兼顧速度和精度的應(yīng)用場(chǎng)景,推出YOLOv3剪裁+蒸餾的壓縮模型,在100ms左右推理時(shí)延上能在COCO數(shù)據(jù)集上達(dá)到25左右的精度。
- 對(duì)于算力比較高的設(shè)備,推出Cascade Faster RCNN模型,最高能在COCO數(shù)據(jù)集上達(dá)到30.2的精度。
高性能:基于飛槳框架的高性能內(nèi)核,實(shí)現(xiàn)了模型的高效訓(xùn)練和推理。
2)PaddleClas
PaddleClas是飛槳為工業(yè)界和學(xué)術(shù)界所準(zhǔn)備的一個(gè)圖像識(shí)別和圖像分類任務(wù)的工具集。支持多種前沿圖像分類、識(shí)別相關(guān)算法,發(fā)布產(chǎn)業(yè)級(jí)特色骨干網(wǎng)絡(luò)PP-HGNet、PP-LCNetv2、 PP-LCNet和SSLD半監(jiān)督知識(shí)蒸餾方案等模型。
| 模型簡(jiǎn)介 | 應(yīng)用場(chǎng)景 |
|---|---|
| PULC 超輕量圖像分類方案 | 固定圖像類別分類方案 |
| PP-ShituV2 輕量圖像識(shí)別系統(tǒng) | 針對(duì)場(chǎng)景數(shù)據(jù)類別頻繁變動(dòng)、類別數(shù)據(jù)多 |
| PP-LCNet 輕量骨干網(wǎng)絡(luò) | 針對(duì)Intel CPU設(shè)備及MKLDNN加速庫(kù)定制 |
| PP-LCNetV2 輕量骨干網(wǎng)絡(luò) | 針對(duì)Intel CPU設(shè)備,適配OpenVINO |
| PP-HGNet 高精度骨干網(wǎng)絡(luò) | GPU設(shè)備上相同推理時(shí)間精度更高 |
3)PaddleOCR
PaddleOCR旨在打造一套豐富、領(lǐng)先、且實(shí)用的OCR工具庫(kù)。最新開(kāi)源的超輕量PP-OCRv3模型大小僅為16.2M。同時(shí)支持中英文識(shí)別;支持傾斜、豎排等多種方向文字識(shí)別;支持GPU、CPU預(yù)測(cè);
| 模型簡(jiǎn)介 | 模型名稱 | 推薦場(chǎng)景 |
|---|---|---|
| 中英文超輕量PP-OCRv3模型(16.2M) | ch_PP-OCRv3_xx | 移動(dòng)端&服務(wù)器端 |
| 英文超輕量PP-OCRv3模型(13.4M) | en_PP-OCRv3_xx | 移動(dòng)端&服務(wù)器端 |
2.推理部署
1)服務(wù)器部署
| 方案 | 硬件 | API 語(yǔ)言 | 模型支持 | 適用場(chǎng)景 |
|---|---|---|---|---|
| Paddle Inference | 服務(wù)器(CPU、GPU) | C++、Python、C、Go等 | 支持飛槳所有模型 | 適合直接應(yīng)用,既可通過(guò)Python API對(duì)性能要求不太高的場(chǎng)景快速支持;也提供C++高性能接口,可與線上系統(tǒng)聯(lián)編;并通過(guò)基礎(chǔ)的C API可擴(kuò)展支持更多語(yǔ)言的生產(chǎn)環(huán)境。 |
| Paddle Serving | 服務(wù)器(CPU、GPU) | C++、Python、Go等 | 適用于將推理計(jì)算作為一個(gè)遠(yuǎn)程調(diào)用服務(wù)的場(chǎng)景,客戶端發(fā)出請(qǐng)求,服務(wù)端返回推理結(jié)果??芍С侄鄼C(jī)部署。 |
Paddle Inference特點(diǎn)
-
內(nèi)存/顯存復(fù)用提升服務(wù)吞吐量
在推理初始化階段,對(duì)模型中的OP輸出Tensor 進(jìn)行依賴分析,將兩兩互不依賴的Tensor在內(nèi)存/顯存空間上進(jìn)行復(fù)用,進(jìn)而增大計(jì)算并行量,提升服務(wù)吞吐量。
-
細(xì)粒度OP橫向縱向融合減少計(jì)算量
在推理初始化階段,按照已有的融合模式將模型中的多個(gè)OP融合成一個(gè)OP,減少了模型的計(jì)算量的同時(shí),也減少了 Kernel Launch的次數(shù),從而能提升推理性能。目前Paddle Inference支持的融合模式多達(dá)幾十個(gè)。
-
內(nèi)置高性能的CPU/GPU Kernel
內(nèi)置同Intel、Nvidia共同打造的高性能kernel,保證了模型推理高性能的執(zhí)行。
-
子圖集成TensorRT加快GPU推理速度
Paddle Inference采用子圖的形式集成TensorRT,針對(duì)GPU推理場(chǎng)景,TensorRT可對(duì)一些子圖進(jìn)行優(yōu)化,包括OP的橫向和縱向融合,過(guò)濾冗余的OP,并為OP自動(dòng)選擇最優(yōu)的kernel,加快推理速度。
-
子圖集成Paddle Lite輕量化推理引擎
Paddle Lite 是飛槳深度學(xué)習(xí)框架的一款輕量級(jí)、低框架開(kāi)銷(xiāo)的推理引擎,除了在移動(dòng)端應(yīng)用外,還可以使用服務(wù)器進(jìn)行 Paddle Lite 推理。Paddle Inference采用子圖的形式集成 Paddle Lite,以方便用戶在服務(wù)器推理原有方式上稍加改動(dòng),即可開(kāi)啟 Paddle Lite 的推理能力,得到更快的推理速度。
-
支持加載PaddleSlim量化壓縮后的模型
PaddleSlim是飛槳深度學(xué)習(xí)模型壓縮工具,Paddle Inference可聯(lián)動(dòng)PaddleSlim,支持加載量化、裁剪和蒸餾后的模型并部署,由此減小模型存儲(chǔ)空間、減少計(jì)算占用內(nèi)存、加快模型推理速度。其中在模型量化方面,Paddle Inference在X86 CPU上做了深度優(yōu)化,常見(jiàn)分類模型的單線程性能可提升近3倍,ERNIE模型的單線程性能可提升2.68倍。
Paddle Inference推理部署流程
- 導(dǎo)出模型文件。
- 對(duì)于動(dòng)態(tài)圖模型,可以通過(guò)paddle.jit.save 接口來(lái)導(dǎo)出用于部署的標(biāo)準(zhǔn)化模型文件。
- 對(duì)于靜態(tài)圖模型,可以使用paddle.static.save_inference_model保存模型。
- 配置推理選項(xiàng)。
Config是飛槳提供的配置管理器API。在使用Paddle Inference進(jìn)行推理部署過(guò)程中,需要使用Config詳細(xì)地配置推理引擎參數(shù),包括但不限于在何種設(shè)備(CPU/GPU)上部署、加載模型路徑、開(kāi)啟/關(guān)閉計(jì)算圖分析優(yōu)化、使用MKLDNN/TensorRT進(jìn)行部署的加速等。參數(shù)的具體設(shè)置需要根據(jù)實(shí)際需求來(lái)定。 - 創(chuàng)建
Predictor。Predictor是飛槳提供的推理引擎API。根據(jù)設(shè)定好的推理配置Config創(chuàng)建推理引擎Predictor,也就是推理引擎的一個(gè)實(shí)例。創(chuàng)建期間會(huì)進(jìn)行模型加載、分析和優(yōu)化等工作。 - 準(zhǔn)備輸入數(shù)據(jù)。準(zhǔn)備好待輸入推理引擎的數(shù)據(jù),首先獲得模型中每個(gè)輸入的名稱以及指向該數(shù)據(jù)塊(CPU或GPU上)的指針,再根據(jù)名稱將對(duì)應(yīng)的數(shù)據(jù)塊拷貝進(jìn)
Tensor。飛槳采用Tensor作為輸入/輸出數(shù)據(jù)結(jié)構(gòu),可以減少額外的拷貝,提升推理性能。 - 調(diào)用Predictor.Run()執(zhí)行推理。
- 獲取推理輸出。與輸入數(shù)據(jù)類似,根據(jù)輸出名稱將輸出的數(shù)據(jù)(矩陣向量)由
Tensor拷貝至(CPU或GPU上)以進(jìn)行后續(xù)的處理。
Paddle Serving特點(diǎn)
- 集成高性能服務(wù)端推理引擎 Paddle Inference 和端側(cè)引擎 Paddle Lite,其他機(jī)器學(xué)習(xí)平臺(tái)(Caffe/TensorFlow/ONNX/PyTorch)可通過(guò) x2paddle 工具遷移模型。
- 具有高性能 C++ Serving 和高易用 Python Pipeline 兩套框架。
- C++ Serving 基于高性能 bRPC 網(wǎng)絡(luò)框架打造高吞吐、低延遲的推理服務(wù)。
- Python Pipeline 基于 gRPC/gRPC-Gateway 網(wǎng)絡(luò)框架和 Python 語(yǔ)言構(gòu)建高易用、高吞吐推理服務(wù)框架。
- 支持 HTTP、gRPC、bRPC 等多種協(xié)議;提供 C++、Python、Java 語(yǔ)言 SDK。
- 設(shè)計(jì)并實(shí)現(xiàn)基于有向無(wú)環(huán)圖(DAG) 的異步流水線高性能推理框架,具有多模型組合、異步調(diào)度、并發(fā)推理、動(dòng)態(tài)批量、多卡多流推理、請(qǐng)求緩存等特性
- 適配 x86(Intel) CPU、ARM CPU、Nvidia GPU、昆侖 XPU、華為昇騰310/910、海光 DCU、Nvidia Jetson 等多種硬件。
- 集成 Intel MKLDNN、Nvidia TensorRT 加速庫(kù),以及低精度量化推理。
- 提供一套模型安全部署解決方案,包括加密模型部署、鑒權(quán)校驗(yàn)、HTTPs 安全網(wǎng)關(guān),并在實(shí)際項(xiàng)目中應(yīng)用。
- 支持云端部署,提供百度云智能云 kubernetes 集群部署 Paddle Serving 。
- 支持大規(guī)模稀疏參數(shù)索引模型分布式部署,具有多表、多分片、多副本、本地高頻 cache 等特性、可單機(jī)或云端部署
- 支持服務(wù)監(jiān)控,提供基于普羅米修斯的性能數(shù)據(jù)統(tǒng)計(jì)及端口訪問(wèn)。
2)端側(cè)部署
| 方案 | 硬件 | API 語(yǔ)言 | 適用場(chǎng)景 |
|---|---|---|---|
| Paddle Lite | 移動(dòng)終端、嵌入式終端廣泛硬件 | C++、Python、Java等 | 適用于移動(dòng)端/嵌入式芯片等端側(cè)硬件中的高性能、輕量化部署。 |
Paddle Lite是飛槳自研的新一代端側(cè)推理推理框架,支持PaddlePaddle/TensorFlow/Caffe/ONNX模型的推理部署,目前已經(jīng)支持ARM CPU, Mali GPU, Adreno GPU, Huawei NPU等多種硬件,正在逐步增加X(jué)86 CPU, Nvidia GPU 等多款硬件。

Paddle Lite推理流程
- 獲取模型:
- 可以直接使用飛槳訓(xùn)練出的模型進(jìn)行部署;
- 也可以使用Caffe, TensorFlow或ONNX平臺(tái)訓(xùn)練的模型,但是需要使用X2Paddle工具將其它框架訓(xùn)練的模型轉(zhuǎn)換到Paddle格式。
- (可選) 模型壓縮:主要優(yōu)化模型大小,借助PaddleSlim提供的剪枝、量化等手段降低模型大小,以便在端上使用。
- 通過(guò)Model Optimize Tool將模型轉(zhuǎn)換為Paddle lite的nb模型,然后開(kāi)始部署。
-
在終端上通過(guò)調(diào)用Paddle Lite提供的API接口(提供C++、Java、Python等API接口),完成推理相關(guān)的所有計(jì)算。
Paddle Lite支持的模型
| 類別 | 類別細(xì)分 | 模型 | 支持平臺(tái) |
|---|---|---|---|
| CV | 分類 | MobileNetV1 | ARM,X86,NPU,RKNPU,APU |
| CV | 分類 | MobileNetV2 | ARM,X86,NPU |
| CV | 分類 | ResNet18 | ARM,NPU |
| CV | 分類 | ResNet50 | ARM,X86,NPU,XPU |
| CV | 分類 | MnasNet | ARM,NPU |
| CV | 分類 | EfficientNet* | ARM |
| CV | 分類 | SqueezeNet | ARM,NPU |
| CV | 分類 | ShufflenetV2* | ARM |
| CV | 分類 | ShuffleNet | ARM |
| CV | 分類 | InceptionV4 | ARM,X86,NPU |
| CV | 分類 | VGG16 | ARM |
| CV | 分類 | VGG19 | XPU |
| CV | 分類 | GoogleNet | ARM,X86,XPU |
| CV | 檢測(cè) | MobileNet-SSD | ARM,NPU* |
| CV | 檢測(cè) | YOLOv3-MobileNetV3 | ARM,NPU* |
| CV | 檢測(cè) | Faster RCNN | ARM |
| CV | 檢測(cè) | Mask RCNN* | ARM |
| CV | 分割 | Deeplabv3 | ARM |
| CV | 分割 | UNet | ARM |
| CV | 人臉 | FaceDetection | ARM |
| CV | 人臉 | FaceBoxes* | ARM |
| CV | 人臉 | BlazeFace* | ARM |
| CV | 人臉 | MTCNN | ARM |
| CV | OCR | OCR-Attention | ARM |
| CV | GAN | CycleGAN* | NPU |
| NLP | 機(jī)器翻譯 | Transformer* | ARM,NPU* |
| NLP | 機(jī)器翻譯 | BERT | XPU |
| NLP | 語(yǔ)義表示 | ERNIE | XPU |
二、安裝PaddlePaddle
1.通過(guò)pip安裝
# 根據(jù)CUDA版本選擇安裝
# cuda 11.2
python -m pip install paddlepaddle-gpu==2.4.2.post112 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
# CPU
python -m pip install paddlepaddle==2.4.2 -i https://pypi.tuna.tsinghua.edu.cn/simple
2.通過(guò)docker安裝
docker hub paddlepaddle/paddle
# 拉取預(yù)安裝 PaddlePaddle 的鏡像
$ sudo docker pull registry.baidubce.com/paddlepaddle/paddle:2.4.2-gpu-cuda11.7-cudnn8.4-trt8.4
# $ sudo docker pull registry.baidubce.com/paddlepaddle/paddle:2.4.2-gpu-cuda11.2-cudnn8.2-trt8.0
# 進(jìn)入Docker容器
$ nvidia-docker run --name paddle -it -v $PWD:/paddle registry.baidubce.com/paddlepaddle/paddle:2.4.2-gpu-cuda11.7-cudnn8.4-trt8.4 /bin/bash
# 測(cè)試paddle
$ paddle --version
grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
PaddlePaddle 2.4.2.post117, compiled with
with_avx: ON
with_gpu: ON
with_mkl: ON
with_mkldnn: ON
with_python: ON
# 容器中安裝paddle2onnx
$ pip install paddle2onnx -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
$ paddle2onnx --version
[INFO] paddle2onnx-1.0.6 with python>=3.6, paddlepaddle>=2.0.0
# 容器中安裝paddleslim
$ pip install paddleslim -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
$ pip list |grep paddleslim
paddleslim 2.4.1
三、模型部署SDK FastDeploy
隨著人工智能的發(fā)展,新的算法模型層出不窮,各種AI硬件芯片也不斷涌現(xiàn)。在實(shí)際算法落地中,也需要處理不同場(chǎng)景(服務(wù)器部署、服務(wù)化部署、嵌入式部署、手機(jī)端部署等),不同操作系統(tǒng)(Linux、Windows、Android、iOS等),不同編程語(yǔ)言(Python、C++等)。
為了解決AI部署落地難題,百度發(fā)布了新一代面向產(chǎn)業(yè)實(shí)踐的推理部署工具FastDeploy,它是一款全場(chǎng)景、易用靈活、極致高效的AI推理部署工具,支持云端、移動(dòng)端和邊緣端部署。

特點(diǎn)
-
簡(jiǎn)單易用
- 多語(yǔ)言統(tǒng)一部署API
- 預(yù)置多種熱門(mén)模型
- 多種端到端部署demo
-
全場(chǎng)景
- 支持多種推理引擎部署
- 原生推理庫(kù)Paddle Inference、輕量化推理引擎Paddle Lite、前端推理引擎Paddle js;
- TensorRT、OpenVINO、ONNX Runtime
- RKNN Toolkit、Poros等
- 多框架支持,實(shí)現(xiàn)模型協(xié)議互轉(zhuǎn)
- FastDeploy中內(nèi)置了X2Paddle和Paddle2ONNX模型轉(zhuǎn)換工具。
- 多硬件適配,快速實(shí)現(xiàn)多硬件跨平臺(tái)部署
- 目前與Intel、NVIDA、瑞芯微、芯原、Graphcore、昆侖芯、飛騰、算能、昇騰等硬件廠商完成了硬件適配。
- 支持多種推理引擎部署
-
極致高效
- 軟硬聯(lián)合自動(dòng)壓縮優(yōu)化,減少部署資源消耗。
- 內(nèi)置PaddleSlim模型量化壓縮工具。
- 端到端前后預(yù)處理優(yōu)化,減少部署資源消耗
- 在CPU上,對(duì)預(yù)處理操作進(jìn)行融合,減少數(shù)據(jù)預(yù)處理過(guò)程中內(nèi)存創(chuàng)建、拷貝和計(jì)算量。
- 在GPU上,引入了CV-CUDA預(yù)處理算子優(yōu)化。
- 在移動(dòng)端,引入高性能圖像預(yù)處理庫(kù)FlyCV,顯著提升圖像數(shù)據(jù)預(yù)處理的性能。
- 軟硬聯(lián)合自動(dòng)壓縮優(yōu)化,減少部署資源消耗。
推理后端及能力

1.編譯安裝
https://github.com/PaddlePaddle/FastDeploy/tree/develop/docs/cn/build_and_install
1)python 預(yù)編譯庫(kù)安裝
# 環(huán)境要求
CUDA >= 11.2
cuDNN >= 8.0
python >= 3.6
# gpu版本
pip install numpy opencv-python fastdeploy-gpu-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html
# cpu版本
pip install numpy opencv-python fastdeploy-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html
2)python sdk編譯安裝
# 環(huán)境要求
gcc/g++ >= 5.4(推薦8.2)
cmake >= 3.18.0
python >= 3.6
cuda >= 11.2
cudnn >= 8.2
git clone https://github.com/PaddlePaddle/FastDeploy.git
cd FastDeploy/python
export ENABLE_ORT_BACKEND=ON
export ENABLE_PADDLE_BACKEND=ON
export ENABLE_OPENVINO_BACKEND=ON
export ENABLE_VISION=ON
export ENABLE_TEXT=ON
export ENABLE_TRT_BACKEND=ON
export WITH_GPU=ON
export TRT_DIRECTORY=/Paddle/TensorRT-8.4.1.5
export CUDA_DIRECTORY=/usr/local/cuda
# OPENCV_DIRECTORY可選,不指定會(huì)在編譯過(guò)程下載FastDeploy預(yù)編譯的OpenCV庫(kù)
export OPENCV_DIRECTORY=/usr/lib/x86_64-linux-gnu/cmake/opencv4 \
python setup.py build
python setup.py bdist_wheel
3)c++ 預(yù)編譯庫(kù)安裝
# g++ 8.2, CUDA 11.2, cuDNN 8.2編譯產(chǎn)出
$ wget https://bj.bcebos.com/fastdeploy/release/cpp/fastdeploy-linux-x64-gpu-1.0.6.tgz
$ tar -zxvf fastdeploy-linux-x64-gpu-1.0.6.tgz
$ tree -L 3 fastdeploy-linux-x64-gpu-1.0.6
├── FastDeploy.cmake
├── FastDeployConfig.cmake
├── FastDeployCSharp.cmake
├── fastdeploy_init.sh
├── include # 頭文件
│ ├── fastdeploy
│ │ ├── benchmark
│ │ ├── core
│ │ ├── encryption
│ │ │ ├── include
│ │ │ │ ├── decrypt.h
│ │ │ │ ├── encrypt.h
│ │ │ │ └── model_code.h
│ │ │ ├── src
│ │ │ └── util
│ │ ├── encryption.h
│ │ ├── fastdeploy_model.h
│ │ ├── function
│ │ │ ├── cast.h
│ │ │ ├── concat.h
│ │ │ ├── cuda_cast.h
│ │ │ ├── cumprod.h
│ │ │ ├── eigen.h
│ │ │ ├── ....
│ │ │ └── transpose.h
│ │ ├── pipeline
│ │ ├── pipeline.h
│ │ ├── pybind
│ │ ├── runtime
│ │ │ ├── backends
│ │ │ │ ├── backend.h
│ │ │ │ ├── common
│ │ │ │ ├── lite
│ │ │ │ ├── openvino
│ │ │ │ ├── ort
│ │ │ │ ├── paddle
│ │ │ │ ├── poros
│ │ │ │ ├── rknpu2
│ │ │ │ ├── sophgo
│ │ │ │ └── tensorrt
│ │ │ ├── enum_variables.h
│ │ │ ├── runtime.h
│ │ │ └── runtime_option.h
│ │ ├── runtime.h
│ │ ├── text
│ │ ├── text.h
│ │ ├── utils
│ │ ├── vision
│ │ │ ├── classification
│ │ │ ├── common
│ │ │ ├── detection
│ │ │ ├── facealign
│ │ │ ├── facedet
│ │ │ ├── faceid
│ │ │ ├── generation
│ │ │ ├── headpose
│ │ │ ├── keypointdet
│ │ │ ├── matting
│ │ │ ├── ocr
│ │ │ ├── segmentation
│ │ │ ├── sr
│ │ │ ├── tracking
│ │ │ ├── utils
│ │ │ └── visualize
│ │ └── vision.h
│ ├── fastdeploy_capi
│ │ ├── core
│ │ ├── internal
│ │ ├── runtime
│ │ ├── vision
│ │ └── vision.h
│ └── onnx
│ ├── backend
│ ├── bin
│ ├── checker.h
│ ├── common
│ ├── defs
│ ├── examples
│ ├── frontend
│ ├── ......
│ ├── test
│ ├── tools
│ └── version_converter
├── lib # fastdeploy動(dòng)態(tài)庫(kù)【已編譯】
│ ├── libfastdeploy.so -> libfastdeploy.so.1.0.6
│ ├── libfastdeploy.so.1.0.6
│ └── libonnxifi.so
├── lib64
│ ├── cmake
│ │ └── ONNX
│ ├── libonnx.a
│ ├── libonnxifi_dummy.so
│ ├── libonnxifi_loader.a
│ └── libonnx_proto.a
├── LICENSE
├── openmp.cmake
├── summary.cmake
├── third_libs # 第三方庫(kù)依賴【已編譯】
│ └── install
│ ├── fast_tokenizer
│ │ ├── commit.log
│ │ ├── FastTokenizer.cmake
│ │ ├── include
│ │ ├── lib
│ │ └── third_party
│ ├── onnxruntime # 推理后端
│ │ ├── include
│ │ └── lib
│ ├── opencv
│ │ ├── bin
│ │ ├── include
│ │ ├── lib64
│ │ └── share
│ ├── openvino # 推理后端
│ │ └── runtime
│ │ ├── 3rdparty
│ │ ├── cmake
│ │ ├── include
│ │ └── lib
│ ├── paddle_inference # 用于paddle模型的服務(wù)器端推理
│ │ ├── CMakeCache.txt
│ │ ├── paddle
│ │ │ ├── extension.h
│ │ │ ├── include
│ │ │ │ ├── crypto
│ │ │ │ ├── paddle_api.h
│ │ │ │ ├── paddle_inference_api.h
│ │ │ │ ├── ......
│ │ │ └── lib
│ │ │ └── libpaddle_inference.so
│ │ ├── third_party # paddle_inference依賴的第三方庫(kù)【已編譯】
│ │ │ ├── externalError
│ │ │ │ └── data
│ │ │ ├── install
│ │ │ │ ├── cryptopp
│ │ │ │ ├── gflags
│ │ │ │ ├── glog
│ │ │ │ ├── mkldnn
│ │ │ │ ├── mklml
│ │ │ │ ├── protobuf
│ │ │ │ ├── utf8proc
│ │ │ │ └── xxhash
│ │ │ └── threadpool
│ │ │ └── ThreadPool.h
│ │ └── version.txt
│ └── tensorrt # 推理后端
│ └── lib
├── ThirdPartyNotices.txt
├── utils
│ └── gflags.cmake
├── utils.cmake
└── VERSION_NUMBER
4)c++ sdk編譯安裝
# 前置依賴
- gcc/g++ >= 5.4(推薦8.2)
- cmake >= 3.18.0
- cuda >= 11.2
- cudnn >= 8.2
sudo apt-get install libopencv-dev
git clone https://github.com/PaddlePaddle/FastDeploy.git
cd FastDeploy
mkdir build && cd build
cmake .. -DENABLE_ORT_BACKEND=ON \
-DENABLE_PADDLE_BACKEND=ON \
-DENABLE_OPENVINO_BACKEND=ON \
-DENABLE_TRT_BACKEND=ON \
-DWITH_GPU=ON \
-DTRT_DIRECTORY=/Paddle/TensorRT-8.4.1.5 \
-DCUDA_DIRECTORY=/usr/local/cuda \
-DCMAKE_INSTALL_PREFIX=${PWD}/compiled_fastdeploy_sdk \
-DENABLE_VISION=ON \
-DOPENCV_DIRECTORY=/usr/lib/x86_64-linux-gnu/cmake/opencv4 \
-DENABLE_TEXT=ON
make -j12
make install
# Run cpack to generate a .deb package 【可選】
cpack -G DEB
# Install .deb package
dpkg -i xxx.deb
5)編譯選項(xiàng)說(shuō)明
| 選項(xiàng) | 說(shuō)明 |
|---|---|
| ENABLE_ORT_BACKEND | 默認(rèn)OFF, 是否編譯集成ONNX Runtime后端(CPU/GPU上推薦打開(kāi)) |
| ENABLE_PADDLE_BACKEND | 默認(rèn)OFF,是否編譯集成Paddle Inference后端(CPU/GPU上推薦打開(kāi)) |
| ENABLE_LITE_BACKEND | 默認(rèn)OFF,是否編譯集成Paddle Lite后端(編譯Android庫(kù)時(shí)需要設(shè)置為ON) |
| ENABLE_RKNPU2_BACKEND | 默認(rèn)OFF,是否編譯集成RKNPU2后端(RK3588/RK3568/RK3566上推薦打開(kāi)) |
| ENABLE_SOPHGO_BACKEND | 默認(rèn)OFF,是否編譯集成SOPHGO后端, 當(dāng)在SOPHGO TPU上部署時(shí),需要設(shè)置為ON |
| WITH_ASCEND | 默認(rèn)OFF,當(dāng)在華為昇騰NPU上部署時(shí), 需要設(shè)置為ON |
| WITH_KUNLUNXIN | 默認(rèn)OFF,當(dāng)在昆侖芯XPU上部署時(shí),需設(shè)置為ON |
| WITH_TIMVX | 默認(rèn)OFF,需要在RV1126/RV1109/A311D上部署時(shí),需設(shè)置為ON |
| ENABLE_TRT_BACKEND | 默認(rèn)OFF,是否編譯集成TensorRT后端(GPU上推薦打開(kāi)) |
| ENABLE_OPENVINO_BACKEND | 默認(rèn)OFF,是否編譯集成OpenVINO后端(CPU上推薦打開(kāi)) |
| ENABLE_VISION | 默認(rèn)OFF,是否編譯集成視覺(jué)模型的部署模塊 |
| ENABLE_TEXT | 默認(rèn)OFF,是否編譯集成文本NLP模型的部署模塊 |
| WITH_GPU | 默認(rèn)OFF, 當(dāng)需要在GPU上部署時(shí),需設(shè)置為ON |
| RKNN2_TARGET_SOC | ENABLE_RKNPU2_BACKEND時(shí)才需要使用這個(gè)編譯選項(xiàng)。無(wú)默認(rèn)值, 可輸入值為RK3588/RK356X, 必須填入,否則 將編譯失敗 |
| CUDA_DIRECTORY | 默認(rèn)/usr/local/cuda, 當(dāng)需要在GPU上部署時(shí),用于指定CUDA(>=11.2)的路徑 |
| TRT_DIRECTORY | 當(dāng)開(kāi)啟TensorRT后端時(shí),必須通過(guò)此開(kāi)關(guān)指定TensorRT(>=8.4)的路徑 |
| ORT_DIRECTORY | 當(dāng)開(kāi)啟ONNX Runtime后端時(shí),用于指定用戶本地的ONNX Runtime庫(kù)路徑;如果不指定,編譯過(guò)程會(huì)自動(dòng)下載ONNX Runtime庫(kù) |
| OPENCV_DIRECTORY | 當(dāng)ENABLE_VISION=ON時(shí),用于指定用戶本地的OpenCV庫(kù)路徑;如果不指定,編譯過(guò)程會(huì)自動(dòng)下載OpenCV庫(kù) |
| OPENVINO_DIRECTORY | 當(dāng)開(kāi)啟OpenVINO后端時(shí), 用于指定用戶本地的OpenVINO庫(kù)路徑;如果不指定,編譯過(guò)程會(huì)自動(dòng)下載OpenVINO庫(kù) |
2.Python SDK使用
1)常用Python API
# fastdeploy.RuntimeOption API 后端配置
set_model_path
use_ascend
use_cpu
set_cpu_thread_num
use_gpu
use_paddle_infer_backend
use_openvino_backend
use_ort_backend
use_trt_backend # Use TensorRT inference
enable_trt_fp16
enable_paddle_to_trt # Use Paddle-TensorRT inference
set_trt_cache_file # 通過(guò)加載保存的緩存,可以快速完成模型加載初始化。
# fastdeploy.Runtime API 多后端推理引擎API
get_input_info
get_output_info
num_inputs
num_outputs
infer
# Vision Processor (圖像預(yù)處理庫(kù))
fastdeploy.vision.common.processors.ResizeByShort
fastdeploy.vision.common.processors.Resize
fastdeploy.vision.common.processors.CenterCrop
fastdeploy.vision.common.processors.Cast
fastdeploy.vision.common.processors.HWC2CHW
fastdeploy.vision.common.processors.Normalize
fastdeploy.vision.common.processors.NormalizeAndPermute
fastdeploy.vision.common.processors.Pad
fastdeploy.vision.common.processors.PadToSize
fastdeploy.vision.common.processors.StridePad
# fastdeploy vision Model API 視覺(jué)任務(wù)模型API
fastdeploy.vision.detection.PPYOLOE
fastdeploy.vision.detection.YOLOv5
preprocessor
predict
batch_predict
postprocessor
2)Python 推理后端使用
Deploy Paddle model with Paddle Inference(CPU/GPU)、TensorRT(GPU)、OpenVINO(CPU)、ONNX Runtime(CPU/GPU)
Deploy ONNX model with TensorRT(GPU)、OpenVINO(CPU)、ONNX Runtime(CPU/GPU)
示例1:
# Deploy Paddle model with Paddle Inference(CPU/GPU)
import fastdeploy as fd
import numpy as np
# 下載模型并解壓
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.tgz"
fd.download_and_decompress(model_url)
option = fd.RuntimeOption()
option.set_model_path("mobilenetv2/inference.pdmodel",
"mobilenetv2/inference.pdiparams")
# **** CPU 配置 ****
option.use_cpu()
option.use_paddle_infer_backend()
option.set_cpu_thread_num(12)
# **** GPU 配置 ***
# 如需使用GPU,使用如下注釋代碼
# option.use_gpu(0)
# **** IPU 配置 ***
# 如需使用IPU,使用如下注釋代碼
# option.use_ipu()
# 初始化構(gòu)造runtime
runtime = fd.Runtime(option)
# 獲取模型輸入名
input_name = runtime.get_input_info(0).name
# 構(gòu)造隨機(jī)數(shù)據(jù)進(jìn)行推理
results = runtime.infer({
input_name: np.random.rand(1, 3, 224, 224).astype("float32")
})
print(results[0].shape)
示例2:
# Deploy ONNX model with TensorRT(GPU)
import fastdeploy as fd
from fastdeploy import ModelFormat
import numpy as np
# 下載模型并解壓
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.onnx"
fd.download(model_url, path=".")
option = fd.RuntimeOption()
option.set_model_path("mobilenetv2.onnx", model_format=ModelFormat.ONNX)
# **** GPU 配置 ***
option.use_gpu(0)
option.use_trt_backend()
# 初始化構(gòu)造runtime
runtime = fd.Runtime(option)
# 獲取模型輸入名
input_name = runtime.get_input_info(0).name
# 構(gòu)造隨機(jī)數(shù)據(jù)進(jìn)行推理
results = runtime.infer({
input_name: np.random.rand(1, 3, 224, 224).astype("float32")
})
print(results[0].shape)
3)使用預(yù)置視覺(jué)網(wǎng)絡(luò)推理
示例1:yolov5
import fastdeploy as fd
import cv2
# 配置runtime,加載模型
option = fd.RuntimeOption()
option.use_trt_backend()
option.set_trt_input_shape("images", [1, 3, 640, 640])
model = fd.vision.detection.YOLOv5(
"yolov5-model.pdmodel",
"yolov5-model.pdiparams",
runtime_option=option,
model_format=fd.ModelFormat.PADDLE)
# 預(yù)測(cè)圖片檢測(cè)結(jié)果
im = cv2.imread(image)
result = model.predict(im)
print(result)
# 預(yù)測(cè)結(jié)果可視化
vis_im = fd.vision.vis_detection(im, result)
cv2.imwrite("visualized_result.jpg", vis_im)
3.C++ SDK使用
1)C++ API
2)C++ 推理后端使用
示例1:Deploy Paddle model with Paddle Inference(CPU/GPU)
#include "fastdeploy/runtime.h"
#include <cassert>
namespace fd = fastdeploy;
int main(int argc, char* argv[]) {
// Download from https://bj.bcebos.com/paddle2onnx/model_zoo/pplcnet.tar.gz
std::string model_file = "pplcnet/inference.pdmodel";
std::string params_file = "pplcnet/inference.pdiparams";
// configure runtime
// How to configure by RuntimeOption, refer its api doc for more information
// https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1RuntimeOption.html
fd::RuntimeOption runtime_option;
runtime_option.SetModelPath(model_file, params_file);
runtime_option.UseCpu();
// If need to configure Paddle Inference backend for more option, we can configure runtime_option.paddle_infer_option
// refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1PaddleBackendOption.html
runtime_option.paddle_infer_option.enable_mkldnn = true;
fd::Runtime runtime;
assert(runtime.Init(runtime_option));
// Get model's inputs information
// API doc refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1Runtime.html
std::vector<fd::TensorInfo> inputs_info = runtime.GetInputInfos();
// Create dummy data fill with 0.5
std::vector<float> dummy_data(1 * 3 * 224 * 224, 0.5);
// Create inputs/outputs tensors
std::vector<fd::FDTensor> inputs(inputs_info.size());
std::vector<fd::FDTensor> outputs;
// Initialize input tensors
// API doc refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1FDTensor.html
inputs[0].SetData({1, 3, 224, 224}, fd::FDDataType::FP32, dummy_data.data());
inputs[0].name = inputs_info[0].name;
// Inference
assert(runtime.Infer(inputs, &outputs));
// Print debug information of outputs
outputs[0].PrintInfo();
// Get data pointer and print it's elements
const float* data_ptr = reinterpret_cast<const float*>(outputs[0].GetData());
for (size_t i = 0; i < 10 && i < outputs[0].Numel(); ++i) {
std::cout << data_ptr[i] << " ";
}
std::cout << std::endl;
return 0;
}
示例2:
#include "fastdeploy/runtime.h"
#include <cassert>
namespace fd = fastdeploy;
int main(int argc, char* argv[]) {
// Download from https://bj.bcebos.com/paddle2onnx/model_zoo/pplcnet.onnx
std::string model_file = "pplcnet.onnx";
// configure runtime
// How to configure by RuntimeOption, refer its api doc for more information
// https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1RuntimeOption.html
fd::RuntimeOption runtime_option;
runtime_option.SetModelPath(model_file, "", fd::ModelFormat::ONNX);
runtime_option.UseTrtBackend();
// Use NVIDIA GPU to inference
// If need to configure TensorRT backend for more option, we can configure runtime_option.trt_option
// refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1TrtBackendOption.html
runtime_option.UseGpu(0);
// Use float16 inference to improve performance
runtime_option.trt_option.enable_fp16 = true;
// Cache trt engine to reduce time cost in model initialize
runtime_option.trt_option.serialize_file = "./model.trt";
fd::Runtime runtime;
assert(runtime.Init(runtime_option));
// Get model's inputs information
// API doc refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1Runtime.html
std::vector<fd::TensorInfo> inputs_info = runtime.GetInputInfos();
// Create dummy data fill with 0.5
std::vector<float> dummy_data(1 * 3 * 224 * 224, 0.5);
// Create inputs/outputs tensors
std::vector<fd::FDTensor> inputs(inputs_info.size());
std::vector<fd::FDTensor> outputs;
// Initialize input tensors
// API doc refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1FDTensor.html
inputs[0].SetData({1, 3, 224, 224}, fd::FDDataType::FP32, dummy_data.data());
inputs[0].name = inputs_info[0].name;
// Inference
assert(runtime.Infer(inputs, &outputs));
// Print debug information of outputs
outputs[0].PrintInfo();
// Get data pointer and print it's elements
const float* data_ptr = reinterpret_cast<const float*>(outputs[0].GetData());
for (size_t i = 0; i < 10 && i < outputs[0].Numel(); ++i) {
std::cout << data_ptr[i] << " ";
}
std::cout << std::endl;
return 0;
}
3)使用預(yù)置視覺(jué)網(wǎng)絡(luò)推理
示例1:yolov5 使用onnx模型
#include "fastdeploy/vision.h"
// onnxruntime cpu
void CpuInfer(const std::string& model_file, const std::string& image_file) {
auto model = fastdeploy::vision::detection::YOLOv5(model_file);
if (!model.Initialized()) {
std::cerr << "Failed to initialize." << std::endl;
return;
}
auto im = cv::imread(image_file);
fastdeploy::vision::DetectionResult res;
if (!model.Predict(&im, &res)) {
std::cerr << "Failed to predict." << std::endl;
return;
}
std::cout << res.Str() << std::endl;
auto vis_im = fastdeploy::vision::VisDetection(im, res);
cv::imwrite("vis_result.jpg", vis_im);
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
}
// onnxruntime gpu
void GpuInfer(const std::string& model_file, const std::string& image_file) {
auto option = fastdeploy::RuntimeOption();
option.UseGpu();
auto model = fastdeploy::vision::detection::YOLOv5(model_file, "", option);
if (!model.Initialized()) {
std::cerr << "Failed to initialize." << std::endl;
return;
}
auto im = cv::imread(image_file);
fastdeploy::vision::DetectionResult res;
if (!model.Predict(&im, &res)) {
std::cerr << "Failed to predict." << std::endl;
return;
}
std::cout << res.Str() << std::endl;
auto vis_im = fastdeploy::vision::VisDetection(im, res);
cv::imwrite("vis_result.jpg", vis_im);
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
}
void TrtInfer(const std::string& model_file, const std::string& image_file) {
auto option = fastdeploy::RuntimeOption();
option.UseGpu();
option.UseTrtBackend();
option.SetTrtInputShape("images", {1, 3, 640, 640});
auto model = fastdeploy::vision::detection::YOLOv5(model_file, "", option);
if (!model.Initialized()) {
std::cerr << "Failed to initialize." << std::endl;
return;
}
auto im = cv::imread(image_file);
fastdeploy::vision::DetectionResult res;
if (!model.Predict(&im, &res)) {
std::cerr << "Failed to predict." << std::endl;
return;
}
std::cout << res.Str() << std::endl;
auto vis_im = fastdeploy::vision::VisDetection(im, res);
cv::imwrite("vis_result.jpg", vis_im);
std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
}
int main(int argc, char* argv[]) {
if (std::atoi(argv[3]) == 0) {
CpuInfer(argv[1], argv[2]);
} else if (std::atoi(argv[3]) == 1) {
GpuInfer(argv[1], argv[2]);
} else if (std::atoi(argv[3]) == 2) {
TrtInfer(argv[1], argv[2]);
}
return 0;
}
4.FastDeploy 工具包
一鍵安裝
# 通過(guò)pip安裝fastdeploy-tools. 此工具包目前支持模型一鍵自動(dòng)化壓縮和模型轉(zhuǎn)換的功能.
pip install fastdeploy-tools==0.0.1
- FastDeploy的python包已包含此工具,不需重復(fù)安裝.
1)模型壓縮工具PaddleSlim
https://github.com/PaddlePaddle/PaddleSlim
PaddleSlim是一個(gè)專注于深度學(xué)習(xí)模型壓縮的工具庫(kù),提供低比特量化、知識(shí)蒸餾、稀疏化和模型結(jié)構(gòu)搜索等模型壓縮策略,幫助開(kāi)發(fā)者快速實(shí)現(xiàn)模型的小型化。
python -m pip install paddlepaddle-gpu==2.4.1.post112 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
pip install paddleslim
-
版本對(duì)齊:
PaddleSlim PaddlePaddle PaddleLite 2.0.0 2.0 2.8 2.1.0 2.1.0 2.8 2.1.1 2.1.1 >=2.8 2.3.0 2.3.0 >=2.11 2.4.0 2.4.0 >=2.11 develop develop >=2.11
自動(dòng)化壓縮
相比于傳統(tǒng)手工壓縮,自動(dòng)化壓縮的“自動(dòng)”主要體現(xiàn)在4個(gè)方面:解耦訓(xùn)練代碼、離線量化超參搜索、策略自動(dòng)組合、硬件感知 (硬件延時(shí)預(yù)估)。
# 導(dǎo)入依賴包
import paddle
from PIL import Image
from paddle.vision.datasets import DatasetFolder
from paddle.vision.transforms import transforms
from paddleslim.auto_compression import AutoCompression
paddle.enable_static()
# 定義DataSet
class ImageNetDataset(DatasetFolder):
def __init__(self, path, image_size=224):
super(ImageNetDataset, self).__init__(path)
normalize = transforms.Normalize(
mean=[123.675, 116.28, 103.53], std=[58.395, 57.120, 57.375])
self.transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(image_size), transforms.Transpose(),
normalize
])
def __getitem__(self, idx):
img_path, _ = self.samples[idx]
return self.transform(Image.open(img_path).convert('RGB'))
def __len__(self):
return len(self.samples)
# 定義DataLoader
train_dataset = ImageNetDataset("./ILSVRC2012_data_demo/ILSVRC2012/train/")
image = paddle.static.data(
name='inputs', shape=[None] + [3, 224, 224], dtype='float32')
train_loader = paddle.io.DataLoader(train_dataset, feed_list=[image], batch_size=32, return_list=False)
# 開(kāi)始自動(dòng)壓縮
ac = AutoCompression(
model_dir="./MobileNetV1_infer",
model_filename="inference.pdmodel",
params_filename="inference.pdiparams",
save_dir="MobileNetV1_quant",
config={"QuantPost": {}, "HyperParameterOptimization": {'ptq_algo': ['avg'], 'max_quant_count': 3}},
### config={"QuantAware": {}, "Distillation": {}}, ### 如果您的系統(tǒng)為Windows系統(tǒng), 請(qǐng)使用當(dāng)前這一行配置
train_dataloader=train_loader,
eval_dataloader=train_loader)
ac.compress()
量化過(guò)程劃分:
- 權(quán)重量化:對(duì)網(wǎng)絡(luò)中的權(quán)重執(zhí)行量化操作??梢赃x擇逐層(layer-wise)或者逐通道(channel-wise)的量化粒度,也就是說(shuō)每層或者每個(gè)通道選取一個(gè)量化scale。在PaddleSlim中所有權(quán)重量化都采用
abs_max或者channel_wise_abs_max的方法。 - 激活量化:即對(duì)網(wǎng)絡(luò)中不含權(quán)重的激活類OP進(jìn)行量化。一般只能采用逐層(layer-wise)的量化粒度。在PaddleSlim的中默認(rèn)采用
moving_average_abs_max的采樣策略。
量化方式:
-
靜態(tài)離線量化
基于采樣數(shù)據(jù),離線的使用KL散度、MSE等方法計(jì)算量化比例因子的方法。
- 加載預(yù)訓(xùn)練的FP32模型,配置用于校準(zhǔn)的DataLoader;
- 讀取小批量樣本數(shù)據(jù),執(zhí)行模型的前向推理,保存更新待量化op的量化Scale等信息;
- 將FP32模型轉(zhuǎn)成INT8模型,進(jìn)行保存。
-
在線量化訓(xùn)練
在模型訓(xùn)練前需要先對(duì)網(wǎng)絡(luò)計(jì)算圖進(jìn)行處理,先在需要量化的算子前插入量化-反量化節(jié)點(diǎn),再經(jīng)過(guò)訓(xùn)練,產(chǎn)出模擬量化的模型。
- 構(gòu)建模型和數(shù)據(jù)集
- 進(jìn)行浮點(diǎn)模型的訓(xùn)練
- 加載預(yù)訓(xùn)練模型,進(jìn)行量化訓(xùn)練微調(diào)
- 導(dǎo)出量化預(yù)測(cè)模型
-
動(dòng)態(tài)離線量化
將模型中特定OP的權(quán)重從FP32類型量化成INT8等類型,該方式的量化有兩種預(yù)測(cè)方式:
- 第一種是反量化預(yù)測(cè)方式(Paddle Lite支持),即是首先將INT8/16類型的權(quán)重反量化成FP32類型,然后再使用FP32浮運(yùn)算運(yùn)算進(jìn)行預(yù)測(cè);
- 第二種量化預(yù)測(cè)方式,即是預(yù)測(cè)中動(dòng)態(tài)計(jì)算量化OP輸入的量化信息,基于量化的輸入和權(quán)重進(jìn)行INT8整形運(yùn)算。
2)模型轉(zhuǎn)換工具X2Paddle
https://github.com/PaddlePaddle/X2Paddle
X2Paddle用于將其它深度學(xué)習(xí)框架的模型遷移至飛槳框架。目前支持推理模型的框架轉(zhuǎn)換與PyTorch訓(xùn)練代碼遷移。
- 目前X2Paddle支持130+ PyTorch OP,90+ ONNX OP,90+ TensorFlow OP 以及 30+ Caffe OP,詳見(jiàn) 支持列表。
# 環(huán)境依賴
python >= 3.5
paddlepaddle >= 2.2.2
tensorflow == 1.14 (如需轉(zhuǎn)換TensorFlow模型)
onnx >= 1.6.0 (如需轉(zhuǎn)換ONNX模型)
torch >= 1.5.0 (如需轉(zhuǎn)換PyTorch模型)
paddlelite >= 2.9.0 (如需一鍵轉(zhuǎn)換成Paddle-Lite支持格式,推薦最新版本)
# 安裝
pip install x2paddle
PyTorch模型轉(zhuǎn)換
from x2paddle.convert import pytorch2paddle
pytorch2paddle(module=torch_module,
save_dir="./pd_model",
jit_type="trace",
input_examples=[torch_input])
# module (torch.nn.Module): PyTorch的Module。
# save_dir (str): 轉(zhuǎn)換后模型的保存路徑。
# jit_type (str): 轉(zhuǎn)換方式。默認(rèn)為"trace"。
# input_examples (list[torch.tensor]): torch.nn.Module的輸入示例,list的長(zhǎng)度必須與輸入的長(zhǎng)度一致。默認(rèn)為None。
ONNX模型轉(zhuǎn)換
x2paddle --framework=onnx \
--model=onnx_model.onnx \
--save_dir=pd_model
3)模型轉(zhuǎn)換工具Paddle2ONNX
https://github.com/PaddlePaddle/Paddle2ONNX
Paddle2ONNX 支持將 PaddlePaddle 模型格式轉(zhuǎn)化到 ONNX 模型格式。
# 安裝
pip install paddle2onnx
# 命令行使用
paddle2onnx --model_dir saved_inference_model \
--model_filename model.pdmodel \
--params_filename model.pdiparams \
--save_file model.onnx \
--enable_dev_version True \
--opset_version 11 \
--enable_onnx_checker True
參數(shù)選項(xiàng)
| 參數(shù) | 參數(shù)說(shuō)明 |
|---|---|
| --model_dir | 配置包含 Paddle 模型的目錄路徑 |
| --model_filename |
[可選] 配置位于 --model_dir 下存儲(chǔ)網(wǎng)絡(luò)結(jié)構(gòu)的文件名 |
| --params_filename |
[可選] 配置位于 --model_dir 下存儲(chǔ)模型參數(shù)的文件名稱 |
| --save_file | 指定轉(zhuǎn)換后的模型保存目錄路徑 |
| --opset_version | [可選] 配置轉(zhuǎn)換為 ONNX 的 OpSet 版本,目前支持 7~16 等多個(gè)版本,默認(rèn)為 9 |
| --enable_dev_version | [可選] 是否使用新版本 Paddle2ONNX(推薦使用),默認(rèn)為 True |
| --enable_onnx_checker | [可選] 配置是否檢查導(dǎo)出為 ONNX 模型的正確性, 建議打開(kāi)此開(kāi)關(guān), 默認(rèn)為 False |
| --enable_auto_update_opset | [可選] 是否開(kāi)啟 opset version 自動(dòng)升級(jí)功能,當(dāng)?shù)桶姹?opset 無(wú)法轉(zhuǎn)換時(shí),自動(dòng)選擇更高版本的 opset進(jìn)行轉(zhuǎn)換, 默認(rèn)為 True |
| --deploy_backend | [可選] 量化模型部署的推理引擎,支持 onnxruntime、tensorrt 或 others,當(dāng)選擇 others 時(shí),所有的量化信息存儲(chǔ)于 max_range.txt 文件中,默認(rèn)為 onnxruntime |
| --save_calibration_file | [可選] TensorRT 8.X版本部署量化模型需要讀取的 cache 文件的保存路徑,默認(rèn)為 calibration.cache |
| --version | [可選] 查看 paddle2onnx 版本 |
| --external_filename | [可選] 當(dāng)導(dǎo)出的 ONNX 模型大于 2G 時(shí),需要設(shè)置 external data 的存儲(chǔ)路徑,推薦設(shè)置為:external_data |
| --export_fp16_model | [可選] 是否將導(dǎo)出的 ONNX 的模型轉(zhuǎn)換為 FP16 格式,并用 ONNXRuntime-GPU 加速推理,默認(rèn)為 False |
| --custom_ops | [可選] 將 Paddle OP 導(dǎo)出為 ONNX 的 Custom OP,例如:--custom_ops '{"paddle_op":"onnx_op"},默認(rèn)為 {} |
Paddle 訓(xùn)練模型導(dǎo)出為 ONNX
import paddle
# export to ONNX
save_path = 'onnx.save/lenet' # 需要保存的路徑
# 調(diào)用 paddle.static.InputSpec API 指定輸入的 shape,如果輸入中某一維為動(dòng)態(tài)的,可以將該維指定為 None
x_spec = paddle.static.InputSpec([None, 1, 28, 28], 'float32', 'x')
# 調(diào)用 paddle.onnx.export 接口,在指定的路徑下生成 ONNX 模型。
paddle.onnx.export(model, save_path, input_spec=[x_spec], opset_version=11)
驗(yàn)證 ONNX 模型
# 導(dǎo)入 ONNX 庫(kù)
import onnx
# 載入 ONNX 模型
onnx_model = onnx.load("model.onnx")
# 使用 ONNX 庫(kù)檢查 ONNX 模型是否合理
check = onnx.checker.check_model(onnx_model)
# 打印檢查結(jié)果
print('check: ', check)
# 隨機(jī)生成輸入,用于驗(yàn)證 Paddle 和 ONNX 的推理結(jié)果是否一致
x = np.random.random((1, 3, 224, 224)).astype('float32')
# predict by ONNXRuntime
ort_sess = onnxruntime.InferenceSession("model.onnx")
ort_inputs = {ort_sess.get_inputs()[0].name: x}
ort_outs = ort_sess.run(None, ort_inputs)
四、精品模型部署
1.PP-YOLOE+
PP-YOLOE是基于PP-YOLOv2的卓越的單階段Anchor-free模型,超越了多種流行的YOLO模型。PP-YOLOE+是PP-YOLOE的升級(jí)版本,從大規(guī)模的obj365目標(biāo)檢測(cè)預(yù)訓(xùn)練模型入手,在大幅提升收斂速度的同時(shí),提升了模型在COCO數(shù)據(jù)集上的速度。同時(shí),PP-YOLOE+大幅提升了包括數(shù)據(jù)預(yù)處理在內(nèi)的端到端的預(yù)測(cè)速度。
- 尺寸多樣:PP-YOLOE根據(jù)不同應(yīng)用場(chǎng)景設(shè)計(jì)了s/m/l/x,4個(gè)尺寸的模型來(lái)支持不同算力水平的硬件,無(wú)論是哪個(gè)尺寸,精度-速度的平衡都超越當(dāng)前所有同等計(jì)算量下的YOLO模型!可以通過(guò)width multiplier和depth multiplier配置。
- 性能卓越:PP-YOLOE-l在COCO test-dev上以精度51.4%,TRT FP16推理速度149 FPS的優(yōu)異數(shù)據(jù),相較YOLOX,精度提升1.3%,加速25%;相較YOLOv5,精度提升0.7%,加速26.8%。訓(xùn)練速度較PP-YOLOv2提高33%,降低模型訓(xùn)練成本。
- 部署友好:PP-YOLOE在結(jié)構(gòu)設(shè)計(jì)上避免使用如deformable convolution或者matrix NMS之類的特殊算子,使其能輕松適配更多硬件。當(dāng)前已經(jīng)完備支持NVIDIA V100、T4這樣的云端GPU架構(gòu)以及如Jetson系列等邊緣端GPU和FPGA開(kāi)發(fā)板。
1)環(huán)境及模型準(zhǔn)備
git clone https://github.com/PaddlePaddle/PaddleDetection.git
cd PaddleDetection
# 安裝PaddleDetection
pip install -r requirements.txt
python setup.py install
# 下載預(yù)訓(xùn)練模型
mkdir -p models/PP-YOLOE+_s && cd models/PP-YOLOE+_s
wget https://paddledet.bj.bcebos.com/models/ppyoloe_plus_crn_s_80e_coco.pdparams
wget https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.6/configs/ppyoloe/ppyoloe_plus_crn_s_80e_coco.yml
cd -
2)paddle源模型推理
# 推理單張圖片
$ CUDA_VISIBLE_DEVICES=0 python tools/infer.py \
-c configs/ppyoloe/ppyoloe_plus_crn_s_80e_coco.yml \
-o weights=models/PP-YOLOE+_s/ppyoloe_plus_crn_s_80e_coco.pdparams \
--infer_img=demo/000000014439_640x640.jpg
Detection bbox results save in output/000000014439_640x640.jpg
3)paddle模型轉(zhuǎn)onnx
由于tensorrt轉(zhuǎn)換時(shí)不支持nms相關(guān)算子,建議設(shè)置exclude_post_process為T(mén)rue,然后自行實(shí)現(xiàn)后處理(參考yolov8)。
# 模型微調(diào),不包含nms,其會(huì)在tensorrt轉(zhuǎn)換時(shí)因缺少TopK算子而報(bào)錯(cuò)
$ python tools/export_model.py -c configs/ppyoloe/ppyoloe_plus_crn_s_80e_coco.yml \
-o weights=models/PP-YOLOE+_s/ppyoloe_plus_crn_s_80e_coco.pdparams \
exclude_post_process=True trt=True
# 默認(rèn)輸出到output_inference
$ ls output_inference/ppyoloe_plus_crn_s_80e_coco/
infer_cfg.yml model.pdiparams model.pdiparams.info model.pdmodel
# 轉(zhuǎn)化成ONNX格式
$ paddle2onnx --model_dir output_inference/ppyoloe_plus_crn_s_80e_coco \
--model_filename model.pdmodel \
--params_filename model.pdiparams \
--opset_version 11 \
--enable_onnx_checker True \
--save_file ppyoloe_plus_crn_s_80e_coco.onnx
-
export_model.py特殊參數(shù)說(shuō)明
參考PaddleDetection/ppdet/modeling/heads/ppyoloe_head.py文件,可知有以下參數(shù)。
class PPYOLOEHead(nn.Layer): __shared__ = [ 'num_classes', 'eval_size', 'trt', 'exclude_nms', 'exclude_post_process', 'use_shared_conv', 'for_distill' ] def __init__(self, in_channels=[1024, 512, 256], num_classes=80, act='swish', fpn_strides=(32, 16, 8), grid_cell_scale=5.0, grid_cell_offset=0.5, reg_max=16, reg_range=None, static_assigner_epoch=4, use_varifocal_loss=True, static_assigner='ATSSAssigner', assigner='TaskAlignedAssigner', nms='MultiClassNMS', eval_size=None, loss_weight={ 'class': 1.0, 'iou': 2.5, 'dfl': 0.5, }, trt=False, attn_conv='convbn', exclude_nms=False, exclude_post_process=False, use_shared_conv=True, for_distill=False):-
MultiClassNMS算子說(shuō)明
該算子在Paddle2ONNX中實(shí)現(xiàn)。
-
-
infer_cfg.yml 配置文件說(shuō)明
mode: paddle draw_threshold: 0.5 metric: COCO use_dynamic_shape: false arch: YOLO min_subgraph_size: 3 Preprocess: # 前處理參數(shù) - interp: 2 keep_ratio: false target_size: - 640 - 640 type: Resize - mean: - 0.0 - 0.0 - 0.0 norm_type: none std: - 1.0 - 1.0 - 1.0 type: NormalizeImage - type: Permute label_list: # 標(biāo)簽列表 - person - bicycle - car - ...... -
onnx模型輸入輸出說(shuō)明
inputs:
- image: float32 [1, 3, 640, 640], 輸入的預(yù)處理后的圖像數(shù)據(jù)
- scale_factor: float32 [1, 2],width和height在預(yù)處理中被縮放的系數(shù)(當(dāng)exclude_post_process為T(mén)rue時(shí)不輸出)
outputs參考代碼
def post_process(self, head_outs, scale_factor): pred_scores, pred_dist, anchor_points, stride_tensor = head_outs pred_bboxes = batch_distance2bbox(anchor_points, pred_dist) pred_bboxes *= stride_tensor if self.exclude_post_process: return paddle.concat( [pred_bboxes, pred_scores.transpose([0, 2, 1])], axis=-1), None, None else: # scale bbox to origin scale_y, scale_x = paddle.split(scale_factor, 2, axis=-1) scale_factor = paddle.concat( [scale_x, scale_y, scale_x, scale_y], axis=-1).reshape([-1, 1, 4]) pred_bboxes /= scale_factor if self.exclude_nms: # `exclude_nms=True` just use in benchmark return pred_bboxes, pred_scores, None else: bbox_pred, bbox_num, nms_keep_idx = self.nms(pred_bboxes, pred_scores) return bbox_pred, bbox_num, nms_keep_idx- 當(dāng)exclude_post_process==True時(shí):
- 輸出: [1, 8400, 84]
- 當(dāng)exclude_post_process==False,exclude_nms==True時(shí):
- 輸出1 pred_bboxes:[1, 8400, 4]
- 輸出2 pred_scores:[1, 80, 8400]
-
issues
- 執(zhí)行deploy/python/infer.py,報(bào)錯(cuò) ValueError: (InvalidArgument) Pass preln_embedding_eltwise_layernorm_fuse_pass has not been registered.
- 檢測(cè)paddlepaddle-gpu cuda版本與tensorrt要求版本是否一致,鏈接。
- 執(zhí)行deploy/python/infer.py,報(bào)錯(cuò) ValueError: (InvalidArgument) Pass preln_embedding_eltwise_layernorm_fuse_pass has not been registered.
4)onnx轉(zhuǎn)tensorrt
trtexec="/usr/src/tensorrt/bin/trtexec"
$trtexec --onnx=./ppyoloe_plus_crn_s_80e_coco.onnx --saveEngine=./ppyoloe_s_bs1.engine --fp16 --buildOnly --workspace=4096
