天天看點

TensorFlow 的 c ++ 實踐及各種坑!

Tensorflow目前官網僅包含python、C、Java、Go的釋出包,并無C++ release包,并且tensorflow官網也注明了并不保證除python以外庫的穩定性,在功能方面python也是最完善的。衆所周知,python在開發效率、易用性上有着巨大的優勢,但作為一個解釋性語言,在性能方面還是存在比較大的缺陷,在各類AI服務化過程中,采用python作為模型快速建構工具,使用進階語言(如C++,java)作為服務化程式實作是大勢所趨。本文重點介紹tensorflow C++服務化過程中實作方式及遇到的各種問題。

對于tensorflow c++庫的使用,有兩種方法:

(1) 最佳方式當然是直接用C++建構graph,但是目前c++tensorflow庫并不像python api那樣full-featured。可參照builds a small graph in c++ here, C++ tensorflow api中還包含cpu和gpu的數字核心實作的類,可用以添加新的op。可參照https://www.tensorflow.org/extend/adding_an_op

(2) 常用的方式,c++調用python生成好的graph。本文主要介紹該方案。

(1) 編譯tensorflow源碼C++ so

(2) 模型訓練輸出結果

(3) 模型固化

(4) 模型加載及運作

(5) 運作問題

環境要求: 公司tlinux2.2版本, GCC版本 >= 4.8.5

安裝元件: protobuf 3.3.0 bazel 0.5.0 python 2.7 java8

機器要求: 4GB記憶體

a. 安裝java8

yum install java

b. 安裝protobuf 3.3.0

下載下傳 下載下傳https://github.com/google/protobuf/archive/v3.3.0.zip

./configure && make && make install

c. 安裝bazel

download https://github.com/bazelbuild/bazel/releases

sh bazel-0.5.0-installer-linux-x86_64.sh

d. 編譯源碼

最好采用最新release版本:https://github.com/tensorflow/tensorflow/releases

bazel build //tensorflow:libtensorflow_cc.so

編譯過程中可能遇到的問題:

問題一: fatal error: unsupported/Eigen/CXX11/Tensor: No such file or directory

安裝Eigen3.3或以上版本

問題二: java.io.IOException: Cannot run program "patch"

yum install patch

問題三: 記憶體不夠

TensorFlow 的 c ++ 實踐及各種坑!

模型訓練輸出可參照改用例去實踐https://blog.metaflow.fr/tensorflow-saving-restoring-and-mixing-multiple-models-c4c94d5d7125 , google上也很多,模型訓練儲存好得到下面檔案:

TensorFlow 的 c ++ 實踐及各種坑!

模型固化方式有三種:

a. freeze_graph 工具

b. 利用freeze_graph.py工具

c. 利用tensorflow python

import os, argparseimport tensorflow as tffrom tensorflow.python.framework import graph_util

在具體實際項目,用方式一與方式二将生成的模型利用tensorflow c++ api加載,報以上錯誤,采用tensorflow python加載模型報同樣錯:

TensorFlow 的 c ++ 實踐及各種坑!

原因是模型中用到了BatchNorm,修複方式如上面c中給出的方案

建構輸入輸出

模型輸入輸出主要就是構造輸入輸出矩陣,相比python的numpy庫,tensorflow提供的Tensor和Eigen::Tensor還是非常難用的,特别是動态矩陣建立,如果你的編譯器支援C++14,可以用xTensor庫,和numpy一樣強大,并且用法機器類似。如果是C++11版本就好好看看eigen庫和tensorflow::Tensor文檔吧。例舉集中簡單的用法:

矩陣指派:

SOFTMAX:

模型加載及session初始化:

運作:

0.10以上的tensorflow庫是線程安全的,是以可多線程調用predict

問題一:運作告警

是因為在編譯tensorflow so庫的時候沒有把這些CPU加速指令編譯進去,是以可以在編譯的時候加入加速指令,在沒有GPU條件下,加入這些庫實測可以将CPU計算提高10%左右。

需要注意的是并不是所有CPU都支援這些指令,一定要實機測試,以免abort。

問題二: C++ libtensorflow和python tensorflow混用

為驗證C++加載模型調用的準确性,利用swig将c++ api封裝成了python庫供python調用,在同時import tensorflow as tf和import封裝好的python swig接口時,core dump

TensorFlow 的 c ++ 實踐及各種坑!

該問題tensorflow官方并不打算解決

本文來自 全球人工智能 微信公衆号