京公网安备 11010802034615号
经营许可证编号:京B2-20210330
CDA数据分析师 出品
相信大家在做一些算法经常会被庞大的数据量所造成的超多计算量需要的时间而折磨的痛苦不已,接下来我们围绕四个方法来帮助大家加快一下Python的计算时间,减少大家在算法上的等待时间。下面为大家讲述有关PyTorch的内容。
在PyTorch模块中,我将展示如何使用torch和检查、初始化GPU设备pycuda,以及如何使算法更快。
PyTorch是建立在torch的机器学习库。它得到了Facebook AI研究小组的支持。在最近开发之后,由于它的简单性,动态图形以及它本质上是Python,它在被开发出来之后变得非常流行。它的速度仍然没有落后,在很多情况下可以说是表现的非常好的。
pycuda允许你从python访问Nvidia的CUDA并行计算API。
要检查是否有cuda可用的设备Torch,可以简单地运行一下下面的代码:
import torch torch.cuda.is_available() # True
要获取设备的基本信息,可以使用torch.cuda。但是,要获取有关设备的更多信息,可以使用pycuda,这是一个围绕CUDA库开发的python包装器。你可以使用:
import torch import pycuda.driver as cuda cuda.init() ##获取默认设备的Id torch.cuda.current_device() # 0 cuda.Device(0).name() # '0'是你的GPU的id # Tesla K80
或者你可以这么用:
torch.cuda.get_device_name(0)#获取ID为'0'的名称设备 #'Tesla K80'
我编写了一个简单的类来获取有关cuda兼容GPU的信息:
#一个简单的类来了解你的cuda设备
import pycuda.driver as cuda
import pycuda.autoinit #必须使用它的功能
cuda.init() # 需要使用它的功能
class aboutCudaDevices():
def __init__(self):
pass
def num_devices(self):
"""返回连接的设备数量."""
return cuda.Device.count()
def devices(self):
"""获取所有连接设备的信息."""
num = cuda.Device.count()
print("%d device(s) found:"%num)
for i in range(num):
print(cuda.Device(i).name(), "(Id: %d)"%i)
def mem_info(self):
"""获得所有设备的可用内存和总内存."""
available, total = cuda.mem_get_info()
print("Available: %.2f GB\nTotal: %.2f GB"%(available/1e9, total/1e9))
def attributes(self, device_id=0):
"""获取设备Id的属性 = device_id"""
return cuda.Device(device_id).get_attributes()
def __repr__(self):
"""类表示为连接到它们的设备的数量."""
num = cuda.Device.count()
string = ""
string += ("%d device(s) found:\n"%num)
for i in range(num):
string += ( " %d) %s (Id: %d)\n"%((i+1),cuda.Device(i).name(),i))
string += (" Memory: %.2f GB\n"%(cuda.Device(i).total_memory()/1e9))
return string
# 你可以通过输入它的名字来打印输出(__repr__):
aboutCudaDevices()
# 1 设备(年代):
# 1) Tesla K80 (Id: 0)
# Memory: 12.00 GB
要获取当前的内存使用情况,你可以使用pyTorch的函数:
import torch #返回当前的GPU内存使用 # 一个给定设备的容量(以字节为单位) torch.cuda.memory_allocated() #函数管理的当前的GPU内存 #以字节为给定设备缓存的分配器 torch.cuda.memory_cached()
在运行应用程序后,可以使用一个简单的命令来清除缓存:
# 释放缓存分配器当前持有的所有为占用的缓存内存 # 以便这些内存可以在其他GPU应用程序中可以使用 # 并且可以在NVIDIA-SMI中可以进行查看 torch.cuda.empty_cache()
但是,使用这个命令不会通过张量释放占用的GPU内存,因此它无法增加可用于PyTorch的GPU内存量。
这些内存方法仅适用于GPU。所以这才是真正需要它的地方。
使用.cuda函数。
如果你想要在CPU上存储一些内容,可以简单地编写代码:
a = torch.DoubleTensor([1., 2.])
这个向量是存储在CPU上的,你对它执行的任何操作都是在CPU上执行完成的。而要将其转移到GPU上,你只需要执行以下操作.cuda:
a = torch.FloatTensor([1., 2.]).cuda()
或者,
a = torch.cuda.FloatTensor([1., 2.])
这将为它选择默认设备,该默认设备可通过以下命令查看:
torch.cuda.current_device() #0
或者,你也可以执行以下操作:
a.get_device() #0
你也可以将一个模型发送到GPU设备。例如,考虑一个简单的模块nn.Sequential:
sq = nn.Sequential( nn.Linear(20,20), nn.ReLU(), nn.Linear( 20,4 ),nn.Softmax() )
要将其发送到GPU设备,只需执行以下操作:
model = sq.cuda()
你可以检查它是否在GPU设备上,为此,你必须检查它的参数是否在GPU设备上,例如:
#可以在这里进行讨论: discuss.pytorch.org/t/how-to-check-if-model-is-on-cuda next(model.parameters()).is_cuda # True
你可以为当前应用/存储选择一个GPU,该GPU可以与你上一个应用/存储选择的GPU不同。
正如在第(2)部分中已经看到的那样,我们可以获得所有与cuda兼容的设备及其Id使用pycuda的情况,在此我们就不再赘述了。
考虑到你有3个cuda兼容的设备,你可以初始化和分配tensors到一个特定的设备,就像这样。
cuda0 = torch.device('cuda:0')
cuda1 = torch.device('cuda:1')
cuda2 = torch.device('cuda:2')
# 如果你只使用 'cuda' , 张量/型号将会被发送到默认(当前)设备。(默认值= 0)
x = torch.Tensor([1., 2.], device=cuda1)
# 或者
x = torch.Tensor([1., 2.]).to(cuda1)
# 或者
x = torch.Tensor([1., 2.]).cuda(cuda1)
# 笔记:
# 如果你想改变默认设备,那么请使用:
torch.cuda.set_device(2) # 设备Id为'2'的地方
# 如果你只想使用3个GPU中的2个,那么你必须设置环境变量CUDA_VISIBLE_DEVICES 等于"0,2",如果你只想使用第一个和第三个GPU的话
#现在如果你想要检查有多少个GPU时,它将显示两个(0,1)
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0,2"
当你对这些Tensors 进行任何操作时,无论选择什么设备,都可以执行该操作,结果会和Tensor保存在同一个设备上。
x = torch.Tensor([1., 2.]).to(cuda2) y = torch.Tensor([3., 4.]).to(cuda2) # 这个Tensor(张量)只会保存在'cuda2' 中 z = x + y
如果你有多个GPU,则可以在其中划分应用程序的工作,但是他们之间的通信会带来开销。但是,如果你不需要过多的进行传递信息,那你可以尝试一下。
实际上还有一个问题。在PyTorch中的所有GPU操作中,默认情况下都是异步的。尽管在CPU和GPU或两个GPU之间复制数据时确实进行了必要的同步,但是,如果你在命令torch.cuda.Stream()的帮助下创建自己的数据流,那么你讲不得不处理指令的同步
举一个PyTorch文档中的例子,这是不正确的:
cuda = torch.device('cuda')
s = torch.cuda.Stream() # 创建一个新的数据流.
A = torch.empty((100, 100), device=cuda).normal_(0.0, 1.0)
with torch.cuda.stream(s):
# 因为 sum() 可能会在normal_()结束之前开始执行!
B = torch.sum(A)
如果你想充分利用多个GPU,那么你可以:
在数据并行性中,我们将数据(从数据生成器中获得的一个批次的数据)分割为较小的小型批次的数据,然后将其发送到多个GPU进行并行计算。
在PyTorch中,数据并行中是使用torch.nn.DataParallel实现的
我们将看到一个简单的例子来了解实际情况。为此,我们将必须使用nn.parallel的某些功能:
#将模块复制到设备id中的设备 replicas = nn.parallel.replicate(module, device_ids) #将输入分配到设备id中的设备 inputs = nn.parallel.scatter(input, device_ids) #将模型应用于相应的输入 outputs = nn.parallel.parallel_apply(replicas, inputs) #收集所有设备的结果到output_device result = nn.parallel.gather(outputs, output_device)
或者,只需要简单地:
model = nn.DataParallel(model, device_ids=device_ids) result = model(input)
训练集数据+Val w/数据加载器+SSD中对真实数据的数据扩充
方式1*V100/CUDA 9/CuDNN 74*V100/CUDA 9/CuDNN 7Pytorch27分钟10分钟Keras(TF)38分钟18分钟Tensorflow33分钟22分钟Chainer29分钟8分钟MXNet(Gluon)29分钟10分钟
训练集W/在内存中的综合数据
方式1*V100/CUDA 9/CuDnn 74*V100/CUDA 9 / CuDNN 7Pytorch25分钟8分钟Keras(TF)36分钟15分钟Tensorflow25分钟14分钟Chainer27分钟7分钟MxNet(Gluon)28分钟8分钟
现在,你可以清楚的看到,即使必须在开始和结束时与主设备进行通信,并行处理也绝对是有帮助的。并且仅在多GPU情况下,PyTorch比所有结果提供结果的时间更快仅仅略低于Chainer。Pytorch只需要通过对DataParallel的一次调用,就会使其变得简单。
torch.multiprocessing是Python multiprocessing模块的包装,其API与原始模块100%兼容。因此,你可以在此处使用Python的多处理模块中的Queue',Pipe',Array'等。此外,为了使其更快,他们添加了一个方法,share_memory_()该方法允许数据进入一个状态,任何进程都可以直接使用它,因此将该数据作为参数传递给不同的进程将不会复制该数据。
你可以共享Tensors,模型的parameters,也可以根据需要在CPU或GPU上共享它们。
来自Pytorch的警告:(关于GPU上的共享) CUDA API要求导出到其他进程的分配只要在被其他进程使用时就保持有效。你应该小心并确保你共享的CUDA Tensors在必要时不会超出范围。这对于共享模型参数应该不是问题,但是传递其他类型的数据时应格外小心。请注意,此限制不适用于共享CPU内存。
你可以在此处的“池和进程”部分中使用上面的方法,并且要获得更快的速度,可以使用share_memory_()方法Tensor在所有进程之间共享(例如)而不被复制。
# import torch.multiprocessing as mp def train(model): for data, labels in data_loader: optimizer.zero_grad() loss_fn(model(data), labels).backward() optimizer.step() # 这一步将更新共享参数 model = nn.Sequential(nn.Linear(n_in, n_h1), nn.ReLU(), nn.Linear(n_h1, n_out)) model.share_memory() # 需要 'fork' 方法工作 processes = [] for i in range(4): # No. 的过程 p = mp.Process(target=train, args=(model,)) p.start() processes.append(p) for p in processes: p.join()
下一期我们继续看加快Python计算的另一种方法——Numba~
CDA学员免费下载查看报告全文:2026全球数智化人才指数报告【CDA数据科学研究院】.pdf
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在数字化时代,数据已成为企业决策的核心驱动力,数据分析与数据挖掘作为解锁数据价值的关键手段,广泛应用于互联网、金融、医疗 ...
2026-04-17在数据处理、后端开发、报表生成与自动化脚本中,将 SQL 查询结果转换为字符串是一项高频且实用的操作。无论是拼接多行数据为逗 ...
2026-04-17面对一份上万行的销售明细表,要快速回答“哪个地区卖得最好”“哪款产品增长最快”“不同客户类型的购买力如何”——这些看似复 ...
2026-04-17数据分析师一天的工作,80% 的时间围绕表格结构数据展开。从一张销售明细表到一份完整的分析报告,表格结构数据贯穿始终。但你真 ...
2026-04-16在机器学习无监督学习领域,Kmeans聚类因其原理简洁、计算高效、可扩展性强的优势,成为数据聚类任务中的主流算法,广泛应用于用 ...
2026-04-16在机器学习建模实践中,特征工程是决定模型性能的核心环节之一。面对高维数据集,冗余特征、无关特征不仅会增加模型训练成本、延 ...
2026-04-16在数字化时代,用户是产品的核心资产,用户运营的本质的是通过科学的指标监测、分析与优化,实现“拉新、促活、留存、转化、复购 ...
2026-04-15在企业数字化转型、系统架构设计、数据治理与AI落地过程中,数据模型、本体模型、业务模型是三大核心基础模型,三者相互支撑、各 ...
2026-04-15数据分析师的一天,80%的时间花在表格数据上,但80%的坑也踩在表格数据上。 如果你分不清数值型和文本型的区别,不知道数据从哪 ...
2026-04-15在人工智能与机器学习落地过程中,模型质量直接决定了应用效果的优劣——无论是分类、回归、生成式模型,还是推荐、预测类模型, ...
2026-04-14在Python网络编程、接口测试、爬虫开发等场景中,HTTP请求的发送与响应处理是核心需求。Requests库作为Python生态中最流行的HTTP ...
2026-04-14 很多新人学完Python、SQL,拿到一张Excel表还是不知从何下手。 其实,90%的商业分析问题,都藏在表格的结构里。 ” 引言:为 ...
2026-04-14在回归分析中,因子(即自变量)的筛选是构建高效、可靠回归模型的核心步骤——实际分析场景中,往往存在多个候选因子,其中部分 ...
2026-04-13在机器学习模型开发过程中,过拟合是制约模型泛化能力的核心痛点——模型过度学习训练数据中的噪声与偶然细节,导致在训练集上表 ...
2026-04-13在数据驱动商业升级的今天,商业数据分析已成为企业精细化运营、科学决策的核心手段,而一套规范、高效的商业数据分析总体流程, ...
2026-04-13主讲人简介 张冲,海归统计学硕士,CDA 认证数据分析师,前云南白药集团资深数据分析师,自媒体 Python 讲师,全网课程播放量破 ...
2026-04-13在数据可视化与业务分析中,同比分析是衡量业务发展趋势、识别周期波动的核心手段,其核心逻辑是将当前周期数据与上年同期数据进 ...
2026-04-13在机器学习模型的落地应用中,预测精度并非衡量模型可靠性的唯一标准,不确定性分析同样不可或缺。尤其是在医疗诊断、自动驾驶、 ...
2026-04-10数据本身是沉默的,唯有通过有效的呈现方式,才能让其背后的规律、趋势与价值被看见、被理解、被运用。统计制图(数据可视化)作 ...
2026-04-10在全球化深度发展的今天,跨文化传播已成为连接不同文明、促进多元共生的核心纽带,其研究核心围绕“信息传递、文化解读、意义建 ...
2026-04-09