我正在做一个项目,在这个项目中,我需要找到am嵌入向量的最近邻居。最近,我尝试使用谷歌的新的人工神经网络工具SCANN github。我能够使用以下代码为一个小数据集(大约200K行,512个值)创建搜索器对象并对其进行序列化
import numpy as np
import scann
data = np.random.random((200k,512))
data = data / np.linalg.norm(data, axis=1)[:, np.newaxis]
searcher = scann.scann_ops_pybind.builder(data, 10, "dot_product").tree(
num_leaves=2000, num_leaves_to_search=100, training_sample_size=250000).score_ah(
2, anisotropic_quantization_threshold=0.2).reorder(100).build()
searcher.serialize('./scann')但是当我尝试使用真实的数据集(大约48M行,512个值)时,我得到了:
In [11]: searcher.serialize('scann/')
---------------------------------------------------------------------------
MemoryError Traceback (most recent call last)
<ipython-input-11-71a5ef71c81f> in <module>
----> 1 searcher.serialize('scann/')
~/.local/lib/python3.6/site-packages/scann/scann_ops/py/scann_ops_pybind.py in serialize(self, artifacts_dir)
70
71 def serialize(self, artifacts_dir):
---> 72 self.searcher.serialize(artifacts_dir)
73
74
MemoryError: std::bad_alloc数据集的.npy文件大小约为90 1TB,我的计算机上至少还有500 1TB的空闲内存和1TB的空闲磁盘:

我运行的是Ubuntu 18.04.5 LTS和Python 3.6.9。Scann模块随Pip一起安装。
你知道会发生什么吗?
谢谢你的帮助
在@MSalters注释之后编辑,我做了一些测试,发现如果要序列化的dataset超过16777220字节(2^24+4),就会失败,并显示bad_alloc消息。我还是不知道为什么会发生这种事。
edit2我从源代码中构建了扫描,并在其中放置了一些调试打印。错误似乎在这一行上:
vector<uint8_t> storage(hash_dim * expected_size);如果我像这样打印它:
std::cout << hash_dim << " " << expected_size <<"\n" << std::flush;
std::cout << hash_dim * expected_size <<"\n" << std::flush;
vector<uint8_t> v2;
std::cout << v2.max_size() << "\n" << std::flush;
vector<uint8_t> storage(hash_dim * expected_size);
std::cout << "after storage creation\n" << std::flush;然后我得到了;
256 8388608
-2147483648
9223372036854775807发布于 2020-12-08 21:59:32
在ScaNN、#427中似乎有一个具有类似错误的现有问题报告。
根据std::cout << hash_dim * expected_size的-2147483648输出,我们可以得出hash_dim * expected_size溢出的结论。
看一下源代码,我们看到hash_dim和expected_size的类型都是int。
因此,可能其中至少有一种类型应该是int64_t、long long,或者更好的是size_t。
通过查看ScaNN的源代码,似乎有更多的地方可以从专门设计用于保存大小(size_t)而不是int的数据类型中受益。
https://stackoverflow.com/questions/65182921
复制相似问题