Невозможно выделить массив с формой и типом данных
Я столкнулся с проблемой выделения огромных массивов в 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
Переведено автоматически
Ответ 1
Вероятно, это связано с режимом избыточной обработки в вашей системе.
В режиме по умолчанию, 0
,
Эвристическая обработка избыточных обязательств. Очевидные избыточные обязательства адресного пространства отклоняются. Используется для типичной системы. Это гарантирует сбой при серьезном необузданном распределении, позволяя избыточным обязательствам уменьшить использование подкачки. В этом режиме root может выделять немного больше памяти. Это значение по умолчанию.
Точная используемая эвристика здесь недостаточно хорошо объяснена, но подробнее это обсуждается в Linux через commit evuristic и на этой странице .
Вы можете проверить свой текущий режим избыточной привязки, выполнив
$ 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
Затем вы можете продолжить запись в любое место в массиве, и система будет выделять физические страницы только при явной записи на эту страницу. Таким образом, вы можете использовать это с осторожностью для разреженных массивов.
Ответ 2
У меня была такая же проблема в Window, и я наткнулся на это решение. Итак, если кто-то столкнется с этой проблемой в Windows, решением для меня было увеличить размер файла подкачки, поскольку для меня это тоже была проблема с избыточным объемом памяти.
Windows 8
- На клавиатуре нажмите WindowsKey + X, затем выберите System во всплывающем меню
- Коснитесь или щелкните Дополнительные системные настройки. Вас могут попросить ввести пароль администратора или подтвердить ваш выбор
- На вкладке Дополнительно в разделе Производительность коснитесь или щелкните Настройки.
- Коснитесь или щелкните вкладку Дополнительно, а затем в разделе Виртуальная память коснитесь или щелкните Изменить
- Снимите флажок Автоматически управлять размером файла подкачки для всех дисков.
- В разделе Диск [Метка тома] коснитесь диска, содержащего файл подкачки, который вы хотите изменить
- Коснитесь или щелкните Пользовательский размер, введите новый размер в мегабайтах в поле начальный размер (МБ) или Максимальный размер (МБ), коснитесь или щелкните Установить, а затем коснитесь или нажмите OK
- Перезагрузите систему
Windows 10
- Нажмите клавишу Windows
- Введите SystemPropertiesAdvanced
- Нажмите Запуск от имени администратора
- В разделе Производительность нажмите Настройки
- Выберите вкладку Дополнительно
- Выберите Изменить...
- Снимите флажок Автоматически управлять размером файла подкачки для всех дисков
- Затем выберите пользовательский размер и заполните соответствующий размер
- Нажмите Set, затем нажмите OK, затем выйдите из диалогового окна виртуальной памяти, параметров производительности и системных свойств.
- Перезагрузите систему
Примечание: У меня в системе не хватило памяти на ~ 282 ГБ в этом примере, но для моего конкретного случая это сработало.
Редактировать
Из здесь предложены рекомендации по размеру файла подкачки:
Существует формула для вычисления правильного размера файла подкачки. Начальный размер равен полутора (1,5) кратному объему общей системной памяти. Максимальный размер равен трем (3) кратному исходному размеру. Итак, допустим, у вас есть 4 ГБ (1 ГБ = 1,024 МБ x 4 = 4,096 МБ) памяти. Начальный размер будет 1,5 x 4096 = 6,144 МБ, а максимальный размер будет 3 x 6,144 = 18,432 МБ.
Некоторые вещи, которые следует иметь в виду отсюда:
Однако при этом не учитываются другие важные факторы и системные настройки, которые могут быть уникальными для вашего компьютера. Опять же, позвольте Windows выбирать, что использовать, вместо того, чтобы полагаться на какую-то произвольную формулу, которая работала на другом компьютере.
Также:
Увеличение размера файла подкачки может помочь предотвратить нестабильность и сбои в Windows. Однако время чтения / записи с жесткого диска намного медленнее, чем было бы, если бы данные находились в памяти вашего компьютера. Больший размер файла подкачки добавит дополнительной нагрузки на ваш жесткий диск, в результате чего все остальное будет работать медленнее. Размер файла подкачки следует увеличивать только при возникновении ошибок нехватки памяти и только в качестве временного исправления. Лучшим решением является добавление большего объема памяти на компьютер.
Ответ 3
Я тоже сталкивался с этой проблемой в 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".
Исходники :
Ответ 4
В моем случае добавление атрибута dtype изменило dtype массива на меньший тип (с float64 на uint8), уменьшив размер массива настолько, чтобы не вызывать MemoryError в Windows (64-разрядная версия).
От
mask = np.zeros(edges.shape)
Для
mask = np.zeros(edges.shape,dtype='uint8')