Libtorch是torch的C++接口,实现了在C++中进行网络训练、网络推理的功能。
由于Libtorch中的大部份接口都是与Pytorch一致的,所以Libtorch还是一个很强大的张量库,有着类似Pytorch的清晰接口,这在C++中是很难得的。如果你用过C++的Tensor库,就会发现写法较为复杂,学习成本较高。由于强类型的限制和通用容器类型的缺失,C++相比于Python而言,语言本身就更加复杂,库设计者因为语言使用习惯,以及为了性能等因素,设计的接口一般都是高效但难用的。而Libtorch采用了与Pytorch类似的函数接口,如果你使用过Pytorch的话,使用Libtorch的学习成本就会比较低。
另一个问题是,很多Python库中基础的操作,例如numpy.einsum
函数,在C++的Tensor库中没有合适的替代,如果要迁移到C++中过程会比较麻烦。Libtorch解决了这个问题,Pytorch中有的它都有,所以在C++中可以简单地用torch::einsum
来使用einsum函数,简直是C++开发者的福音。
此外,Libtorch是支持GPU的,主要用于模型的推理过程,Libtorch的Tensor操作在速度上相比别的C++ Tensor库可能有优势,具体速度需要测试对比。当然使用C++代码的话速度不是瓶颈,本身CPU代码就够快了。
Libtorch另一个优势是编译简单,只要你安装了Pytorch,Libtorch就可以直接使用,省去了复杂的安装和配置,一分钟内就能跑起来一个简单的的示例程序。
总结来说,Libtorch有以下很吸引人的特性:
Pytorch官网首页可以下载对应版本的Libtorch压缩包,下载好后将其解压即可,可以自行配置环境变量。
写了一个小程序,并保存在example.cpp文件中:
// 引入Torch头文件,Tensor类定义在此头文件中
#include
#include
int main() {
// 使用arange构造一个一维向量,再用reshape变换到5x5的矩阵,这里需要用到花括号,因为C++没有tuple类型
torch::Tensor foo = torch::arange(25).reshape({5, 5});
// 计算矩阵的迹
torch::Tensor bar = torch::einsum("ii", foo);
// 输出矩阵和对应的迹
std::cout << "==> matrix is:\n " << foo << std::endl;
std::cout << "==> trace of it is:\n " << bar << std::endl;
}
接着在同级目录下创建一个build
文件夹和一个CMakeLists.txt
文件,文件中写入以下内容:
# 指定要求的CMake的最低版本
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
# 定义项目的名称,会在build目录中生成Project_Name.sln --> OXI_Model_Project.sln
project(OXI_Model_Project)
# 设置Libtorch的路径,具体到Torch目录
set(Torch_DIR D:/LibTorch/libtorch/share/cmake/Torch)
# 查找并加载Torch库
find_package(Torch REQUIRED)
# 将TORCH_CXX_FLAGS添加到CMAKE_CXX_FLAGS中,以确保正确的编译选项和标志
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
# 将源文件example.cpp添加到可执行文件oxi_model中,可执行文件的名字自己设置
add_executable(oxi_model example.cpp)
# 将TORCH_LIBRARIES链接到可执行文件oxi_model中,以确保正确的链接Torch库
target_link_libraries(oxi_model "${TORCH_LIBRARIES}")
# 将目标可执行文件oxi_model的C++标准设置为C++14;Libtorch是基于C++14实现的
set_property(TARGET oxi_model PROPERTY CXX_STANDARD 14)
然后打开Developer Command Prompt for vs 2022
命令行窗口,cd到build目录中,依次输入以下命令:
cmake -DCMAKE_PREFIX_PATH=`D:\LibTorch\libtorch\share\cmake\Torch` .. // 编译配置文件
msbuild OXI_Model_Project.sln /p:Configuration=Release /m // 生成可执行文件,放在Release目录中
最后,在Release目录中双击可执行文件,或者在命令行窗口cd进入Release目录,再输入oxi_model即可运行可执行文件oxi_model.exe。运行的结果如下所示:
==> matrix is:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
[ CPULongType{5,5} ]
==> trace of it is:
60
[ CPULongType{} ]
可以看到5x5的tensor对象可以直接用std::cout
打印出来,同时数据后面也显示了数据所在的后端(这里是CPU)和数据类型(LongType)以及对应的维度。
右键点击项目,属性 -> 配置属性 -> VC++目录,在包含目录中添加以下内容:
D:\LibTorch\libtorch\include
D:\LibTorch\libtorch\include\torch\csrc\api\include
在库目录中添加以下内容:
D:\LibTorch\libtorch\lib
右键点击项目,属性 -> 链接器 -> 输入,在附加依赖项中添加以下内容:
asmjit.lib
c10.lib
clog.lib
cpuinfo.lib
dnnl.lib
fbgemm.lib
fbjni.lib
kineto.lib
libprotobuf-lite.lib
libprotobuf.lib
libprotoc.lib
pthreadpool.lib
pytorch_jni.lib
torch.lib
torch_cpu.lib
XNNPACK.lib
如果出现LINK: fatal error LNK1104: 无法打开文件“c10_cuda.lib”
这类问题,可以把附加依赖项中的对应文件删除。
如果出现由于找不到c10.dll,无法继续执行代码
这种情况,可以右键点击项目,属性 -> 调试,在环境中添加内容PATH=D:\LibTorch\libtorch\lib;%PATH%
。