问题来源
在安装百度apollo教育版edu_sim_contest时,编译通过,DreamView启动也很顺利。但是prediction模块起不来,表现为一打开prediction开关,prediction模块就自动退出,导致静态障碍物绕行仿真case本地复现不了。
问题排查
分析contest_debug.pb.txt,点击prediction切换开关时,相关文件为:
/apollo/modules/prediction/dag/prediction.dag
采用mainboard指令debug:
mainboard -d /apollo/modules/prediction/dag/prediction.dag
输出:
在no kernel image is available,有人遇到相同的问题。结论大概就是,docker里面安装的libtorch编译时,没有考虑本机显卡对应的架构,然后就不能计算了。
本机显卡为GTX 960M,已经更新了驱动,支持cuda 12.0版本:
docker中cuda的版本为11.1:
利用下面的代码可以测试出已经安装的libtorch版本为1.7.0:
- torch_debug.cc
#include <torch/script.h>
#include <torch/torch.h>
#include <iostream>
int main() {
std::cout << "检查CDUA是否可用: " << torch::cuda::is_available() << std::endl;
std::cout << "检查cudnn是否可用: " << torch::cuda::cudnn_is_available() << std::endl;
std::cout << "PyTorch版本: "
<< TORCH_VERSION_MAJOR << "."
<< TORCH_VERSION_MINOR << "."
<< TORCH_VERSION_PATCH << std::endl;
// std::clock_t s, e;
// s = clock();
// torch::Tensor cuda_output;
// for (int i=0;i<1;i++) {
// cuda_output = torch::randn({ 5, 4 }, torch::device(torch::kCUDA));
// }
// std::cout << cuda_output << std::endl;
// e = clock();
// std::cout << "use time: " << (e - s) << " 微秒" << std::endl;
return 0;
}
- CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(torch_gpu_debug)
set(Torch_DIR "/usr/local/libtorch_gpu/share/cmake/Torch/")
find_package(PythonInterp REQUIRED)
find_package(Torch REQUIRED)
include_directories(${TORCH_INCLUDE_DIRS})
message(STATUS "Find Torch VERSION: ${Torch_VERSION}")
add_definitions(-DTORCH_VERSION_MAJOR=${Torch_VERSION_MAJOR})
add_definitions(-DTORCH_VERSION_MINOR=${Torch_VERSION_MINOR})
add_definitions(-DTORCH_VERSION_PATCH=${Torch_VERSION_PATCH})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS} -Wno-dev")
add_executable(torch_gpu_debug torch_debug.cc)
target_link_libraries(torch_gpu_debug ${TORCH_LIBRARIES})
set_property(TARGET torch_gpu_debug PROPERTY CXX_STANDARD 14)
解决方案
一搜这个问题,不少人都遇到过。比较有用的是:pytorch和cuda的匹配关系,libtorch的下载链接汇总。解决问题有两个思路:一是更换docker中libtorch的版本,二是本地编译libtorch。
更换libtorch
在不更换cuda的版本时,可以更新libtorch的版本,具体流程如下:
- 参考如何在 Ubuntu 20.04 安装 Nvidia 驱动程序给宿主机安装驱动,之后参考nvidia docker gpus工具的安装与使用方法以及NvdiaDocker安装工具包,保证docker中能访问到宿主机的显卡驱动
- 显卡驱动装好后,确认一下cuda的版本在显卡驱动能够支持的范围内,可以用nvcc -V命令,也可以编译CUDA Samples之后运行deviceQuery查看
- 在下载链接汇总中,根据自己的cuda版本选择对应的torch版本下载
- 编译时,替换libtorch库为自己下载的libtorch库
在替换了好几个torch版本之后,依然不行,错误转移了,但是转移后的错误也解决不了。
编译libtorch
这里选择编译pytorch v1.7.0-rc2的版本,参考Build Libtorch from Source Code for x86和build from source 安装 PyTorch及很多坑,原因是edu_sim_contest中安装libtorch_gpu的脚本install_libtorch.sh给出的pytorch版本为1.7.0-2。
本地编译pytorch得到libtorch,库文件用起来可能比pytorch要慢,参考why my personal compiled libtorch is so slow? 2~3 times slower than caffe, PyTorch vs LibTorch:网络推理速度谁更快?, libtorch性能问题调研
本地编译时,NCCL模块有可能出错,我本地编译的错误和这个就不一样。NCCL主要在多块显卡集群部署的时候起作用,可以通过export USE_NCCL=OFF来关闭。
经过测试,第一次编译v1.7.0-rc2成功,后面编译v1.8.1以及v1.8.0都失败了。
编译成功的完整指令为:
git clone --recursive https://github.com/pytorch/pytorch
cd pytorch
git checkout v1.7.0-rc2
git submodule sync
git submodule update --init --recursive
mkdir build_x86 && cd build_x86
export USE_NCCL=OFF
python3 ../tools/build_libtorch.py
最终结果
编译通过之后,在build_x86/build/lib下面是所有的静态链接库和动态链接库,下面会用到这些库。
编译链接torch_debug.cc得到可执行文件,用ldd指令查看链接了哪些torch相关的库:
cd到该目录下,用cp替换docker中默认的库文件:
sudo cp libc10.so /usr/local/libtorch_gpu/lib/
sudo cp libtorch_cpu.so /usr/local/libtorch_gpu/lib/
sudo cp libtorch_cuda.so /usr/local/libtorch_gpu/lib/
sudo cp libtorch.so /usr/local/libtorch_gpu/lib/
sudo cp libc10_cuda.so /usr/local/libtorch_gpu/lib/
替换成功之后,取消注释torch_debug.cc中torch以及cuda相关代码,也能正常运行了:
prediction模块也能正常启动:
横向避障宽度修改前后的运行结果对比: