Estou me deparando com um problema estranho. Tenho lutado para que a passagem da GPU funcione corretamente em uma VM do Windows 11 e finalmente encontrei algo que funciona, mas não é tão ideal quanto esperava. Essencialmente, se eu adicionar aos /etc/modprobe.d/vfio.conf
meus IDs PCI
options vfio-pci ids=10de:2684,10de:22ba
VFIO vinculados na inicialização e posso usá-lo perfeitamente para passagem de GPU. Mas se eu tentar reconectar a GPU aos drivers da nvidia, não consigo usá-la com o pytorch (embora nvidia-smi
funcione bem).
Se eu remover o arquivo vfio.conf e reiniciar, a GPU será vinculada à nvidia e o torch funcionará muito bem, mas quando tento desvincular da nvidia e vincular ao vfio-pci, quando inicio a VM recebo o código de erro 43 no driver da Nvidia e o seguinte erro nos logs da libvirt:
2024-04-09T15:38:49.796258Z qemu-system-x86_64: -device vfio-pci,host=0000:01:00.0,id=hostdev0,bus=pci.5,addr=0x0: Failed to mmap 0000:01:00.0 BAR 1. Performance may be slow
2024-04-09T15:39:07.971124Z qemu-system-x86_64: vfio_region_write(0000:01:00.0:region1+0x8c, 0x1,4) failed: Cannot allocate memory
É realmente estranho, porque de todas as minhas inspeções parece que a GPU está devidamente isolada, mas parece que não consigo passá-la para a GPU sem vincular explicitamente a vfio via /etc/modprobe.d/vfio.conf
e, quando faço isso, não consigo vinculá-la corretamente de volta à nvidia. Mais uma vez, tudo parece bem quando eu o ligo novamente à nvidia, mas o torch não consegue mais detectar a GPU. Alguma ideia?
Minha solução alternativa funciona bem por enquanto, mas requer reinicialização se eu quiser iniciar minha VM. O ideal é poder vincular/desvincular minha GPU nvidia sob demanda quando quiser alternar entre usá-la no host ou na VM do Windows 11. Exemplo de ligação ao script VFIO:
#!/bin/bash
set -x
# Stop display manager
systemctl stop display-manager
# Unbind VTconsoles: might not be needed
echo 0 > /sys/class/vtconsole/vtcon0/bind
echo 0 > /sys/class/vtconsole/vtcon1/bind
# Unload NVIDIA kernel modules
modprobe -r nvidia_drm
modprobe -r nvidia_modeset
modprobe -r nvidia_uvm
modprobe -r nvidia
# Detach GPU devices from host
# Use your GPU and HDMI Audio PCI host device
sudo virsh nodedev-detach pci_0000_01_00_0
sudo virsh nodedev-detach pci_0000_01_00_1
# Load vfio module
modprobe vfio-pci
Se eu correr
lspci -nnk -d 10de:2684
lspci -nnk -d 10de:22ba
Parece corretamente vinculado ao vfio-pci:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2684] (rev a1)
Subsystem: Gigabyte Technology Co., Ltd Device [1458:40e5]
Kernel driver in use: vfio-pci
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:22ba] (rev a1)
Subsystem: Gigabyte Technology Co., Ltd Device [1458:40e5]
Kernel driver in use: vfio-pci
Kernel modules: snd_hda_intel
Se eu reiniciar com vfio.conf aplicado e inspecionar as coisas, parece o mesmo, mas estranhamente funciona ao iniciar minha VM do Windows 11:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2684] (rev a1)
Subsystem: Gigabyte Technology Co., Ltd Device [1458:40e5]
Kernel driver in use: vfio-pci
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:22ba] (rev a1)
Subsystem: Gigabyte Technology Co., Ltd Device [1458:40e5]
Kernel driver in use: vfio-pci
Kernel modules: snd_hda_intel
Mas se eu desvincular do vfio e vincular à nvidia:
#!/bin/bash
set -x
# Attach GPU devices to host
# Use your GPU and HDMI Audio PCI host device
sudo virsh nodedev-reattach pci_0000_01_00_0
sudo virsh nodedev-reattach pci_0000_01_00_1
# Unload vfio module
modprobe -r vfio-pci
#stop race condition
sleep 2
# Load NVIDIA kernel modules
modprobe nvidia
modprobe nvidia_modeset
modprobe nvidia_uvm
modprobe nvidia_drm
# Bind VTconsoles: might not be needed
echo 1 > /sys/class/vtconsole/vtcon0/bind
echo 1 > /sys/class/vtconsole/vtcon1/bind
nvidia-smi
funciona bem:
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.161.07 Driver Version: 535.161.07 CUDA Version: 12.2 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA GeForce RTX 4090 Off | 00000000:01:00.0 Off | Off |
| 0% 49C P0 67W / 450W | 0MiB / 24564MiB | 0% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| No running processes found |
+---------------------------------------------------------------------------------------+
Mas quando executo algo no Docker que usa pytorch:
RuntimeError: Torch is not able to use GPU
Pior ainda, quando tento religar ao vfio ele funciona como se eu não tivesse habilitado vfio.conf
e recebo o mesmo erro ao iniciar a VM do Windows 11:
2024-04-09T16:04:45.089687Z qemu-system-x86_64: -device vfio-pci,host=0000:01:00.0,id=hostdev0,bus=pci.5,addr=0x0: Failed to mmap 0000:01:00.0 BAR 1. Performance may be slow
2024-04-09T16:04:55.682373Z qemu-system-x86_64: vfio_region_write(0000:01:00.0:region1+0x8c, 0x1,4) failed: Cannot allocate memory
Parece bastante claro para mim que algo ainda está usando a nvidia de alguma forma, mesmo que esteja usando o driver do kernel vfio-pci e lsof /dev/nvidia0
retorne uma string em branco. Alguma ideia? Estou ficando um pouco louco aqui!
Após mais investigação, descobri que este é o mesmo problema: https://www.reddit.com/r/VFIO/s/ASQ3Bx3RGq
Rastreador de problemas relacionados: https://gitlab.freedesktop.org/drm/amd/-/issues/2794
Basicamente, tudo se resume ao fato de que eu estava tentando usar meu iGPU em minha CPU AMD no host e uma GPU NVIDIA para passagem. Aparentemente, isso se deve ao fato de as técnicas de cache serem diferentes na AMD e na NVIDIA e o kernel não lidar com isso corretamente no momento. Este repositório tem dicas sobre como corrigir seu Kernel: https://github.com/Kinsteen/win10-gpu-passthrough
Como eu realmente não me importo muito em usar a exibição do meu host ao usar a VM, simplesmente fui em frente e coloquei o amdgpu na lista negra e simplesmente encerrei meu gerenciador de exibição antes de iniciar minha VM do Windows 11. Isso funciona muito bem.
Antes disso, tentei atualizar para o Ubuntu 24 porque ouvi que esse problema foi corrigido no Kernel 6.6 e o Ubuntu 24 usa o Kernel 6.8, mas acabei com o mesmo problema. Portanto, a passagem única de GPU parecia a melhor opção por enquanto.