我正在做一个项目,我需要找到嵌入 vector 的最近邻。最近,我正在尝试使用谷歌新的人工神经网络工具 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
的大小数据集的文件约为 90GB,我的计算机上至少有 500GB 的可用 RAM 和 1TB 的可用磁盘:
我正在运行 Ubuntu 18.04.5 LTS 和 Python 3.6.9。 Scann 模块是用 Pip 安装的。
对可能发生的事情有任何想法吗?
谢谢您的帮助
[编辑] 在@MSalters 发表评论后,我做了一些测试,发现如果要序列化的数据集超过 16777220 字节 (2^24+4),它会失败并显示
bad_alloc
信息。我仍然不知道为什么会发生这种情况......[edit2] 我从源代码构建 SCANN,并在其中放置一些调试打印。错误似乎在这一行:
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
最佳答案
ScaNN 中似乎存在一个问题报告,#427 ,有类似的错误。
基于 的输出-2147483648
对于 std::cout << hash_dim * expected_size
我们可以得出结论 hash_dim * expected_size
溢出。
查看源代码,我们看到 hash_dim
的类型和 expected_size
是 int
.
所以可能至少其中一个的类型应该是 int64_t
, long long
或者,更好的是,size_t
.
通过查看 ScaNN 的来源,似乎有更多的地方可以受益于专门设计用于保持大小 (size_t
) 而不是 int
的数据类型。 .
关于python - python中的C++内存不足,剩余空间很大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65182921/