Risponderemo a tutte le tue domande!

Applicazioni e Guide

Intel Habana Gaudi 2: installazione e test

Prima di iniziare l'installazione del software degli acceleratori Gaudi 2, c'è una caratteristica importante che vale la pena menzionare. Siamo abituati al fatto che l'addestramento e l'inferenza delle reti neurali possono essere eseguiti utilizzando le GPU. Tuttavia, Intel Habana Gaudi 2 è molto diverso dalle GPU e rappresenta un'altra classe di dispositivi progettati esclusivamente per accelerare le attività di intelligenza artificiale.

Molte applicazioni e framework già noti non funzioneranno senza aver prima preparato il sistema operativo e, in alcuni casi, senza uno speciale GPU Migration Toolkit. Questo spiega il gran numero di passaggi preparatori che descriviamo in questo articolo. Iniziamo con ordine.

Passo 1. Installare lo stack software SynapseAI

Per iniziare a lavorare con gli acceleratori Intel Habana Gaudi 2, è necessario installare lo stack SynapseAI. Esso comprende uno speciale compilatore di grafi che trasforma la topologia del modello di rete neurale per ottimizzare efficacemente l'esecuzione sull'architettura Gaudi, librerie API per la scalabilità orizzontale e un SDK separato per la creazione di algoritmi e modelli di apprendimento automatico ad alte prestazioni.

Separatamente, notiamo che SynapseAI è la parte che permette di creare un ponte tra framework popolari come PyTorch/TensorFlow e gli acceleratori di intelligenza artificiale Gaudi 2. Questo permette di lavorare con astrazioni familiari. Ciò consente di lavorare con astrazioni già note e Gaudi 2 ottimizza autonomamente i calcoli Gli operatori specifici per i quali gli acceleratori non dispongono di supporto hardware vengono eseguiti sulla CPU.

Per semplificare l'installazione dei singoli componenti di SynapseAI, è stato creato un comodo script di shell. Scarichiamolo:

wget -nv https://vault.habana.ai/artifactory/gaudi-installer/latest/habanalabs-installer.sh

Rendere il file eseguibile:

chmod +x habanalabs-installer.sh

Eseguire lo script:

./habanalabs-installer.sh install --type base

Seguire le indicazioni del sistema durante l'installazione. Il file di registro contiene un rapporto dettagliato. È possibile vedere quali pacchetti sono stati installati e se gli acceleratori sono stati trovati e inizializzati con successo.

I registri sono qui: /var/log/habana_logs/install-YYY-MM-DD-HH-MM-SS.log

[  +3.881647] habanalabs hl5: Found GAUDI2 device with 96GB DRAM
[  +0.008145] habanalabs hl0: Found GAUDI2 device with 96GB DRAM
[  +0.032034] habanalabs hl3: Found GAUDI2 device with 96GB DRAM
[  +0.002376] habanalabs hl4: Found GAUDI2 device with 96GB DRAM
[  +0.005174] habanalabs hl1: Found GAUDI2 device with 96GB DRAM
[  +0.000390] habanalabs hl2: Found GAUDI2 device with 96GB DRAM
[  +0.007065] habanalabs hl7: Found GAUDI2 device with 96GB DRAM
[  +0.006256] habanalabs hl6: Found GAUDI2 device with 96GB DRAM

Proprio come l'utility nvidia-smi fornisce informazioni sulle GPU installate e sui processi di calcolo in esecuzione, SynapseAI ha un programma simile. È possibile eseguirlo per ottenere un rapporto sullo stato attuale degli acceleratori Gaudi 2 AI:

hl-smi
hl-smi screenshot

Passo 2. Test di TensorFlow

TensorFlow è una delle piattaforme più popolari per l'apprendimento automatico. Utilizzando lo stesso script di installazione, è possibile installare una versione pre-costruita di TensorFlow con il supporto per gli acceleratori Gaudi 2. Iniziamo installando le dipendenze generali:

./habanalabs-installer.sh install -t dependencies

Successivamente, installeremo le dipendenze per TensorFlow:

./habanalabs-installer.sh install -t dependencies-tensorflow

Installare la piattaforma TensorFlow all'interno di un ambiente virtuale implementato utilizzando il meccanismo Python Virtual Environment (venv):

./habanalabs-installer.sh install --type tensorflow --venv

Attiviamo l'ambiente virtuale creato:

source habanalabs-venv/bin/activate

Creare un semplice esempio di codice Python che utilizzi le capacità dell'acceleratore Gaudi 2:

nano example.py

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
import os
# Import Habana Torch Library
import habana_frameworks.torch.core as htcore
class SimpleModel(nn.Module):
   def __init__(self):
       super(SimpleModel, self).__init__()
       self.fc1   = nn.Linear(784, 256)
       self.fc2   = nn.Linear(256, 64)
       self.fc3   = nn.Linear(64, 10)
   def forward(self, x):
       out = x.view(-1,28*28)
       out = F.relu(self.fc1(out))
       out = F.relu(self.fc2(out))
       out = self.fc3(out)
       return out
def train(net,criterion,optimizer,trainloader,device):
   net.train()
   train_loss = 0.0
   correct = 0
   total = 0
   for batch_idx, (data, targets) in enumerate(trainloader):
       data, targets = data.to(device), targets.to(device)
       optimizer.zero_grad()
       outputs = net(data)
       loss = criterion(outputs, targets)
       loss.backward()
       # API call to trigger execution
       htcore.mark_step()
       optimizer.step()
       # API call to trigger execution
       htcore.mark_step()
       train_loss += loss.item()
       _, predicted = outputs.max(1)
       total += targets.size(0)
       correct += predicted.eq(targets).sum().item()
   train_loss = train_loss/(batch_idx+1)
   train_acc = 100.0*(correct/total)
   print("Training loss is {} and training accuracy is {}".format(train_loss,train_acc))
def test(net,criterion,testloader,device):
   net.eval()
   test_loss = 0
   correct = 0
   total = 0
   with torch.no_grad():
       for batch_idx, (data, targets) in enumerate(testloader):
           data, targets = data.to(device), targets.to(device)
           outputs = net(data)
           loss = criterion(outputs, targets)
           # API call to trigger execution
           htcore.mark_step()
           test_loss += loss.item()
           _, predicted = outputs.max(1)
           total += targets.size(0)
           correct += predicted.eq(targets).sum().item()
   test_loss = test_loss/(batch_idx+1)
   test_acc = 100.0*(correct/total)
   print("Testing loss is {} and testing accuracy is {}".format(test_loss,test_acc))
def main():
   epochs = 20
   batch_size = 128
   lr = 0.01
   milestones = [10,15]
   load_path = './data'
   save_path = './checkpoints'
   if(not os.path.exists(save_path)):
       os.makedirs(save_path)
   # Target the Gaudi HPU device
   device = torch.device("hpu")
   # Data
   transform = transforms.Compose([
       transforms.ToTensor(),
   ])
   trainset = torchvision.datasets.MNIST(root=load_path, train=True,
                                           download=True, transform=transform)
   trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,
                                           shuffle=True, num_workers=2)
   testset = torchvision.datasets.MNIST(root=load_path, train=False,
                                       download=True, transform=transform)
   testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,
                                           shuffle=False, num_workers=2)
   net = SimpleModel()
   net.to(device)
   criterion = nn.CrossEntropyLoss()
   optimizer = optim.SGD(net.parameters(), lr=lr,
                       momentum=0.9, weight_decay=5e-4)
   scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=milestones, gamma=0.1)
   for epoch in range(1, epochs+1):
       print("=====================================================================")
       print("Epoch : {}".format(epoch))
       train(net,criterion,optimizer,trainloader,device)
       test(net,criterion,testloader,device)
       torch.save(net.state_dict(), os.path.join(save_path,'epoch_{}.pth'.format(epoch)))
       scheduler.step()
if __name__ == '__main__':
   main()

Infine, eseguite l'applicazione:

python3 example.py

Per uscire dall'ambiente virtuale, eseguire il seguente comando:

deactivate

Passo 3. Clonare il repository di formazione

Clonare il repository con il codice MLperf:

git clone https://github.com/mlcommons/training_results_v3.0

Creare una cartella separata che sarà utilizzata dal contenitore Docker con MLperf:

mkdir -p mlperf

Cambiare la directory:

cd mlperf

Esportiamo alcune variabili d'ambiente:

export MLPERF_DIR=/home/usergpu/mlperf
export SCRATCH_DIR=/home/usergpu/mlperf/scratch
export DATASETS_DIR=/home/usergpu/mlperf/datasets

Creare nuove directory utilizzando le variabili create:

mkdir -p $MLPERF_DIR/Habana
mkdir -p $SCRATCH_DIR
mkdir -p $DATASETS_DIR

Copiare l'applicazione di benchmark in $MLPERF_DIR/Habana:

cp -R training_results_v3.0/Intel-HabanaLabs/benchmarks/ $MLPERF_DIR/Habana

Esportare un'altra variabile che memorizzerà un link per scaricare la versione desiderata del contenitore Docker:

export MLPERF_DOCKER_IMAGE=vault.habana.ai/gaudi-docker-mlperf/ver3.1/pytorch-installer-2.0.1:1.13.99-41

Passo 4. Installare Docker

La nostra istanza esegue Ubuntu Linux 22.04 LTS e non supporta Docker per impostazione predefinita. Quindi, prima di scaricare ed eseguire i container, è necessario installare il supporto per Docker. Aggiorniamo la cache dei pacchetti e installiamo alcuni pacchetti di base che ci serviranno in seguito:

sudo apt update && sudo apt -y install apt-transport-https ca-certificates curl software-properties-common

Per installare Docker, è necessario aggiungere un repository di progetto con firma digitale. Scaricare la chiave di firma digitale e aggiungerla all'archivio chiavi del sistema operativo:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Docker può essere eseguito su piattaforme con diverse architetture. Il comando seguente rileverà l'architettura del server e aggiungerà la riga del repository corrispondente all'elenco del gestore di pacchetti APT:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Aggiornare la cache dei pacchetti e le policy e installare docker-ce (Docker Community Edition):

sudo apt update && apt-cache policy docker-ce && sudo apt install docker-ce

Infine, verificare che il demone Docker sia attivo e funzionante:

sudo systemctl status docker

Passo 5. Eseguire il contenitore Docker

Avviamo il contenitore in modalità privilegiata utilizzando le variabili precedentemente specificate:

sudo docker run --privileged --security-opt seccomp=unconfined \
  --name mlperf3.0 -td                    \
  -v /dev:/dev                            \
  --device=/dev:/dev                      \
  -e LOG_LEVEL_ALL=6                      \
  -v /sys/kernel/debug:/sys/kernel/debug  \
  -v /tmp:/tmp                            \
  -v $MLPERF_DIR:/root/MLPERF             \
  -v $SCRATCH_DIR:/root/scratch           \
  -v $DATASETS_DIR:/root/datasets/        \
  --cap-add=sys_nice --cap-add=SYS_PTRACE \
  --user root --workdir=/root --net=host  \
  --ulimit memlock=-1:-1 $MLPERF_DOCKER_IMAGE

Per comodità, è possibile accedere al terminale all'interno del contenitore tramite SSH:

sudo docker exec mlperf3.0 bash -c "service ssh start"

Per aprire una shell di comando (bash) nella sessione corrente, eseguire il seguente comando:

sudo docker exec -it mlperf3.0 bash

Passo 6. Preparare un set di dati

Per eseguire i test di implementazione di Bert da MLperf, è necessario un set di dati preparato. Il metodo ottimale è quello di generare un set di dati da dati precaricati. Il repository MLperf include uno script speciale, prepare_data.sh, che richiede un insieme specifico di pacchetti per funzionare. Passiamo alla seguente directory:

cd /root/MLPERF/Habana/benchmarks/bert/implementations/PyTorch

Installare tutti i pacchetti necessari utilizzando l'elenco pre-generato e il gestore di pacchetti pip:

pip install -r requirements.txt

Impostare la variabile PYTORCH_BERT_DATA per indicare allo script dove memorizzare i dati:

export PYTORCH_BERT_DATA=/root/datasets/pytorch_bert

Eseguire lo script:

bash input_preprocessing/prepare_data.sh -o $PYTORCH_BERT_DATA

La procedura di generazione è piuttosto lunga e può richiedere diverse ore. Si prega di essere pazienti e di non interrompere il processo. Se si prevede di disconnettersi dalla sessione SSH, si consiglia di utilizzare l'utilità schermo immediatamente prima di avviare il contenitore Docker.

Passo 7. Impacchettare il set di dati

Il passo successivo consiste nel "tagliare" il dataset in pezzi uguali per il successivo lancio di MLperf. Creiamo una cartella separata per i dati impacchettati:

mkdir $PYTORCH_BERT_DATA/packed

Eseguire lo script di impacchettamento:

python3 pack_pretraining_data_pytorch.py \
  --input_dir=$PYTORCH_BERT_DATA/hdf5/training-4320/hdf5_4320_shards_uncompressed \
  --output_dir=$PYTORCH_BERT_DATA/packed \
  --max_predictions_per_seq=76

Passo 8. Eseguire un test

Ora che il set di dati è stato preparato, è il momento di eseguire il test. Tuttavia, è impossibile farlo senza una preparazione preliminare. Gli autori del test Bert hanno lasciato alcuni valori codificati nello script, che interferiranno con l'esecuzione del test. Innanzitutto, rinominare la seguente directory:

mv $PYTORCH_BERT_DATA/packed $PYTORCH_BERT_DATA/packed_data_500_pt

Cambiare la directory:

cd /root/MLPERF/Habana/benchmarks/bert/implementations/HLS-Gaudi2-PT

Poiché l'editor GNU Nano non è installato all'interno del contenitore, deve essere installato separatamente. In alternativa, si può usare l'editor Vi integrato:

apt update && apt -y install nano

Ora, modificate lo script di lancio del test:

nano launch_bert_pytorch.sh

Individuare la prima riga:

DATA_ROOT=/mnt/weka/data/pytorch/bert_mlperf/packed_data

Sostituire con la seguente:

DATA_ROOT=/root/datasets/pytorch_bert

Trovare la seconda riga:

INPUT_DIR=$DATA_ROOT/packed

Sostituire con la seguente:

INPUT_DIR=$DATA_ROOT/packed_data_500_pt

Salvare il file e uscire.

Il codice del test include una funzione di limitazione che impedisce al gradiente di superare determinati valori, impedendo una potenziale crescita esponenziale. Per ragioni a noi sconosciute, questa funzione è assente nella versione di PyTorch utilizzata nel contenitore, causando l'interruzione anomala del test durante la fase di riscaldamento.

Una possibile soluzione potrebbe essere quella di rimuovere temporaneamente questa funzione dal codice del file fastddp.py. Per farlo, aprire il file:

nano ../PyTorch/fastddp.py

Trovate e commentate le seguenti tre righe di codice usando il simbolo # (shebang), in modo che appaiano così:

#from habana_frameworks.torch import _hpex_C
#    clip_global_grad_norm = _hpex_C.fused_lamb_norm(grads, 1.0)
#    _fusion_buffer.div_((clip_global_grad_norm * _all_reduce_group_size).to(_fusion_buffer.dtype))

Inoltre, salvare il file e uscire. Cambiare la directory:

cd ../HLS-Gaudi2-PT

Infine, eseguire lo script. Ci vorranno circa 20 minuti per completarlo:

./launch_bert_pytorch.sh

Vedi anche:



Aggiornato: 12.08.2025

Pubblicato: 23.01.2025