Tensorflow-1.xソースコードコンパイルおよびC++API呼び出し

10625 ワード

ネット上で多くの人がTensorflow C++環境構成の方法を共有したことがあります.私はC++アプリケーションでTensorFlow APIを呼び出した使用中に踏んだ穴だけを記録しました.
一、環境及びバージョンシステム環境:docker、システムCentOS 7;ホストは会社のサーバーで、GPU 8本、nvidia Aシリーズ、具体的なバージョンはnvidia-smiで見て、公開記録しませんでした.TensorFlowバージョン:1.13.2.Python:2.7.JDK:8.
二、TensorFlowのソースコードをコンパイルする環境準備1、bazelのインストールここにバージョン対応の問題があり、TensorFlowの公式サイトは各バージョンとbazelのバージョンの間の最適な対応関係を提供し、対応するbazelのインストールスクリプトをダウンロードして実行すれば完了し、最後に環境変数を~/.bashrc里:export PTAH=/usr/local/bin/:PATH2、protobufをインストールしてTensorFlowをコンパイルして、各種のヘッダファイルが見つからないで、bazelをインストールしただけでTensorFlowをコンパイルしたいのは明らかにだめで、protobufとEigenをインストールしなければなりません.protobufは限定版がないようで、私は3.6をインストールしました.1.公式サイトはソースコードのインストールパッケージをダウンロードして、それから
#./autogen.sh
#./configure --prefix=/usr/local/bin  #       
#make
#make check
#make install

make checkの時に私はエラーに遭遇したことがありますが、ネット上では気にしなくても大丈夫です......TensorFlowコンパイルの時にbazel-genfilesのpbファイルが使われるので、これらのpbファイルはprobobufによって生成され、これらのpbファイルを生成するprotobufとコンパイルの時に使うバージョンが一致しなくてもだめです.引用するpb.hファイルにはそのバージョン制限が書かれています.
3、EigenEigenをインストールしても現在バージョンの制限は発見されていないので、直接最新の3.3をインストールした.9.それとも公式サイトはソースコードのインストールパッケージをダウンロードして、解凍した後にこのディレクトリに入って、それから
#mkdir build
#cd build
#cmake ..
#make install

INSTALLファイルにインストールの説明があります.protobufとeigenはtensorflow/contrib/makefile/下のbuild_を通じてall_linux.shは直接インストールできますが、通常はネットが下りません.downloadが呼び出されましたdependencies.shですが、このスクリプトに問題があります.インターネットで検索して、他の人が提供した方法によって解凍の部分を変更しました.
if [[ "${url}" == "*gz"]]; then             #  ""
    ···
elif [[ "${url}" == "*zip"]]; then          #  ""
    ···

最後のreplaceもありますby_sed呼び出しは、他のアーキテクチャのプラットフォームのために使われているように見え、それも注釈されています.その後は運行できるようになったが、ネットが動かず、最後までやってみなかったので、参考にした.
4、cudaとcudnnをインストールしてGPUでTensorFlowをコンパイルするときはcudaサポートオプションを追加する必要があります.明らかにcudaをインストールする必要があります.私がインストールした10.0バージョンですが、私が使っているハードウェア環境にとって公式に推奨されているバージョンは11.0ですが、どれも使えるようで、そんなに影響はないので、11.0でもいいと思います.オンラインインストールが大変だったので、以前のオフラインインストールファイルを探しました.cuda_10.0.130_410.48_linux.run実行、構成は需要に応じて選択します.後でこのバージョンではこのハードウェア環境を使用しないかもしれないことに気づきましたが、このようにインストールしても使えます.nvidia-smiをインストールしたらcudaバージョンが見えますが、ここに表示されているバージョンは11.0ですが、使えます.これは駆動と関係があるのではないかと疑っていますが...ネット上ではこれについて話していますが、今のところ使用に影響がないので、私は先に放っておきます.次に環境変数を追加
export PATH="/usr/local/cuda-10.0/bin:$PATH"
export LD_LIBRARY="/usr/local/cuda-10.0/lib64:$LD_LIBRARY_PATH"

cudnnがなければだめです.TensorFlowがコンパイルする前に構成するときはcudnnのサポートを提供する必要があります.なければコンパイルするときはcudnnに関するエラーに遭遇します.Cudnnは、いくつかのダイナミックライブラリとヘッダファイルであり、ダウンロードまたは見つけ、対応するディレクトリに格納されます.cudnn.h cudaインストールディレクトリcuda-10.0/includeディレクトリの下に置くlibcudnn.so.7.6.5(これは私が使用しているバージョンです.cudaバージョンと対応関係があるはずです)とlibcudnn_static.aをcuda-10.0/lib 64ディレクトリの下に配置し、2つのリンクlibcudnn.so->libcudnn.so.7->libcudnn.so.7.5を構築します.呼び出すときにlibcudnn.soを調整し、有効なlibcudnnダイナミックライブラリが存在し、指向することを保証します.
5、Nvidia GPU駆動インストール再コンパイルTensorFlowまたダブルso.1エラーが発生しました.これは私が最後によく見ていませんでしたが、/usr/libまたは/usr/lib/x 86_64_linux_gnuの下でlibcudaを指しますso.xxx.xxライブラリ(xxxはグラフィックカードのバージョンを代表して、nvidia-smiの中で表示するDriver Version)を見て、私は確かにありません.実験の結果はそれがグラフィックカードの駆動と関係があるかもしれないことを表明して、私は再びグラフィックカードの駆動をインストールしてあります.nvidiaの公式サイトの下の.runのインストールファイル、実行して、どんなコアモジュールがすでにロードされたことをヒントにして、私が先にcudaとnvをインストールしたためかもしれませんidia-smiとか、後から-a-N--ui=none--no-kernel-moduleパラメータを付けて、sh NVIDIA_Linux-x86_64-xxx.run -a -N --ui=none --no-kernel-module xxxはまだ対応するGPUバージョンです
6、gccはまさかコンパイルが成功しないとは思わなかった.エラーのヒントはgccのヘッダファイルが欠けていることだ.例えばstdint.hなんて、gccバージョンが低くなったと思いますが、その時は手当たり次第に4.8を入れました.5、後にdevtoolset-7をインストールし、gccを7.3にアップグレードした.1でいいです.
7、他にもabseilを参照する必要があります.abseil-cpp-masterをダウンロードして解凍すればいいです.
三、TensorFlowのlibtensorflwをコンパイルするcc.soはまず./configure GPUが必要なので、cudaはyを選択することをサポートしています.cudaとそれに関連する他のデフォルトオプションを使用すればいいです.コンパイルコマンド#bazel build --config=opt --config=cuda //tensorflow:libtensorflow_cc.so GPUを使用するには、--config=cudaオプションを追加する必要があります.コンパイルに成功して生成された2つのファイル:libtensorflow_cc.soとlibtensorflow_framework.soは最終的に必要であり、bazel-bin/tensorflowディレクトリの下にあります.......コンパイルtensorflowの最大の難点はネットワークであり,gfwという障害があることである.なぜ私がdockerを探しているのか、会社のサーバーが何もできないからです.
四、自分のアプリケーション1をコンパイルし、呼び出し方式はネット上の画像処理ルーチンを参考にし、音声認識のdemoを書いた.
#include 
#include 
#include 
 
#include "tensorflow/cc/ops/const_op.h"
#include "tensorflow/cc/ops/image_ops.h"
#include "tensorflow/cc/ops/standard_ops.h"
 
#include "tensorflow/core/framework/graph.pb.h"
#include "tensorflow/core/framework/tensor.h"
 
#include "tensorflow/core/graph/default_device.h"
#include "tensorflow/core/graph/graph_def_builder.h"
 
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/stringpiece.h"
#include "tensorflow/core/lib/core/threadpool.h"
#include "tensorflow/core/lib/io/path.h"
#include "tensorflow/core/lib/strings/stringprintf.h"
 
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/util/command_line_flags.h"

#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/types.h"
 
 
using namespace tensorflow::ops;
using namespace tensorflow;
using namespace std;
using tensorflow::Flag;
using tensorflow::Tensor;
using tensorflow::Status;
using tensorflow::string;
using tensorflow::int32 ;
 

int main(int argc, char** argv )
{
    /*--------------------------------      ------------------------------*/
    string model_path="model.pb";       //       pb  
    string input_tensor_name="InputName";   //     
    string output_tensor_name="forPbOutput";    //     
 
    /*--------------------------------  session------------------------------*/
    Session* session;
    Status status = NewSession(SessionOptions(), &session);//     Session
 
    /*-------------------------------- pb       --------------------------------*/
    GraphDef graphdef; //Graph Definition for current model
 
    Status status_load = ReadBinaryProto(Env::Default(), model_path, &graphdef); // pb        ;
    if (!status_load.ok()) {
        cout << "ERROR: Loading model failed..." << model_path << std::endl;
        cout << status_load.ToString() << "
"; return -1; } Status status_create = session->Create(graphdef); // Session ; if (!status_create.ok()) { cout << "ERROR: Creating graph in session failed..." << status_create.ToString() << std::endl; return -1; } cout << ""<< endl; /*--------------------------------- -------------------------------------*/ cout<"<> wavName; vector feats; int row = 0; while (1) { getline(featFile, line); istringstream rowData(line); row++; string data; while (rowData >> data) { if (data != "]") { float value = atof(data.c_str()); feats.push_back(value); } } if (data == "]") { break; } } cout<().data()); /*----------------------------------- -----------------------------------------*/ cout<"< outputs; string output_node = output_tensor_name; Status status_run = session->Run({{input_tensor_name, resized_tensor}}, {output_node}, {}, &outputs); if (!status_run.ok()) { cout << "ERROR: RUN failed..." << std::endl; cout << status_run.ToString() << "
"; return -1; } // cout << "Output tensor size:" << outputs.size() << std::endl; for (std::size_t i = 0; i < outputs.size(); i++) { cout << outputs[i].DebugString()<()(0, i) << " "; // } cout << endl; return 0; }

2、コンパイルに必要なヘッダファイルディレクトリはtensorflow-1.13を含む.2eigen-3.3.9 abseil-cpp-masterbazel-genfilesダイナミックライブラリはlibtensorflow_cc.soとlibtensorflow_framework.so,経路bazel-bin/tensorflow/tensorflow-1.13.2ディレクトリの下で行われるテストプログラムのコンパイル:#g++ test.cpp -I . -I eigen.3.3.9 -I abseil-cpp-master -I bazel-genfiles/ -L bazel-bin/tensorflow -ltensorflow_cc -ltensorflow_framework実行可能プログラムを実行する前に環境変数をインポートする:export LD_LIBRARY_PATH=bazel-bin/tensorflow:PATH五、他の環境でtensorflowダイナミックライブラリを呼び出して自分のアプリケーションをコンパイルするコンパイル環境のないマシン上で、コンパイルされたプログラムを実行するだけで、libtensorflow_を提供する必要がある以外はcc.soとlibtensorflow_framework.so以外にもprotobuf,eigen 3をインストールする必要がある.libtensorflowを利用したいならcc.soとlibtensorflow_framework.so独自のアプリケーションをコンパイルするには、以上の実行環境に加えてeigen、abseil、bazelコンパイルtensorflow後に生成されるbazel-genfilesファイル、tensorflowソースコードの下のtensorflowディレクトリ、third_partyディレクトリ.#g++ test.cpp -I . -I eigen.3.3.9 -I abseil-cpp-master -I bazel-genfiles/ -L bazel-bin/tensorflow -ltensorflow_cc -ltensorflow_framework -I /usr/local/include/eigen3/
六、問題記録1、提示cuInit失敗、UNKNOWN_ERRORエラー.2021.03.02更新、GPUが使えない問題は私が使っているdockerと関係があるかもしれませんが、コンパイルしたプログラムを実機に移動すれば大丈夫です.2、tensorflow/compiler/xla/service/gpu/llvm_が現れるgpu_backend/nvptx_backend_lib.cc:134] Unknown compute capability (7, 5) .Defaulting to telling LLVM that we're compiling for sm_30エラー、compute ability 7.5はサポートされていないはずですが、コンパイル時にconfigureに表示されるcudnnサポート範囲は3.0-7.0で、エラーコードの位置によって、その関数にはtensorflowがサポートするcompute ability範囲が1.13リストされています.2確かに7.5は含まれていませんが、以下の1.14を見ました.0は含まれていますが、1.14で試してみることにしました.0この問題を回避できるかどうか.(1)tensorflow-r 1.14コンパイルtensorflow-r 1.14でfrom builtins import bytes#pylin:disable=redefined-builtinエラーが発生しました.python 2.7でbuiltins?builtins?futureがインストールされてからでいいかもしれません.pip install futureでgoogle/protobuf/port_def.incが欠けていると教えてくれました.インストールパスの下を見てみましたが本当にありませんでした.調べてみました.3.6です.1バージョンは本当にありません......私は新しいバージョンをアンインストールするしかありませんが、あまりにも新しいので、3.15.1再コンパイルtensorlow生成の.pb.hファイルには3.7と書いてあります.x、bazelバージョンと関係があるかもしれないと思います.再読み込み3.7.1はい、結構です.