O Jupyter Lab congela o computador quando está sem RAM - como evitá-lo?


12

Recentemente, comecei a usar o Jupyter Lab e meu problema é que trabalho com conjuntos de dados muito grandes (geralmente o conjunto de dados em si é de aproximadamente 1/4 da RAM do computador). Após algumas transformações, salvas como novos objetos Python, tendem a ficar sem memória. O problema é que, quando estou aproximando o limite de RAM disponível e realizando qualquer operação que precise de outro espaço de RAM, meu computador congela e a única maneira de corrigi-lo é reiniciá-lo. Esse é um comportamento padrão no Jupyter Lab / Notebook ou são algumas configurações que devo definir? Normalmente, eu esperaria que o programa travasse (como no RStudio, por exemplo), não todo o computador


Eu tive o mesmo problema antes, é realmente desagradável. Dei uma olhada rápida nos problemas de bobagem e não encontrei nada. Isso acontece também se você executar o console do IPython (não o python simples)?
Bzazz 22/10/19

Qual pacote / módulo você usou? Qual sistema operacional é esse? Você trocou? Qual versão do Jupyter Lab? Se fosse Linux, qual a versão do kernel?
Nizam Mohamed

É principalmente Pandas, mas não acho que seja relacionado a pacotes. O sistema operacional é o Ubuntu 16.04.6 LTS e a versão do kernel é 4.15.0-65-genérica. A versão do Jupyter Lab é 1.0.2. Eu tenho um SWAP definido para 12 GB (atribuído a 2 arquivos), que é 1,5 da minha RAM.
Jakes

Respostas:


5

Absolutamente a solução mais robusta para esse problema seria usar contêineres Docker. Você pode especificar quanta memória alocar para o Jupyter e, se o contêiner ficar sem memória, isso simplesmente não será um grande problema (lembre-se de salvar com frequência, mas isso não é necessário dizer).

Este blog o levará a maior parte do caminho até lá. Há também algumas instruções decentes sobre como configurar o Jupyter Lab a partir de uma das imagens Jupyter disponíveis gratuitamente e mantidas oficialmente aqui:

https://medium.com/fundbox-engineering/overview-d3759e83969c

e, em seguida, você pode modificar o docker runcomando conforme descrito no tutorial como (por exemplo, para 3 GB):

docker run --memory 3g <other docker run args from tutorial here>

Para sintaxe nas opções de memória do docker, consulte esta pergunta:

Que unidade a janela de encaixe executa a opção "--memory"?


4

Se você estiver usando o Ubuntu, confira os OOM killers, você pode obter informações aqui

Você pode usar o earlyoom . Ele pode ser configurado como você deseja, por exemplo earlyoom -s 90 -m 15, iniciará earlyoome quando o tamanho da troca for menor que% 90 e a memória for menor que% 15, interromperá o processo que causa o OOM e impedirá o congelamento de todo o sistema. Você também pode configurar a prioridade dos processos.


2

Também trabalho com conjuntos de dados muito grandes (3 GB) no Jupyter Lab e estou enfrentando o mesmo problema no Labs. Não está claro se você precisa manter o acesso aos dados pré-transformados; caso contrário, comecei a usar delvariáveis ​​de dataframe grandes não utilizadas, se não precisar delas. delremove variáveis ​​da sua memória. Editar **: existem várias possibilidades para o problema que estou encontrando. Encontro isso com mais frequência quando estou usando uma instância jupyter remota e no spyder também quando estou realizando grandes transformações.

por exemplo

df = pd.read('some_giant_dataframe') # or whatever your import is
new_df = my_transform(df)
del df # if unneeded.

Jakes, você também pode achar útil esse encadeamento em grandes fluxos de trabalho de dados . Estive pesquisando no Dask para ajudar no armazenamento de memória.

Percebi no spyder e no jupyter que o congelamento geralmente acontece quando se trabalha em outro console enquanto um grande console de memória é executado. Quanto ao porquê de apenas congelar em vez de travar, acho que isso tem algo a ver com o kernel. Existem alguns problemas de memória em aberto no github IPython - # 10082 e # 10117 parecem mais relevantes. Um usuário aqui sugere desativar a conclusão da guia jediou atualizar o jedi.

Em 10117, eles propõem verificar a saída de get_ipython().history_manager.db_log_output. Tenho os mesmos problemas e minha configuração está correta, mas vale a pena conferir


1

Você também pode usar notebooks na nuvem também, como o Google Colab aqui . Eles forneceram facilidade para as RAMs recomendadas e o suporte ao notebook Jupyter é por padrão.


0

Eu acho que você deveria usar pedaços. Curtiu isso:

df_chunk = pd.read_csv(r'../input/data.csv', chunksize=1000000)
chunk_list = []  # append each chunk df here 

# Each chunk is in df format
for chunk in df_chunk:  
    # perform data filtering 
    chunk_filter = chunk_preprocessing(chunk)

    # Once the data filtering is done, append the chunk to list
    chunk_list.append(chunk_filter)

# concat the list into dataframe 
df_concat = pd.concat(chunk_list)

Para obter mais informações, consulte: https://towardsdatascience.com/why-and-how-to-use-pandas-with-large-data-9594dda2ea4c

Sugiro que não acrescente uma lista novamente (provavelmente a RAM será sobrecarregada novamente). Você deve terminar seu trabalho nesse loop for.


Eu acho que o problema aqui não é como não ficar sem memória, mas como evitar o computador travando e precisando reiniciar. O Python deve travar ou gerar um erro de memória, mas não estragar tudo.
Bzazz 22/10/19

0

Vou resumir as respostas da pergunta a seguir . Você pode limitar o uso de memória do seu programa. A seguir, esta será a função ram_intense_foo(). Antes de chamar que você precisa chamar a funçãolimit_memory(10)

import resource
import platform
import sys
import numpy as np 

def memory_limit(percent_of_free):
    soft, hard = resource.getrlimit(resource.RLIMIT_AS)
    resource.setrlimit(resource.RLIMIT_AS, (get_memory() * 1024 * percent_of_free / 100, hard))

def get_memory():
    with open('/proc/meminfo', 'r') as mem:
        free_memory = 0
        for i in mem:
            sline = i.split()
            if str(sline[0]) == 'MemAvailable:':
                free_memory = int(sline[1])
                break
    return free_memory

def ram_intense_foo(a,b):
    A = np.random.rand(a,b)
    return A.T@A

if __name__ == '__main__':
    memory_limit(95)
    try:
        temp = ram_intense_foo(4000,10000)
        print(temp.shape)
    except MemoryError:
        sys.stderr.write('\n\nERROR: Memory Exception\n')
        sys.exit(1)

-4

Não há motivo para exibir toda a saída de um grande quadro de dados. Visualizar ou manipular grandes quadros de dados utilizará desnecessariamente grandes quantidades de recursos do seu computador.

Tudo o que você está fazendo pode ser feito em miniatura. É muito mais fácil trabalhar na codificação e manipulação de dados quando o quadro de dados é pequeno. A melhor maneira de trabalhar com big data é criar um novo quadro de dados que leve apenas uma pequena parte ou uma pequena amostra do quadro de dados grande. Depois, você pode explorar os dados e fazer sua codificação no quadro de dados menor. Depois de explorar os dados e colocar seu código funcionando, basta usar esse código no quadro de dados maior.

A maneira mais fácil é simplesmente pegar o primeiro n, número das primeiras linhas do quadro de dados usando a função head (). A função head imprime apenas n, número de linhas. Você pode criar um mini quadro de dados usando a função de cabeçalho no quadro de dados grande. Abaixo, escolhi selecionar as primeiras 50 linhas e passar seu valor para small_df. Isso pressupõe que o BigData é um arquivo de dados que vem de uma biblioteca que você abriu para este projeto.

library(namedPackage) 

df <- data.frame(BigData)                #  Assign big data to df
small_df <- head(df, 50)         #  Assign the first 50 rows to small_df

Isso funcionará na maioria das vezes, mas às vezes o quadro de big data vem com variáveis ​​pré-classificadas ou com variáveis ​​já agrupadas. Se o big data for assim, você precisará coletar uma amostra aleatória das linhas do big data. Em seguida, use o código a seguir:

df <- data.frame(BigData)

set.seed(1016)                                          # set your own seed

df_small <- df[sample(nrow(df),replace=F,size=.03*nrow(df)),]     # samples 3% rows
df_small                                                         # much smaller df
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.