gpt4 book ai didi

python - 高效的HDF5/PyTables布局,可在大张量上保存和操作

转载 作者:行者123 更新时间:2023-12-02 09:47:23 28 4
gpt4 key购买 nike

我试图为我的用例(一个研究项目)找出最佳的数据布局。这不是我的专长,因此尽管我可以清楚地说出我想要的东西,以及我认为可行的东西,但我还是试图避开失败之路。

现在,假设原始数据类似于几个大文本集,它们被分成多个序列(例如句子),每个序列都包含多个标记(例如单词)。我以句子为基础提取,处理和保存信息,但在随后的分析中需要对其进行不同的操作。
具体来说,每个句子中的每个标记都与一个大的 vector (可以是数字的)相关联,该 vector 由许多已经实现的操作准备。每个序列都与一些元数据相关联。该操作以及由此数据的准备仅发生一次。

因此:初始操作的输出是三维张量D [x,y,z]加上与x维相关的元数据。 x维表示序列,y维表示序列中的 token 位置(但不是唯一 token id,例如单词编码,它是序列元数据的一部分),而z是信息的列(成千上万)为了那个 token 。因此,每个序列与作为行的 token 矩阵和作为列的信息矩阵关联。如果需要,可以使元数据适合第一行。请注意,每个序列的长度相同。

Sequence 1
Meta-data: [..]
Column 1 | Column 2 | ...
Token 1 | [...] | [...] | ...
Token 2 | [...] | [...] | ...
...
Token N | [...] | [...] | ...

Sequence 2
Meta-data: [..]
Column 1 | Column 2 | ...
Token 1 | [...] | [...] | ...
Token 2 | [...] | [...] | ...
...
Token N | [...] | [...] | ...

通过不同的后续分析,该数据被多次摄取。因此,我需要此数据的不同“ View ”,如下所示:
  • 我需要能够查询每个序列并获得token-> values的完整矩阵。那就是输出3D张量,我沿第一个维度查询。能够一次“ slice ”多个序列(例如ML模型的随机批次等)会很好。
  • 我需要能够通过唯一的 token ID(例如单词“hello”)进行查询,请注意每个 token 可能会以几种顺序出现在不同的位置。这不是对张量维度的查询,而是查询将唯一 token ID映射到其在序列中位置的数据(或每个序列中允许此类查询的元数据)。
  • 我最终为每个序列的每个标记生成并保存进一步的摘要值,我试图极快地查询,其中该序列中的其他信息无关紧要。

  • 所有后续建模的共同点是
  • 在后续分析中,我需要尽可能多的RAM,换句话说,数据可能会或可能不需要推送到磁盘。这就是为什么我要寻找一种既允许内存访问又允许内存访问的解决方案。特别是,整个张量可能根本不适合内存(随后在x维度上建立)
  • 在给定的固定结构下,索引和 slice 相对简单,但是我可能经常需要选择不相邻的条目,例如从无关序列中选择标记。
  • 整个过程不应成为后续分析的瓶颈。如果它有些可移植并且不需要其他软件,那么结果也将是有益的,以便其他研究人员可以轻松分发和复制结果。实际上,如果可能(合法),我想将此数据提供下载
  • 由于这是输入,因此我主要对从python或其他语言访问这些数据的速度感兴趣。

  • 基于此,我暂时决定使用h5py或pyTables,但是我愿意接受其他选择。

    尽管数据很大,但并不是很大(在中等大小的服务器上)磁盘空间是个问题。我进一步迭代每个序列至少一次以执行初始操作。因此,我计划将每个所需的“ View ”保存到单独的数据集中,每个数据集的布局均可实现有效访问。

    我的计划如下:
  • 我将输出张量保存为pyTables中的多维数组。索引维将是序列号。我可能会查询几个序列,但总是摄取整个序列的2D表。我希望pyTables允许我将整个3D张量保留在磁盘上,并且仅将所需的数据读取到RAM中。
  • 我将保存一个新的数据集,该数据集具有唯一的 token ID作为索引,具有序列ID作为第二列,然后具有所需的信息作为数组。这样,我可以通过 token ID查询并获取所有序列中关联的所有数据。这包括很多重复,但是应该允许快速查询(?)
  • 最后,我将为每个序列的每个 token ID(作为索引)使用关联的摘要数据创建一个较小的数据集。

  • 您认为在计算时间方面会很有效吗?

    我看到的另一条路线是关系数据库,例如SQL。在这里,我可以简单地为序列中的每个实际单词输入条目,并带有相关的 token ID,序列号和所需的数据。然后可以使用SQL查询以我选择的任何方式获取数据。此外,任何元数据都可以按顺序或 token 保存在其他表中,而没有太多限制。

    但是,我不确定这是否是最快的选择,因为我不需要SQL提供的许多功能,例如额外的灵活性(我的查询/ View 是固定的,而索引/ slice 始终是固定的)或所有访问保护等等。另外,如果只是一些数据集文件,则可移植性会更好。

    我也不确定SQL如何处理内存中和内存外的问题。在某些情况下,我的大部分数据实际上都可以放入RAM,因此我也希望在其中具有灵活性。

    问题:
  • 您认为最佳方法是什么?我的计划健全吗?
  • SQL似乎显然更灵活,它是否甚至更快?
  • 在HDF5中,我尚不了解的是分块和分组如何参与其中。似乎我无法真正对数据进行分块,因为我需要能够高频查询非成功数据。在我的用例中,我不应该分块吗?
  • 同样,组和链接。我的数据结构不像一棵树,因为每个 token 可能以许多顺序出现,这就是为什么我选择只产生完全不同的数据集的原因。尝试使用硬链接(hard link)或组会更有效吗?
  • HDF5的内存模型将如何工作(以python实现)?我可以查询3D张量,并且仅将结果保存在内存中,还可以为经常查询的序列或 token 提供缓存吗?

  • 如果我的描述不清楚,请告诉我。感谢您抽出宝贵的时间阅读所有这些内容。

    最佳答案

    对于遇到这个问题的任何人,让我给您结果。

    上面使用pyTables可以正常工作。它可以做得相当快。但是,逻辑会迅速生成幽默程度极高的文件,因此我只能建议您找到其他方法。尤其是,磁盘空间比RAM的使用更具问题,尤其是可以稀疏的事物。

    定制的将数据子集到内存的解决方案比使用pyTables分块更为成功。因此,实际上,在几乎所有情况下,上述都不是一个好主意。

    关于python - 高效的HDF5/PyTables布局,可在大张量上保存和操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58455134/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com