当前位置: 首页 > 面试题库 >

保存到hdf5非常慢(Python冻结)

储仲渊
2023-03-14
问题内容

我正在尝试将瓶颈值保存到新创建的hdf5文件中。瓶颈值成批出现(120,10,10, 2048)。单独保存一个批处理将占用超过16个演出,而python似乎在冻结该批处理。根据最近的发现(请参阅更新,看来hdf5占用大内存是可以的,但是冻结的部分似乎是一个小故障。

我只是想保存前
批用于测试目的,而只保存训练数据集(再一次,这是一次测试运行),但是我什至不能超过第一批。它只会在第一批中停顿,并且不会循环到下一个迭代。如果我尝试检查hdf5,资源管理器将变慢,Python将冻结。如果我尝试杀死Python(即使不检查hdf5文件),Python也无法正确关闭,并会强制重启。

以下是相关的代码和数据:

总数据点约为90,000 ish,分120个批次发布。

Bottleneck shape is (120,10,10,2048)

所以我要保存的第一批是 (120,10,10,2048)

这是我尝试保存数据集的方式:

with h5py.File(hdf5_path, mode='w') as hdf5:
                hdf5.create_dataset("train_bottle", train_shape, np.float32)
                hdf5.create_dataset("train_labels", (len(train.filenames), params['bottle_labels']),np.uint8)
                hdf5.create_dataset("validation_bottle", validation_shape, np.float32)
                hdf5.create_dataset("validation_labels",
                                              (len(valid.filenames),params['bottle_labels']),np.uint8)



 #this first part above works fine

                current_iteration = 0
                print('created_datasets')
                for x, y in train:

                    number_of_examples = len(train.filenames) # number of images
                    prediction = model.predict(x)
                    labels = y
                    print(prediction.shape) # (120,10,10,2048)
                    print(y.shape) # (120, 12)
                    print('start',current_iteration*params['batch_size']) # 0
                    print('end',(current_iteration+1) * params['batch_size']) # 120

                    hdf5["train_bottle"][current_iteration*params['batch_size']: (current_iteration+1) * params['batch_size'],...] = prediction
                    hdf5["train_labels"][current_iteration*params['batch_size']: (current_iteration+1) * params['batch_size'],...] = labels
                    current_iteration += 1
                    print(current_iteration)
                    if current_iteration == 3:
                       break

这是print语句的输出:

(90827, 10, 10, 2048) # print(train_shape)

(6831, 10, 10, 2048)  # print(validation_shape)
created_datasets
(120, 10, 10, 2048)  # print(prediction.shape)
(120, 12)           #label.shape
start 0             #start of batch
end 120             #end of batch

# Just stalls here instead of printing `print(current_iteration)`

它只是在这里停顿了一段时间(超过20分钟),并且hdf5文件的大小缓慢增长(在我强制杀死之前,现在大约有20个演出)。实际上,我什至不能用任务管理器强制终止,在这种情况下,我必须重新启动操作系统才能终止Python。

更新资料

在玩了一段时间我的代码之后,似乎有一个奇怪的错误/行为。

相关部分在这里:

          hdf5["train_bottle"][current_iteration*params['batch_size']: (current_iteration+1) * params['batch_size'],...] = prediction
                hdf5["train_labels"][current_iteration*params['batch_size']: (current_iteration+1) * params['batch_size'],...] = labels

如果我运行这些行中的任何一条,我的脚本将经历迭代,并按预期自动中断。因此,如果我执行“或”操作,则不会冻结。它的发生也相当快-不到一分钟。

如果我运行第一行('train_bottle'),我的内存将占用大约69-72个演出,即使只有几个批处理也是如此。如果我尝试更多批次,则内存是相同的。因此,我假设我是train_bottle
根据分配数据集的大小参数(而不是实际填充时间)决定存储的。因此,尽管有72个演出,但它运行得相当快(一分钟)。

如果我运行第二行,则train_labels我的内存将占用几兆字节。迭代没有问题,并且执行了break语句。

但是,现在这是问题所在,如果我尝试同时运行这两行(在我的情况下这是必需的,因为我需要同时保存“ train_bottle”和“
train_labels”),那么我在第一次迭代时就遇到了冻结,即使经过20分钟也不会继续进行第二次迭代。Hdf5文件正在缓慢增长,但是如果我尝试访问它,则Windows资源管理器的速度将降低为蜗牛,并且我无法关闭Python
-我必须重新启动操作系统。

因此,我不确定在尝试同时运行这两行时是什么问题-好像我在运行内存不足的train_data行一样,如果运行正常并且在一分钟内结束。


问题答案:

将数据写入HDF5

如果您在不指定块形状的情况下写入块数据集,则h5py将自动为您执行此操作。由于h5py无法知道您将如何从数据集中写入或读取数据,因此这通常会导致性能下降。

您还使用默认的1
MB块缓存大小。如果您仅写入块的一部分,而该块不适合缓存(这很可能是1MP块高速缓存大小),则整个块将在内存中读取,修改并写回到磁盘。如果多次发生这种情况,您将看到性能远远超过HDD
/ SSD的顺序IO速度。

在下面的示例中,我假设您仅沿第一个维度进行读取或写入。如果不是这样,则必须根据您的需要进行修改。

import numpy as np
import tables #register blosc
import h5py as h5
import h5py_cache as h5c
import time

batch_size=120
train_shape=(90827, 10, 10, 2048)
hdf5_path='Test.h5'
# As we are writing whole chunks here this isn't realy needed,
# if you forget to set a large enough chunk-cache-size when not writing or reading 
# whole chunks, the performance will be extremely bad. (chunks can only be read or written as a whole)
f = h5c.File(hdf5_path, 'w',chunk_cache_mem_size=1024**2*200) #200 MB cache size
dset_train_bottle = f.create_dataset("train_bottle", shape=train_shape,dtype=np.float32,chunks=(10, 10, 10, 2048),compression=32001,compression_opts=(0, 0, 0, 0, 9, 1, 1), shuffle=False)
prediction=np.array(np.arange(120*10*10*2048),np.float32).reshape(120,10,10,2048)
t1=time.time()
#Testing with 2GB of data
for i in range(20):
    #prediction=np.array(np.arange(120*10*10*2048),np.float32).reshape(120,10,10,2048)
    dset_train_bottle[i*batch_size:(i+1)*batch_size,:,:,:]=prediction

f.close()
print(time.time()-t1)
print("MB/s: " + str(2000/(time.time()-t1)))

编辑 循环中的数据创建花费了很多时间,因此我在时间测量之前创建了数据。

这应至少提供900 MB / s的吞吐量(CPU限制)。使用实际数据和较低的压缩率,您应该轻松达到硬盘的顺序IO速度。

如果您多次错误地调用此块,则使用with语句打开HDF5-File也会导致性能下降。这将关闭并重新打开文件,删除块缓存。



 类似资料:
  • 我正在尝试新的Python Interactive Broker API,但我在第一步遇到了一些严重的速度问题... 下面的代码(见下文)重复了两次 直到数据被接收完毕 直到应用程序完全断开连接。。。 为什么这么慢?最好的加速方法是什么? 我还试图在后台持续运行它,以便只在运行时提交请求 但速度也非常慢。有什么建议吗

  • 我目前正在开发一个智能助手程序(基本上,它只是听用户说什么,然后根据用户说的内容对代码进行处理)。直到今天,当我切换到笔记本电脑时,它一直工作正常。程序不会打印出任何错误,但也不会打印出我说的话。我正在使用Python语音识别库3.8版。1.有人知道这个图书馆的替代品吗?如果是,请尝试解释我将如何“即时”使用它(无需先录制文件,然后将其发送到服务器,更像是实时语音)。 编辑:我忘了在帖子里说,我正

  • 问题内容: 我很想使用BrowserSync进行开发。但是,页面加载(不仅是更改后重新加载)非常慢。 我使用模式。在没有BrowserSync的情况下浏览网页的速度应该很快。 原因之一可能是我安装BrowserSync时出现以下错误: 我从头开始安装节点(使用和软件包安装程序),但无法摆脱错误。 此外,如果使用Gulp或在命令行上运行BrowserSync,也没有什么不同。 任何想法? 问题答案:

  • 我使用的是David Walsh的脚本,它通过IMAP连接到Gmail,并在屏幕上输出电子邮件数据。 我已经运行了两个测试案例: 使用 IMAP 从我自己的域读取电子邮件。 使用 IMAP 从 gmail 读取电子邮件。 读120封邮件的时间差别很大。对于Gmail,整个脚本需要大约5秒,其中1.2秒连接,3.8秒阅读邮件,0.1629秒连接,0.0238秒阅读邮件。 这些价值观与我的预期大相径庭

  • 问题内容: 一些背景信息:我想在Red Hat服务器上运行脚本以从/ dev / random中读取一些数据,并使用Perl unpack()命令将其转换为十六进制字符串,以备后用(基准数据库操作)。我在/ dev / random上运行了一些“ head -1”,它看起来工作得很好,但是多次调用后,它还是会挂起。几分钟后,它将最终输出一小段文本,然后结束。 我切换到/ dev / urandom

  • 问题内容: 这是我用来填写QT Designer中绘制的表格的代码。设计为对任何表通用,它可以正常工作,但是…当我尝试显示包含18列和〜12000行的datasat时,它冻结30秒或更长时间。因此,我做错了什么,有没有办法加快速度,保持代码仍然适合任何表? 那是我的代码: 问题答案: 这里是一个测试脚本,它比较了几种填充表格的方法。 自定义模型要快得多,因为它不必先创建所有项- 但请注意,这是一个