Execute top to bottom. One host reboot in step 1. Ubuntu install is manual in step 3.
0. BIOS
- SVM + IOMMU on (AMD CBS > NBIO)
- Above 4G decoding on
- Resizable BAR on; off if passthrough breaks
- CSM off · UEFI only · secure boot off
- Primary display: GT710 slot (or headless)
- XMP/DOCP on · disable wait-for-F1
- XTX: top x16 · 2 separate 8-pin · 750W+
1. Host prep: IOMMU + VFIO + D3cold
cp /etc/modprobe.d/vfio.conf /etc/modprobe.d/vfio.conf.bak.$(date +%F) 2>/dev/null || true
cp /etc/default/grub /etc/default/grub.bak.$(date +%F)
sed -i 's|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt video=efifb:off pcie_aspm=off pcie_port_pm=off pci=realloc,reset"|' /etc/default/grub
cat > /etc/modprobe.d/vfio.conf <<'EOF'
options vfio-pci ids=1002:744c,1002:ab30 disable_vga=1 disable_idle_d3=1
softdep amdgpu pre: vfio-pci
EOF
cat > /etc/modprobe.d/blacklist-amdgpu.conf <<'EOF'
blacklist amdgpu
EOF
for m in vfio vfio_iommu_type1 vfio_pci; do
grep -qx "$m" /etc/initramfs-tools/modules 2>/dev/null || echo "$m" >> /etc/initramfs-tools/modules
done
cat > /etc/udev/rules.d/99-vfio-d3cold.rules <<'EOF'
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x744c", ATTR{d3cold_allowed}="0"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0xab30", ATTR{d3cold_allowed}="0"
EOF
update-initramfs -u -k all
update-grub # ZFS root: proxmox-boot-tool refresh
udevadm control --reload-rules
reboot
# at shutdown: PSU off, hold power 10s, boot (clears D3cold)
2. Host verify
cat /proc/cmdline
cat /sys/module/vfio_pci/parameters/disable_idle_d3 # Y
cat /sys/bus/pci/devices/0000:09:00.0/power_state # D0 or D3hot
cat /sys/bus/pci/devices/0000:09:00.0/d3cold_allowed # 0
lspci -nnk -s 0000:09:00 # vfio-pci
dmesg | grep -iE 'd3cold|vfio.*reset'
3. VM: create + install Ubuntu
Replace 108 with your VM’s ID
qm list
qm create 108 --name ollama --memory 16384 --cores 16 --sockets 1 \
--cpu host --numa 0 --machine q35 --bios ovmf --ostype l26 \
--scsihw virtio-scsi-single --agent 1 --balloon 0
qm set 108 --efidisk0 local-lvm:0,efitype=4m,pre-enrolled-keys=0
qm set 108 --scsi0 local-lvm:128,discard=on,iothread=1,ssd=1
qm set 108 --ide2 local:iso/ubuntu-24.04.5-live-server-amd64.iso,media=cdrom
qm set 108 --net0 virtio,bridge=vmbr0,tag=50,queues=4
qm set 108 --boot 'order=scsi0;ide2;net0'
qm start 108
# install Ubuntu Server, enable OpenSSH
qm shutdown 108
qm set 108 --delete ide2
4. VM: attach GPU
qm set 108 --hostpci0 0000:09:00,pcie=1,rombar=0
qm start 108
5. Guest: GPU + ROCm
sudo apt update && sudo apt full-upgrade -y
sudo apt install -y pciutils curl rocminfo qemu-guest-agent
sudo systemctl enable --now qemu-guest-agent
lspci -nnk | grep -iA3 vga # amdgpu
# only if /dev/kfd is missing
D=$(cat /sys/class/kfd/kfd/dev); sudo mknod /dev/kfd c ${D%:*} ${D#*:}; sudo chmod 666 /dev/kfd
sudo tee /etc/systemd/system/kfd-node.service <<'EOF'
[Unit]
Description=/dev/kfd node
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'd=$(cat /sys/class/kfd/kfd/dev 2>/dev/null); [ -n "$d" ] && [ -e /dev/kfd ] || (mknod /dev/kfd c $(echo "$d" | cut -d: -f1) $(echo "$d" | cut -d: -f2) && chmod 666 /dev/kfd)'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now kfd-node
sudo usermod -aG render,video $USER
rocminfo | grep -i gfx # gfx1100
6. Guest: Ollama
curl -fsSL https://ollama.com/install.sh | sh
sudo usermod -aG render,video ollama
sudo mkdir -p /etc/systemd/system/ollama.service.d
sudo tee /etc/systemd/system/ollama.service.d/override.conf >/dev/null <<'EOF'
[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
Environment="OLLAMA_NUM_PARALLEL=1"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Environment="OLLAMA_CONTEXT_LENGTH=32768"
Environment="OLLAMA_KEEP_ALIVE=30m"
Environment="OLLAMA_HOST=0.0.0.0:11434"
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now ollama
sudo systemctl restart ollama
journalctl -u ollama -n 50 | grep -iE 'rocm|gfx|gpu'
7. Guest: models
ollama pull huihui_ai/qwen3.5-abliterated:9b
cat > ~/qwen35-32k.Modelfile <<'EOF'
FROM huihui_ai/qwen3.5-abliterated:9b
PARAMETER num_ctx 32768
PARAMETER num_gpu 999
PARAMETER temperature 0.6
PARAMETER top_p 0.95
PARAMETER top_k 20
EOF
cat > ~/qwen35-256k.Modelfile <<'EOF'
FROM huihui_ai/qwen3.5-abliterated:9b
PARAMETER num_ctx 262144
PARAMETER num_gpu 999
PARAMETER temperature 0.6
PARAMETER top_p 0.95
PARAMETER top_k 20
EOF
ollama create qwen35-32k -f ~/qwen35-32k.Modelfile
ollama create qwen35-256k -f ~/qwen35-256k.Modelfile
8. Use
ollama run qwen35-32k
ollama run qwen35-256k
With opencode if the AI VM is on LAN. Ensure the port is open on the server, the server has a route to LAN PC, the LAN PC has a route server, then just run open code and switch model. The installed models appear running or not. To update the advertised install models you can run ollama list and it updates it.
9. Troubleshoot
Diagnose
VMID=108
GPU=0000:09:00.0
qm start $VMID
echo "== config =="; qm config $VMID
echo "== cmdline =="; cat /proc/cmdline
echo "== driver =="; lspci -nnk -s ${GPU%.*}
echo "== modules =="; lsmod | grep -E 'vfio|amdgpu|radeon'
echo "== iommu groups =="
for f in /sys/bus/pci/devices/${GPU%.*}.*; do
g=$(basename "$(readlink "$f/iommu_group")")
echo "-- ${f##*/} in group $g"
for d in /sys/kernel/iommu_groups/$g/devices/*; do lspci -nns "${d##*/}"; done
done
echo "== kernel log =="; dmesg | grep -i -E 'vfio|iommu|amdgpu|bar|amd-vi' | tail -60
Fallbacks
# a) expose the VBIOS ROM
qm set 108 --hostpci0 0000:09:00,pcie=1,rombar=1
# b) pass only the GPU function, not the audio function
qm set 108 --hostpci0 0000:09:00.0,pcie=1,rombar=0
# c) update Proxmox/QEMU
apt update && apt full-upgrade
# d) pin the previous kernel
proxmox-boot-tool kernel list
# proxmox-boot-tool kernel pin <older-version>
# proxmox-boot-tool refresh
PCIe link health
dmesg | grep -iE 'pcieport|broken device|retraining|link'
# inside the guest
lspci -nnk | grep -iA3 amd
dmesg | grep -i amdgpu
rocm-smi