Parâmetro scikit-learn n_jobs sobre uso e memória da CPU

11

Na maioria dos estimadores no scikit-learn, há um n_jobsparâmetro em fit/ predictmethods para criar trabalhos paralelos usando joblib. Notei que configurá-lo para -1criar apenas 1 processo Python e maximizar os núcleos, fazendo com que o uso da CPU atinja 2500% no topo. Isso é bem diferente de configurá-lo para um número inteiro positivo> 1, que cria vários processos Python com ~ 100% de uso.

Como essa configuração afeta o uso da CPU e do núcleo em um servidor Linux com várias CPUs? (por exemplo, se n_jobs=8há 8 CPUs totalmente bloqueadas ou as CPUs ainda reservam alguns núcleos para outras tarefas / processos?)

Além disso, recebo MemoryErrorocasionalmente ao definir n_jobs=-1grandes conjuntos de dados. No entanto, o uso de memória geralmente oscila entre 30 e 40% para o único processo Python. Como os dados e a memória estão sendo gerenciados / copiados, dependendo do valor de n_jobs?

Snympi
fonte
11
Lembre-se também de que você pode configurá-lo como -2, que utilizará todos os núcleos disponíveis, exceto um, deixando a máquina pelo menos um pouco funcionando. Muito correto que problemas de memória geralmente começam a morder para muitos núcleos, especialmente se os conjuntos de dados grandes
Ken Syme

Respostas:

4

Eu posso imaginar que um valor -1consome todos os recursos disponíveis quando e quando eles se tornam disponíveis. Dependendo de qual função você está falando, parece que os dados são copiados para cada um dos trabalhos, o que pode levar a problemas de memória se o conjunto de dados for grande o suficiente. Aqui está um trecho de informação da documentação do GridSearchCV :

If `n_jobs` was set to a value higher than one, the data is copied for each
point in the grid (and not `n_jobs` times). This is done for efficiency
reasons if individual jobs take very little time, but may raise errors if
the dataset is large and not enough memory is available.  A workaround in
this case is to set `pre_dispatch`. Then, the memory is copied only
`pre_dispatch` many times. A reasonable value for `pre_dispatch` is `2 *
n_jobs`.

Portanto, pode ser uma boa ideia usar pre_dispatchum limite superior ao consumo de memória.

Caso contrário, por que você está configurando isso -1? Você deve configurá-lo apenas para o número de núcleos físicos em sua máquina, ou talvez 2 vezes esse número, se a tarefa puder ser multiencadeada.

EDITAR:

Parece que a configuração n_jobs=-1apenas seleciona todos os núcleos físicos e maximiza seu uso. Dê uma olhada nos comentários nesta resposta no StackOverflow .

Se você não configurou pre_dispatch, é claro que tentará copiar muito. É por isso que você fica sem memória. Se você possui 4 núcleos, haverá, por padrão, 8 cópias do conjunto de dados feitas (conforme descrito acima na citação).

Aqui está outro tópico , que parece mais com o lado do desempenho

n1k31t4
fonte
11
portanto, usamos pre_dispatch para limitar as cópias dos dados, mas por que definir como -1 há um problema de memória?
11
@sweetyBaby - veja os links adicionados. A configuração n_jobs = -1não levará em consideração a memória, apenas o número de núcleos na CPU, o que pode, naturalmente, levar a problemas de memória.
N1k31t4