python - C++在python中内存不足,剩余空间充足

标签 python c++ python-3.x numpy out-of-memory

我正在做一个项目,我需要找到嵌入 vector 的最近邻居。最近,我正在尝试使用 Google 的新 ANN 工具 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')

但是当我尝试使用真实数据集(约 4800 万行,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 可用内存和 1TB 可用磁盘:

enter image description here

我正在运行 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 - C++在python中内存不足,剩余空间充足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65182921/

相关文章:

python - 在 AWS 中运行 Python 脚本的最佳位置在哪里?

c++ - 将模板类作为参数传递给类方法并使用模板类作为 vector 模板类型

c++ - "smart pointer"代码会泄漏内存吗?

python - Django - 没有这样的表 : main. auth_user__old

python - Pytesseract 回溯错误 "file not found"

python - 控制数字是否在 python 中向上或向下舍入

python - 如何查找Python数据框中单元格中第一次出现匹配的行索引(包含日期)

python - 为 Pandas 中的组分配唯一的数字组 ID

python - 如何确定将哪些列设置为 Pandas DataFrame 中的索引?

c++ - 如果表达式的求值需要对引用求值,为什么表达式不是 "core constant expression"?