Bối cảnh: Khi iGPU nằm không mà CPU thì ngộp
Mình chạy homelab với Proxmox VE quản lý 12 VM và container — đây là playground để test mọi thứ trước khi đưa lên production. Một hôm mình muốn chạy Jellyfin trên VM để transcode video H.265 4K, nhưng CPU software transcode thì chậm khủng khiếp và ăn hết tài nguyên của cả cluster. Mua card GPU rời chỉ để transcode thì lãng phí, trong khi cái CPU Intel i7-8700 đang cắm trên board đã có iGPU UHD 630 nằm chơi không.
Đó là lúc mình đào ra Intel GVT-g (Graphics Virtualization Technology – graphics). Thay vì passthrough toàn bộ iGPU cho 1 VM như VFIO thông thường, GVT-g cho phép tạo nhiều vGPU ảo từ 1 iGPU vật lý và chia cho nhiều VM dùng đồng thời. Mỗi VM thấy một thiết bị đồ họa riêng, hoạt động độc lập.
Về tương thích phần cứng: GVT-g hỗ trợ từ Intel Broadwell (thế hệ 5) trở lên. Thực tế thì Skylake (thế hệ 6, series i-6xxx) mới ổn định và được test kỹ — board cũ hơn thì thử trước khi kỳ vọng nhiều.
Khi nào GVT-g phù hợp?
- Transcode video phần cứng (H.264/H.265) trong Plex hoặc Jellyfin chạy trên VM
- VM Windows cần GPU nhẹ để render giao diện, chạy ứng dụng đồ họa văn phòng
- VM Linux desktop cần hardware acceleration (WebGL, VA-API)
- Dev/test ứng dụng OpenCL trong môi trường ảo hóa
Nói thẳng: GVT-g không phải giải pháp cho gaming hay render 3D nặng — đó vẫn cần GPU rời với VFIO passthrough hoàn toàn. GVT-g phù hợp workload nhẹ đến vừa. Với homelab, đây là cách tận dụng phần cứng sẵn có mà không tốn thêm đồng nào.
Chuẩn bị môi trường trước khi bắt đầu
Kiểm tra phần cứng
Trước tiên, xác nhận host Proxmox đã nhận ra iGPU Intel chưa:
lspci | grep -i vga
# Kết quả mong đợi:
# 00:02.0 VGA compatible controller: Intel Corporation UHD Graphics 630 (rev 02)
# Kiểm tra driver i915 đã được load
lsmod | grep i915
Không thấy output từ lspci? Vào BIOS kiểm tra iGPU có bị disable không — một số board tự tắt iGPU khi cắm GPU rời.
Yêu cầu phần mềm
- Proxmox VE 7.x hoặc 8.x (khuyến nghị 8.x với kernel 6.2+)
- Kernel Linux 5.4 trở lên (Proxmox VE 7 dùng 5.15, VE 8 dùng 6.2+)
Cài đặt: Kích hoạt GVT-g từng bước
Bước 1: Bật VT-d trong BIOS/UEFI
Vào BIOS tìm mục VT-d (Intel Virtualization Technology for Directed I/O) và bật lên. Tên tùy theo board, thường nằm trong Advanced CPU Configuration hoặc Chipset Settings.
Bước 2: Thêm kernel parameters
Chỉnh file /etc/default/grub trên Proxmox host:
nano /etc/default/grub
Tìm dòng GRUB_CMDLINE_LINUX_DEFAULT và sửa thành:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt i915.enable_gvt=1"
Ba flag này làm gì:
intel_iommu=on— Kích hoạt IOMMU của Intel (VT-d)iommu=pt— Pass-through mode, giảm overhead cho thiết bị không cần IOMMUi915.enable_gvt=1— Bật tính năng GVT trong driver i915
update-grub
reboot
Bước 3: Load kernel modules cần thiết
Sau khi reboot, thêm các module vào /etc/modules:
echo "kvmgt" >> /etc/modules
echo "vfio-mdev" >> /etc/modules
echo "mdev" >> /etc/modules
# Load ngay mà không cần reboot
modprobe kvmgt
modprobe vfio-mdev
modprobe mdev
Kiểm tra GVT-g đã kích hoạt:
dmesg | grep -i gvt
# Output OK:
# [ 5.12] i915 0000:00:02.0: GVT-g enabled
# Xem các loại vGPU có thể tạo
ls /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/
# i915-GVTg_V5_1 i915-GVTg_V5_2 i915-GVTg_V5_4 i915-GVTg_V5_8
Cấu hình chi tiết: Tạo vGPU và gán cho VM
Chọn loại vGPU phù hợp
Proxmox liệt kê 4 loại vGPU, khác nhau ở dung lượng VRAM và số instance chạy đồng thời:
i915-GVTg_V5_1— 512MB VRAM, tối đa 7 instancesi915-GVTg_V5_2— 1GB VRAM, tối đa 3 instancesi915-GVTg_V5_4— 2GB VRAM, tối đa 1 instancei915-GVTg_V5_8— 2GB VRAM (high-res support), 1 instance
Với Jellyfin transcode, mình chọn V5_2 (1GB VRAM) cho 2 VM song song — vừa đủ và vẫn còn dư margin.
Tạo vGPU (mediated device)
# Sinh UUID cho vGPU
UUID1=$(uuidgen)
echo $UUID1
# VD: a297db4a-f4c2-11ee-b956-0242ac120002
# Tạo vGPU với type V5_2
echo "$UUID1" > /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/i915-GVTg_V5_2/create
# Xác nhận đã tạo
ls /sys/bus/mdev/devices/
# a297db4a-f4c2-11ee-b956-0242ac120002
Để vGPU tự động tạo lại sau mỗi lần reboot, viết systemd service:
cat > /etc/systemd/system/gvt-g-create.service << 'EOF'
[Unit]
Description=Create Intel GVT-g vGPU devices
After=syslog.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c 'echo "a297db4a-f4c2-11ee-b956-0242ac120002" > /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/i915-GVTg_V5_2/create'
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now gvt-g-create.service
Gán vGPU vào VM trong Proxmox
File config mỗi VM trong Proxmox nằm ở /etc/pve/qemu-server/. Với VM ID 100:
nano /etc/pve/qemu-server/100.conf
Paste dòng sau vào, thay UUID bằng cái vừa gen:
hostpci0: 0000:00:02.0,mdev=a297db4a-f4c2-11ee-b956-0242ac120002
Một điểm quan trọng mà mình mất khá nhiều thời gian mới tìm ra: VM phải dùng BIOS SeaBIOS và machine type i440fx, không phải OVMF/UEFI hay q35. GVT-g legacy mode chỉ hoạt động tốt với i440fx:
# Kiểm tra trong file conf VM
bios: seabios
machine: pc-i440fx-8.1
Khởi động VM và kiểm tra bên trong:
# Trong VM Linux
lspci | grep -i vga
# 00:02.0 VGA compatible controller: Intel Corporation ...
# Xem thông tin GPU
vainfo
# libva info: VA-API version 1.x.x
# libva info: Trying to open /dev/dri/renderD128
# vainfo: VA-API version: 1.x (libva 2.x.x)
# vainfo: Driver version: Intel i965 driver
Kiểm tra và Monitoring
Theo dõi GPU usage trên host
# Cài intel-gpu-tools
apt install intel-gpu-tools
# Real-time GPU usage
intel_gpu_top
# Xem residency (GPU có đang hoạt động không)
cat /sys/class/drm/card0/gt/gt0/rc6_residency_ms
Khi Jellyfin đang transcode 4K H.265, mình thấy VCS engine (Video Codec) chạy 60-80% trong intel_gpu_top — đó là dấu hiệu hardware transcoding đang hoạt động thay vì software.
Cấu hình Jellyfin dùng hardware transcoding
# Cho user jellyfin quyền đọc /dev/dri
usermod -aG render,video jellyfin
# Kiểm tra device
ls -la /dev/dri/
# crw-rw---- 1 root video 226, 0 card0
# crw-rw---- 1 root render 226, 128 renderD128
Trong Jellyfin Admin Dashboard → Playback → Transcoding: chọn Intel QuickSync (QSV) và bật H.264, H.265, VP9.
Một số lỗi hay gặp
“GVT-g is not enabled” — Chạy cat /proc/cmdline xem parameter i915.enable_gvt=1 có trong đó không. Nếu thiếu thì update-grub chưa được chạy đúng.
VM không nhận GPU sau khi boot — Thử thêm x-vga=1 vào dòng hostpci: hostpci0: 0000:00:02.0,mdev=UUID,x-vga=1. Một số CPU thế hệ cũ cần flag này.
Jellyfin vẫn transcode bằng software — Lỗi permission là thủ phạm 9/10. Chạy journalctl -u jellyfin | grep dri xem lỗi cụ thể, sau đó usermod -aG render jellyfin và restart service.
Sau vài tuần chạy setup này, Jellyfin transcode 4K H.265 trên VM chỉ dùng ~15% CPU thay vì 100% khi dùng software — toàn bộ cluster vẫn chạy mượt mà. Đây là cách tận dụng phần cứng đã có mà không phải chi thêm đồng nào cho GPU rời.

