caffe2 version 0.8.3 (given)
环境: gcc4.8.5 + cuda9.0 + cudnn7.0 + python3.6 + centos7 (需要换一个libstdc++.so.6.0.x (x>=21)的版本)
or gcc 6.1.0 + cuda9.2 + cudnn7.3 + python3.7 + ubuntu18.04
or gcc5.4.0 + cuda9.0 + cudnn7.0 + python3.7 + ubuntu16.04
上述三种配置均可
没有root权限 所以一些包只能install from source
因为反复装了好几遍,centos和ubuntu都用过,所以下述命令两种系统的都有。
如果使用ubuntu18.04, 需要注意该caffe2在gcc>=7上编译有问题,要换成低一些的版本,而ubuntu18.04编译caffe2要求gcc>=6;gcc6.1.0与cuda9.0/9.1兼容性不好,因此采取gcc6.x + cuda9.2是比较合理的。
官方的non-local代码基于caffe2,并且在caffe2并入pytorch之前,里面一些需要的第三方库已经不能正常下载,导致无法直接编译。 找到了知乎上一篇文章 https://zhuanlan.zhihu.com/p/36045849 ,讲了如何安装non-local的caffe2环境。但我在实际配置过程中发现还有很多坑,所以希望记录一下,本文的基本顺序也基于知乎上的这篇文章。
很多依赖都可以通过apt-get xxx来安装,但是需要root权限,所以如果compile from source那么需要按照下述操作:
一般我们需要安装的依赖都很大众,所以在github上直接按名字搜仓库就能搜到
下载到本地: git clone --recursive https:xxxxxxxxxxxx
下载好依赖的源码后 cd 到文件夹内开始正式编译。一般文件夹内会有CMakeList.txt或者configure或者./autogen.sh用来指导编译过程。三者在这一步需要的命令略有不同。
(0)不论是哪种,在这一步先mkdir build 然后cd build 这一步是为了将编译过程中的中间变量都存在build文件夹下,如果编译不成功,需要重新编译只需要rm -rf build即可清理掉中间文件,然后再重新编译。
mkdir build
cd build
(1)CMakeList.txt:
此时的工作路径在bulid下,执行编译命令:
cmake -DCMAKE_INSTALL_PREFIX=/path/to/install ..
-DCMAKE_INSTALL_CMAKE用来指定该依赖的安装路径
(2) 如果没有CMakeList.txt,可能有configure,此时:
../configure --prefix=/path/to/install
(3) autogen.sh
先执行一下该文件,然后按照(1)或(2)编译
./autogen.sh mkdir build cd build ../configure --prefix=/path/to/install # cmake -DCMAKE_INSTALL_CMAKE=/path/to/install ..
此时工作路径在build下
make -j 8 #-j 后的数字表示该编译过程用几个cpu并行处理 (有多少用多少,越多越快
此过程将上一步骤生成的xxx.h或libxxx.a文件拷贝到1.过程中指定的文件夹中。
make install
将install后得到的include lib lib64 所在路径,加入环境变量中:
export PATH=/path/to/include:$PATH export PATH=/path/to/lib:$PATH
下载代码:
https://github.com/CivilNet/video_nonlocal_net_caffe2
sudo大法好!!!如果可以sudo,那么直接执行0.,跳过1-10,按照知乎上的攻略安装依赖即可。
依赖安装完成后,可以直接编译工程下的caffe2,查看输出,缺少哪些依赖就安装哪些依赖(can not find xxx),直到没有找不到的依赖。几乎所有需要的依赖都可以在自带的third_party文件夹下找到源码进行编译,按照我的编译过程,这一步骤还需要安装的依赖有下面的11–15.
apt-get update && apt-get install -y --no-install-recommends \
libgoogle-glog-dev \
libgtest-dev \
libiomp-dev \
liblapack-dev \
libleveldb-dev \
liblmdb-dev \
libopencv-dev \
libopenmpi-dev \
libsnappy-dev \
libprotobuf-dev \
openmpi-bin \
openmpi-doc \
protobuf-compiler \
python-dev \
python-pip \
build-essential \
cmake \
git \
ffmpeg \
python-yaml \
python-setuptools
pip install --no-cache-dir kafka-python redis future opencv-python numpy protobuf networkx joblib pandas lmdb
首先推荐用conda安装
conda install ffmpeg
conda install -c menpo opencv
如果不work,考虑用源码安装:
https://www.jianshu.com/p/f4ca1039eadf 注意切换到2.8版本 方法见 https://www.runoob.com/w3cnote/android-tutorial-git-repo-create.html 据说兼容性比较好
编译过程提示缺少yasm: 安装 . yasm用prefix指定安装位置后 将该位置加到环境变量中 但安装ffmpeg时仍无法找到yasm 所以最后还是用yasm/build中的libyasm.so 很迷
../configure --prefix=/path/to/install --enable-shared
首先推荐用conda安装
conda install -c menpo opencv
如果不work,考虑用源码安装:
需要的依赖项一定要安装(pkg-config),但libavcodec-dev libavformat-dev libswscale-dev在ffmpeg安装时已经生成,无需重复安装.
gtk2.0是必要的依赖 安装命令:(需要root)
yum install libgnomeui-devel
yum install gtk2 gtk2-devel gtk2-devel-docs
yum install gnome-devel gnome-devel-docs
安装完成后测试: pkg-config --modversion gtk±2.0
输出版本号 说明成功
libpng jpeg 在anaconda中已经有了 所以不重复安装
上述依赖安装后,开始编译opencv 注意一定要指定使用ffmpeg 。我用的编译命令为
cmake -D CMAKE_BUILD_TYPE=Release -D WITH_FFMPEG=ON -D CMAKE_INSTALL_PREFIX=/home/gaof/tools/package/opencv -D PYTHON3_EXECUTABLE=/home/gaof/anaconda3/bin/python3.7 -D PYTHON3_LIBRARIES=/home/gaof/anaconda3/lib/libpython3.7m.so -D PYTHON3_NUMPY_INCLUDE_DIRS=/home/gaof/anaconda3/lib/python3.7/site-packages/numpy/core/include ..
#注意-D后有一个空格,此外需要注意的是,不同版本的opencv可能cmake的参数名字不完全一致,具体需要根据CMakeList.txt进行调整。
然后正常make -j 8 && make install
编译过程报错:
undefined reference to `png_set_strip_16@PNG16_0'
解决方法:
参考 https://blog.csdn.net/u013021895/article/details/52150778
cmake 后注意FFMPEG状态是否为ON
如果找不到ffmpeg,可能是因爲pkg-config沒找到libswscale.fc等文件,解決方法參照:https://blog.csdn.net/yangzhenzhen/article/details/62417021
编译后对python2及python3均生成了cv2.so,(但python3生成的cv2.so不是这个名字)。
将生成的.so加到python3的库中,便于在任意位置可以通过import cv2导入。
cp ~/tools/package/opencv/lib/python3.7/site-packages/cv2/python-3.7/cv2.cpython-37m-x86_64-linux-gnu.so /home/gaozl/anaconda3/lib/python3.7/site-packages
其中 ~/tools/package/opencv 是opencv的安装位置。
安装了anaconda后就有了
yum groupinstall "Development Tools"
在anaconda中已经安装,如果没有安装,可用
pip install pyyaml
python-setuptools同理
https://github.com/gflags/gflags
https://github.com/google/leveldb
安装要加gpu
video_nonlocal_caffe2-master/third_party/cub中自带cub.cuh 路径为: video_nonlocal_caffe2-master/third_party/cub/cub/cub.cuh,直接加入PATH即可。注意路径要写到xxx/third_party/cub,因为FindCub.cmake 中的搜索路径是 /cub/cub.cuh
编译出错 见下
In file included from /home/gaof/tools/pybind11/tests/test_eigen.cpp:12:0: /home/gaof/tools/pybind11/include/pybind11/eigen.h:36:22: fatal error: Eigen/Core: No such file or directory #include
eigen不在编译器的搜索路径中 关于编译器的搜索路径可用下述命令查询
echo | gcc -v -x c++ -E -
echo | gcc++ -v -x c++ -E -
编译器的搜索路径与环境变量PATH路径并不一致
所以用root权限将eigen的include/Eigen copy 到/usr/local/include中 或 将该路径增加到环境变量CPLUS_INCLUDE_PATH中
third_party中有代码 直接编译即可 但注意需要编译生成shared lib 需要额外设置一下。
cmake -DNNPACK_LIBRARY_TYPE=shared -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_PREFIX=/home/gaozl/video_nonlocal_net_caffe2-master/third_party/NNPACK/install ..
编译过程报错 no module named confu:
解决:
pip install confu
pip install --upgrade git+https://github.com/Maratyszcza/confu
third_party中有源码,但编译有略微区别,可按照附带的READ.ME编译,在nccl下直接:
make CUDA_HOME=/usr/local/cuda-9.0 PREFIX=/XXX
#这个两个参数好像传不进去.....可以直接在Makefile中改
环境设置:
LD_LIBRAYR_PATH=/home/gaof/video_nonlocal_net_caffe2-master/third_party/nccl/build/lib:$LD_LIBRAYR_PATH
PATH=/home/gaof/video_nonlocal_net_caffe2-master/third_party/nccl/build/include:$PATH
cmake -DCMAKE_INSTALL_PREFIX=/home/gaozl/tools/package/gloo -DUSE_CUDA=TRUE -DBUILD_SHARED_LIBS=TRUE ..
注意要改一下 cmake/Modules/FindGloo.cmake:
#REQUIRED_VARS Gloo_INCLUDE_DIR Gloo_LIBRARY
REQUIRED_VARS Gloo_INCLUDE_DIR Gloo_INCLUDE_DIR
把lib加到LIBRARY_PATH的环境变量中
cmake -DCUDA_ARCH_NAME=Manual -DCUDA_ARCH_BIN="35 52 60 61" -DCUDA_ARCH_PTX="61" -DUSE_NNPACK=OFF -DUSE_ROCKSDB=OFF -DBUILD_TEST=OFF -DUSE_NATIVE_ARCH=ON ..
运行代码时报警告
E0626 23:41:21.145236 347 init_intrinsics_check.cc:54] CPU feature avx is present on your machine, but the Caffe2 binary is not compiled with it. It means you may not get the full speed of your CPU.
E0626 23:41:21.145258 347 init_intrinsics_check.cc:54] CPU feature avx2 is present on your machine, but the Caffe2 binary is not compiled with it. It means you may not get the full speed of your CPU.
E0626 23:41:21.145263 347 init_intrinsics_check.cc:54] CPU feature fma is present on your machine, but the Caffe2 binary is not compiled with it. It means you may not get the full speed of your CPU.
所以加上了 -DUSE_NATIVE_ARCH=ON
如果找不到anaconda中的python,使用系统的python,就会导致缺少numpy,也会导致找不到安装的opencv:
上网查询后发现是按照PYTHON_EXECUTABLE、PYTHON_LIBRARY、PYTHON_INCLUDE_DIR去找python,命令改为:
cmake -DCUDA_ARCH_NAME=Manual -DCUDA_ARCH_BIN="35 52 60 61" -DCUDA_ARCH_PTX="61" -DUSE_NNPACK=OFF -DUSE_ROCKSDB=OFF -DBUILD_TEST=OFF -DPYTHON_LIBRARY=/home/gaozl/anaconda3/lib -DPYTHON_INCLUDE_DIR=/home/gaozl/anaconda3/include/python3.7m -DPYTHON_EXECUTABLE=/home/gaozl/anaconda3/bin/python -DUSE_NATIVE_ARCH=ON ..
make -j 32
python setup_caffe2.py install
这一步主要是生成caffe2_pybind11_state_gpu.so 和 caffe2_pybind11_state.so 库文件
[ 99%] Linking CXX shared module python/caffe2_pybind11_state.cpython-37m-x86_64-linux-gnu.so
[100%] Linking CXX shared module python/caffe2_pybind11_state_gpu.cpython-37m-x86_64-linux-gnu.so
操作:
[gaof@iZwz9bz9tm8t1elkjztmuhZ video_nonlocal_net_caffe2-master]$ cp -r ./build/lib.linux-x86_64-3.7/ lib/
ln -s lib/caffe2/python/caffe2_pybind11_state.cpython-37m-x86_64-linux-gnu.so lib/caffe2/python/caffe2_pybind11_state.so
ln -s lib/caffe2/python/caffe2_pybind11_state_gpu.cpython-37m-x86_64-linux-gnu.so lib/caffe2/python/caffe2_pybind11_state_gpu.so
export PYTHONPATH=/home/gaof/video_nonlocal_net_caffe2-master/lib/
export OMP_NUM_THREADS=1
数据库的处理可以直接看https://github.com/facebookresearch/video-nonlocal-net/blob/master/DATASET.md
直接用xiaolongwang生成好的数据库索引文件修改一下路径即可
用vim打开process_data/kinetics/vallist.txt,执行:train set同理
:%s+/scratch/xiaolonw/kinetics/data/compress+/home/gaozl/kinetcis_256
数据库样本数目:
train set: 234,619 ## 完整的set是246,535 有些下载链接失效了
val set: 19761
shuffle各个epoch的样本。执行路径process_data/kinetics:
python shuffle_list_rep.py trainlist_shuffle_rep.txt
mkdir ../../data
mkdir ../../data/lmdb
mkdir ../../data/lmdb/kinetics_lmdb_multicrop
python create_video_lmdb.py --dataset_dir ../../data/lmdb/kinetics_lmdb_multicrop/train --list_file trainlist_shuffle_rep.txt
python create_video_lmdb.py --dataset_dir ../../data/lmdb/kinetics_lmdb_multicrop/val --list_file vallist.txt
python create_video_lmdb_test_multicrop.py --dataset_dir ../../data/lmdb/kinetics_lmdb_multicrop/test --list_file vallist.txt
mkdir ../../data/lmdb/kinetics_lmdb_flipcrop
python create_video_lmdb_test_flipcrop.py --dataset_dir ../../data/lmdb/kinetics_lmdb_flipcrop/test --list_file vallist.txt
mkdir ../../data/lmdb/kinetics_lmdb_singlecrop
python create_video_lmdb_test.py --dataset_dir ../../data/lmdb/kinetics_lmdb_singlecrop/test --list_file vallist.txt
复现实验 run_i3d_nlnet_affine_400k.sh
配置8 x p100 + 54核
耗时:6x24h (由于evaluate耗时较大(实测需17min),所以改为20k evaluate一次)
run_i3d_nlnet_affine_400k.sh | top1-acc | top5-acc |
---|---|---|
report | 76.5 | 92.6 |
reproduce | 76.05 | 92.68 |
top1相差0.45; top5吻合。top1的gap可能是因为train dataset 缺失了一部分训练样本,并且我们的pretrained mdoel是迭代300k的,但是官方训练时用的好像是400k的。我们用的train set规模是234,619,并且短边被resize到256;完整的set是246,535。
error: /home/gaof/video_nonlocal_net_caffe2-master/caffe2/python/pybind_state.h:197:61: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive] str = PyUnicode_AsUTF8AndSize(input[i], &strSize);
解决方法:
//str = PyUnicode_AsUTF8AndSize(input[i], &strSize);
str = const_cast(PyUnicode_AsUTF8AndSize(input[i], &strSize));
/home/gaozl/video_nonlocal_net_caffe2/third_party/googletest/googletest/src/gtest.cc:331:13: error: ‘bool testing::internal::GTestIsInitialized()’ defined but not used [-error=unused-function]
解决方法:
在 googletest/xcode/Config/General.xcconfig 与 googletest/cmake/internal_utils.cmake 中去掉 -werror:
set(cxx_base_flags "-Wall -Wshadow")
##set(cxx_base_flags "-Wall -Wshadow -Werror")
WARNING_CFLAGS = -Wall -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow
//WARNING_CFLAGS = -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow
home/gaozl/video_nonlocal_net_caffe2/third_party/googletest/googletest/src/gtest-typed-test.cc:118:1: error: expected ‘}’ at end of input
} // namespace testing
解决方法:
export LIBRARY_PATH=/home/gaozl/tools/package/gtest/lib:$LD_LIBRARY_PATH
export CPLUS_INCLUDE_PATH=/home/gaozl/tools/package/gtest/include:$CPLUS_INCLUDE_PATH
export C_INCLUDE_PATH=/home/gaozl/tools/package/gtest/include:$C_INCLUDE_PATH
error:
/home/gaozl/video_nonlocal_net_caffe2/third_party/eigen/Eigen/Core:59:34: fatal error: math_functions.hpp: No such file or directory
#include
解决方法:
将math_functions.hpp加入编译器搜索路径 注意cuda-9.2以下的版本路径不需要crt
export CPLUS_INCLUDE_PATH=/home/gaozl/tools/cuda-9.2/include/crt:$CPLUS_INCLUDE_PATH
/usr/bin/ld: cannot find -lgloo
解决方法:
cp /home/gaozl/package/gloo/lib/libgloo* /usr/lib/
ps: 此步需要root,网上说可以通过增加LIBRARY_PATH这个环境变量解决,但是我尝试,不work。
/home/gaozl/tools/package/gcc_6_1_0/include/c++/6.1.0/tuple:483:67: error: mismatched argument pack lengths while expanding ‘std::is_constructible<_Elements, _UElements&&>’
return __and_...>::value;
cuda9.0 不匹配 gcc6.1,考虑将cuda换成9.2(上网查说也不匹配cuda9.1)
error: /home/gaof/video_nonlocal_net_caffe2-master/caffe2/python/pybind_state.h:197:61: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
str = PyUnicode_AsUTF8AndSize(input[i], &strSize);
改:
str = const_cast(PyUnicode_AsUTF8AndSize(input[i], &strSize))
error: ‘CV_RGB2GRAY’ was not declared in this scope
cvtColor(res, temp_, CV_RGB2GRAY);
opencv >= 4.0时,部分函数名发生变化,解决方法:在报错的函数中增加:
#if CV_MAJOR_VERSION >= 4//gzl
#define CV_LOAD_IMAGE_COLOR cv::IMREAD_COLOR
#define CV_CAP_PROP_FPS cv::CAP_PROP_FPS
#define CV_CAP_PROP_POS_FRAMES cv::CAP_PROP_POS_FRAMES
#define CV_CAP_PROP_FRAME_COUNT cv::CAP_PROP_FRAME_COUNT
#define CV_LOAD_IMAGE_GRAYSCALE cv::IMREAD_GRAYSCALE
#define CV_BGR2GRAY cv::COLOR_BGR2GRAY
#define CV_GRAY2BGR cv::COLOR_GRAY2BGR
#endif
E0530 21:01:11.908900 21911 init_intrinsics_check.cc:43] CPU feature avx2 is present on your machine, but the Caffe2 binary is not compiled with it. It means you may not get the full speed of your CPU.
caffe2编译时,加上
-DUSE_NATIVE_ARCH=ON
WARNING:
You should always run with libnvidia-ml.so that is installed with your
NVIDIA Display Driver. By default it's installed in /usr/lib and /usr/lib64.
libnvidia-ml.so in GDK package is a stub library that is attached only for
build purposes (e.g. machine that you build your application doesn't have
to have Display Driver installed).
原因: 找到了错误的libnvidia-ml.so 详见https://codeyarns.com/2017/11/13/stub-library-warning-on-libnvidia-ml-so/
解决方法: 按上述描述更换正确的libnvidia-ml.so
还有一个关于nccl的多gpu报错:
RuntimeError: [enforce fail at cuda_nccl_gpu.cc:24] status == ncclSuccess. 2 vs 0. Error at: /workspace/gaozl/video_nonlocal_net_caffe2/caffe2/contrib/nccl/cuda_nccl_gpu.cc24: system error Error from operator:
解决方法:
https://github.com/pytorch/pytorch/compare/6120fbe7a4ac62af00b269fa089477779da3da42..3ea26d6d77b7423c00524d73a1d27693aea542ad
python2 vs 3
代码中还有一些因为python版本不同导致的错误,主要是python3中对string 和 byte数据类型做了严格的区分。
一些短视频被忽略
warning:
caffe2 insufficient data to determine video format
解决方法:
https://github.com/facebookresearch/video-nonlocal-net/issues/12
网络运行前会输出当前网络的flops与param,发现实际跑non-local网络时输出的flops与官方的log.txt中的flops不相符。后来发现是因为官方log文件对应的内版代码在计算flops时没有算non-local中矩阵相乘的flops,但release的官方代码lib/utils/misc.py中已经把这部分算上了,所以才会出现偏差。
下图1,为官方log文件中的flops与param;下图2第二行第三行为现在代码中的自然输出,官方的代码中如果只统计fc与conv的flops就是图2第一行,与图一吻合。
find /home/to/xxx -name xxx.py
在某路径下,按照某名字搜索文件。
grep -rb "string_abc" /path
在path下搜索所有文件中的字符串,-rb为大小写敏感,-rbi 大小写不敏感。
which xx_package
查看当前的编译环境下使用的package是哪个
Findxxxx.cmake
caffe2中需要的依赖,如果不是root安装,那么需要将编译安装生成的include / lib 路径放入环境变量中。修改了环境变量后如果找不到该依赖,可以进入caffe2工程中的Findxxx.cmake文件,(在cmake/Module中)查看caffe2编译时对这个依赖的lib文件及.h文件的路径设置。可以配合message(STATUS “===${XXXX}=-=”)函数输出默认的完整搜索路径。这个FindGloo.cmake函数,找不到libgloo.so,所以修改了一下FindGloo.cmake。
编译器的搜索路径设置
#include //注意是尖括号
xxx需要被放在编译器的搜索路径下,可在环境变量CPLUS_INCLUDE_PATH, C_INCLUDE_PATH 中增加该文件所在路径。
而环境变量 LIBRARY_PATH 是编译器lib文件的搜索路径。
一般都是在CMakeList.txt或者configure中给一个输入相关的输入参数,常见的可能有 :
–enabel-shared -ENABLE_SHARED_LIBS等,可根据share或SHARE进行关键字查询。生成的lib文件若以 .so 结尾,说明成功,反之若以 .a结尾 说明设置失败。
make > build.log 2>&1 -j 48
install gcc w/o root previlige
http://www.xieqiang.site/2017/07/31/install-gcc-5.4-without-root/
modify the gcc version:
https://github.com/google/sanitizers/issues/822
https://github.com/suaefar/ryzen-test/issues/6
问:笔者一共踩过多少坑>_<…