Mam problem z przydzielaniem ogromnych tablic w Numpy na Ubuntu 18, podczas gdy nie napotykam tego samego problemu na MacOS.
Próbuję przydzielić pamięć dla tablicy numpy z kształtem (156816, 36, 53806)
z
np.zeros((156816, 36, 53806), dtype='uint8')
i gdy otrzymuję błąd w systemie Ubuntu OS
>>> 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
Nie dostaję tego na 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)
Czytałem gdzieś, co np.zeros
nie powinno tak naprawdę przydzielać całej pamięci potrzebnej dla tablicy, ale tylko dla niezerowych elementów. Mimo że maszyna Ubuntu ma 64 GB pamięci, podczas gdy mój MacBook Pro ma tylko 16 GB.
wersje:
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: również nie udało się w Google Colab
python
numpy
data-science
Martin Brisiak
źródło
źródło
top
ifree -m
te polecenia, w których wrzucano 60 GB pamięci za darmo i więcejnp.zeros
nie tworzysparse
macierzy. Może wystąpić opóźnienie w wypełnianiu zer. Ale zobacz stackoverflow.com/q/27464039Odpowiedzi:
Jest to prawdopodobnie spowodowane trybem obsługi overcommit w systemie .
W trybie domyślnym
0
,Dokładna heurystyka nie jest tutaj dobrze wyjaśniona, ale jest to omówione bardziej szczegółowo w Linuksie w porównaniu z heurystyką zatwierdzania i na tej stronie .
Możesz sprawdzić aktualny tryb overcommit, uruchamiając
$ cat /proc/sys/vm/overcommit_memory 0
W tym przypadku przydzielasz
>>> 156816 * 36 * 53806 / 1024.0**3 282.8939827680588
~ 282 GB, a jądro mówi dobrze, oczywiście, że nie ma możliwości, abym był w stanie poświęcić na to tyle fizycznych stron, i odmawia alokacji.
Jeśli (jako root) uruchomisz:
$ echo 1 > /proc/sys/vm/overcommit_memory
Umożliwi to tryb „zawsze overcommit” i przekonasz się, że system rzeczywiście pozwoli ci dokonać alokacji bez względu na to, jak duża jest (przynajmniej w ramach 64-bitowego adresowania pamięci).
Sam to przetestowałem na maszynie z 32 GB RAM-u. Z trybem overcommit
0
również dostałemMemoryError
, ale po zmianie z powrotem na1
to działa:>>> import numpy as np >>> a = np.zeros((156816, 36, 53806), dtype='uint8') >>> a.nbytes 303755101056
Następnie możesz kontynuować zapisywanie w dowolnym miejscu w tablicy, a system przydzieli fizyczne strony tylko wtedy, gdy jawnie zapiszesz na tej stronie. Możesz więc ostrożnie używać tego do rzadkich tablic.
źródło
/proc/sys
ustawienia w swojej dystrybucji.Miałem ten sam problem na Windowsie i natknąłem się na to rozwiązanie. Więc jeśli ktoś napotka ten problem w systemie Windows, rozwiązaniem dla mnie było zwiększenie rozmiaru pliku stronicowania , ponieważ dla mnie był to również problem z nadmiernym zaangażowaniem pamięci.
Windows 8
Windows 10
Uwaga: w moim systemie nie było wystarczającej ilości pamięci dla ~ 282 GB w tym przykładzie, ale w moim konkretnym przypadku zadziałało.
EDYTOWAĆ
Od tutaj sugerowane zalecenia dotyczące rozmiaru pliku strony:
Niektóre rzeczy, aby pamiętać, ze tutaj :
Również:
źródło
MemoryError: Unable to allocate 10.3 PiB for an array with shape (38137754, 38137754) and data type float64
Natknąłem się na ten problem również w systemie Windows. Rozwiązaniem dla mnie było przejście z 32-bitowej na 64-bitową wersję Pythona . Rzeczywiście, oprogramowanie 32-bitowe, podobnie jak 32-bitowy procesor, może adresować maksymalnie 4 GB pamięci RAM (2 ^ 32). Jeśli więc masz więcej niż 4 GB pamięci RAM, wersja 32-bitowa nie może z tego skorzystać.
W przypadku 64-bitowej wersji Pythona (tej oznaczonej x86-64 na stronie pobierania) problem zniknął.
Możesz sprawdzić, którą wersję posiadasz, wpisując tłumacza. Ja, w wersji 64-bitowej, mam teraz
Python 3.7.5rc1 (tags/v3.7.5rc1:4082f600a5, Oct 1 2019, 20:28:14) [MSC v.1916 64 bit (AMD64)]
:, gdzie [MSC v.1916 64-bitowy (AMD64)] oznacza „64-bitowy Python”.Uwaga : w chwili pisania tego tekstu (maj 2020 r.) Matplotlib nie jest dostępne na pythonie39, więc zalecam zainstalowanie pythona37 w wersji 64-bitowej.
Źródła:
Quora - błąd pamięci generowany przez dużą tablicę numpy
Stackoverflow: 32- lub 64-bitowa wersja Pythona
źródło
W moim przypadku dodanie atrybutu dtype zmieniło dtype tablicy na mniejszy typ (z float64 na uint8), zmniejszając rozmiar tablicy na tyle, aby nie zgłaszać MemoryError w systemie Windows (64 bit).
od
do
mask = np.zeros(edges.shape,dtype='uint8')
źródło
Czasami ten błąd pojawia się, ponieważ jądro osiągnęło swój limit. Spróbuj ponownie uruchomić jądro, powtórz niezbędne kroki.
źródło
zmienić typ danych na inny, który zużywa mniej pamięci. U mnie zmieniam typ danych na numpy.uint8:
data['label'] = data['label'].astype(np.uint8)
źródło