1. 程式人生 > 其它 >linux 下 tensorflow C++ CPU編譯過程記錄,已編譯CPU庫直接下載(測試ubuntu18.04、ubuntu20、debian10測試未發現依賴問題)

linux 下 tensorflow C++ CPU編譯過程記錄,已編譯CPU庫直接下載(測試ubuntu18.04、ubuntu20、debian10測試未發現依賴問題)

背景(跳過,並沒有什麼用)

最近專案中要做一個NSFW檢測,在網上找到一個別人訓練好的tensorflow 的PB模型,但是程式碼是Python, 想用C++ 去呼叫這個模型,預測。

因為我覺得C++ 首先客戶部署簡單(和客戶確定好libc基礎下),只需要整理好相關.so檔案,不像python,除了搭建環境外,還需要通過pip安裝很多依賴。客戶操作步驟越多,就越容易部署過程中出問題。

之所以寫這篇隨筆,主要因為在百度搜索tensorflow編譯時,大部分都在說直接系統下編譯,這樣很可能會出現問題,因為每個linux發行版的glic、gcc預設安裝版本會有區別,比如我本機使用debian 10,在apt-get install gcc時,會裝gcc 11,如果是ubuntu 18 apt-get install gcc時, 會裝gcc7。

我一開始也是在本機中使用gcc11編譯,喜提gcc編譯錯誤。

這一點在官網中有宣告:https://tensorflow.google.cn/install/source?hl=zh_cn

也就是說,最好使用gcc7版本進行編譯

如果你當前是ubuntu,可以嘗試在本機編譯,如果其他發行版,強烈建議docker 內下載ubuntu 編譯,編譯完成後,取出so庫到生產環境。

經測試, debian10、ubuntu 18.04、ubuntu 20.04,在docker ubuntu 18.04環境下編譯出來的tensorflow庫,可以直接使用。

首先,建議使用隨筆最下方提供的連結,下載已編譯好的SO庫,和整理好的標頭檔案,嘗試直接呼叫。

整體步驟

強烈建議docker 內下載ubuntu 編譯

0. 真機擴大記憶體,可以動態生成swap檔案: swapon swap檔案路徑新增swap記憶體,具體百度

1. 安裝docker、下載ubuntu 18.04

2. 進入虛擬環境,搭建安裝編譯所需要的bazel、gcc、g++、python3、python3-dev、git...

3. git 拉取指定版本tensorflow

4. 執行tensorflow 中的configure程式,生成構建檔案。

5. bazle 編譯

6. 使用docker cp,把docker內ubuntu中編譯好的so庫提取到生產環境。

編譯環境

因為是在docker中構建的,所以就不過多介紹真機環境

tensorflow: 1.15.4

bazel: 3.1.0

  bazel 下載慢,可以使用華為雲映象:https://mirrors.huaweicloud.com/bazel/

docker: ubuntu 18.04

記憶體: 8G, 交換空間(磁碟空間當記憶體): 8G

  主要注意一下記憶體,必須10G以上,因為bazel編譯時,會時不時佔用很大記憶體,如果記憶體不夠用電腦就會因為記憶體不夠卡死。

  在tensorflow官網中介紹構建時使用 --local_ram_resources=2048 引數限制記憶體在2G左右,但我嘗試了一下並沒有效果。

gcc: 7.5.0

初始化環境

使用docker 進入ubuntu 容器,執行:

apt-get update
apt-get install git python3 python3-dev vi wget unzip python3-pip
# 編譯時會涉及到python指令碼執行,用到了numpy
pip3 install numpy
# 建立python3軟連線,python 指令碼執行,預設使用python命令
ln -s /usr/bin/python3 /usr/bin/python

拉取專案:

git clone -b v1.15.4 https://gitee.com/mirrors/tensorflow.git

下載bazel:

我使用的是tensorflow 1.15.4, bazel版本是:3.1.0。

如果不清楚該使用什麼版本bazel,可以先隨意下載一個版本,執行./configure,如果版本不對,會告訴當前bazel版本不對,應使用那個版本。

華為雲bazel 國內映象

通過wget 下載以上兩個檔案中其中一個,一個是安裝sh指令碼,一個是可執行二進位制檔案:

wget https://mirrors.huaweicloud.com/bazel/3.1.0/bazel-3.1.0-installer-linux-x86_64.sh
chmod +x bazel-3.1.0-installer-linux-x86_64.sh
./bazel-3.1.0-installer-linux-x86_64.sh

ps: 使用指令碼安裝,要保證本機已安裝unzip,上方搭建環境中已把unzip加入到其中

生成編譯檔案

# 進入tensorflow 專案目錄下,執行
./configure

一路回車,主要是選擇Python路徑、GPU選項等等

開始編譯

1. 編譯前,要確保記憶體(實體記憶體+交換空間swap)在10G以上,最好16G,不然會編譯時耗盡記憶體卡死,最後被系統殺死

2. 編譯過程中,會去github倉庫下載專案,由於國內github不穩定,這個過程是很容易出錯的,出錯內容不僅僅是timeout,有可能是no search xxx,當出錯後,反覆多嘗試幾次

建議白天編譯,晚上早上好像github會很慢。如果有條件,da梯子編譯最好。

3. 當你到達這一步的時候,那麼恭喜你,編譯過程最困難的地方已經結束了,到這裡基本不會有其他問題了(保證是GCC7)。

4. 建議在機器效能好的環境下編譯,不然編譯會很慢

bazel build --config=opt //tensorflow:libtensorflow_cc.so

ps: 注意,//tensorflow:libtensorflow_cc.so 不是註釋,這也是bazel引數一部分!!一定要複製全了,不能光是bazel build --config=opt

提出庫檔案

編譯成功後,進入bazel-bin/tensorflow目錄下,正常情況會有so庫檔案:

把庫打包,通過docker cp 複製到宿主機環境:

tar -zcvf lib.tar *.so*

宿主機下:

docker cp {docker 容器ID}:/{bazel編譯路徑}/lib.tar /{宿主機目錄}

已編譯庫連結

連結: https://quqi.avyeld.com/s/6273754/oBIsB31RssXZ5s4D

  加壓後執行build.sh,通過g++ 構建hello world程式,需要把libtensorflow_cc.so.2.5.0和libtensorflow_framework.so.2.5.0放到系統庫目錄下。

  g++11,使用此庫構建成功。