CUDA® initialization: Unexpected error from cudaGetDeviceCount()
Alcune configurazioni di server, come quelle con 8 x A100 SXM4, presentano una caratteristica peculiare. Quando si sceglie Ubuntu come sistema operativo e si installano i più recenti driver NVIDIA® e CUDA® Toolkit, il tentativo di eseguire un'applicazione costruita con il framework PyTorch provoca spesso un errore. L'errore si presenta tipicamente come segue:
CUDA initialization: Unexpected error from cudaGetDeviceCount()
L'errore può essere riprodotto non solo attraverso l'applicazione, ma anche direttamente nella console interattiva di Python:
python3
>>> import torch >>> torch.cuda.is_available() /usr/local/lib/python3.10/dist-packages/torch/cuda/__init__.py:128: UserWarning: CUDA initialization: Unexpected error from cudaGetDeviceCount(). Did you run some cuda functions before calling NumCudaDevices() that might have already set an error? Error 802: system not yet initialized (Triggered internally at ../c10/cuda/CUDAFunctions.cpp:108.) return torch._C._cuda_getDeviceCount() > 0
Questo errore indica che CUDA® non è in grado di determinare correttamente il numero di GPU disponibili e quindi non può allocare le risorse per il calcolo. Stranamente, se si esegue il comando per contare i dispositivi disponibili, viene visualizzato il numero corretto:
>>> torch.cuda.device_count() 8
L'utilità standard nvidia-smi funziona correttamente, ma le funzioni aggiuntive come MIG sono disabilitate. L'aggiornamento o il downgrade del sistema operativo, dei driver della GPU o di CUDA® non risolve il problema.
Possibile motivo
L'errore è dovuto al metodo di rilevamento delle GPU disponibili da parte del sistema. Per impostazione predefinita, i moduli PyTorch vengono caricati per rilevare i dispositivi di calcolo disponibili. Questi moduli inviano le richieste cuDeviceGetByPCIBusId o cuDeviceGetPCIBusId all'API del driver CUDA®. Se queste richieste falliscono, il sistema presume che non ci siano dispositivi disponibili, impedendo a PyTorch di usarli.
Preparazione del server
Prima di affrontare il problema del rilevamento, isoliamo il nostro ambiente Python usando un ambiente virtuale come precauzione. Installate il pacchetto:
sudo apt install python3-venv
Creare una directory per memorizzare tutti i file e le cartelle dell'ambiente virtuale:
mkdir /home/usergpu/venv
Creare un ambiente isolato:
python -m venv /home/usergpu/venv
Attiviamo l'ambiente. Tutte le azioni successive, come l'installazione di pacchetti o l'esecuzione di altre attività legate a Python, saranno limitate a questo ambiente isolato. Queste azioni non influenzeranno il sistema operativo:
source /home/usergpu/venv/bin/activate
Installare PyTorch con supporto CUDA® 12.4:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
Soluzione
Ora è tutto pronto per risolvere il problema che causa l'errore. È necessario impostare successivamente tre variabili d'ambiente:
- CUDA_DEVICE_ORDER="PCI_BUS_ID" - ordinerà le GPU, ordinando i loro ID con gli ID sul bus PCIe.
- PYTORCH_NVML_BASED_CUDA_CHECK=1 - eseguire un controllo della disponibilità utilizzando NVML(NVIDIA® Management Library). NVML è un livello API per ottenere dati direttamente dall'utilità nvidia-smi.
- CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 - forza mostrare al sistema gli ID delle GPU disponibili.
Ora che il sistema è a conoscenza delle GPU installate, si può procedere all'esecuzione di Python. Il comando completo apparirà come segue:
CUDA_DEVICE_ORDER="PCI_BUS_ID" PYTORCH_NVML_BASED_CUDA_CHECK=1 CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 python3
Controllo:
>>> import torch >>> torch.cuda.is_available() True
È ora possibile eseguire qualsiasi applicazione sul framework PyTorch senza incontrare questo errore.
Un altro possibile motivo
A volte, la soluzione sopra descritta potrebbe non funzionare a causa di un problema meno evidente. Configurazioni come 8 x A100 SXM4 utilizzano il software NVIDIA® Fabric Manager (FM). FM funge da coordinatore, ottimizzando le connessioni delle GPU e garantendo il bilanciamento del carico. È anche responsabile del monitoraggio e delle funzioni di servizio, compresa la presentazione delle GPU al sistema operativo.
FM comunica costantemente con il driver API NVIDIA®, quindi la sua versione deve corrispondere a quella del driver installato. In caso di mancata corrispondenza, il demone FM smette di funzionare. Questo porta al comportamento descritto in precedenza, in cui il framework richiede i dispositivi disponibili ma riceve dati errati e non può distribuire correttamente le attività di calcolo.
Per escludere questo potenziale problema, eseguite una semplice diagnosi:
sudo systemctl status nvidia-fabricmanager
× nvidia-fabricmanager.service - NVIDIA fabric manager service Loaded: loaded (/lib/systemd/system/nvidia-fabricmanager.service; enabled; vendor preset: enabled) Active: failed (Result: exit-code) since Thu 2024-10-17 21:01:05 UTC; 8h ago Process: 3992 ExecStart=/usr/bin/nv-fabricmanager -c /usr/share/nvidia/nvswitch/fabricmanager.cfg (code=exited, status=1/FAILURE) CPU: 11ms Oct 17 21:01:05 ubuntu22044 systemd[1]: Starting NVIDIA fabric manager service... Oct 17 21:01:05 ubuntu22044 nv-fabricmanager[3994]: fabric manager NVIDIA GPU driver interface version 550.90.07 don't match with driver version 550.54.15. Please update with matching NVIDIA driver package. Oct 17 21:01:05 ubuntu22044 systemd[1]: Failed to start NVIDIA fabric manager service.
L'esempio precedente mostra che FM non è riuscito ad avviarsi perché la sua versione non corrisponde a quella del driver installato. La soluzione più semplice è scaricare e installare una versione del driver che corrisponda esattamente alla versione di FM (550.90.07). Esistono vari modi per farlo, ma il più semplice è scaricare un archivio autoestraente in formato .run.
wget https://download.nvidia.com/XFree86/Linux-x86_64/550.90.07/NVIDIA-Linux-x86_64-550.90.07.run
Rendere questo file eseguibile:
sudo chmod a+x NVIDIA-Linux-x86_64-550.90.07.run
E avviare l'installazione:
sudo ./NVIDIA-Linux-x86_64-550.90.07.run
Una Volta™ installato il driver, avviare manualmente il demone:
sudo systemctl start nvidia-fabricmanager
Verificare che l'avvio sia avvenuto con successo:
sudo systemctl status nvidia-fabricmanager
● nvidia-fabricmanager.service - NVIDIA fabric manager service Loaded: loaded (/lib/systemd/system/nvidia-fabricmanager.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2024-10-18 05:45:26 UTC; 5s ago Process: 36614 ExecStart=/usr/bin/nv-fabricmanager -c /usr/share/nvidia/nvswitch/fabricmanager.cfg (code=exited, status=0/SUCCESS) Main PID: 36616 (nv-fabricmanage) Tasks: 19 (limit: 629145) Memory: 16.2M CPU: 32.350s CGroup: /system.slice/nvidia-fabricmanager.service └─36616 /usr/bin/nv-fabricmanager -c /usr/share/nvidia/nvswitch/fabricmanager.cfg Oct 18 05:45:02 ubuntu22044 systemd[1]: Starting NVIDIA fabric manager service... Oct 18 05:45:15 ubuntu22044 nv-fabricmanager[36616]: Connected to 1 node. Oct 18 05:45:26 ubuntu22044 nv-fabricmanager[36616]: Successfully configured all the available GPUs and NVSwitches to route NVLink traffic. Oct 18 05:45:26 ubuntu22044 systemd[1]: Started NVIDIA fabric manager service.
Ora si può provare a eseguire l'applicazione basata su PyTorch per verificare se tutte le GPU sono disponibili.
Vedere anche:
Aggiornato: 28.03.2025
Pubblicato: 17.10.2024