deploy hermes
This commit is contained in:
281
docs/astro-orbiter-gpu-passthrough.md
Normal file
281
docs/astro-orbiter-gpu-passthrough.md
Normal file
@@ -0,0 +1,281 @@
|
||||
# astro-orbiter: AMD GPU Passthrough & Ollama/ROCm Setup
|
||||
|
||||
**Host:** `tomorrowland` (10.1.71.12) — Proxmox node
|
||||
**VM:** `astro-orbiter` (10.1.71.130, VM ID 71130)
|
||||
**GPU:** MSI Radeon RX 5700 (Navi 10, gfx1010) via Minisforum DEG1 eGPU dock + OCuLink
|
||||
**Purpose:** Ollama inference host for `jarvis` AI assistant
|
||||
**Date:** 2026-05-25
|
||||
|
||||
---
|
||||
|
||||
## Hardware
|
||||
|
||||
- Minisforum MS-01 (`tomorrowland`)
|
||||
- Minisforum DEG1 eGPU dock connected via M.2 OCuLink
|
||||
- MSI Radeon RX 5700 8GB
|
||||
- Montech BETA 2 650W ATX PSU powering the eGPU dock
|
||||
|
||||
---
|
||||
|
||||
## Part 1: tomorrowland Host Setup
|
||||
|
||||
### 1.1 Network Interface Rename (eGPU side effect)
|
||||
|
||||
Adding the eGPU dock shifted PCIe bus numbers, renaming all NICs. Fix:
|
||||
|
||||
```bash
|
||||
# Back up interfaces config
|
||||
cp /etc/network/interfaces /etc/network/interfaces.bak
|
||||
|
||||
# Apply renames (adjust if hardware differs)
|
||||
sed -i 's/enp87s0/enp93s0/g' /etc/network/interfaces
|
||||
sed -i 's/enp2s0f0np0/enp5s0f0np0/g' /etc/network/interfaces
|
||||
sed -i 's/enp2s0f0np1/enp5s0f0np1/g' /etc/network/interfaces
|
||||
|
||||
# Reboot to apply (do from console/JetKVM, not SSH)
|
||||
reboot
|
||||
```
|
||||
|
||||
### 1.2 Verify GPU Enumeration
|
||||
|
||||
After reboot, confirm the GPU is visible:
|
||||
|
||||
```bash
|
||||
lspci | grep -i amd
|
||||
# Expected:
|
||||
# 01:00.0 PCI bridge: AMD/ATI Navi 10 XL Upstream Port
|
||||
# 02:00.0 PCI bridge: AMD/ATI Navi 10 XL Downstream Port
|
||||
# 03:00.0 VGA compatible controller: AMD/ATI Navi 10 [Radeon RX 5600/5700]
|
||||
# 03:00.1 Audio device: AMD/ATI Navi 10 HDMI Audio
|
||||
```
|
||||
|
||||
### 1.3 Verify IOMMU
|
||||
|
||||
```bash
|
||||
dmesg | grep -i iommu | head -5
|
||||
# Must show: iommu: Default domain type: Translated
|
||||
|
||||
# Verify GPU is in its own IOMMU groups (no ACS override needed)
|
||||
find /sys/kernel/iommu_groups/*/devices/ -name "*03:00*"
|
||||
# Expected: groups 17 and 18, one device each
|
||||
```
|
||||
|
||||
### 1.4 Blacklist amdgpu and Bind vfio-pci
|
||||
|
||||
```bash
|
||||
# Blacklist host GPU drivers
|
||||
echo "blacklist amdgpu
|
||||
blacklist radeon" > /etc/modprobe.d/blacklist-amdgpu.conf
|
||||
|
||||
# Bind vfio-pci to the GPU at boot
|
||||
# 1002:731f = RX 5700 VGA, 1002:ab38 = Navi 10 HDMI Audio
|
||||
echo "options vfio-pci ids=1002:731f,1002:ab38" > /etc/modprobe.d/vfio.conf
|
||||
|
||||
# Load vfio modules early
|
||||
echo "vfio
|
||||
vfio_iommu_type1
|
||||
vfio_pci
|
||||
vfio_virqfd" > /etc/modules-load.d/vfio.conf
|
||||
|
||||
# Rebuild initramfs and reboot
|
||||
update-initramfs -u -k all
|
||||
reboot
|
||||
```
|
||||
|
||||
Verify after reboot:
|
||||
```bash
|
||||
lspci -k -s 03:00.0
|
||||
# Must show: Kernel driver in use: vfio-pci
|
||||
|
||||
lspci -k -s 03:00.1
|
||||
# Must show: Kernel driver in use: vfio-pci
|
||||
```
|
||||
|
||||
### 1.5 Fix GPU D3 Power State on VM Restart (Required — RX 5700 lacks FLR)
|
||||
|
||||
The RX 5700 does not support PCIe Function Level Reset (FLR). Without a fix,
|
||||
the GPU gets stuck in D3 power state on every VM restart, requiring a full host
|
||||
reboot to recover.
|
||||
|
||||
**Fix: `pcie_port_pm=off` kernel parameter**
|
||||
|
||||
`vendor-reset` was attempted but causes a QEMU PCI IRQ assertion failure
|
||||
(`pci_irq_handler: Assertion 0 <= irq_num`) on PVE 7.0.2 with this hardware.
|
||||
`pcie_port_pm=off` prevents the card from entering D3 entirely and is the
|
||||
correct solution for this setup.
|
||||
|
||||
```bash
|
||||
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="pcie_port_pm=off /' /etc/default/grub
|
||||
update-grub
|
||||
reboot
|
||||
```
|
||||
|
||||
Verify after reboot — VM should restart cleanly without host reboot:
|
||||
```bash
|
||||
qm reboot 71130
|
||||
# wait 30 seconds
|
||||
ssh wed@astro-orbiter 'lsmod | grep amdgpu'
|
||||
# Should be non-empty
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Part 2: astro-orbiter VM Provisioning
|
||||
|
||||
### 2.1 Terraform Provisioning
|
||||
|
||||
VM was provisioned manually (not via NetBox pipeline) due to PCIe passthrough
|
||||
requirements. Run from `city-hall`:
|
||||
|
||||
```bash
|
||||
cd /opt/git/homelab/terraform/proxmox/vm
|
||||
|
||||
terraform apply \
|
||||
-var='proxmox_api_url=https://fantasyland.local.mk-labs.cloud:8006' \
|
||||
-var='proxmox_api_token=terraform@pve!terraform-token=<secret>' \
|
||||
-var='vm_id=71130' \
|
||||
-var='hostname=astro-orbiter' \
|
||||
-var='ip_address=10.1.71.130' \
|
||||
-var='target_node=tomorrowland' \
|
||||
-var='template_name=ubuntu-24.04-large' \
|
||||
-var='datastore=liberty-tree' \
|
||||
-var='data_disk_enabled=true' \
|
||||
-var='data_disk_size=128' \
|
||||
-var='data_disk_datastore=utilidor'
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
- `datastore=liberty-tree` for OS disk — iSCSI storage does not support EFI disk
|
||||
cloning from templates. OS disk stays on Ceph.
|
||||
- `data_disk_datastore=utilidor` for model storage — fresh disk creation works fine
|
||||
on iSCSI.
|
||||
- `pcie_passthrough_enabled` is NOT passed — the `bpg/proxmox` provider's
|
||||
`dynamic "hostpci"` block does not work reliably. PCIe passthrough is applied
|
||||
manually via `qm set` after provisioning (see 2.2).
|
||||
|
||||
### 2.2 Post-Provisioning: PCIe and Machine Type
|
||||
|
||||
The template uses `i440fx` machine type. PCIe passthrough requires `q35`.
|
||||
Run after Terraform provisioning, with VM shut down:
|
||||
|
||||
```bash
|
||||
# Switch to q35 machine type (required for PCIe passthrough)
|
||||
qm set 71130 -machine q35
|
||||
|
||||
# Add GPU passthrough (both VGA and audio functions)
|
||||
qm set 71130 -hostpci0 0000:03:00,pcie=1,rombar=1
|
||||
|
||||
# Add data disk on utilidor
|
||||
qm set 71130 -scsi1 utilidor:128,format=raw,discard=on
|
||||
|
||||
# Increase RAM to 8GB
|
||||
qm set 71130 -memory 8192
|
||||
|
||||
# Start the VM
|
||||
qm start 71130
|
||||
```
|
||||
|
||||
Verify config landed:
|
||||
```bash
|
||||
qm config 71130 | grep -E "hostpci|machine|memory|scsi1"
|
||||
```
|
||||
|
||||
### 2.3 Ansible Deployment
|
||||
|
||||
From `city-hall` in the `ansible/` directory:
|
||||
|
||||
```bash
|
||||
# OS baseline
|
||||
ansible-playbook playbooks/day0_baseline.yml --limit astro-orbiter --ask-vault-pass
|
||||
|
||||
# Ollama + ROCm
|
||||
ansible-playbook playbooks/day1_deploy_ollama.yml --ask-vault-pass
|
||||
```
|
||||
|
||||
The `day1_deploy_ollama.yml` playbook includes a pre-flight `lspci` check that
|
||||
will fail fast if the GPU is not visible to the VM.
|
||||
|
||||
---
|
||||
|
||||
## Part 3: Verification
|
||||
|
||||
### 3.1 GPU visible in VM
|
||||
```bash
|
||||
lspci | grep -i amd
|
||||
# Expected: 01:00.0 VGA ... Navi 10 [Radeon RX 5600/5700]
|
||||
# 01:00.1 Audio ... Navi 10 HDMI Audio
|
||||
```
|
||||
|
||||
### 3.2 amdgpu driver loaded
|
||||
```bash
|
||||
lsmod | grep amdgpu
|
||||
# Should show amdgpu and dependent modules
|
||||
```
|
||||
|
||||
### 3.3 ROCm sees the GPU
|
||||
```bash
|
||||
/opt/rocm/bin/rocm-smi
|
||||
# Should show Device 0 with VRAM%, GPU%, temperature
|
||||
```
|
||||
|
||||
### 3.4 Ollama GPU inference
|
||||
```bash
|
||||
ollama run qwen3:8b "say hello"
|
||||
# While running, check rocm-smi — GPU% and power draw should spike
|
||||
/opt/rocm/bin/rocm-smi
|
||||
# GPU% > 0%, power > 18W idle = GPU is doing inference
|
||||
```
|
||||
|
||||
### 3.5 VM restart test
|
||||
```bash
|
||||
# On tomorrowland:
|
||||
qm reboot 71130
|
||||
# Wait 30 seconds, then on astro-orbiter:
|
||||
lsmod | grep amdgpu
|
||||
# Should be non-empty — if empty, vendor-reset is not working
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Known Issues & Lessons Learned
|
||||
|
||||
| Issue | Cause | Fix |
|
||||
|---|---|---|
|
||||
| NIC names changed after eGPU install | PCIe bus renumbering | Update `/etc/network/interfaces` with new names |
|
||||
| `can't allocate space in iscsi storage` on clone | iSCSI doesn't support EFI disk cloning | Use `liberty-tree` for OS disk |
|
||||
| `q35 machine model is not enabled` on hostpci | Template built with i440fx | `qm set <vmid> -machine q35` before adding hostpci |
|
||||
| GPU stuck in D3 on VM restart | RX 5700 lacks FLR support | `pcie_port_pm=off` kernel param on host. `vendor-reset` builds but causes QEMU PCI IRQ assertion failure on PVE 7.0.2 — do not use. |
|
||||
| `dynamic "hostpci"` block not applying | `bpg/proxmox` provider limitation | Use `qm set` workaround post-provisioning |
|
||||
| `rocm-smi` not in PATH | ROCm installs to `/opt/rocm-6.2.0/bin/` | `/etc/profile.d/rocm.sh` sets PATH (via Ansible role) |
|
||||
| Ollama install script 404 | `OLLAMA_VERSION=latest` is not a valid version string | Omit env var when version is `latest` — script self-determines |
|
||||
|
||||
---
|
||||
|
||||
## ROCm Configuration
|
||||
|
||||
The RX 5700 is RDNA 1 (gfx1010). ROCm's official support starts at gfx1030
|
||||
(RDNA 2). The `HSA_OVERRIDE_GFX_VERSION=10.1.0` environment variable tells ROCm
|
||||
to treat the GPU as a supported target.
|
||||
|
||||
This is set via systemd drop-in at:
|
||||
`/etc/systemd/system/ollama.service.d/override.conf`
|
||||
|
||||
```ini
|
||||
[Service]
|
||||
Environment="OLLAMA_HOST=0.0.0.0:11434"
|
||||
Environment="OLLAMA_MODELS=/var/lib/ollama"
|
||||
Environment="HSA_OVERRIDE_GFX_VERSION=10.1.0"
|
||||
Environment="ROCR_VISIBLE_DEVICES=0"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Parking Lot
|
||||
|
||||
- **P.PACKER:** Ubuntu VM templates should be built with `machine: q35` by default
|
||||
to support PCIe passthrough without manual intervention.
|
||||
- **P.TERRAFORM:** Fix `bpg/proxmox` provider `hostpci` dynamic block or find
|
||||
correct syntax for the installed provider version.
|
||||
- **P.PIPELINE:** Update n8n workflow to pass `data_disk_enabled`, `data_disk_size`,
|
||||
and `pcie_device_id` from NetBox custom fields to Terraform for pipeline-driven
|
||||
GPU VM provisioning.
|
||||
Reference in New Issue
Block a user