Istanze vs. core quando si utilizza EC2


12

Lavorando su quelli che spesso si potrebbero definire progetti di "dati medi", sono stato in grado di parallelizzare il mio codice (principalmente per la modellazione e la previsione in Python) su un singolo sistema attraverso un numero di core compreso tra 4 e 32. Ora sto cercando di passare ai cluster su EC2 (probabilmente con StarCluster / IPython, ma aperto anche ad altri suggerimenti), e sono rimasto perplesso su come conciliare la distribuzione del lavoro tra i core su un'istanza rispetto alle istanze su un cluster.

È anche pratico parallelizzare tra le istanze e tra i core di ciascuna istanza? Se è così, qualcuno può dare una rapida carrellata dei pro + contro dell'esecuzione di molti casi con pochi core ciascuno rispetto a pochi casi con molti core? Esiste una regola empirica per scegliere il giusto rapporto tra istanze e core per istanza?

La larghezza di banda e la RAM sono preoccupazioni non banali nei miei progetti, ma è facile individuare quando si tratta di colli di bottiglia e riaggiustamenti. Immagino che sia molto più difficile paragonare il giusto mix di core alle istanze senza ripetuti test, e i miei progetti variano troppo per ogni singolo test da applicare a tutte le circostanze. Grazie in anticipo, e se non sono riuscito a cercarlo correttamente su Google, sentiti libero di indicarmi la risposta giusta da qualche altra parte!

Risposte:


11

Quando si utilizza IPython, quasi non ci si deve preoccupare (a scapito di una perdita di efficienza / maggiore sovraccarico di comunicazione). Il plug-in IPython parallelo in StarCluster avvierà di default un motore per core fisico su ciascun nodo (credo che sia configurabile ma non so dove). Basta eseguire tutto ciò che si desidera su tutti i motori utilizzando l'API DirectView (map_sync, apply_sync, ...) o i comandi magici% px. Se stai già utilizzando IPython in parallelo su una macchina, usarlo su un cluster non è diverso.

Rispondere ad alcune delle vostre domande specifiche:

"come conciliare la distribuzione del lavoro tra core su un'istanza rispetto a istanze su un cluster" - Ottieni un motore per core (almeno); il lavoro viene distribuito automaticamente su tutti i core e su tutte le istanze.

"È persino pratico parallelizzare tra le istanze e tra i core di ciascuna istanza?" - Sì :) Se il codice che stai eseguendo è imbarazzantemente parallelo (esatto stesso algo su più set di dati), puoi principalmente ignorare dove è in esecuzione un determinato motore. Se il core richiede molta comunicazione tra i motori, ovviamente è necessario strutturarlo in modo tale che i motori comunichino principalmente con altri motori sulla stessa macchina fisica; ma quel tipo di problema non è l'ideale per IPython, credo.

"Se è così, qualcuno può dare una rapida panoramica dei pro + contro di eseguire molti casi con pochi core ciascuno rispetto a pochi casi con molti core? Esiste una regola empirica per scegliere il giusto rapporto tra istanze e core per istanza? " - Utilizzare le istanze c3 più grandi per i problemi legati al calcolo e il più piccolo per i problemi legati alla larghezza di banda della memoria; per problemi legati al passaggio di messaggi, utilizzare anche le istanze più grandi ma provare a partizionare il problema in modo che ogni partizione venga eseguita su un computer fisico e la maggior parte del passaggio dei messaggi si trovi all'interno della stessa partizione. I problemi che sarebbero notevolmente più lenti su istanze N quadruple c3 rispetto a 2N double c3 sono rari (un esempio artificiale potrebbe essere l'esecuzione di più filtri semplici su un gran numero di immagini, in cui si passano tutte le immagini per ciascun filtro anziché tutti i filtri per il stessa immagine).


1
Penso che dovresti notare che per i processi su una singola macchina puoi memorizzare le variabili della mappa con joblib / Numpy. Perdi quella capacità per i processi su macchine diverse.
Gallamina,

11

Una regola empirica generale è quella di non distribuire fino a quando non è necessario. Di solito è più efficiente avere N server di una determinata capacità rispetto a 2N server della metà di quella capacità. La maggior parte dell'accesso ai dati sarà locale e quindi veloce nella memoria rispetto a quella lenta attraverso la rete.

A un certo punto, il ridimensionamento di una macchina diventa antieconomico perché il costo di risorse aggiuntive si ridimensiona più che linearmente. Tuttavia, questo punto è ancora incredibilmente alto.

In particolare, su Amazon, l'economia di ciascun tipo di istanza può variare molto se si utilizzano istanze di mercato spot. Il prezzo predefinito più o meno significa che la stessa quantità di risorse costa più o meno la stessa indipendentemente dal tipo di istanza, che può variare molto; le istanze di grandi dimensioni possono essere più economiche di quelle di piccole dimensioni oppure N istanze di piccole dimensioni possono essere molto più economiche di una macchina di grandi dimensioni con risorse equivalenti.

Una grande considerazione qui è che il paradigma di calcolo può cambiare molto quando si passa da una macchina a più macchine. I compromessi che le spese generali di comunicazione inducono potrebbero costringerti, ad esempio, ad adottare un paradigma parallelo ai dati per ridimensionarlo. Ciò significa una diversa scelta di strumenti e algoritmo. Ad esempio, SGD sembra abbastanza diverso in memoria e in Python rispetto a MapReduce. Quindi dovresti considerare questo prima di parallelizzare.

Puoi scegliere di distribuire il lavoro su un cluster, anche se un singolo nodo e paradigmi non distribuiti funzionano per te, per affidabilità. Se un singolo nodo fallisce, perdi tutto il calcolo; un calcolo distribuito può potenzialmente recuperare e completare solo la parte del calcolo persa.


6

Tutto considerato uguale (costo, CPU perf, ecc.) Potresti scegliere l'istanza più piccola in grado di contenere tutti i miei set di dati in memoria e ridimensionarli. Quel modo

  • ti assicuri di non indurre latenze inutili dovute alle comunicazioni di rete e
  • tendi a massimizzare la larghezza di banda di memoria disponibile complessiva per i tuoi processi.

Supponendo che tu stia eseguendo una sorta di schema di convalida incrociata per ottimizzare alcuni meta-parametri del tuo modello, assegna a ciascun core un valore da testare e scegli molte istanze in base alle necessità per coprire tutto lo spazio dei parametri in tutti i round che ritieni più adatti.

Se i tuoi dati non si adattano alla memoria di un sistema, ovviamente dovrai distribuirli su più istanze. Quindi si tratta di bilanciare la latenza di memoria (meglio con molte istanze) con la latenza di rete (meglio con un minor numero di istanze) ma, data la natura di EC2, scommetto che spesso preferirai lavorare con poche istanze complesse.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.