前置条件
显卡驱动
在命令行输入nvidia-smi
查看驱动信息,如果信息异常或 CUDA 支持版本较低的话
前往下载驱动
plaintext
|
|
CUDA Toolkit
- 前往下载 CUDA Toolkit
- CUDA 的版本需要小于等于驱动中的
CUDA Version
- 重点!!这里的 CUDA 版本需要和 LibTorch 使用的 CUDA 版本一致,建议先确定好 LibTorch 要使用的 CUDA 版本
- 下载完成后无脑下一步即可,默认安装目录
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\[version]
- 验证安装
- 在命令行输入
nvcc --version
查看 CUDA 版本信息 - 在命令行运行 [安装目录]\extras\demo_suite 目录下的
bandwidthTest.exe
、deviceQuery.exe
,确保在最后都有输出Result = PASS
- 在命令行输入
cuDNN
cuDNN(NVIDIA CUDA® Deep Neural Network library) 是 NVIDIA 专门针对深度神经网络(Deep Neural Networks)中的基础操作而设计基于 GPU 的加速库
- 前往下载 cuDNN
- 下载完成解压后,将目录中的 bin、include、lib 文件夹拷贝到 CUDA Toolkit 的安装目录
下载 LibTorch
注意:
- !!这里下载的 LibTorch 使用的 CUDA 版本需要与你的 CUDA 版本一致
- 在 Windows 下 Debug 和 Release 是不兼容
- 在一些特殊的情况下,你还需要考虑下载的 Libtorch 是否支持你的 GPU 算力, 前往查看GPU算力 , 前往查看Torch支持算力 (这里需要自己在里面查找信息)
- 前往下载 LibTorch
- 下载完成后将文件解压到你想存放的目录,如解压到
S:\libtorch
- 按下 win 键 > 输入"编辑系统环境变量" > “环境变量” > 在系统变量中的"Path"添加
S:\libtorch\lib
vs2022 中的配置
CUDA toolkit 目录:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1
LibTorch 目录:S:\libtorch\lib
以下配置都将在以上安装目录的基础上进行
创建一个 C++ 控制台项目
配置项目属性
项目右键 > 属性
常规
- C++语言标准:将“语言标准”设置为
ISO C++ 17 标准 (/std:c++17)
或更高版本
- C++语言标准:将“语言标准”设置为
C/C++
- 常规 > 附加包含目录:添加以下目录
S:\libtorch\include
S:\libtorch\include\torch\csrc\api\include
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1\include
- 常规 > 附加包含目录:添加以下目录
链接器
常规 > 附加库目录:添加以下目录
S:\libtorch\lib
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1\lib\x64
输入 > 附加依赖项:添加以下库(二选一即可)
按需引入
plaintext全部引入
命令行 > 其他选项:输入以下内容(如果不添加的话不能使用 CUDA)
12.x 的版本只需要第一句即可
测试
- 需要将里面的附加包含目录、附加库目录替换成你的目录
测试代码
cpp1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
#include <cuda_runtime.h> #include <iostream> #include <torch/torch.h> #include <torch/version.h> // 将 SM 版本转换为核心数的辅助函数 int _ConvertSMVer2Cores(int major, int minor); int main() { // 版本信息 std::cout << "LibTorch 版本:" << TORCH_VERSION << std::endl; // 检查是否支持CUDA if (torch::cuda::is_available()) { std::cout << "CUDA 可用!使用 GPU" << std::endl; std::cout << "cuDNN 可用状态:" << (torch::cuda::cudnn_is_available() ? "true" : "false") << std::endl; int device_count = torch::cuda::device_count(); //cudaGetDeviceCount(&device_count); std::cout << "CUDA 设备数量:" << device_count << std::endl; for (int i = 0; i < device_count; ++i) { cudaDeviceProp prop; cudaGetDeviceProperties(&prop, i); std::cout << "设备 " << i << ": " << prop.name << std::endl; std::cout << " 总内存:" << prop.totalGlobalMem / (1024 * 1024) << " MB" << std::endl; std::cout << " 多处理器:" << prop.multiProcessorCount << std::endl; std::cout << " CUDA 核心:" << prop.multiProcessorCount * _ConvertSMVer2Cores(prop.major, prop.minor) << std::endl; std::cout << " CUDA 算力:" << prop.major << "." << prop.minor << std::endl; } } else { std::cout << "CUDA 不可用。正在使用 CPU。" << std::endl; } // 创建张量 torch::Tensor tensor = torch::rand({ 2, 3 }); std::cout << "随机张量:" << tensor << std::endl; // 基本运算 torch::Tensor tensor_a = torch::tensor({ 1, 2, 3 }, torch::kFloat32); torch::Tensor tensor_b = torch::tensor({ 4, 5, 6 }, torch::kFloat32); torch::Tensor result = tensor_a + tensor_b; std::cout << "张量添加:" << result << std::endl; // 自动求导 torch::Tensor x = torch::tensor({ 1.0, 2.0, 3.0 }, torch::requires_grad()); torch::Tensor y = x * 2; y.backward(torch::ones_like(y)); std::cout << "坡度:" << x.grad() << std::endl; // 简单的线性回归模型 struct Model : torch::nn::Module { Model() { fc = register_module("fc", torch::nn::Linear(3, 1)); } torch::Tensor forward(torch::Tensor x) { return fc->forward(x); } torch::nn::Linear fc{ nullptr }; }; auto model = std::make_shared<Model>(); torch::optim::SGD optimizer(model->parameters(), torch::optim::SGDOptions(0.01)); // 模拟一些数据 torch::Tensor inputs = torch::rand({ 10, 3 }); torch::Tensor targets = torch::rand({ 10, 1 }); // 训练模型 for (size_t epoch = 1; epoch <= 100; ++epoch) { optimizer.zero_grad(); torch::Tensor outputs = model->forward(inputs); torch::Tensor loss = torch::mse_loss(outputs, targets); loss.backward(); optimizer.step(); if (epoch % 10 == 0) { std::cout << "Epoch [" << epoch << "/100], Loss: " << loss.item<float>() << std::endl; } } // CUDA 测试 if (torch::cuda::is_available()) { torch::Tensor tensor_cuda = torch::rand({ 2, 3 }, torch::device(torch::kCUDA)); std::cout << "CUDA 上的随机张量:" << tensor_cuda << std::endl; torch::Tensor result_cuda = tensor_cuda * 2; std::cout << "CUDA 上的张量乘法:" << result_cuda << std::endl; } return 0; } int _ConvertSMVer2Cores(int major, int minor) { switch ((major << 4) + minor) { case 0x30: // Kepler case 0x32: // Kepler case 0x35: // Kepler case 0x37: // Kepler return 192; case 0x50: // Maxwell case 0x52: // Maxwell case 0x53: // Maxwell return 128; case 0x60: // Pascal return 64; case 0x61: // Pascal case 0x62: // Pascal return 128; case 0x70: // Volta case 0x72: // Volta case 0x75: // Turing return 64; // 新增架构支持 case 0x80: // Ampere case 0x86: // Ampere return 128; case 0x87: // Ampere return 64; case 0x90: // Hopper case 0x92: // Hopper return 128; case 0x89: // 假设的新架构 return 256; // 示例值 default: return -1; // 未知架构 } }
输出
plaintext1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
算力LibTorch 版本:2.3.1 CUDA 可用!使用 GPU CUDA 设备数量:1 设备 0: NVIDIA GeForce GTX 1660 Ti 总内存:6143 MB 多处理器:24 CUDA 核心:1536 CUDA 算力:7.5 随机张量: 0.2155 0.1309 0.6969 0.1763 0.3493 0.3799 [ CPUFloatType{2,3} ] 张量添加: 5 7 9 [ CPUFloatType{3} ] 坡度: 2 2 2 [ CPUFloatType{3} ] Epoch [10/100], Loss: 0.137609 Epoch [20/100], Loss: 0.107415 Epoch [30/100], Loss: 0.0934079 Epoch [40/100], Loss: 0.0868109 Epoch [50/100], Loss: 0.0836093 Epoch [60/100], Loss: 0.0819671 Epoch [70/100], Loss: 0.0810442 Epoch [80/100], Loss: 0.0804563 Epoch [90/100], Loss: 0.0800275 Epoch [100/100], Loss: 0.0796769 CUDA 上的随机张量: 0.7906 0.9510 0.5951 0.6755 0.9932 0.4448 [ CUDAFloatType{2,3} ] CUDA 上的张量乘法: 1.5813 1.9021 1.1902 1.3511 1.9864 0.8897 [ CUDAFloatType{2,3} ]
异常笔记
找不到 mkl_avx2.1.dll / mkl_def.1.dll
Intel MKL FATAL ERROR: Cannot load mkl_avx2.1.dll or mkl_def.1.dll
即使下载了最新版本的 intel oneApi 也不行,是因为他依赖与 2021.4 的版本。参考 issue ,解决方法如下
在解决方案目录创建一个空文件夹
lib
在命令行输入
pip install mkl==2021.4
安装 mkl 2021.4 版本从 python 库安装目录中将依赖拷贝到步骤 1的文件夹中
python 下载的 dll 一般存放在
[Python]\Library\bin
下目录这里只需要拷贝以下几个文件即可
打开 Vs > 项目右键 > 属性 > 生成事件 > 生成后事件 > 命令行中输入以下内容
找不到 nvToolsExt
Failed to find nvToolsExt
出现这个情况大概率是使用的 12.x 版本的 CUDA Toolkit,Nvidia 在 12.x 版本中移除了 nvToolsExt,解决方法如下
- 前往 CUDA Toolkit Archive 下载 11.8.0 版本的 CUDA Toolkit,推荐下载网络安装包
- 下载完成后打开安装包,选择自定义安装,只选择 Nsight NVTX 即可,如下