pytorch 算子调用kernel示例(MINIST)

news/2024/9/22 5:22:18 标签: pytorch, 深度学习, 人工智能, GPU, CUDA, 机器学习, python

pytorch_kernelMINIST_0">pytorch 算子调用kernel示例(MINIST)

当进行 MNIST 分类任务时,PyTorch 中的每一个算子会根据设备类型(CPU 或 CUDA)自动选择合适的内核(kernel)进行计算。本文以GPU为例,介绍算子调用kernel的过程。

1. 模型定义与前向传播

python">import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F

class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)  # 卷积层1
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)  # 卷积层2
        self.fc1 = nn.Linear(64 * 7 * 7, 128)  # 全连接层1
        self.fc2 = nn.Linear(128, 10)  # 全连接层2
    
    def forward(self, x):
        x = F.relu(self.conv1(x))  # 激活函数 ReLU
        x = F.max_pool2d(x, 2)  # 最大池化
        x = F.relu(self.conv2(x))  # 激活函数 ReLU
        x = F.max_pool2d(x, 2)  # 最大池化
        x = x.view(-1, 64 * 7 * 7)  # 张量展平
        x = F.relu(self.fc1(x))  # 全连接层激活
        x = self.fc2(x)  # 输出层
        return F.log_softmax(x, dim=1)  # 计算 softmax 概率

GPU_30">2. 数据加载与模型放置到 GPU

python">from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 加载MNIST数据集
transform = transforms.Compose([transforms.ToTensor()])
train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

# 将模型和数据移动到 GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = SimpleCNN().to(device)  # 模型加载到 GPU
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 训练过程
for epoch in range(1, 2):  # 运行1个 epoch
    model.train()
    for data, target in train_loader:
        data, target = data.to(device), target.to(device)  # 数据加载到 GPU
        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()

GPU__58">3. 算子调用与 GPU 内核函数

当模型和数据都在 GPU 上时,PyTorch 的每一个算子会通过其调度机制(dispatch mechanism)调用相应的 CUDA 内核来加速计算。

GPU__62">(1) Conv2d (卷积层) 的 GPU 调用

在卷积操作中,PyTorch 会调用 Conv2d 算子。此时,设备被指定为 CUDA,调度系统会调用 GPU 专用的内核。

  • 算子调用:

    python">x = F.relu(self.conv1(x))
    
  • 内核调用

    • 对于 CUDA:调用 conv2d_cuda_kernel
  • CUDA 实现的原型代码conv2d_cuda_kernel 使用高度优化的 cuDNN 库来执行卷积操作,具体原型可能如下:

Tensor conv2d_cuda(
    const Tensor& input,
    const Tensor& weight,
    const Tensor& bias,
    IntArrayRef stride,
    IntArrayRef padding,
    IntArrayRef dilation,
    int64_t groups) {
    
    // 使用 cuDNN 卷积函数来加速计算
    return at::cudnn_convolution(input, weight, bias, padding, stride, dilation, groups);
}

at::cudnn_convolution 是一个封装好的接口,用于调用 cuDNN 库中的卷积操作。cuDNN 提供了一系列高度优化的卷积算法,能够根据输入数据的大小和 GPU 的架构,自动选择最优的计算方式。

GPU__96">(2) ReLU (激活函数) 的 GPU 调用

ReLU 激活函数会根据设备类型,调用 CUDA 内核来进行计算。

  • 算子调用

    python">
    x = F.relu(self.conv1(x))
    
  • 内核调用

    • 对于 CUDA:调用 relu_cuda_kernel
  • CUDA 实现的原型代码

    Tensor relu_cuda(const Tensor& self) {
      // 使用 CUDA 进行并行计算 ReLU
      return at::clamp_min_cuda(self, 0);
    }
    
GPU__120">(3) MaxPool2d (池化层) 的 GPU 调用
  • 算子调用

    python">x = F.max_pool2d(x, 2)
    
  • 内核调用

    • 对于 CUDA:调用 max_pool2d_cuda_kernel
  • CUDA 实现的原型代码

    Tensor max_pool2d_cuda(
        const Tensor& self,
        IntArrayRef kernel_size,
        IntArrayRef stride,
        IntArrayRef padding,
        bool ceil_mode) {
      // 使用 CUDA 并行池化运算
      ...
    }
    
GPU__146">(4) Linear (全连接层) 的 GPU 调用
  • 算子调用

    python">
    x = F.relu(self.fc1(x))
    
  • 内核调用

    • 对于 CUDA:调用 linear_cuda_kernel
  • CUDA 实现的原型代码

    Tensor linear_cuda(
        const Tensor& input,
        const Tensor& weight,
        const Tensor& bias) {
      // 使用 CUDA 进行矩阵乘法和偏置加法
      return at::addmm_cuda(bias, input, weight.t());
    }
    
GPU__171">(5) Softmax (输出层) 的 GPU 调用
  • 算子调用

    python">
    return F.log_softmax(x, dim=1)
    
  • 内核调用

    • 对于 CUDA:调用 log_softmax_cuda_kernel
  • CUDA 实现的原型代码

    Tensor log_softmax_cuda(const Tensor& self, int64_t dim, bool half_to_float) {
      // 使用 CUDA 并行计算 softmax
      ...
    }
    

Reference:

  1. https://github.com/pytorch/pytorch
  2. https://docs.nvidia.com/deeplearning/cudnn/api/index.html
  3. https://github.com/pytorch/pytorch

http://www.niftyadmin.cn/n/5669722.html

相关文章

基于主从Reactor模型实现高并发服务器

目录 1. 项目简介1.1 环境介绍1.2 项目定位1.3 功能模块整体划分 2. Reactor简介2.1 Reactor模型分析2.2 多Reactor多线程分析:多I/O多路复用线程池(业务处理) 3. 日志宏的编写4. Server模块4.1 Buffer模块4.1.1 Buffer的功能4.1.2 Buffer的实…

树莓派配置Qt+OpenCV

本次教程使用的树莓派镜像:树莓派镜像带图像界面下载 Qt的安装: 在命令行依次输入以下命令安装Qt: sudo apt-get updatesudo apt-get upgrade sudo apt-get install qtbase5-dev qtchooser sudo apt-get install qt5-qmake qtbase5-dev-t…

5、论文阅读:深水下的图像增强

深水下的图像增强 前言介绍贡献UWCNN介绍网络架构残差Residuals块 Blocks网络层密集串联网络深度减少边界伪影网络损失Loss后处理前言 水下场景中,与波长相关的光吸收和散射会降低图像的可见度,导致对比度低和色偏失真。为了解决这个问题,我们提出了一种基于卷积神经网络的…

好用的工具网址

代码类: 1,json解析:JSON在线解析及格式化验证 - JSON.cn 2.传参转化编码 在线url网址编码、解码器-BeJSON.com 日常: 1.莆田医院查询:滚蛋吧!莆田系

python禁止位置传参函数

这种函数定义方式使用了 Python 3.x 中的关键字参数(keyword-only arguments)的特性,通过在参数列表中使用 * 符号作为分隔符,来明确指示该函数之后的参数必须使用关键字(即参数名)来传递,而不能…

探索《藏汉翻译通》小程序:跨平台的藏文翻译利器

亲爱的读者们,当谈及藏文与汉语之间的翻译工具时,您可能已经对安卓平台的《藏汉翻译通》应用和iOS平台的《藏语翻译通》应用有所耳闻。今天,我们想要向您推荐一款既实用又便捷的新工具——《藏汉翻译通》小程序。 这款小程序不仅能够提供精确…

ubuntu 安装minikube,并拉取k8s镜像

不要使用最新版,重要的事情说三遍,刚开始也是最求新一点的版本,但问题很多,主要是版本之间的依赖问题,不是某个依赖的版本不支持某些功能,就是依赖之间的版本不能对应上,所以就降低几个版本&…

【开源免费】基于SpringBoot+Vue.JS图书馆管理系统(JAVA毕业设计)

本文项目编号 T 044 ,文末自助获取源码 \color{red}{T044,文末自助获取源码} T044,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…