第 5 章:使用 Vulkan 进行推理​

🏷️ 365会被黑吗 📅 2026-02-11 20:06:16 ✍️ admin 👀 4084 ❤️ 693
第 5 章:使用 Vulkan 进行推理​

Are you an LLM? You can read better optimized documentation at /public/blog\2025-02\ncnn\05.vulkan.md for this page in Markdown format第 5 章:使用 Vulkan 进行推理 ​1. 什么是 Vulkan2. NCNN 如何使用 Vulkan2.1 安装 Vulkan 支持2.2 在项目中使用 Vulkan2.3 使用合适的分配器2.4 使用零复制的一致的内存设备2.5 使用 CPU/GPU 混合推理3. 零复制的 GPU 链式推理4. 批量推理5. 控制优化策略6. 调试模型参考1. 什么是 Vulkan ​Vulkan 是一种新的图形和计算 API,它是一种低开销、跨平台、高性能的 3D 图形和计算 API。Vulkan 旨在提供更好的性能和更均衡的 CPU/GPU 使用,同时提供更好的多线程能力。

Vulkan 被认为更便捷的方案,并且得到多种供应商和跨平台低层图形 API 的支持。相反,CUDA 仅在 NVIDIA 设备上可用,Metal 仅在 MacOS 和 iOS 上可用,而 OpenCL 则在 Android 7.0+ 中禁被禁用,并且不支持 iOS。

2. NCNN 如何使用 Vulkan ​Vulkan 的支持性:

支持性WindowsLinuxAndroidMaciOSIntel✅✅❔❔❌AMD✅✅❌❔❌Nvidia✅✅❔❌❌Qcom❌❌✅❌❌Apple❌❌❌❔✅ARM❌❔❔❌❌2.1 安装 Vulkan 支持 ​在使用之前,我们需要开启 Vulkan 的支持。在你的系统上安装 Vulkan 支持,一些系统已经内置支持了 Vulkan:

bashsudo dnf install vulkan-devel2.2 在项目中使用 Vulkan ​在编译项目时指定参数来开启 Vulkan 功能:

bashcmake -DNCNN_VULKAN=ON ..为了支持 Vulkan 推理,还需要在 Net 对象中启用 Vulkan:

cppncnn::Net net;

net.opt.use_vulkan_compute = 1;指定使用 Vulkan 的网络运行在哪个 GPU 上:

cpp// 获取 GPU 数量

int gpu_count = ncnn::get_gpu_count();

// 设置 Vulkan 设备

net.set_vulkan_device(0); // 将使用 device-02.3 使用合适的分配器 ​cpp// 获取 Vulkan 的分配器

ncnn::VkAllocator* blob_vkallocator = vkdev.acquire_blob_allocator();

ncnn::VkAllocator* staging_vkallocator = vkdev.acquire_blob_allocator();

net.opt.blob_vkallocator = blob_vkallocator;

net.opt.workspace_vkallocator = blob_vkallocator;

net.opt.staging_vkallocator = staging_vkallocator;

// 推理

// ...

// 推理后

vkdev.reclaim_blob_allocator(blob_vkallocator);

vkdev.reclaim_staging_allocator(staging_vkallocator);2.4 使用零复制的一致的内存设备 ​cppncnn::VkMat blob_gpu;

ncnn::Mat mapped = blob_gpu.mapped();

// 下面可以直接使用 mapped.data2.5 使用 CPU/GPU 混合推理 ​cppncnn::Extractor ex_cpu = net.create_extractor();

ncnn::Extractor ex_gpu = net.create_extractor();

ex_cpu.set_vulkan_compute(false);

ex_gpu.set_vulkan_compute(true);

#pragma omp parallel sections

{

#pragma omp section

{

ex_cpu.input();

ex_cpu.extract();

}

#pragma omp section

{

ex_gpu.input();

ex_gpu.extract();

}

}3. 零复制的 GPU 链式推理 ​cppncnn::Extractor ex1 = net1.create_extractor();

ncnn::Extractor ex2 = net2.create_extractor();

ncnn::VkCompute cmd(&vkdev);

ncnn::VkMat conv1;

ncnn::VkMat conv2;

ncnn::VkMat conv3;

ex1.input("conv1", conv1);

ex1.extract("conv2", conv2, cmd);

ex2.input("conv2", conv2);

ex2.extract("conv3", conv3, cmd);

cmd.submit();

cmd.wait();4. 批量推理 ​cppint max_batch_size = vkdev->info.compute_queue_count;

ncnn::Mat inputs[1000];

ncnn::Mat outputs[1000];

#pragma omp parallel for num_threads(max_batch_size)

for (int i = 0; i < 1000; i++) {

ncnn::Extractor ex = net1.create_extractor();

ex.input("data", inputs[i]);

ex.extract("prob", outputs[i]);

}5. 控制优化策略 ​禁用低精度优化,使用 float32 精度:

cppncnn::Net net;

net.opt.use_fp16_packed = false;

net.opt.use_fp16_storage = false;

net.opt.use_fp16_arithmetic = false;

net.opt.use_int8_storage = false;

net.opt.use_int8_arithmetic = false;6. 调试模型 ​目前 Vulkan 不能直接进行调试,需要修改 NCNN 的源码 src/gpu.cpp 中的宏指令:

cpp#define ENABLE_VALIDATION_LAYER 1修改为 1 可以获得调试输出。

参考 ​[1] https://github.com/Tencent/ncnn/wiki/vulkan-notes

🎯 相关推荐

PPF和PPC的区别
365会被黑吗

PPF和PPC的区别

📅 07-09 👀 8626
暗黑3 攻略 第四章
约彩365官网

暗黑3 攻略 第四章

📅 01-02 👀 4265
为什么大多数的女明星生产后都不喂母乳!为什么明星不母乳喂养!