У меня проблема с выделением огромных массивов в numpy в Ubuntu 18, но не с такой же проблемой в MacOS.
Я пытаюсь выделить память для массива numpy с формой (156816, 36, 53806)
с
np.zeros((156816, 36, 53806), dtype='uint8')
и пока я получаю сообщение об ошибке в ОС Ubuntu
>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
numpy.core._exceptions.MemoryError: Unable to allocate array with shape (156816, 36, 53806) and data type uint8
У меня не получается на MacOS:
>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
array([[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
...,
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]]], dtype=uint8)
Я где-то читал, что на np.zeros
самом деле не следует выделять всю память, необходимую для массива, а только для ненулевых элементов. Несмотря на то, что машина Ubuntu имеет 64 ГБ памяти, в то время как мой MacBook Pro имеет только 16 ГБ.
версии:
Ubuntu
os -> ubuntu mate 18
python -> 3.6.8
numpy -> 1.17.0
mac
os -> 10.14.6
python -> 3.6.4
numpy -> 1.17.0
PS: тоже не удалось на Google Colab
python
numpy
data-science
Мартин Брисиак
источник
источник
top
иfree -m
те команды, где пихают 60 ГБ памяти бесплатно и большеnp.zeros
не создаетsparse
матрицу. Может быть задержка с заполнением нулей. Но увидеть stackoverflow.com/q/27464039Ответы:
Скорее всего, это связано с режимом обработки избыточной нагрузки вашей системы .
В режиме по умолчанию
0
,Точная используемая эвристика здесь недостаточно объяснена, но в Linux она обсуждается больше, чем эвристика фиксации и на этой странице .
Вы можете проверить текущий режим перегрузки, запустив
$ cat /proc/sys/vm/overcommit_memory 0
В этом случае вы выделяете
>>> 156816 * 36 * 53806 / 1024.0**3 282.8939827680588
~ 282 ГБ, и ядро говорит хорошо, очевидно, я не смогу закрепить такое количество физических страниц для этого, и оно отказывается от выделения.
Если (как root) вы запустите:
$ echo 1 > /proc/sys/vm/overcommit_memory
Это включит режим «всегда сверхкоммитировать», и вы обнаружите, что действительно система позволит вам сделать выделение независимо от того, насколько оно велико (по крайней мере, в пределах 64-битной адресации памяти).
Я сам тестировал это на машине с 32 ГБ оперативной памяти. В режиме overcommit у
0
меня тоже естьMemoryError
, но после его возврата1
он работает:>>> import numpy as np >>> a = np.zeros((156816, 36, 53806), dtype='uint8') >>> a.nbytes 303755101056
Затем вы можете продолжить и записать в любое место в массиве, и система будет выделять физические страницы только тогда, когда вы явно пишете на эту страницу. Таким образом, вы можете использовать это с осторожностью для разреженных массивов.
источник
/proc/sys
настройки в вашем дистрибутиве.У меня была такая же проблема с Window, и я нашел это решение. Так что, если кто-то сталкивается с этой проблемой в Windows, решением для меня было увеличение размера файла подкачки , так как для меня это тоже была проблема с перегрузкой памяти.
Windows 8
Windows 10
Примечание: у меня не было достаточно памяти в моей системе для ~ 282 ГБ в этом примере, но для моего конкретного случая это сработало.
РЕДАКТИРОВАТЬ
Из здесь предложенных рекомендаций по размеру файла подкачки:
Некоторые вещи , чтобы иметь в виду , от сюда :
Также:
источник
Я столкнулся с этой проблемой и в Windows. Решением для меня был переход с 32-битной на 64-битную версию Python . Действительно, 32-разрядное программное обеспечение, такое как 32-разрядный процессор, может адресовать максимум 4 ГБ ОЗУ (2 ^ 32). Поэтому, если у вас более 4 ГБ ОЗУ, 32-разрядная версия не сможет воспользоваться ею.
С 64-битной версией Python (той, что обозначена как x86-64 на странице загрузки) проблема исчезла.
Вы можете проверить, какая у вас версия, введя интерпретатор. У меня с 64-битной версией теперь есть:,
Python 3.7.5rc1 (tags/v3.7.5rc1:4082f600a5, Oct 1 2019, 20:28:14) [MSC v.1916 64 bit (AMD64)]
где [MSC v.1916 64 bit (AMD64)] означает «64-битный Python».Примечание : на момент написания этой статьи (май 2020 г.) matplotlib недоступен на python39, поэтому я рекомендую установить python37, 64 бита.
Источники:
Quora - ошибка памяти, вызванная большим массивом numpy
Stackoverflow: 32- или 64-разрядная версия Python
источник
В моем случае добавление атрибута dtype изменило dtype массива на меньший тип (с float64 на uint8), уменьшив размер массива настолько, чтобы не вызывать ошибку MemoryError в Windows (64-разрядная версия).
из
к
mask = np.zeros(edges.shape,dtype='uint8')
источник
Иногда эта ошибка появляется из-за того, что ядро достигло предела. Попробуйте перезапустить ядро, повторите необходимые действия.
источник
изменить тип данных на другой, который использует меньше памяти. Для меня я меняю тип данных на numpy.uint8:
data['label'] = data['label'].astype(np.uint8)
источник