Невозможно выделить массив с формой и типом данных
Я столкнулся с проблемой выделения огромных массивов в 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
Я где-то читал, что np.zeros на самом деле не следует выделять всю память, необходимую для массива, а только для ненулевых элементов. Несмотря на то, что на компьютере Ubuntu установлено 64 ГБ памяти, в то время как на моем MacBook Pro - только 16 ГБ.
Эвристическая обработка избыточных обязательств. Очевидные избыточные обязательства адресного пространства отклоняются. Используется для типичной системы. Это гарантирует сбой при серьезном необузданном распределении, позволяя избыточным обязательствам уменьшить использование подкачки. В этом режиме root может выделять немного больше памяти. Это значение по умолчанию.
~ 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".
В моем случае добавление атрибута dtype изменило dtype массива на меньший тип (с float64 на uint8), уменьшив размер массива настолько, чтобы не вызывать MemoryError в Windows (64-разрядная версия).