- Posted on
- • Artificial Intelligence
Artificial Intelligence VM Case Studies
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence VM Case Studies: Practical Patterns for Linux Bash Users
Ever had a working AI stack break after a system update? Or wished you could sandbox a risky experiment without risking your main OS? With a Linux box, KVM, and a few Bash one-liners, you can spin up reliable, reproducible AI environments in minutes—complete with snapshots, isolation, and optional GPU passthrough. This post walks through real VM-based AI setups you can copy and adapt today.
What you’ll get:
Why VMs still matter for AI in 2026
A quick, distro-agnostic setup checklist
Three hands-on case studies (CPU farm, GPU passthrough dev box, and a reproducible research sandbox)
A tuning checklist for better performance
Why AI in VMs is worth it
Reproducibility: Pin OS, drivers, libraries. Snapshot. Roll back. Share the exact image with a teammate.
Isolation and security: Keep untrusted notebooks, data, or model evals cordoned off. Perfect for compliance or air-gapped work.
Controlled upgrades: Test CUDA, ROCm, kernels, and toolchains in a VM before touching the host.
Portability: Move your VM from workstation to cloud to lab server unchanged.
Resource pooling: Use CPU farms for batch inference; use passthrough for one powerful GPU VM when needed.
Prereqs: Verify virtualization and install the stack
1) Check hardware virtualization:
lscpu | grep -i virtualization
egrep -q 'vmx|svm' /proc/cpuinfo && echo "HW virt: OK" || echo "HW virt: MISSING"
lsmod | grep kvm
2) Install KVM/QEMU, libvirt, virt-install, virt-manager, UEFI firmware (OVMF), and cloud-init tools.
Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager virtinst ovmf cloud-image-utils genisoimage qemu-guest-agent
Fedora/RHEL (dnf):
sudo dnf install -y @virtualization virt-install virt-manager edk2-ovmf cloud-utils genisoimage qemu-guest-agent
sudo systemctl enable --now libvirtd
openSUSE/SLES (zypper):
sudo zypper install -y qemu-kvm libvirt-daemon libvirt-client bridge-utils virt-manager virt-install ovmf cloud-init cloud-guest-utils genisoimage qemu-guest-agent
3) Enable libvirt, add your user, and activate the default network:
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm $USER
newgrp libvirt
virsh net-start default || true
virsh net-autostart default
4) Grab a base cloud image:
mkdir -p ~/vm-images && cd ~/vm-images
wget -c https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
Note: Virt tools are distro-agnostic; your VMs can run any supported guest OS (Ubuntu, Rocky, openSUSE, etc.).
Case Study 1: CPU-only inference farm you can scale in minutes
Goal: Build several small VMs to run batched CPU inference services with FastAPI + ONNX Runtime. Easy to clone, snapshot, and autoscale by count.
1) Create cloud-init files:
cd ~/vm-images
cat > user-data.yaml <<'YAML'
#cloud-config
users:
- name: ai
groups: [sudo]
sudo: ['ALL=(ALL) NOPASSWD:ALL']
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA...your_ssh_key_here
package_update: true
packages:
- python3
- python3-venv
- python3-pip
runcmd:
- python3 -m pip install --upgrade pip onnxruntime uvicorn fastapi
- |
cat >/home/ai/app.py <<'PY'
from fastapi import FastAPI
import onnxruntime as ort
app = FastAPI()
@app.get("/health")
def health():
return {"ok": True, "providers": ort.get_available_providers()}
PY
- chown ai:ai /home/ai/app.py
- |
cat >/etc/systemd/system/inference.service <<'UNIT'
[Unit]
Description=Minimal inference API
After=network-online.target
[Service]
User=ai
WorkingDirectory=/home/ai
ExecStart=/usr/bin/python3 -m uvicorn app:app --host 0.0.0.0 --port 8000
Restart=always
[Install]
WantedBy=multi-user.target
UNIT
- systemctl daemon-reload
- systemctl enable --now inference
YAML
cat > meta-data.yaml <<'YAML'
instance-id: ai-cpu-1
local-hostname: ai-cpu-1
YAML
Build a NoCloud seed ISO (use whichever tool is available):
Option A (cloud-localds):
cloud-localds ai-seed.iso user-data.yaml meta-data.yaml
Option B (genisoimage):
genisoimage -output ai-seed.iso -volid cidata -joliet -rock user-data.yaml meta-data.yaml
2) Create the first VM:
virt-install \
--name ai-cpu-1 \
--memory 4096 --vcpus 4 \
--cpu host-passthrough \
--disk path=$HOME/vm-images/ai-cpu-1.qcow2,backing_store=$HOME/vm-images/jammy-server-cloudimg-amd64.img,format=qcow2,size=20 \
--disk path=$HOME/vm-images/ai-seed.iso,device=cdrom \
--network network=default,model=virtio \
--graphics none \
--import --os-variant ubuntu22.04
3) Discover the IP and test:
virsh domifaddr ai-cpu-1
curl http://<VM-IP>:8000/health
4) Scale to N instances (update instance-id per VM for clean cloud-init runs):
for i in 2 3; do
sed "s/ai-cpu-1/ai-cpu-$i/g" meta-data.yaml > meta-$i.yaml
cloud-localds ai-seed-$i.iso user-data.yaml meta-$i.yaml
virt-install \
--name ai-cpu-$i \
--memory 4096 --vcpus 4 --cpu host-passthrough \
--disk path=$HOME/vm-images/ai-cpu-$i.qcow2,backing_store=$HOME/vm-images/jammy-server-cloudimg-amd64.img,format=qcow2,size=20 \
--disk path=$HOME/vm-images/ai-seed-$i.iso,device=cdrom \
--network network=default,model=virtio \
--graphics none --import --os-variant ubuntu22.04
done
Optional (manual installs inside a guest, if not using cloud-init):
- apt:
sudo apt update && sudo apt install -y python3 python3-venv python3-pip
- dnf:
sudo dnf install -y python3 python3-pip
- zypper:
sudo zypper install -y python3 python3-pip
Case Study 2: Single-GPU passthrough dev VM for training and prototyping
Goal: Give a VM full access to a discrete GPU for CUDA/ROCm-based work without polluting your host.
Warning: GPU passthrough can make a system unbootable if misconfigured. Back up, keep a rescue USB handy, and document each change.
1) Ensure IOMMU is enabled:
- Edit /etc/default/grub and add one of:
- Intel: intel_iommu=on iommu=pt
- AMD: amd_iommu=on iommu=pt
Regenerate bootloader:
- Debian/Ubuntu (apt):
sudo update-grub
sudo reboot
- Fedora/RHEL (dnf):
sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg # UEFI
# or, for BIOS:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot
- openSUSE/SLES (zypper):
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot
Verify after reboot:
dmesg | egrep -i 'iommu|dmar'
2) Bind the GPU to vfio-pci on the host:
GPU=$(lspci -nn | awk '/VGA.*(NVIDIA|AMD)/{print $1}')
AUDIO=$(lspci -nn | awk '/Audio.*(NVIDIA|AMD)/{print $1}')
echo "GPU=$GPU AUDIO=$AUDIO"
lspci -nn -s $GPU
lspci -nn -s $AUDIO
echo "options vfio-pci ids=$(lspci -nn -s $GPU | sed -n 's/.*\[\(....:....\)\].*/\1/p'),$(lspci -nn -s $AUDIO | sed -n 's/.*\[\(....:....\)\].*/\1/p') disable_vga=1" | sudo tee /etc/modprobe.d/vfio.conf
NVIDIA hosts often need nouveau blacklisted:
echo -e "blacklist nouveau\noptions nouveau modeset=0" | sudo tee /etc/modprobe.d/blacklist-nouveau.conf
Rebuild initramfs and reboot:
- Debian/Ubuntu (apt):
sudo update-initramfs -u && sudo reboot
- Fedora/RHEL/openSUSE (dnf/zypper):
sudo dracut -f && sudo reboot
Confirm vfio-pci is bound:
lspci -k -s $GPU
lspci -k -s $AUDIO
# Look for "Kernel driver in use: vfio-pci"
3) Create a GPU VM with UEFI and hostdev mappings:
virt-install \
--name ai-gpu-dev \
--memory 16384 --vcpus 8 \
--cpu host-passthrough,cache.mode=passthrough \
--hugepages \
--disk path=$HOME/vm-images/ai-gpu-dev.qcow2,size=100,format=qcow2,cache=none,discard=unmap \
--disk path=$HOME/vm-images/ai-seed.iso,device=cdrom \
--network network=default,model=virtio \
--graphics spice --video virtio \
--hostdev $GPU \
--hostdev $AUDIO \
--boot uefi \
--os-variant ubuntu22.04
Inside the VM:
Install the vendor GPU driver and toolkit (CUDA/ROCm) appropriate for the guest OS and kernel following the vendor’s official instructions.
Then install your frameworks (e.g., PyTorch, TensorFlow) in a venv/conda environment.
Tip: For large datasets, mount a host directory with virtiofs for speed:
# On modern libvirt/QEMU, add a virtiofs share
virsh edit ai-gpu-dev
# Add within <devices>:
# <filesystem type='mount' accessmode='passthrough'>
# <driver type='virtiofs'/>
# <source dir='/data/datasets'/>
# <target dir='datasets'/>
# </filesystem>
Then inside the VM:
sudo mkdir -p /mnt/datasets
sudo mount -t virtiofs datasets /mnt/datasets
Case Study 3: Reproducible research sandbox with Jupyter over SSH
Goal: A clean, versioned, and shareable environment for experiments. No open ports; access via SSH tunnel.
1) Create cloud-init to set up Jupyter Lab:
cd ~/vm-images
cat > research-user-data.yaml <<'YAML'
#cloud-config
users:
- name: ai
groups: [sudo]
sudo: ['ALL=(ALL) NOPASSWD:ALL']
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA...your_ssh_key_here
package_update: true
packages:
- python3
- python3-pip
runcmd:
- python3 -m pip install --upgrade pip
- python3 -m pip install jupyterlab numpy pandas matplotlib scikit-learn
- |
cat >/etc/systemd/system/jupyter.service <<'UNIT'
[Unit]
Description=Jupyter Lab (loopback only)
After=network-online.target
[Service]
User=ai
ExecStart=/usr/bin/python3 -m jupyter lab --ip 127.0.0.1 --no-browser --NotebookApp.token='' --NotebookApp.password=''
Restart=on-failure
[Install]
WantedBy=multi-user.target
UNIT
- systemctl daemon-reload
- systemctl enable --now jupyter
YAML
cat > research-meta.yaml <<'YAML'
instance-id: ai-research-1
local-hostname: ai-research-1
YAML
cloud-localds research-seed.iso research-user-data.yaml research-meta.yaml \
|| genisoimage -output research-seed.iso -volid cidata -joliet -rock research-user-data.yaml research-meta.yaml
2) Start the VM:
virt-install \
--name ai-research-1 \
--memory 8192 --vcpus 4 --cpu host-passthrough \
--disk path=$HOME/vm-images/ai-research-1.qcow2,backing_store=$HOME/vm-images/jammy-server-cloudimg-amd64.img,format=qcow2,size=40 \
--disk path=$HOME/vm-images/research-seed.iso,device=cdrom \
--network network=default,model=virtio \
--graphics none --import --os-variant ubuntu22.04
3) Tunnel to Jupyter securely:
VMIP=$(virsh domifaddr ai-research-1 | awk '/ipv4/{print $4}' | cut -d/ -f1)
ssh -L 8888:127.0.0.1:8888 ai@$VMIP
# Open http://localhost:8888 in your browser
Optional (inside the VM, extra tooling):
- apt:
sudo apt update && sudo apt install -y git podman
- dnf:
sudo dnf install -y git podman
- zypper:
sudo zypper install -y git podman
Performance tuning checklist (copy/paste ready)
- Use host CPU features for better vectorization:
virsh setvcpus <vm> <n> --config
virsh setmem <vm> <bytes> --config
# In virt-install: --cpu host-passthrough
- Hugepages for better memory performance (host):
echo 4096 | sudo tee /proc/sys/vm/nr_hugepages
# Then add --hugepages to virt-install and ensure the VM memory fits in hugepages.
Paravirtualized drivers:
- Use virtio for network and disks (default with virt-install above).
- Use virtiofs to share large datasets read-mostly from host.
Disk format and caching:
# Use qcow2 for snapshots, raw for max performance.
# Consider cache=none, discard=unmap for better I/O semantics with SSD/NVMe.
- NUMA and pinning (advanced):
virsh vcpupin <vm> 0 0
virsh vcpupin <vm> 1 1
# Pin vCPUs to host cores near your PCIe root complex if doing GPU passthrough.
Troubleshooting quick notes
- Can’t get an IP? Ensure the default libvirt network is active:
virsh net-list --all
virsh net-start default
Cloud-init didn’t run as expected? Increment instance-id in meta-data and reboot, or recreate the VM.
GPU not bound to vfio-pci? Secure Boot, initramfs, or driver blacklists might be interfering. Confirm:
lspci -k -s $GPU
sudo dmesg | grep -i vfio
Conclusion and next steps
You don’t need a cluster to build robust AI workflows. Start with the CPU inference farm to get the hang of cloud-init and virt-install. Once you’re comfortable, graduate to GPU passthrough for heavier training workloads. Keep your research sandbox as a reproducible “golden image” you can share with your team.
Call to action:
Pick one case study and implement it today.
Snapshot your working VM.
Measure performance changes as you apply the tuning checklist.
Share your Bash and XML snippets with the team so everyone can spin up identical environments.
If you’d like a follow-up deep dive (multi-node VM clusters, SR-IOV vGPU, or CI-driven VM image builds), let me know which topic you want first.