Quizá todavía no lo conceis, pero Proxmox es el software definitivo si queréis montar vuestra propia infraestructura en casa (o en vuestra empresa), es un hypervisor que os permite tener vuestra propia «nube» creando máquinas virtuales, contenedores y gestionando almacenamiento, backups y alta disponibilidad.
Yo llevo unos meses con esto, desde que me compré y quise dar uso, unas placas chinas para aprovechar los Xeon de segunda mano que ahora se encuentran tan baratos y, la verdad, es como tener un AWS particular (salvando muuuuchas diferencias). El caso es que lo único que me quedaba por probar era cómo tener una máquina virtual controlada por proxmox que me permitiese hacer AI… Pero para eso necesitaba usar una GPU y esto no es taaan sencillo. Así que partamos de un servidor que tiene una tarjeta gráfica (en mi caso una RTX 3070) y veamos cómo configurar el ordenador para meterlo en un cluster proxmox estando preparado para tener VMs que usen esa GPU.

¿cual es el problema realmente?
El problema es que un hypervisor lo que hace es ejecutar máquinas virtuales a las que ha asignado cierta parte de sus recursos (disco, memoria, etc) y permitir el uso compartido de todo lo que se puede compartir. Por desgracia la GPU no se puede compartir de la misma manera que una CPU (hay algunos modelos que tienen una tecnología que se llama VGPU que parece que si permitirán hacerlo, pero por ahora las que tengo yo no). Es por eso que lo que se hace es pasarle a la máquina virtual todo el bus PCI en cuestión para que lo gestione de manera independiente. Para que esto se pueda llevar a cabo es importante que el SO de proxmox no esté usando este bus para nada (que no tenga los drives instalados siquiera). El servidor que yo he usado tenía video integrado y configuré la bios para que usase ese como video primario (y así instalé proxmox sin utilizar la tarjeta gráfica). Pasos importantes con la BIOS:
- Activar la tarjeta integrada (si la tiene)
- Activar todos los modos de multihilo VT-d y cualquier referencia a IOMMU
Dejo un enlace que lo explica para varias placas base.
Lo siguiente, desde el servidor con ya proxmox instalado será editar el arranque de grub poniendo lo siguiente en el archivo /etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"
Y ejecuta después update-grub, tras lo cual tendrás que reiniciar la máquina.
Para comprobar que está todo activo ejecuta este comandos:
dmesg | grep -e DMAR -e IOMMU
El resultado tendría que ser algo como esto:
[ 0.008366] ACPI: DMAR 0x000000007A29ED38 0000A8 (v01 INTEL EDK2 00000002 01000013)
[ 0.008390] ACPI: Reserving DMAR table memory at [mem 0x7a29ed38-0x7a29eddf]
[ 0.098662] DMAR: IOMMU enabled
[ 0.255710] DMAR: Host address width 39
[ 0.255711] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[ 0.255721] DMAR: dmar0: reg_base_addr fed90000 ver 1:0 cap 1c0000c40660462 ecap 19e2ff0505e
[ 0.255723] DMAR: DRHD base: 0x000000fed91000 flags: 0x1
[ 0.255727] DMAR: dmar1: reg_base_addr fed91000 ver 1:0 cap d2008c40660462 ecap f050da
[ 0.255728] DMAR: RMRR base: 0x00000079d2f000 end: 0x00000079d4efff
[ 0.255731] DMAR: RMRR base: 0x0000007b800000 end: 0x0000007fffffff
[ 0.255733] DMAR-IR: IOAPIC id 2 under DRHD base 0xfed91000 IOMMU 1
[ 0.255734] DMAR-IR: HPET id 0 under DRHD base 0xfed91000
[ 0.255735] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[ 0.257485] DMAR-IR: Enabled IRQ remapping in x2apic mode
[ 0.600499] DMAR: No ATSR found
[ 0.600500] DMAR: No SATC found
[ 0.600501] DMAR: IOMMU feature fl1gp_support inconsistent
[ 0.600502] DMAR: IOMMU feature pgsel_inv inconsistent
[ 0.600503] DMAR: IOMMU feature nwfs inconsistent
[ 0.600504] DMAR: IOMMU feature pasid inconsistent
[ 0.600505] DMAR: IOMMU feature eafs inconsistent
[ 0.600506] DMAR: IOMMU feature prs inconsistent
[ 0.600507] DMAR: IOMMU feature nest inconsistent
[ 0.600508] DMAR: IOMMU feature mts inconsistent
[ 0.600509] DMAR: IOMMU feature sc_support inconsistent
[ 0.600509] DMAR: IOMMU feature dev_iotlb_support inconsistent
[ 0.600510] DMAR: dmar0: Using Queued invalidation
[ 0.600513] DMAR: dmar1: Using Queued invalidation
[ 0.600990] DMAR: Intel(R) Virtualization Technology for Directed I/O
Donde lo relevante es el IOMMU enabled y Enabled IRQ remmaping. Si todo está ok podemos ver os grupos iommu con este comando:
pvesh get /nodes/pascal/hardware/pci --pci-class-blacklist ""
Que nos debería dar una salida como la siguiente:
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? class ? device ? id ? iommugroup ? vendor ? device_name ? mdev ? su
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
...
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? 0x030000 ? 0x2484 ? 0000:01:00.0 ? 2 ? 0x10de ? GA104 [GeForce RTX 3070] ? ? 0x
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Ahora nos falta asegurarnos de que proxmox no va a utilizar esta gpu y estaríamos casi listos para crear nuestra vm:
echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf
echo "vfio" >> /etc/modules
echo "vfio_iommu_type1" >> /etc/modules
echo "vfio_pci" >> /etc/modules
update-initramfs -u -k all
systemctl reboot
Comprobaremos que se carga vfio y pondremos en lista negra los drivers de nuestra gpu
dmesg | grep -i vfio
echo "options kvm ignore_msrs=1 report_ignored_msrs=0" > /etc/modprobe.d/kvm.conf
lspci -nn | grep 'NVIDIA'
Veremos los ids de nuestro dispositivo
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)
Y los usaremos para ponerlos en lista negra para los drivers posibles:
echo "options vfio-pci ids=10de:2484,10de:228b" >> /etc/modprobe.d/vfio.conf
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidia" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidiafb" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidia_drm" >> /etc/modprobe.d/blacklist.conf
systemctl reboot
Y con esto ya está listo nuestro proxmox para compartir el PCI… Os recomiendo que si vais a unirlo a un cluster lo hagáis ahora, luego si creais una vm os va a ser más complicado. En cualquier caso, lo que queda es crear una máquina virtual y añadirle el pci de la tarjeta.
Para ello simplement creamos una máquina virtual, en mi caso digo que voy a instalar un linux y antes de arrancarla vamos al apartado de hardware y añadimos estos PCI:

Una vez arrancada la máquina e instalado el sistema operativo podemos comprobar si tenemos los drivers de nvida configurados ejecutando nvidia-smi

Así que ya tenemos una máquina con GPU para poder ejecutar nuestros trabajos de AI. Para ello podéis seguir estas instrucciones para instalar ollama o stable difussion en esta máquina virtual… Con la ventaja que aporta tenerlo controlado por Proxmox para hacer backups arrancarlo o pararlo a voluntad, monitorizarlo, etc.