极智AI | 谈谈GPU并行推理的几个方式

简介: 大家好,我是极智视界,本文主要聊一下 GPU 并行推理的几个方式。

大家好,我是极智视界。本文主要聊一下 GPU 并行推理的几个方式。

CUDA流 表示一个 GPU 操作队列,该队列中的操作将以添加到流中的先后顺序而依次执行。可以将一个流看做是GPU 上的一个任务,不同任务可以并行执行。使用 CUDA流,首先要选择一个支持设备重叠(Device Overlap)功能的设备,支持设备重叠功能的 GPU 能够在执行一个 CUDA 核函数的同时,还能在主机和设备之间执行复制数据操作。

支持重叠功能的设备的这一特性很重要,可以在一定程度上提升 GPU 程序的执行效率。一般情况下,CPU 内存远大于 GPU 内存,对于数据量比较大的情况,不可能把 CPU 缓冲区中的数据一次性传输给 GPU,需要分块传输,如果能够在分块传输的同时,GPU 也在执行核函数运算,这样就形成了异步操作,能够提高极大提升运算性能。

下面实际介绍几种 GPU 并行的方式。


1 Cuda 核函数并行

void privateBlobFromImagesGpu(const float* imageDatas, int batchCount, int width, int height, const float* mean, const float* std, float* blob, cudaStream_t stream)
{
  const dim3 block(3, width);
  const dim3 grid(height, batchCount);
  meanAndStdAndSplit <<<grid, block, 0, stream >>> (blob, imageDatas, mean, std);
}
global static void meanAndStdAndSplit(float* blob, const float* imageDatas, const float* mean, const float* std)
{
  const int c = threadIdx.x;
  const int x = threadIdx.y;
  const int y = blockIdx.x;
  const int idx = blockIdx.y; 
  const unsigned int blobIdx = idx * blockDim.x * blockDim.y * gridDim.x + c * blockDim.y * gridDim.x + y * blockDim.y + x;
  const unsigned int imagesIdx = idx * blockDim.x * blockDim.y * gridDim.x + y * blockDim.x * blockDim.y + x * blockDim.x + c;
  blob[blobIdx] = (imageDatas[imagesIdx] - mean[c]) / std[c];
}
for (int i = 0; i < thNB; i++)
{
  privateBlobFromImagesGpu((float*)m_converArray, imgdata.size.size(), m_inputW, m_inputH, m_mean_GPU, m_std_GPU,
  (float*)m_Bindings.at(m_InputIndex), cudaStream[i]);
}
for (int i = 0; i < thNB; i++)
{
  cudaStreamSynchronize(cudaStream);
}


2 调用英伟达 API 库并行

for (int i = 0; i < imgdata.size.size(); i++)
{
  cv::cuda::GpuMat gpuRgbSrcImg(cv::Size(imgdata.size[i].w, imgdata.size[i].h), CV_8UC3, (cv::uint8_t*)imgdata.data + i * imgdata.size[i].w * imgdata.size[i].h);
  cv::cuda::GpuMat gpuRgbDstImg(cv::Size(m_inputW, m_inputH), CV_8UC3, (cv::uint8_t*)m_resizeArray + i * m_inputC * m_inputH * m_inputW);
  cv::cuda::resize(gpuRgbSrcImg, gpuRgbDstImg, cv::Size(m_inputW, m_inputH), 0.0, 0.0, cv::INTER_LINEAR);
  cv::cuda::GpuMat dst_conver(outputSize, CV_32FC3, (float*)m_converArray + i * m_inputC * m_inputH * m_inputW);
  gpuRgbDstImg.convertTo(dst_conver, CV_32F, 1.0 / 255, 0);
}
stream.waitForCompletion();


3 TRT 并行

int testStream()
{
  int outNB = 0;
  std::string model_path = "./data/";
  int batchsize = 4;
  int streamNB = 2;
  DoInference *doInfer_stream1 = new DoInference();
  std::vector<int> outputSize;
  bool isInit1 = doInfer_stream1->InitModle(model_path, OD, TensorRT, outputSize, streamNB, batchsize);
  std::vector<float*> inputData;
  std::vector<cudaStream_t> cudaStream;
  std::vector<vector<void*>>imgdata_stream;
  inputData.resize(streamNB);
  cudaStream.resize(streamNB);
  int* size = new int[4];
  size[0] = 512 * 512 * 3;
  size[1] = 135168;
  size[2] = 33792;
  size[3] = 8848;
  imgdata_stream.resize(streamNB);
  for (int i = 0; i < streamNB; i++)
  {
    cudaStreamCreate(&cudaStream.at(i));
    cudaStreamCreateWithFlags(&cudaStream.at(i), cudaStreamNonBlocking);
    cudaMallocHost(&inputData.at(i), batchsize * size[0] * sizeof(float));
    imgdata_stream.at(i).resize(4);
    for (int j = 0; j < 4; j++)
    {
      cudaMalloc(&imgdata_stream.at(i).at(j), batchsize * size[j] * sizeof(float));
    }
    for (int z = 0; z < size[0]; z++)
    {
      inputData.at(i)[z] = z;
    } 
  }
  for (int count = 0; count < 5; count++)
  {
    for (int i = 0; i < streamNB; i++)
    {
      cudaMemcpyAsync(imgdata_stream.at(i).at(0), inputData.at(i), batchsize * size[0] * sizeof(float), cudaMemcpyHostToDevice, cudaStream.at(i));
      doInfer_stream1->DoinferTestStream(imgdata_stream.at(i), batchsize, i, cudaStream.at(i));
    }
  }
  for (int i = 0; i < streamNB; i++)
  {
    cudaStreamSynchronize(cudaStream.at(i));
  }
  //cudaStreamSynchronize(cudaStream1);
  //cudaStreamSynchronize(cudaStream2); 
  return 0;
}


好了,以上聊了下 GPU 并行推理的几个方式,希望我的分享能对你的学习有一点帮助。


logo_show.gif

相关实践学习
在云上部署ChatGLM2-6B大模型(GPU版)
ChatGLM2-6B是由智谱AI及清华KEG实验室于2023年6月发布的中英双语对话开源大模型。通过本实验,可以学习如何配置AIGC开发环境,如何部署ChatGLM2-6B大模型。
相关文章
|
8月前
|
人工智能 中间件 数据库
沐曦 GPU 融入龙蜥,共筑开源 AI 基础设施新底座
沐曦自加入社区以来,一直与龙蜥社区在推动 AIDC OS 的开源社区建设等方面保持合作。
|
9月前
|
存储 机器学习/深度学习 算法
​​LLM推理效率的范式转移:FlashAttention与PagedAttention正在重塑AI部署的未来​
本文深度解析FlashAttention与PagedAttention两大LLM推理优化技术:前者通过分块计算提升注意力效率,后者借助分页管理降低KV Cache内存开销。二者分别从计算与内存维度突破性能瓶颈,显著提升大模型推理速度与吞吐量,是当前高效LLM系统的核心基石。建议收藏细读。
1741 125
|
8月前
|
存储 人工智能 安全
《Confidential MaaS 技术指南》发布,从 0 到 1 构建可验证 AI 推理环境
Confidential MaaS 将从前沿探索逐步成为 AI 服务的安全标准配置。
|
9月前
|
存储 人工智能 NoSQL
用Context Offloading解决AI Agent上下文污染,提升推理准确性
上下文工程是将AI所需信息(如指令、数据、工具等)动态整合到模型输入中,以提升其表现。本文探讨了“上下文污染”问题,并提出“上下文卸载”策略,通过LangGraph实现,有效缓解长文本处理中的信息干扰与模型幻觉,提升AI代理的决策准确性与稳定性。
1132 2
用Context Offloading解决AI Agent上下文污染,提升推理准确性
|
8月前
|
人工智能 并行计算 PyTorch
以Lama Cleaner的AI去水印工具理解人工智能中经常会用到GPU来计算的CUDA是什么? 优雅草-卓伊凡
以Lama Cleaner的AI去水印工具理解人工智能中经常会用到GPU来计算的CUDA是什么? 优雅草-卓伊凡
772 4
|
9月前
|
人工智能 监控 数据可视化
如何破解AI推理延迟难题:构建敏捷多云算力网络
本文探讨了AI企业在突破算力瓶颈后,如何构建高效、稳定的网络架构以支撑AI产品化落地。文章分析了典型AI IT架构的四个层次——流量接入层、调度决策层、推理服务层和训练算力层,并深入解析了AI架构对网络提出的三大核心挑战:跨云互联、逻辑隔离与业务识别、网络可视化与QoS控制。最终提出了一站式网络解决方案,助力AI企业实现多云调度、业务融合承载与精细化流量管理,推动AI服务高效、稳定交付。
|
8月前
|
消息中间件 人工智能 安全
云原生进化论:加速构建 AI 应用
本文将和大家分享过去一年在支持企业构建 AI 应用过程的一些实践和思考。
2075 77
|
8月前
|
人工智能 运维 Kubernetes
Serverless 应用引擎 SAE:为传统应用托底,为 AI 创新加速
在容器技术持续演进与 AI 全面爆发的当下,企业既要稳健托管传统业务,又要高效落地 AI 创新,如何在复杂的基础设施与频繁的版本变化中保持敏捷、稳定与低成本,成了所有技术团队的共同挑战。阿里云 Serverless 应用引擎(SAE)正是为应对这一时代挑战而生的破局者,SAE 以“免运维、强稳定、极致降本”为核心,通过一站式的应用级托管能力,同时支撑传统应用与 AI 应用,让企业把更多精力投入到业务创新。
815 30

热门文章

最新文章