【学习笔记】科学计算

[pytorch 加速] CPU传输 & GPU计算的并行(pin_memory,non_blocking)

https://www.bilibili.com/video/BV15Xxve1EtZ

from IPython.display import Image
import os
os.environ['http_proxy'] = 'http://127.0.0.1:7890'
os.environ['https_proxy'] = 'http://127.0.0.1:7890'
  • references
    • https://tigress-web.princeton.edu/~jdh4/PyTorchPerformanceTuningGuide_GTC2021.pdf
      • https://pytorch.org/blog/optimizing-cuda-rnn-with-torchscript/
    • https://towardsdatascience.com/optimize-pytorch-performance-for-speed-and-memory-efficiency-2022-84f453916ea6
    • https://blog.dailydoseofds.com/p/memory-pinning-to-accelerate-model
import torch
import torch.jit
import timeit

更快的数据传输

for epoch in range(epochs): for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)optimizer.zero_grad()output = model(data)loss = criterion(output, target)loss.backward()        optimizer.step()

standard PyTorch model training loop

  • data, target = data.to(device), target.to(device) transfers the data to the GPU from the CPU.
  • Everything executes on the GPU after the data transfer.

在这里插入图片描述

  • When the model is being trained on the 1st mini-batch, the CPU can transfer the 2nd mini-batch to the GPU.
  • This ensures that the GPU does not have to wait for the next mini-batch of data as soon as it completes processing an existing mini-batch.

在这里插入图片描述

  • While the CPU may remain idle, this process ensures that the GPU (which is the actual accelerator for our model training) always has data to work with.

  • Formally, this process is known as memory pinning, and it is used to speed up the data transfer from the CPU to the GPU by making the training workflow asynchronous.

  • enable pin_memory and set num_workers (muti-core processors) for faster transfers

train_loader = DataLoader(train_dataset,batch_size=64, shuffle=True,pin_memory=True, num_workers=8)
  • during the data transfer step in the training step, specify non_blocking=True, as depicted below:
for epoch in range(epochs):for batch_idx, (data, target) in enumerate(train_loader):data = data.to(device, non_blocking=True)target = target.to(device, non_blocking=True)optimizer.zero_grad()        output = model(data)loss = criterion(output, target)loss.backward()optimizer.step()

减少分页内存和pin memory的swap

以下以MNIST图像分类任务为例:

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import time
from tqdm.notebook import tqdm# 定义数据转换
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))
])# 加载 MNIST 数据集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)class SimpleNet(nn.Module):def __init__(self):super(SimpleNet, self).__init__()self.fc = nn.Sequential(nn.Flatten(),nn.Linear(28*28, 512),nn.ReLU(),nn.Linear(512, 10))def forward(self, x):return self.fc(x)device = torch.device("cuda" if torch.cuda.is_available() else "cpu")def train(loader, model, optimizer, device, non_blocking=False, epochs=5):model.train()total_loss = 0start_time = time.time()for epoch in tqdm(range(epochs), desc="Epochs"):batch_bar = tqdm(enumerate(loader), total=len(loader), desc=f"Epoch {epoch+1}/{epochs}", leave=False)for batch_idx, (data, target) in batch_bar:# 将数据移到设备上data = data.to(device, non_blocking=non_blocking)target = target.to(device, non_blocking=non_blocking)optimizer.zero_grad()output = model(data)loss = nn.functional.cross_entropy(output, target)loss.backward()optimizer.step()total_loss += loss.item()end_time = time.time()avg_loss = total_loss / (len(loader)*epochs)elapsed_time = end_time - start_timereturn avg_loss, elapsed_timefrom multiprocessing import cpu_count
loader1 = DataLoader(train_dataset, batch_size=64, shuffle=True)
loader2 = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=cpu_count()//2, pin_memory=True)model1 = SimpleNet().to(device)
optimizer1 = optim.SGD(model1.parameters(), lr=0.01)
avg_loss1, time1 = train(loader1, model1, optimizer1, device, non_blocking=False, epochs=5)
print(f"设置 1 - 平均损失: {avg_loss1:.4f}, 训练时间: {time1:.2f} 秒")

这样的运行情况是:

Epochs:   0%|          | 0/5 [00:00<?, ?it/s]
Epoch 1/5:   0%|          | 0/938 [00:00<?, ?it/s]
Epoch 2/5:   0%|          | 0/938 [00:00<?, ?it/s]
Epoch 3/5:   0%|          | 0/938 [00:00<?, ?it/s]
Epoch 4/5:   0%|          | 0/938 [00:00<?, ?it/s]
Epoch 5/5:   0%|          | 0/938 [00:00<?, ?it/s]
设置 1 - 平均损失: 0.3854, 训练时间: 42.71

然后我们换一种方式,使用num_workers为CPU核的一半,并使用pin_memory

model2 = SimpleNet().to(device)
optimizer2 = optim.SGD(model2.parameters(), lr=0.01)
avg_loss2, time2 = train(loader2, model2, optimizer2, device, non_blocking=True, epochs=5)
print(f"设置 2 - 平均损失: {avg_loss2:.4f}, 训练时间: {time2:.2f} 秒")

运行结果为:

Epochs:   0%|          | 0/5 [00:00<?, ?it/s]
Epoch 1/5:   0%|          | 0/938 [00:00<?, ?it/s]
Epoch 2/5:   0%|          | 0/938 [00:00<?, ?it/s]
Epoch 3/5:   0%|          | 0/938 [00:00<?, ?it/s]
Epoch 4/5:   0%|          | 0/938 [00:00<?, ?it/s]
Epoch 5/5:   0%|          | 0/938 [00:00<?, ?it/s]
设置 2 - 平均损失: 0.3847, 训练时间: 19.92

大约提升一倍的时间

另一个是JIT(Just-In-Time compilation) )

  • JIT 通过将模型编译成中间表示(Intermediate Representation, IR),然后进一步将其转换为机器代码
  • Fuse the pointwise (elementwise) operations into a single kernel by PyTorch JIT
    • JIT fuse the pointwise operations
# 创建一个大型的随机张量作为输入数据
x = torch.randn(15000, 15000)# 使用 JIT 编译的函数
@torch.jit.script
def fused_gelu(x):return x * 0.5 * (1.0 + torch.erf(x / 1.41421))# 未使用 JIT 编译的相同函数
def gelu(x):return x * 0.5 * (1.0 + torch.erf(x / 1.41421))# 使用 timeit 测量 JIT 编译函数的执行时间
jit_time = timeit.timeit('fused_gelu(x)', globals=globals(), number=100)
nonjit_time = timeit.timeit('gelu(x)', globals=globals(), number=100)print(jit_time, nonjit_time) # 20.05574530499871 31.39065190600013

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/474061.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2、计算机网络七层封包和解包的过程

计算机网络osi七层模型 1、网络模型总体预览2、数据链路层4、传输层5.应用层 1、网络模型总体预览 图片均来源B站&#xff1a;网络安全收藏家&#xff0c;没有本人作图 2、数据链路层 案例描述&#xff1a;主机A发出一条信息&#xff0c;到路由器A&#xff0c;这里封装目标MAC…

在云服务器搭建 Docker

操作场景 本文档介绍如何在腾讯云云服务器上搭建和使用 Docker。本文适用于熟悉 Linux 操作系统&#xff0c;刚开始使用腾讯云云服务器的开发者。如需了解更多关于 Docker 相关信息&#xff0c;请参见 Docker 官方。 说明&#xff1a; Windows Subsystem for Linux&#xff…

Isaac Sim+SKRL机器人并行强化学习

目录 Isaac Sim介绍 OmniIssacGymEnvs安装 SKRL安装与测试 基于UR5的机械臂Reach强化学习测评 机器人控制 OMNI GYM环境编写 SKRL运行文件 训练结果与速度对比 结果分析 运行体验与建议 Isaac Sim介绍 Isaac Sim是英伟达出的一款机器人仿真平台&#xff0c;适用于做机…

【时间之外】IT人求职和创业应知【37】-AIGC私有化

目录 新闻一&#xff1a;2024智媒体50人成都会议暨每经20周年财经媒体峰会召开 新闻二&#xff1a;全球机器学习技术大会在北京召开 新闻三&#xff1a;区块链技术在金融领域的应用取得新突破 不知不觉的坚持了1个月&#xff0c;按照心理学概念&#xff0c;还要坚持2个月&am…

亿咖通科技应邀出席微软汽车行业智享会,分享ECARX AutoGPT全新实践

11月14日&#xff0c;全球出行科技企业亿咖通科技&#xff08;纳斯达克股票代码&#xff1a;ECX&#xff09;应邀于广州参加由微软举行的汽车行业智享会&#xff0c;揭晓了亿咖通科技对“AI定义汽车”时代的洞察与技术布局&#xff0c;分享了亿咖通科技汽车垂直领域大模型ECARX…

三维测量与建模笔记 - 点特征提取 - 4.3 Harris特征点

在3D重建应用中&#xff0c;很重要的一个场景是找到两幅图像中的同名特征点&#xff0c;这个过程需要对特征点进行提取和描述。 从上面描述可以看出&#xff0c;如果窗口处于颜色变化不明显或者没有变化的区域&#xff0c;E的值很小或为0&#xff1b;如果窗口处于边缘位置&…

C指针之舞——指针探秘之旅

❤博客主页&#xff1a;折枝寄北-CSDN博客 ❤专栏内容&#xff1a;C语言学习专栏https://blog.csdn.net/2303_80170533/category_12794764.html?spm1001.2014.3001.5482 指针基础学习 在之前的博客文章中&#xff0c;简单总结了指针的基础概念 我们知道了指针的概念&#xf…

[Qt platform plugin问题] Could not load the Qt platform plugin “xcb“

Qt platform plugin 是 Qt 应用程序启动时加载的插件。不同的平台有不同的插件。 常见的插件有:linuxfb Wayland xcb 简单来说就是启动一个GUI程序, 离不开这些插件.选择其中一个就好 出现这个问题要么就是没有插件&#xff0c;要么就是插件依赖的库没有。 要么就是插件选则的…

Skywalking搭建-来自于图灵课堂

Skywalking主要用于链路追踪&#xff0c;日志收集查看&#xff0c;异常日志查看&#xff0c;服务监控弱一些&#xff0c;服务器监控可以使用prometheus 一、搭建服务端&#xff0c;使用startup.bat启动 配置持久化&#xff0c;如果是用mysql持久化&#xff0c;拷贝mysql链接包…

Relaxcert SSL证书申请与自动续签之IIS

Relaxcert SSL证书申请与自动续签之IIS 1.下载安装自动续签程序2.配置客户端秘钥3.HTTP站点升级HTTPS4.关于SSL自动续签 Relaxcert SSL证书申请与自动续签工具 控制台地址 https://cert.relaxcert.com 文档地址 https://doc.relaxcert.com 1.下载安装自动续签程序 登录控制台…

spi 回环

///tx 极性0 &#xff08;sclk信号线空闲时为低电平&#xff09; /// 相位0 (在sclk信号线第一个跳变沿进行采样) timescale 1ns / 1ps//两个从机 8d01 8d02 module top(input clk ,input rst_n,input [7:0] addr ,input …

IDEA旗舰版编辑器器快速⼊门(笔记)

简介&#xff1a;javaweb开发必备软件之IDEA期间版介绍 DEA编辑器器版本介绍 官⽹网&#xff1a;https://www.jetbrains.com/地址&#xff1a;https://www.jetbrains.com/idea/download/#sectionmac DEA 分社区版(Community) 和 旗舰版(Ultimate)&#xff0c;我们做JavaWeb开…

WPF的基础控件详解

WPF的基础控件详解 在WPF学习中 基本控件是最简单也是最基础的东西。也是很初学者容易忽略的 本此笔记教程主要针对WPF中基础控件使用和应用进行手把手教学&#xff0c;如果学习了此笔记对你有帮助记得一键三连哦~~~~ TextBlock 基本用法 长字串处理 LineBreak标籤在指定的地…

MySQL的聚簇索引和二级索引

索引按照物理实现方式&#xff0c;索引可以分为 2 种&#xff1a;聚簇&#xff08;聚集&#xff09;和非聚簇&#xff08;非聚集&#xff09;索引。也可以把非聚集索引称为二级索引或者辅助索引。 一.聚簇索引 聚簇索引并不是一种单独的索引类型&#xff0c;而是一种数据存储方…

2.5D视觉——Aruco码定位检测

目录 1.什么是Aruco标记2.Aruco码解码说明2.1 Original ArUco2.2 预设的二维码字典2.3 大小Aruco二维码叠加 3.函数说明3.1 cv::aruco::detectMarkers3.2 cv::solvePnP 4.代码注解4.1 Landmark图说明4.2 算法源码注解 1.什么是Aruco标记 ArUco标记最初由S.Garrido-Jurado等人在…

能源革命持续发力,华普微隔离器助力储能行业“向绿向新”

能源是工业的粮食&#xff0c;是国民经济的命脉&#xff0c;亦是实现可持续发展的关键之处。在各国“双碳”目标战略的引领下&#xff0c;能源革命正全面席卷而来&#xff0c;而加速培育能源新质生产力&#xff0c;构建清洁低碳、安全高效的新型能源体系&#xff0c;已成为全球…

微信小程序-prettier 格式化

一.安装prettier插件 二.配置开发者工具的设置 配置如下代码在setting.json里&#xff1a; "editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","prettier.documentSelectors": ["**/*.wxml"…

sapiens推理的安装与使用

文章目录 1、安装1.1 克隆代码库1.2 设置 Sapiens-Lite 的代码路径1.3 创建 Conda 环境并安装必要的依赖1.4 下载模型检查点 2、推理 sapiens&#xff0c;是meta发布的以人为中心的视觉大模型&#xff0c;"sapiens"这个词来源于拉丁语&#xff0c;意为“智慧的”或“…

leetcode-44-通配符匹配

题解&#xff1a; 代码&#xff1a; 参考&#xff1a; (1)牛客华为机试HJ71字符串通配符 (2)leetcode-10-正则表达式匹配

Linux守护Pythom脚本运行——Supervisor学习总结

Supervisor能做什么&#xff1f; 在工作中有时会遇到在Linux服务器上编写各种脚本来实现日志的推送、数据的传输、流量的监控等&#xff0c;这些脚本在整个系统运行中也需要和其他服务端应用程序一样持续且稳定运行&#xff0c;为了达到这种目的就需要使用进程守护工具来对正在…