Estoy enfrentando un problema con la asignación de matrices enormes en numpy en Ubuntu 18 mientras no enfrento el mismo problema en MacOS.
Estoy tratando de asignar memoria para una matriz numpy con forma (156816, 36, 53806)
con
np.zeros((156816, 36, 53806), dtype='uint8')
y mientras recibo un error en el sistema operativo 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
No lo obtengo en 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)
Leí en algún lugar que np.zeros
no debería estar asignando toda la memoria necesaria para la matriz, sino solo para los elementos distintos de cero. Aunque la máquina Ubuntu tiene 64 GB de memoria, mientras que mi MacBook Pro solo tiene 16 GB.
versiones:
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
PD: también falló en Google Colab
python
numpy
data-science
Martin Brisiak
fuente
fuente
top
yfree -m
, esos comandos donde empujarnp.zeros
no crea unasparse
matriz. Tal vez haya un retraso en completar los ceros. Pero vea stackoverflow.com/q/27464039Respuestas:
Esto probablemente se deba al modo de manejo de sobreasignación de su sistema .
En el modo predeterminado
0
,La heurística exacta utilizada no se explica bien aquí, pero esto se discute más en Linux sobre la heurística de confirmación y en esta página .
Puede comprobar su modo de sobreasignación actual ejecutando
$ cat /proc/sys/vm/overcommit_memory 0
En este caso estás asignando
>>> 156816 * 36 * 53806 / 1024.0**3 282.8939827680588
~ 282 GB, y el kernel dice que, obviamente, no hay forma de que pueda comprometer tantas páginas físicas en esto, y rechaza la asignación.
Si (como root) ejecuta:
$ echo 1 > /proc/sys/vm/overcommit_memory
Esto habilitará el modo "siempre sobreasignar" y encontrará que, de hecho, el sistema le permitirá realizar la asignación sin importar cuán grande sea (al menos dentro del direccionamiento de memoria de 64 bits).
Lo probé yo mismo en una máquina con 32 GB de RAM. Con el modo de overcommit
0
también obtuve unMemoryError
, pero después de volver a cambiarlo1
funciona:>>> import numpy as np >>> a = np.zeros((156816, 36, 53806), dtype='uint8') >>> a.nbytes 303755101056
Luego puede continuar y escribir en cualquier ubicación dentro de la matriz, y el sistema solo asignará páginas físicas cuando escriba explícitamente en esa página. Por lo tanto, puede usar esto, con cuidado, para matrices dispersas.
fuente
/proc/sys
configuración en su distribución.Tuve este mismo problema en Windows y encontré esta solución. Entonces, si alguien se encuentra con este problema en Windows, la solución para mí fue aumentar el tamaño del archivo de paginación , ya que también era un problema de sobreasignación de memoria para mí.
Windows 8
Windows 10
Nota: No tenía suficiente memoria en mi sistema para los ~ 282GB en este ejemplo, pero para mi caso particular esto funcionó.
EDITAR
A partir de aquí, las recomendaciones sugeridas para el tamaño del archivo de página:
Algunas cosas a tener en cuenta a partir de aquí :
También:
fuente
También encontré este problema en Windows. La solución para mí fue cambiar de una versión de 32 bits a una de 64 bits de Python . De hecho, un software de 32 bits, como una CPU de 32 bits, puede utilizar un máximo de 4 GB de RAM (2 ^ 32). Entonces, si tiene más de 4 GB de RAM, una versión de 32 bits no puede aprovecharlo.
Con una versión de Python de 64 bits (la etiquetada x86-64 en la página de descarga), el problema desapareció.
Puedes comprobar qué versión tienes ingresando al intérprete. Yo, con una versión de 64 bits, ahora tengo:,
Python 3.7.5rc1 (tags/v3.7.5rc1:4082f600a5, Oct 1 2019, 20:28:14) [MSC v.1916 64 bit (AMD64)]
donde [MSC v.1916 64 bits (AMD64)] significa "Python de 64 bits".Nota : en el momento de escribir este artículo (mayo de 2020), matplotlib no está disponible en python39, por lo que recomiendo instalar python37, 64 bits.
Fuentes:
Quora: error de memoria generado por una gran matriz numpy
Stackoverflow: versión de Python de 32 o 64 bits
fuente
En mi caso, agregar un atributo dtype cambió dtype de la matriz a un tipo más pequeño (de float64 a uint8), disminuyendo el tamaño de la matriz lo suficiente como para no lanzar MemoryError en Windows (64 bits).
desde
a
mask = np.zeros(edges.shape,dtype='uint8')
fuente
A veces, este error aparece porque el kernel ha alcanzado su límite. Intente reiniciar el kernel y vuelva a realizar los pasos necesarios.
fuente
cambiar el tipo de datos a otro que utilice menos memoria funciona. Para mí, cambio el tipo de datos a numpy.uint8:
data['label'] = data['label'].astype(np.uint8)
fuente