最近因为离职太忙了之前的很多内容没有更新,离开BYD进入新的环境中成长。
本文包含了Segformer的网络结构重构后如何部署到算法平台中方便标注训练推理的过程,以及如何应用到项目中(BYD最后一个项目:异物检测系统)
C++做Segformer的推理加速,Python做Segformer平台部署,C#调用算法接口实现项目开发。
前言
本章将前面的segfomer网络结构的学习和重构、segformer双显卡推理部署、算法平台开发、c#使用pythonnet调用python多进程项目、windows forms图形界面的开发,c++加cuda对模型推理加速的所有内容贯穿起来完成一个大型项目的整个开发起来。
一、算法平台的开发
1、在现有的算法平台添加该深度学习模块,避免后面的项目用到该模型重复造轮子,增加标注训练功能和推理工具

2、推理功能接口提供pytorch\onnx\tensort三种推理方式

3、项目逻辑功能:实现相机和电机和机械手的控制

4、图片算法逻辑功能实现,输出分割区域
二、c++和cuda 实现segformer推理加速
c++推理代码
int load_model(std::string modelPath, int cudaDevice,int width,int height,int batchSize, int classNum)
{
cudaSetDevice(cudaDevice);
/*******************************************************************************************************
一、读取本地模型
*******************************************************************************************************/
//引擎文件绝对地址
//std::string engine_name = R"(D:\Drivers\TensorRT-8.5.3.1\bin\models_YW240619.trt)"; //D:\Drivers\TensorRT - 8.5.3.1\bin\models_YW240619.trt
std::string engine_name = modelPath;//R"(D:\model\models.trt)"; //D:\Drivers\TensorRT - 8.5.3.1\bin\models_YW240619.trt F:\model\models_YW240619.trt
//该文件保存了模型的所有信息以及电脑的配置信息,因此该模型文件不支持在不同电脑上使用。
std::ifstream file(engine_name, std::ios::binary);
if (!file.good())
std::cerr << "文件无法打开,请确定文件是否可用!" << std::endl;
size_t size = 0;
file.seekg(0, file.end); // 将读指针从文件末尾开始移动0个字节
size = file.tellg(); // 返回读指针的位置,此时读指针的位置就是文件的字节数
file.seekg(0, file.beg); // 将读指针从文件开头开始移动0个字节
char* modelStream = new char[size];
//将模型文件信息读取到内存中
file.read(modelStream, size);
file.close();
/*******************************************************************************************************
二、构建引擎
*******************************************************************************************************/
//创建反序列化引擎并使用日志记录接口---使用全局 TensorRT API 方法用于创建 iRuntime 类型的对象
this->runtime = nvinfer1::createInferRuntime(glogger);
//调用反序列化引擎来创建推理引擎,即反序列化获取模型(modelStream)中的引擎---通过调用运行时方法 deserializeCudaEngine() 来创建引擎
this->engine = runtime->deserializeCudaEngine(modelStream, size, nullptr);
//判断推理引擎是否为空
if (engine == NULL) {
printf("modelStream 为空,模型加载失败");
delete[] modelStream;
return 0;
}
else
{
//创建推理上下文---为后面进行模型推理的类
this->context = this->engine->createExecutionContext();
delete[] modelStream;
//创建GPU缓存区,使用这些索引,创建buffers指向 GPU 上输入和输出缓冲区
std::string inputBindingname = this->engine->getBindingName(inputBindingindex);
std::string outputBindingname = this->engine->getBindingName(outputBindingindex);
this->inputIndex = this->engine->getBindingIndex(inputBindingname.c_str());
this->outputIndex = this->engine->getBindingIndex(outputBindingname.c_str());
inputDims.nbDims = 4;
inputDims.d[0] = 1;
inputDims.d[1] = 3;
inputDims.d[2] = 512;
inputDims.d[3] = 512;
this->context->setBindingDimensions(this->inputIndex, inputDims);
//创建GPU显存输入缓存区---输入推理数据(GPU)
cudaMalloc(&buffers[this->inputIndex], (3 * 512 * 512) * sizeof(float));
//创建GPU显存输出缓存区--输出推理结果数据(GPU)
cudaMalloc(&buffers[this->outputIndex], (classNum * 512 * 512) * sizeof(float));
cudaMalloc((void**)&srcDevData, sizeof(uchar) * (width * height * 3 * batchSize));
cudaMalloc((void**)&srcResizeData, sizeof(uchar) * (512 * 512 * 3 * batchSize));
//使用CUDA流数据加载,将结果数据(CPU内存)输出到float变量中
cudaMalloc((void**)&post_device_data, sizeof(uchar) * (512 * 512 * batchSize));
cudaMalloc((void**)&post_resize_data, sizeof(uchar) * (width * height * batchSize));
scr = new uchar[batchSize * 3 * width * height];
post_host_data = new uchar[width * height * batchSize];
return 1;
}
}
cuda核函数代码
__global__ void process(const uchar* srcData, float* tgtData, const int h, const int w)
{
int ix = threadIdx.x + blockIdx.x * blockDim.x;
int iy = threadIdx.y + blockIdx.y * blockDim.y;
int idx = ix + iy * w;
int idx3 = idx * 3;
if (ix < w && iy < h)
{
tgtData[idx] = ((float)srcData[idx3 + 2] - 123.675f) / 58.359; // R pixel
tgtData[idx + h * w] = ((float)srcData[idx3 + 1] -116.28)/ 57.12; // G pixel
tgtData[idx + h * w * 2] = ((float)src

最低0.47元/天 解锁文章
1077





