天天看點

Ubuntu 20.04 源碼編譯Paddle2.2.2

做研發,總是要不停裝新機器和新系統。今天嘗試了一下編譯Paddle2.2.2。

先說結果:

(1)Ubuntu20.04 + Python3.8.10 + gcc-8

(2)cuda和cudnn的版本分别是:

cuda_11.4.3_470.82.01_linux.run

cudnn-11.4-linux-x64-v8.2.4.15.tgz

下面介紹過程和碰到的問題,首先參考Paddle官網的說明,

源碼編譯 — Paddle-Inference documentation

找到那段“基于 Ubuntu 18.04”的說明,我們一步步根據這個說明來編譯安裝。

一:環境準備

首先是安裝必須的工具,官網上是說

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      

我的系統裡已經有python3.8.10這個預設的版本了,就沒有再安裝python3這些。opencv我昨天已經編譯安裝了opencv4.5.5這個版本的,是以也不需要重複安裝,

如果你沒有自己編譯安裝opencv,那麼就可以在這裡選擇安裝libopencv-dev。patchefl這些都是必須的,沒裝的話無法編譯通過,不嫌麻煩的話也可以在編譯報錯了之後再一步步安裝。

cuda和cudnn的版本分别是:

cuda_11.4.3_470.82.01_linux.run

cudnn-11.4-linux-x64-v8.2.4.15.tgz

官方有這麼一段話,

編譯飛槳過程中可能會打開很多檔案,Ubuntu 18.04 預設設定最多同時打開的檔案數是1024(參見 ulimit -a),需要更改這個設定值。

在 /etc/security/limits.conf 檔案中添加兩行。

* hard noopen 102400
* soft noopen 102400      
重新開機計算機,重新開機後執行以下指令,請将${user}切換成目前使用者名。
su ${user}
ulimit -n 102400      

 我都照做了。值得說明的是,如果你碰到下面這樣的錯誤,

/usr/bin/ld: 找不到 ../operators/math/libsampler.a: Too many open files

/usr/bin/ld: 找不到 ../framework/libgenerator.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libgru_compute.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libmaxouting.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libpooling.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libsequence2batch.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libsequence_pooling.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libsoftmax.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libbeam_search.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libfc.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/liblapack_function.a: Too many open files

/usr/bin/ld: 找不到 ../platform/dynload/libdynload_lapack.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libmatrix_bit_code.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libunpooling.a: Too many open files

/usr/bin/ld: 找不到 ../operators/math/libvol2col.a: Too many open files

....

通常是因為你的"ulimit -n 102400"設定沒起作用(比如你重新開機了機器,打開了新的終端等),是以重新設定一下就好了。我實際用的指令是

ulimit -n 20480

二:編譯指令

使用 Git 将飛槳代碼克隆到本地,并進入目錄,切換到穩定版本(git tag顯示的标簽名,如 release/2.0)。 飛槳使用 develop 分支進行最新特性的開發,使用 release 分支釋出穩定版本。在 GitHub 的 Releases 頁籤中,可以看到飛槳版本的釋出記錄。

git clone https://github.com/PaddlePaddle/Paddle.git
cd Paddle
git checkout release/2.2      

下面以 GPU 版本為例說明編譯指令。其他環境可以參考“CMake編譯選項表”修改對應的cmake選項。比如,若編譯 CPU 版本,請将 WITH_GPU 設定為 OFF。

# 建立并進入 build 目錄
~$ mkdir build_cuda && cd build_cuda
# 執行cmake指令
~$ cmake .. -DPY_VERSION=3 \
        -DWITH_TESTING=OFF \
        -DWITH_MKL=ON \
        -DWITH_GPU=ON \
        -DON_INFER=ON \
        ..
~$ nproc
12      

使用make編譯

make -j12

編譯成功後可在dist目錄找到生成的.whl包

比如我的編譯生成包在這裡,

~/ocr/01/Paddle/build_cuda/python/dist/paddlepaddle_gpu-0.0.0-cp38-cp38-linux_x86_64.whl

官方給出的版本是(前面官方明明說是GPU版本,可看上去很像CPU版本),

pip3 install python/dist/paddlepaddle-2.0.0-cp38-cp38-linux_x86_64.whl

不清楚為什麼會有這樣的版本差別。

預測庫編譯

make inference_lib_dist -j4

cmake編譯環境表

以下介紹的編譯方法都是通用步驟,根據環境對應修改cmake選項即可。

三:編譯時碰到的問題

系統預設的是gcc-9.4.0,編譯時碰到的問題我列舉在下面,

(1)file failed to open for reading (No such file or directory)  /home/mc/ocr/Paddle/NCCL_INCLUDE_DIR-NOTFOUND/nccl.h

參考:

https://github.com/PaddlePaddle/Paddle/pull/8540

https://github.com/PaddlePaddle/Paddle/issues/5035

https://docs.nvidia.com/deeplearning/nccl/install-guide/index.html

解決辦法,安裝libnccl

In the following commands, please replace <architecture> with your CPU architecture: x86_64, ppc64le, or sbsa, and replace <distro> with the Ubuntu version, for example ubuntu1604, ubuntu1804, or ubuntu2004.

說明:<distro>=ubunt2004, <architecture>=x86_64

(1). Install the keys.

When installing using the network repo for Ubuntu 20.04/18.04:

---> sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/<distro>/<architecture>/7fa2af80.pub

(2). Install the repository.

or the local NCCL repository:

---> sudo dpkg -i nccl-repo-<version>.deb

For the network repository:

---> sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/<distro>/<architecture>/ /"

(3). Update the APT database:

sudo apt update

(4). Install the libnccl2 package with APT. Additionally, if you need to compile applications with NCCL, you can install the libnccl-dev package as well:

Note: If you are using the network repository, the following command will upgrade CUDA to the latest version.

---> sudo apt install libnccl2 libnccl-dev

If you prefer to keep an older version of CUDA, specify a specific version, for example:

---> sudo apt install libnccl2=2.4.8-1+cuda11.4 libnccl-dev=2.4.8-1+cuda11.4

---> sudo apt install libnccl2=2.4.8-1+cuda10.0 libnccl-dev=2.4.8-1+cuda10.0

Refer to the download page for exact package versions.

https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/libnccl2_2.11.4-1+cuda11.4_amd64.deb

https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/libnccl-dev_2.11.4-1+cuda11.4_amd64.deb

具體有哪些包你可以直接到nvidia的官網上去查,找到合适你的cuda版本的那個包就可以了。

(2)Could NOT find PY_google.protobuf (missing: PY_GOOGLE.PROTOBUF) 

-- Could NOT find PY_google.protobuf (missing: PY_GOOGLE.PROTOBUF) 

CMake Error at cmake/python_module.cmake:27 (message):

  python module google.protobuf is not found

Call Stack (most recent call first):

  cmake/external/python.cmake:71 (find_python_module)

  cmake/third_party.cmake:243 (include)

  CMakeLists.txt:334 (include)

這是一個小問題,主要是我的系統上有多個版本的python,關閉掉那些不用的版本就可以了,比如,使用anaconda的話,就

~$ conda deactivate

(3)error: moving a local object in a return statement prevents copy elision [-Werror=pessimizing-move]

/opt/Paddle-1.8.3/paddle/fluid/string/string_helper.h:54:23: note: remove 'std::move' call

/opt/Paddle-1.8.3/paddle/fluid/string/string_helper.h: In instantiation of 'std::string paddle::string::format_string(const char*, ARGS&& ...) [with ARGS = {const char*}; std::string =

std::__cxx11::basic_string<char>]':

/opt/Paddle-1.8.3/paddle/fluid/framework/io/fs.cc:115:71:   required from here

/opt/Paddle-1.8.3/paddle/fluid/string/string_helper.h:54:23: error: moving a local object in a return statement prevents copy elision [-Werror=pessimizing-move]

/opt/Paddle-1.8.3/paddle/fluid/string/string_helper.h:54:23: note: remove 'std::move' call

/opt/Paddle-1.8.3/paddle/fluid/string/string_helper.h: In instantiation of 'std::string paddle::string::format_string(const char*, ARGS&& ...) [with ARGS = {const char*, const char*, co

nst char*}; std::string = std::__cxx11::basic_string<char>]':

/opt/Paddle-1.8.3/paddle/fluid/framework/io/fs.cc:345:78:   required from here

/opt/Paddle-1.8.3/paddle/fluid/string/string_helper.h:54:23: error: moving a local object in a return statement prevents copy elision [-Werror=pessimizing-move]

/opt/Paddle-1.8.3/paddle/fluid/string/string_helper.h:54:23: note: remove 'std::move' call

[  5%] Built target data_feed_proto

說明,這個問題和後面那個一樣,是由編譯器引起的,是以如果換編譯器的話,下面的資訊就不用理會。

如果隻是針對這個問題,解決辦法請參考這裡,

​​std::move報錯 · Issue #26878 · PaddlePaddle/Paddle · GitHub​​

我使用的這個指令,

find SRCROOT -type f -name CMakeLists.txt -exec sed -i -e '$aset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=pessimizing-move")' {} \;      

 (4)avx512fintrin.h(9146): error: identifier "__builtin_ia32_rndscaless_round" is undefined

[ 10%] Building CXX object paddle/fluid/operators/math/CMakeFiles/pooling.dir/pooling.cc.o

/usr/lib/gcc/x86_64-linux-gnu/9/include/avx512fintrin.h(9146): error: identifier "__builtin_ia32_rndscaless_round" is undefined

/usr/lib/gcc/x86_64-linux-gnu/9/include/avx512fintrin.h(9155): error: identifier "__builtin_ia32_rndscalesd_round" is undefined

/usr/lib/gcc/x86_64-linux-gnu/9/include/avx512fintrin.h(14797): error: identifier "__builtin_ia32_rndscaless_round" is undefined

/usr/lib/gcc/x86_64-linux-gnu/9/include/avx512fintrin.h(14806): error: identifier "__builtin_ia32_rndscalesd_round" is undefined

/usr/lib/gcc/x86_64-linux-gnu/9/include/avx512dqintrin.h(1365): error: identifier "__builtin_ia32_fpclassss" is undefined

/usr/lib/gcc/x86_64-linux-gnu/9/include/avx512dqintrin.h(1372): error: identifier "__builtin_ia32_fpclasssd" is undefined

 說明:這個問題是直接導緻我放棄gcc-9.4.0的主要原因。因為這些builtin函數我們無法自己定義,也不能在編譯器外找到他們,加上我對編譯器并不了解,是以也沒敢去修改源碼,最後直接換成了gcc-8.4.0才編譯成功。