Questo post è stato scritto in collaborazione con Tomer Berkovich, Yitzhak LeviE Max Rabin.
La selezione appropriata delle istanze per i carichi di lavoro di machine learning (ML) è una decisione importante con implicazioni potenzialmente significative sulla velocità e sui costi di sviluppo. In un messaggio precedente abbiamo ampliato questo processo, proposto una metrica per prendere questa importante decisione e evidenziato alcuni dei numerosi fattori da prendere in considerazione. In questo post dimostreremo l’opportunità di ridurre i costi di formazione del modello AI adottando Istanza spot disponibilità in considerazione quando si prende una decisione sulla selezione dell’istanza basata su cloud.
Una delle opportunità più significative per risparmiare sui costi nel cloud è sfruttare il basso costo Istanze Spot di Amazon EC2. Le istanze Spot sono motori di calcolo scontati dalla capacità in eccesso del servizio cloud. In cambio del prezzo scontato, AWS mantiene il diritto di anticipare l’istanza con poco o nessun preavviso. Di conseguenza, la rilevanza dell’utilizzo delle istanze Spot è limitata ai carichi di lavoro con tolleranza agli errori. Fortunatamente, attraverso un uso efficace di checkpoint del modello I carichi di lavoro di formazione ML possono essere progettati per essere tolleranti ai guasti e per sfruttare l’offerta di istanze Spot. Infatti, Amazon SageMaker, il servizio gestito di AWS per lo sviluppo di ML, semplifica l’addestramento sulle istanze Spot gestire il ciclo di vita end-to-end di Spot per te.
Purtroppo, Capacità dell’istanza Spotche misura la disponibilità delle istanze Spot per l’uso, è soggetto a fluttuazioni costanti e può essere molto difficile da prevedere. Amazon offre assistenza parziale nella valutazione del Capacità dell’istanza Spot di un tipo di istanza scelto tramite its Punteggio del posizionamento spot (SPS) che indica la probabilità che una richiesta Spot abbia successo in un dato dato regione o zona di disponibilità (AZ). Ciò è particolarmente utile quando hai la libertà di scegliere di addestrare il tuo modello in una delle numerose posizioni diverse. Tuttavia, la funzionalità SPS non offre garanzie.
Quando scegli di addestrare un modello su una o più istanze Spot, corri il rischio che il tipo di istanza scelto non abbia alcuna capacità Spot (ovvero, il tuo processo di addestramento non venga avviato) o, peggio, che inserisci un ciclo iterativo in cui la formazione viene eseguita ripetutamente solo per un numero limitato di passaggi di formazione e viene interrotta prima che tu abbia compiuto progressi significativi, il che può far aumentare i costi di formazione senza alcun ritorno.
Negli ultimi due anni, le sfide legate all’utilizzo puntuale delle istanze sono state particolarmente acute quando si tratta di multi-GPU EC2 tipi di istanza come g5,12xgrande E p4d.24xlarge. Un enorme aumento della domanda di potenti acceleratori di formazione (guidato in parte dai progressi nel campo dell’intelligenza artificiale generativa) combinato con le interruzioni nella catena di fornitura globale, hanno reso praticamente impossibile dipendere in modo affidabile dalle istanze Spot multi-GPU per la formazione ML. Il naturale ripiego è utilizzare quello più costoso Su richiesta (Odore istanze riservate. Tuttavia, nel nostro messaggio precedente abbiamo sottolineato l’importanza di considerare molte alternative diverse per la scelta del tipo di istanza. In questo post dimostreremo i potenziali vantaggi derivanti dalla sostituzione delle istanze on demand multi-GPU con più istanze Spot a GPU singola.
Sebbene la nostra dimostrazione utilizzerà Amazon Web Services, è possibile raggiungere conclusioni simili su piattaforme di servizi cloud alternative (CSP). Si prega di non interpretare la nostra scelta del CSP o dei servizi come un’approvazione. L’opzione migliore per te dipenderà dai dettagli unici del tuo progetto. Inoltre, prendi in considerazione la possibilità che il tipo di risparmio sui costi che dimostreremo non si riprodurrà nel caso del tuo progetto e/o che la soluzione che proponiamo non sarà applicabile (ad esempio, per qualche motivo che esula dallo scopo di questo post ). Assicurati di condurre una valutazione dettagliata della pertinenza e dell’efficacia della proposta prima di adattarla al tuo caso d’uso.
Al giorno d’oggi, l’addestramento di modelli IA su più dispositivi GPU in parallelo è un processo chiamato formazione distribuita – è un luogo comune. Mettendo da parte i prezzi delle istanze, quando puoi scegliere tra un tipo di istanza con più GPU e più tipi di istanza con lo stesso tipo di singole GPU, in genere scegli l’istanza multi-GPU. L’addestramento distribuito richiede in genere una notevole quantità di comunicazione di dati (ad esempio, condivisione del gradiente) tra le GPU. La vicinanza delle GPU su una singola istanza è destinata a facilitare una maggiore larghezza di banda di rete e una minore latenza. Inoltre, alcune istanze multi-GPU includono interconnessioni GPU-to-GPU dedicate che possono accelerare ulteriormente la comunicazione (ad esempio, NVLink SU p4d.24xlarge). Tuttavia, quando la capacità Spot è limitata a singole istanze GPU, l’opzione di addestramento su più istanze GPU singole a un costo molto inferiore diventa più interessante. Per lo meno, merita una valutazione delle sue opportunità di risparmio sui costi.
Quando l’addestramento distribuito viene eseguito su più istanze, le GPU comunicano tra loro tramite la rete tra le macchine host. Per ottimizzare la velocità dell’addestramento e ridurre la probabilità e/o l’impatto di un collo di bottiglia della rete, dobbiamo garantire una latenza di rete minima e il massimo throughput dei dati. Questi possono essere influenzati da una serie di fattori.
Collocazione di istanze
La latenza della rete può essere notevolmente influenzata dalle posizioni relative delle istanze EC2. Idealmente, quando richiediamo più istanze basate su cloud, vorremmo che fossero tutte collocate sullo stesso rack fisico. In pratica, senza un’opportuna configurazione, potrebbero non trovarsi nemmeno nella stessa città. Nella nostra dimostrazione di seguito utilizzeremo a Configurazione VPC oggetto di programmare un processo di formazione Amazon SageMaker per utilizzare una singola sottorete di un Amazon Virtual Private Cloud (VPC). Questa tecnica garantirà che tutte le istanze di formazione richieste saranno le stesse zona di disponibilità (AZ). Tuttavia, la collocazione nella stessa AZ potrebbe non essere sufficiente. Inoltre, il metodo che abbiamo descritto prevede la scelta di una sottorete associata ad una specifica AZ (ad esempio, quella con il valore più alto Punteggio del posizionamento spot). Un’API preferita soddisferebbe la richiesta in qualsiasi AZ che disponga di capacità sufficiente.
Un modo migliore per controllare il posizionamento delle nostre istanze è avviarle all’interno di un file gruppo di posizionamentonello specifico a gruppo di posizionamento cluster. Ciò non solo garantirà che tutte le istanze saranno le stesse ILma li posizionerà anche sullo “stesso segmento di larghezza di banda ad alta bisezione della rete” in modo da massimizzare le prestazioni del traffico di rete tra di loro. Tuttavia, al momento in cui scriviamo SageMaker lo fa non fornire la possibilità di specificare a gruppo di posizionamento. Per trarre vantaggio dai gruppi di collocamento dovremmo utilizzare una soluzione di servizio di formazione alternativa (come dimostreremo di seguito).
Rete EC2 Be vincoli di larghezza
Assicurati di prendere in considerazione il massimo larghezza di banda della rete supportato dalle istanze EC2 che scegli. Si noti, in particolare, che le larghezze di banda di rete associate alle macchine con GPU singola sono spesso documentate come “fino a” un certo numero di Gbps. Assicurati di capire cosa significa e come può influire sulla velocità dell’allenamento nel tempo.
Tieni presente che la comunicazione dei dati da GPU a GPU (ad esempio, la condivisione del gradiente) potrebbe dover condividere la larghezza di banda di rete limitata con altri dati che fluiscono attraverso la rete, ad esempio campioni di addestramento trasmessi in streaming nelle istanze di addestramento o artefatti di addestramento caricati su persistenti. magazzinaggio. Considerare modi per ridurre il carico utile di ciascuna categoria di dati per ridurre al minimo la probabilità di un collo di bottiglia della rete.
Adattatore per tessuto elastico (EFA)
Supporta un numero crescente di tipi di istanze EC2 Adattatore per tessuto elastico (EFA)un’interfaccia di rete dedicata per ottimizzare la comunicazione tra nodi. L’utilizzo dell’EFA può avere un impatto decisivo sulle prestazioni di runtime del carico di lavoro di formazione. Tieni presente che la larghezza di banda sul canale di rete EFA è diversa dalla larghezza di banda documentata della rete standard. Al momento della stesura di questo articolo, è difficile ottenere una documentazione dettagliata delle capacità dell’EFA e solitamente è meglio valutarne l’impatto attraverso tentativi ed errori. Considera l’utilizzo di un file Istanza EC2 che supporta il tipo EFA quando rilevante.
Dimostreremo ora il rapporto prezzo-prestazioni dell’allenamento su quattro GPU singole EC2 g5 Istanze Spot (ml.g5.2xlarge e ml.g5.4xlarge) rispetto a una singola istanza on demand con quattro GPU (ml.g5.12xlarge). Utilizzeremo lo script di training riportato di seguito contenente un modello di classificazione supportato da Vision Transformer (ViT) (addestrato su dati sintetici).
import os, torch, time
import torch.distributed as dist
from torch.utils.data import Dataset, DataLoader
from torch.cuda.amp import autocast
from torch.nn.parallel import DistributedDataParallel as DDP
from timm.models.vision_transformer import VisionTransformerbatch_size = 128
log_interval = 10
# use random data
class FakeDataset(Dataset):
def __len__(self):
return 1000000
def __getitem__(self, index):
rand_image = torch.randn((3, 224, 224), dtype=torch.float32)
label = torch.tensor(data=(index % 1000), dtype=torch.int64)
return rand_image, label
def mp_fn():
local_rank = int(os.environ('LOCAL_RANK'))
dist.init_process_group("nccl")
torch.cuda.set_device(local_rank)
# model definition
model = VisionTransformer()
loss_fn = torch.nn.CrossEntropyLoss()
model.to(torch.cuda.current_device())
model = DDP(model)
optimizer = torch.optim.Adam(params=model.parameters())
# dataset definition
num_workers = os.cpu_count()//int(os.environ('LOCAL_WORLD_SIZE'))
dl = DataLoader(FakeDataset(), batch_size=batch_size, num_workers=num_workers)
model.train()
t0 = time.perf_counter()
for batch_idx, (x, y) in enumerate(dl, start=1):
optimizer.zero_grad(set_to_none=True)
x = x.to(torch.cuda.current_device())
y = torch.squeeze(y.to(torch.cuda.current_device()), -1)
with autocast(enabled=True, dtype=torch.bfloat16):
outputs = model(x)
loss = loss_fn(outputs, y)
loss.backward()
optimizer.step()
if batch_idx % log_interval == 0 and local_rank == 0:
time_passed = time.perf_counter() - t0
samples_processed = dist.get_world_size() * batch_size * log_interval
print(f'{samples_processed / time_passed} samples/second')
t0 = time.perf_counter()
if __name__ == '__main__':
mp_fn()
Il blocco di codice seguente mostra come abbiamo utilizzato il file Pacchetto SageMaker Python (versione 2.203.1) per eseguire i nostri esperimenti. Tieni presente che per gli esperimenti a quattro istanze configuriamo l’uso di un VPC con una singola sottorete, come spiegato sopra.
from sagemaker.pytorch import PyTorch
from sagemaker.vpc_utils import VPC_CONFIG_DEFAULT# Toggle flag to switch between multiple single-GPU nodes and
# single multi-GPU node
multi_inst = False
inst_count=1
inst_type='ml.g5.12xlarge'
use_spot_instances=False
max_wait=None #max seconds to wait for Spot job to complete
subnets=None
security_group_ids=None
if multi_inst:
inst_count=4
inst_type='ml.g5.4xlarge' # optinally change to ml.g5.2xlarge
use_spot_instances=True
max_wait=24*60*60 #24 hours
# configure vpc settings
subnets=('<VPC subnet>')
security_group_ids=('<Security Group>')
estimator = PyTorch(
role='<sagemaker role>',
entry_point='train.py',
source_dir='<path to source dir>',
instance_type=inst_type,
instance_count=inst_count,
framework_version='2.1.0',
py_version='py310',
distribution={'torch_distributed': {'enabled': True}},
subnets=subnets,
security_group_ids=security_group_ids,
use_spot_instances=use_spot_instances,
max_wait=max_wait
)
# start job
estimator.fit()
Tieni presente che il nostro codice dipende dalla terza parte timm Pacchetto Python a cui puntiamo in un file require.txt nella radice della directory di origine. Ciò presuppone che il VPC sia stato configurato su abilitare l’accesso a Internet. In alternativa, è possibile definire un server PyPI privato (come descritto Qui) o creare un’immagine personalizzata con le dipendenze di terze parti preinstallate (come descritto Qui).
Riassumiamo i risultati del nostro esperimento nella tabella seguente. I prezzi su richiesta sono stati presi da Pagina dei prezzi di SageMaker (al momento della stesura di questo articolo, gennaio 2024). I valori di risparmio Spot sono stati raccolti dal report risparmi gestiti sulla formazione spot del lavoro completato. Si prega di consultare il Documentazione sui prezzi spot EC2 per avere un’idea di come vengono calcolati i risparmi Spot riportati.
I nostri risultati dimostrano chiaramente il potenziale di notevoli risparmi quando si utilizzano quattro istanze Spot a GPU singola anziché una singola istanza On Demand a quattro GPU. Dimostrano inoltre che, sebbene il costo di un tipo di istanza g5.4xlarge on demand sia più elevato, la maggiore potenza della CPU e/o la larghezza di banda di rete combinata con maggiori risparmi Spot, hanno comportato risparmi molto maggiori.
È importante sottolineare che tieni presente che i risultati relativi alle prestazioni possono variare considerevolmente in base ai dettagli del tuo lavoro e ai prezzi Spot nel momento in cui esegui gli esperimenti.
In un messaggio precedente abbiamo descritto come creare un ambiente gestito personalizzato sopra un servizio non gestito, come ad esempio AmazonEC2. Uno dei fattori motivanti elencati era il desiderio di avere un maggiore controllo sul posizionamento del dispositivo in una configurazione multiistanza, ad esempio utilizzando un gruppo di posizionamento clustercome discusso sopra. In questa sezione dimostriamo la creazione di una configurazione multinodo utilizzando un gruppo di posizionamento cluster.
Il nostro codice presuppone la presenza di a VPC predefinito così come la creazione (una tantum) di a gruppo di posizionamento clusterdimostrato qui utilizzando il file Kit SDK AWS Python (versione 1.34.23):
import boto3ec2 = boto3.client('ec2')
ec2.create_placement_group(
GroupName='cluster-placement-group',
Strategy='cluster'
)
Nel blocco di codice seguente utilizziamo il file Kit SDK AWS Python per avviare le nostre istanze Spot:
import boto3ec2 = boto3.resource('ec2')
instances = ec2.create_instances(
MaxCount=4,
MinCount=4,
ImageId='ami-0240b7264c1c9e6a9', # replace with image of choice
InstanceType='g5.4xlarge',
Placement={'GroupName':'cluster-placement-group'},
InstanceMarketOptions={
'MarketType': 'spot',
'SpotOptions': {
"SpotInstanceType": "one-time",
"InstanceInterruptionBehavior": "terminate"
}
},
)
Si prega di consultare il nostro messaggio precedente per suggerimenti passo passo su come estenderlo a una soluzione di formazione automatizzata.
In questo post, abbiamo illustrato come dimostrare flessibilità nella scelta del tipo di istanza di addestramento può aumentare la tua capacità di sfruttare la capacità dell’istanza Spot e ridurre il costo complessivo della formazione.
Poiché le dimensioni dei modelli di intelligenza artificiale continuano a crescere e i costi degli acceleratori di formazione sull’intelligenza artificiale continuano ad aumentare, diventa sempre più importante esplorare modi per mitigare le spese di formazione. La tecnica qui descritta è solo uno dei numerosi metodi per ottimizzare il rapporto costi-prestazioni. Ti invitiamo a esplorare il nostro post precedenti per approfondimenti su ulteriori opportunità in questo ambito.
Fonte: towardsdatascience.com