源码编译优化
源碼編譯優化
深度學習的發展十分迅速,對科研或工程人員來說,可能會遇到一些需要自己開發op的場景,可以在python層面編寫op,但如果對性能有嚴格要求的話,必須在C++層面開發op,對于這種情況,需要用戶源碼編譯飛槳paddle,使之生效。 此外對于絕大多數使用C++將模型部署上線的工程人員來說,可以直接通過飛槳paddle官網下載已編譯好的預測庫,快捷開啟飛槳paddle使用之旅。飛槳paddle官網提供了多個不同環境下編譯好的預測庫。如果用戶環境與官網提供環境不一致(如cuda 、cudnn、tensorrt版本不一致等),或對飛槳paddle源代碼有修改需求,或希望進行定制化構建,可查閱本文檔自行源碼編譯得到預測庫。
編譯原理
目標產物
飛槳paddle框架的源碼編譯包括源代碼的編譯和鏈接,最終生成的目標產物包括:
? 含有 C++ 接口的頭文件及其二進制庫:用于C++環境,將文件放到指定路徑即可開啟飛槳paddle使用之旅。
? Python Wheel 形式的安裝包:用于Python環境,此安裝包需要參考飛槳paddle安裝教程進行安裝操作。也就是說,前面講的pip安裝屬于在線安裝,這里屬于本地安裝。
基礎概念
飛槳paddle主要由C++語言編寫,通過pybind工具提供了Python端的接口,飛槳paddle的源碼編譯主要包括編譯和鏈接兩步。
? 編譯過程由編譯器完成,編譯器以編譯單元(后綴名為 .cc 或 .cpp 的文本文件)為單位,將 C++ 語言 ASCII 源代碼翻譯為二進制形式的目標文件。一個工程通常由若干源碼文件組織得到,所以編譯完成后,將生成一組目標文件。
? 鏈接過程使分離編譯成為可能,由鏈接器完成。鏈接器按一定規則將分離的目標文件組合成一個能映射到內存的二進制程序文件,并解析引用。由于這個二進制文件通常包含源碼中指定可被外部用戶復用的函數接口,所以也被稱作函數庫。根據鏈接規則不同,鏈接可分為靜態和動態鏈接。靜態鏈接對目標文件進行歸檔;動態鏈接使用地址無關技術,將鏈接放到程序加載時進行。配合包含聲明體的頭文件(后綴名為 .h 或 .hpp),用戶可以復用程序庫中的代碼開發應用。靜態鏈接構建的應用程序可獨立運行,而動態鏈接程序在加載運行時需到指定路徑下搜尋其依賴的二進制庫。
編譯方式
飛槳paddle框架的設計原則之一是滿足不同平臺的可用性。然而,不同操作系統慣用的編譯和鏈接器是不一樣的,使用命令也不一致。比如,Linux 一般使用 GNU 編譯器套件(GCC),Windows 則使用 Microsoft Visual C++(MSVC)。為了統一編譯腳本,飛槳paddle使用了支持跨平臺構建的 CMake,可以輸出上述編譯器所需的各種 Makefile 或者 Project 文件。
為方便編譯,框架對常用的CMake命令進行了封裝,如仿照 Bazel工具封裝了 cc_binary 和 cc_library ,分別用于可執行文件和庫文件的產出等,對CMake感興趣的,可在 cmake/generic.cmake 中查看具體的實現邏輯。Paddle的CMake中集成了生成python wheel包的邏輯,對如何生成wheel包感興趣的,可參考相關文檔。
編譯步驟
飛槳paddle分為 CPU 版本和 GPU 版本。如果計算機沒有 Nvidia GPU,選擇 CPU 版本構建安裝。如果計算機含有 Nvidia GPU且預裝有 CUDA / CuDNN,也可選擇 GPU 版本構建安裝。本節簡述飛槳paddle在常用環境下的源碼編譯方式,歡迎訪問飛槳paddle官網獲取更詳細內容。請閱讀本節內容。
推薦配置及依賴項
1、穩定的互聯網連接,主頻 1 GHz 以上的多核處理器,9 GB 以上磁盤空間。
2、Python 版本 2.7 或 3.5 以上,pip 版本 9.0 及以上;CMake v3.5 及以上;Git 版本 2.17 及以上。將可執行文件放入系統環境變量中以方便運行。
3、GPU 版本額外需要 Nvidia CUDA 9 / 10,CuDNN v7 及以上版本。根據需要還可能依賴 NCCL 和 TensorRT。
基于Ubuntu 18.04
- 環境準備
除了本節開頭提到的依賴,在 Ubuntu 上進行飛槳paddle的源碼編譯,還需要準備 GCC8 編譯器等工具,可使用下列命令安裝:
sudo apt-get install gcc g++ make cmake git vim unrar python3 python3-dev python3-pip swig wget patchelf libopencv-dev
pip3 install numpy protobuf wheel setuptools
若需啟用 cuda 加速,需準備 cuda、cudnn、nccl。上述工具的安裝請參考 nvidia 官網,以 cuda10.1,cudnn7.6 為例配置 cuda 環境。
cuda
sh cuda_10.1.168_418.67_linux.run
export PATH=/usr/local/cuda-10.1/binKaTeX parse error: Expected '}', got 'EOF' at end of input: {PATH:+:{PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-10.1/KaTeX parse error: Expected '}', got 'EOF' at end of input: …LIBRARY_PATH:+:{LD_LIBRARY_PATH}}
cudnn
tar -xzvf cudnn-10.1-linux-x64-v7.6.4.38.tgz
sudo cp -a cuda/include/cudnn.h /usr/local/cuda/include/
sudo cp -a cuda/lib64/libcudnn* /usr/local/cuda/lib64/
nccl
install nccl local deb 參考https://docs.nvidia.com/deeplearning/sdk/nccl-install-guide/index.html
sudo dpkg -i nccl-repo-ubuntu1804-2.5.6-ga-cuda10.1_1-1_amd64.deb
根據安裝提示,還需要執行sudo apt-key add /var/nccl-repo-2.5.6-ga-cuda10.1/7fa2af80.pub
sudo apt update
sudo apt install libnccl2 libnccl-dev
sudo ldconfig
編譯飛槳paddle過程中可能會打開很多文件,Ubuntu 18.04 默認設置最多同時打開的文件數是1024(參見 ulimit -a),需要更改這個設定值。
在 /etc/security/limits.conf 文件中添加兩行。
- hard noopen 102400
- soft noopen 102400
重啟計算機,重啟后執行以下指令,請將${user}切換成當前用戶名。
su ${user}
ulimit -n 102400
- 編譯命令
使用 Git 將飛槳paddle代碼克隆到本地,并進入目錄,切換到穩定版本(git tag顯示的標簽名,如v2.0.0)。
飛槳paddle使用 develop 分支進行最新特性的開發,使用 release 分支發布穩定版本。在 GitHub 的 Releases 選項卡中,可以看到飛槳paddle版本的發布記錄。
git clone https://github.com/PaddlePaddle/Paddle.git
cd Paddle
git checkout v2.0.0
下面以 GPU 版本為例說明編譯命令。其它環境可以參考“CMake編譯選項表”修改對應的cmake選項。比如,若編譯 CPU 版本,將 WITH_GPU 設置為 OFF。如果要使用TensorRT加速功能,將WITH_TENSORRT設置為ON,并通過TENSORRT_ROOT指定TensorRT安裝路徑。
創建并進入 build 目錄
mkdir build_cuda && cd build_cuda
執行cmake指令
cmake -DPY_VERSION=3
-DWITH_TESTING=OFF
-DWITH_MKL=ON
-DWITH_GPU=ON
-DWITH_TENSORRT=ON
-DTENSORRT_ROOT=/home/work/nvidia/TensorRT-7.1.3.4
-DON_INFER=ON
-DCMAKE_BUILD_TYPE=RelWithDebInfo
…
使用make編譯
make -j4
編譯成功后可在dist目錄找到生成的.whl包
pip3 install python/dist/paddlepaddle-2.0.0-cp36-cp36m-linux_x86_64.whl
預測庫編譯
make inference_lib_dist -j4
CMake 編譯選項表
以下介紹的編譯方法都是通用步驟,根據環境對應修改cmake選項即可。
基于Windows 10
- 環境準備
除了本節開頭提到的依賴,在 Windows 10 上編譯飛槳paddle,還需要準備 Visual Studio 2015 Update3 以上版本。本節以 Visual Studio 企業版 2019(C++ 桌面開發,含 MSVC 14.24)、Python 3.8 為例介紹編譯過程。
在命令提示符輸入下列命令,安裝必需的 Python 組件。
pip3 install numpy protobuf wheel - 編譯命令
使用 Git 將飛槳paddle代碼克隆到本地,并進入目錄,切換到穩定版本(git tag顯示的標簽名,如v2.0.0)。
飛槳paddle使用 develop 分支進行最新特性的開發,使用 release 分支發布穩定版本。在 GitHub 的 Releases 選項卡中,可以看到 Paddle 版本的發布記錄。
git clone https://github.com/PaddlePaddle/Paddle.git
cd Paddle
git checkout v2.0.0
創建一個構建目錄,并在其中執行 CMake,生成解決方案文件 Solution File,以編譯 CPU 版本為例說明編譯命令,其它環境可以參考“CMake編譯選項表”修改對應的cmake選項。
mkdir build
cd build
cmake … -G “Visual Studio 16 2019” -A x64 -DWITH_GPU=OFF -DWITH_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DPY_VERSION=3
使用 Visual Studio 打開解決方案文件,在窗口頂端的構建配置菜單中選擇 Release x64,單擊生成解決方案,等待構建完畢即可。
CMake 編譯選項表
結果驗證
- Python Wheel 安裝包
編譯完畢后,會在 python/dist 目錄下生成一個文件名類似 paddlepaddle-2.0.0-cp36-cp36m-linux_x86_64.whl 的 Python Wheel 安裝包,安裝測試的命令為:
pip3 install python/dist/paddlepaddle-2.0.0-cp36-cp36m-linux_x86_64.whl
安裝完成后,可以使用 python3 進入python解釋器,輸入以下指令,出現PaddlePaddle is installed successfully!,說明安裝成功。
import paddle
paddle.utils.run_check() - C++ 預測庫及頭文件
預測庫編譯后,所有產出均位于build目錄下的paddle_inference_install_dir目錄內,目錄結構如下。version.txt 中記錄了該預測庫的版本信息,包括Git Commit ID、使用OpenBlas或MKL數學庫、CUDA/CUDNN版本號。
paddle_inference_install_dir
├── CMakeCache.txt
├── paddle
│ ├── include
│ │ ├── crypto
│ │ ├── internal
│ │ ├── paddle_analysis_config.h
│ │ ├── paddle_api.h
│ │ ├── paddle_infer_declare.h
│ │ ├── paddle_inference_api.h
│ │ ├── paddle_mkldnn_quantizer_config.h
│ │ └── paddle_pass_builder.h
│ └── lib
│ ├── libpaddle_fluid.a
│ └── libpaddle_fluid.so
├── third_party
│ ├── cudaerror
│ │ └── data
│ ├── install
│ │ ├── cryptopp
│ │ ├── gflags
│ │ ├── glog
│ │ ├── openblas
│ │ ├── protobuf
│ │ └── xxhash
│ └── threadpool
│ └── ThreadPool.h
└── version.txt
Include目錄下包括了使用飛槳paddle預測庫需要的頭文件,lib目錄下包括了生成的靜態庫和動態庫,third_party目錄下包括了預測庫依賴的其它庫文件。
可以編寫應用代碼,與預測庫聯合編譯并測試結果。請參“單機服務器部署中的“ 基于C++ API的推理部署”一節。
總結
- 上一篇: 推理部署概述
- 下一篇: 服务化部署框架Paddle Servin