AMD Strix Halo Local LLM Setup: Ollama, llama.cpp, and BIOS Configuration
Why This Setup Matters
Running large language models locally requires careful attention to memory allocation. The AMD Strix Halo series integrates GPU and CPU memory into a unified pool. Your BIOS settings determine how much VRAM is available for LLM inference.
This guide covers the configuration needed to run 70B+ parameter models on a Strix Halo system with 128GB RAM.
Hardware Context
Target System:
- AMD Strix Halo 395+ (16-core/32-thread)
- 128GB DDR5 unified memory
- Integrated RDNA3.5 graphics
Why This Configuration: The Strix Halo architecture uses true unified memory — the GPU and CPU share the same physical RAM pool. Unlike discrete GPUs with fixed VRAM, the AMD iGPU can dynamically access the full 128GB as needed.
The BIOS UMA Setting:
The “UMA Frame Buffer Size” in BIOS only pre-allocates a portion of RAM for the GPU at boot time. It does not limit the GPU’s maximum accessible memory. With proper kernel parameters (iommu=pt, amd_iommu=aperture), the GPU can dynamically allocate from the full 128GB pool regardless of the BIOS setting.
Practical Impact:
- 2GB BIOS UMA: GPU starts with 2GB pre-allocated, but can grow to use more as needed
- 4GB BIOS UMA: Slightly faster initial allocation, same maximum capacity
- Full 128GB accessible: Both configurations allow the GPU to use the entire memory pool for large models
This is why you can run 122B models without “CPU offloading” — the GPU accesses the full unified memory pool dynamically.
Step 1: BIOS Configuration
UMA Frame Buffer Size
The critical setting for LLM workloads is the UMA Frame Buffer Size (sometimes labeled “iGPU Memory” or “Integrated Graphics Memory”).
What to Change:
- Enter BIOS (typically
DelorF2during boot) - Navigate to
Advanced→AMD CBS→NBIO Common Options→GFX Configuration - Find UMA Frame Buffer Size
- Set to 2GB for models up to 35B parameters
- Set to 4GB or higher for models 70B+
Why 2GB Works for Testing: A 2GB allocation allows you to run smaller models (7B-14B) entirely on GPU while leaving 126GB+ for system RAM. For larger models that exceed GPU VRAM, llama.cpp automatically offloads layers to system RAM. You still get functional inference—just slower.
Tradeoffs:
- Higher UMA (4-8GB): Better performance for mid-sized models (35B-70B)
- Lower UMA (1-2GB): More system RAM available for multitasking
- Auto: System decides (often suboptimal for LLM workloads)
Recommendation: Start with 2GB. If you regularly run 70B models and have headroom, increase to 4GB.
Additional BIOS Settings
Disable Power Saving Features:
Global C-state Control→ DisabledCool'n'Quiet→ DisabledPower Supply Idle Control→ Typical Current Idle
These settings prevent the CPU from downclocking during inference, which can cause stuttering in real-time applications.
Enable Resizable BAR:
Above 4G Decoding→ EnabledRe-Size BAR Support→ Enabled
This allows the CPU to access the full GPU memory space at once, improving data transfer speeds for llama.cpp.
Step 2: Boot Parameters (GRUB Configuration)
After BIOS changes, ensure Linux recognizes the memory layout correctly.
Edit GRUB Configuration
sudo nano /etc/default/grub
Add These Kernel Parameters
Find the GRUB_CMDLINE_LINUX_DEFAULT line and add:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash iommu=pt amd_iommu=aperture=256M"
Parameter Breakdown:
iommu=pt- Pass-through mode for better GPU performanceamd_iommu=aperture=256M- Sets IOMMU aperture size for large memory mappings
For Systems With Memory Hotplug Issues
Some Strix Halo systems report incorrect memory totals without this parameter:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash iommu=pt amd_iommu=aperture=256M memmap=128G$0"
Warning: The memmap parameter forces the kernel to recognize exactly 128GB. Only use this if your system reports less than installed RAM.
Update GRUB and Reboot
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot
Verify Memory After Boot:
# Check total memory
free -h
# Check GPU memory recognition
radeontop # Requires root: sudo radeontop
# Check IOMMU status
dmesg | grep -i iommu
Step 3: Install llama.cpp
Clone and Build
# Install dependencies
sudo dnf install -y git cmake gcc gcc-c++ make
# Clone the repository
git clone https://github.com/ggerganov/llama.cpp.git
cd llama.cpp
# Build with GPU acceleration
make clean
LLAMA_CUDA=1 make -j$(nproc)
For AMD ROCm Support (Optional): If you want ROCm acceleration instead of CUDA compatibility layer:
# Install ROCm dependencies first
sudo dnf install -y rocm-dev hipblas rocblas
# Build with ROCm
make clean
LLAMA_HIPBLAS=1 make -j$(nproc)
Note: CUDA support via LLAMA_CUDA=1 works on AMD GPUs through the HIP compatibility layer. ROCm-native builds (LLAMA_HIPBLAS=1) offer better performance but require more setup.
Install System-Wide (Optional)
sudo make install
This installs binaries to /usr/local/bin, making llama-cli, llama-server, and other tools available globally.
Step 4: Install Ollama
Ollama provides a simpler interface for running models with automatic GPU detection and built-in model management.
Download and Install
curl -fsSL https://ollama.com/install.sh | sh
This script:
- Downloads the latest Ollama binary
- Installs it to
/usr/local/bin/ollama - Creates the
ollamaservice - Sets up automatic updates
Enable and Start Service
# Enable service to start on boot
sudo systemctl enable ollama
# Start the service now
sudo systemctl start ollama
# Verify it's running
sudo systemctl status ollama
Configure Ollama (Optional)
Set Environment Variables:
Create or edit /etc/systemd/system/ollama.service.d/environment.conf:
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_NUM_GPU=999"
Environment="OLLAMA_MAX_LOADED_MODELS=3"
Reload and Restart:
sudo systemctl daemon-reload
sudo systemctl restart ollama
Parameter Breakdown:
OLLAMA_HOST- Listen address (use127.0.0.1:11434for local-only)OLLAMA_NUM_GPU- Layers to offload to GPU (999 = all)OLLAMA_MAX_LOADED_MODELS- Max models in memory simultaneously
Verify Installation
# Check version
ollama --version
# List installed models
ollama list
# Check service status
sudo systemctl status ollama
Pull and Run Models
# Pull a 7B model for testing
ollama pull llama3.2
# Pull a larger model (requires significant RAM)
ollama pull llama3.1:70b
# Pull Qwen models
ollama pull qwen2.5:7b
ollama pull qwen2.5:32b
Run Inference
Interactive Mode:
ollama run llama3.2
You’ll drop into an interactive REPL where you can chat with the model. Type /bye to exit.
API Mode:
# Generate text via API
curl http://localhost:11434/api/generate -d '{
"model": "llama3.2",
"prompt": "Why is the sky blue?",
"stream": false
}'
# Chat completion
curl http://localhost:11434/api/chat -d '{
"model": "llama3.2",
"messages": [
{"role": "user", "content": "What is Linux?"}
],
"stream": false
}'
Manage Ollama Models
# Show model details
ollama show llama3.2
# Copy a model
ollama cp llama3.2 my-custom-model
# Delete a model
ollama rm llama3.1:70b
# Create a custom Modelfile
echo "FROM llama3.2" > Modelfile
echo "PARAMETER temperature 0.7" >> Modelfile
ollama create my-llama3 -f Modelfile
Ollama vs llama.cpp
| Feature | Ollama | llama.cpp |
|---|---|---|
| Setup | One-command install | Manual build |
| Model Management | Built-in library | Manual downloads |
| API | OpenAI-compatible | llama.cpp native |
| GPU Support | Automatic | Manual configuration |
| Customization | Limited | Full control |
| Best For | Quick deployment | Production tuning |
Recommendation: Use Ollama for quick setup and testing. Use llama.cpp with systemd for production deployments requiring fine-tuned performance.
For complete Ollama documentation, see: https://github.com/ollama/ollama/blob/main/docs
Step 5: Configure Model Quantization
Not all models need full precision. Quantization reduces memory requirements with minimal quality loss.
Understanding Quantization Levels
| Quantization | Memory (7B model) | Memory (70B model) | Quality |
|---|---|---|---|
| FP16 | 14GB | 140GB | Full |
| Q8_0 | 8GB | 80GB | ~99% |
| Q6_K | 6GB | 60GB | ~98% |
| Q4_K_M | 4GB | 40GB | ~95% |
| Q3_K_S | 3GB | 30GB | ~90% |
For 128GB Systems:
- Run Q8_0 for 7B models (8GB used, 120GB free)
- Run Q4_K_M for 70B models (40GB used, 88GB free)
- Run FP16 only for models under 35B
Download Quantized Models
# Using ollama (automatic quantization)
ollama pull llama3.2:1b # Smallest
ollama pull llama3.2:3b
ollama pull llama3.2:7b
ollama pull llama3.1:8b
ollama pull llama3.1:70b
# Using llama.cpp (manual GGUF files)
# Visit huggingface.co/TheBloke for quantized models
Step 6: Running Models with llama.cpp
Download the Model
For the Qwen3.5-122B-A10B model, download the quantized GGUF files:
# Create models directory
mkdir -p ~/models
cd ~/models
# Download the model (3-part GGUF, ~70GB total for Q4_K_XL)
wget https://huggingface.co/unsloth/Qwen3.5-122B-A10B-GGUF/resolve/main/Qwen3.5-122B-A10B-UD-Q4_K_XL-00001-of-00003.gguf
wget https://huggingface.co/unsloth/Qwen3.5-122B-A10B-GGUF/resolve/main/Qwen3.5-122B-A10B-UD-Q4_K_XL-00002-of-00003.gguf
wget https://huggingface.co/unsloth/Qwen3.5-122B-A10B-GGUF/resolve/main/Qwen3.5-122B-A10B-UD-Q4_K_XL-00003-of-00003.gguf
# Download the multimodal projector (required for this model)
wget https://huggingface.co/unsloth/Qwen3.5-122B-A10B-GGUF/resolve/main/mmproj-F16.gguf
Expected Sizes:
- Q4_K_XL quantization: ~70GB total (3 files)
- mmproj file: ~2GB
- Total disk space needed: ~75GB
Basic Inference (Testing Only)
# Quick test before setting up systemd service
./llama-cli -m ~/models/Qwen3.5-122B-A10B-UD-Q4_K_XL-00001-of-00003.gguf \
-p "What is quantum computing?" \
-n 256 \
-c 4096
Key Parameters:
-m- Model file path (first GGUF part)-p- Prompt-n- Number of tokens to generate-c- Context window size-t- Number of threads (default: all cores)-ngl- Number of layers to offload to GPU (999 = all)
GPU Offloading (For Testing)
# Offload all layers to GPU (fastest, for testing only)
# On Strix Halo, the GPU can access full 128GB dynamically
./llama-cli -m ~/models/Qwen3.5-122B-A10B-UD-Q4_K_XL-00001-of-00003.gguf \
-p "Your prompt here" -ngl 999
# Note: On Strix Halo with unified memory, -ngl 999 uses the full memory pool
# No partial offloading needed - the GPU dynamically allocates from 128GB
How -ngl Works on Strix Halo:
-ngl 999tells llama.cpp to load all layers into GPU memory- On Strix Halo, “GPU memory” = the full unified 128GB pool
- No need to manually calculate layer counts - the system handles dynamic allocation
- The BIOS UMA setting (2GB vs 4GB) only affects pre-allocation, not maximum capacity
Production Setup: systemd Service (Recommended)
For persistent operation, run llama-server as a systemd service. This is the recommended approach for production use.
Create the Service File:
sudo nano /etc/systemd/system/llama-server.service
Paste This Configuration:
[Unit]
Description=Llama.cpp ROCm Inference Engine (Strix Halo)
After=network.target
[Service]
Type=simple
User=james
WorkingDirectory=/home/james/llama.cpp
ExecStart=/home/james/llama.cpp/build/bin/llama-server \
-m /home/james/models/UD-Q4_K_XL/Qwen3.5-122B-A10B-UD-Q4_K_XL-00001-of-00003.gguf \
--mmproj /home/james/models/UD-Q4_K_XL/mmproj-F16.gguf \
--host 0.0.0.0 \
--port 8080 \
-c 131072 \
-b 2048 \
-ub 512 \
--parallel 1 \
--cache-type-k q8_0 \
--cache-type-v q8_0 \
--flash-attn on \
--timeout 600 \
--chat-template-kwargs '{"enable_thinking":true}'
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Customize These Paths:
User=james→ Your usernameWorkingDirectory→ Path to your llama.cpp buildExecStartpaths → Your actual model and binary locations
Parameter Breakdown:
-m- First GGUF part (llama.cpp auto-loads remaining parts)--mmproj- Multimodal projector (required for Qwen3.5-122B-A10B)--host 0.0.0.0- Listen on all interfaces (use127.0.0.1for local-only)-c 131072- Context window (128K for this model)-b 2048- Batch size-ub 512- Unbatch size--cache-type-k q8_0- KV cache quantization (saves VRAM)--flash-attn on- Flash attention for speed--timeout 600- Connection timeout (10 minutes)
Enable and Start the Service:
# Reload systemd to recognize new service
sudo systemctl daemon-reload
# Enable service to start on boot
sudo systemctl enable llama-server
# Start the service now
sudo systemctl start llama-server
# Check status
sudo systemctl status llama-server
Manage the Service:
# View logs
sudo journalctl -u llama-server -f
# Restart service
sudo systemctl restart llama-server
# Stop service
sudo systemctl stop llama-server
# Check if running
systemctl is-active llama-server
Test the API:
# Simple health check
curl http://localhost:8080/health
# Generate text
curl http://localhost:8080/completion \
-H "Content-Type: application/json" \
-d '{
"prompt": "Explain quantum entanglement simply.",
"n_predict": 512,
"temperature": 0.7
}'
# Chat completion (if supported)
curl http://localhost:8080/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "What is Linux?"}
],
"max_tokens": 512
}'
Troubleshooting the Service:
# View full logs
sudo journalctl -u llama-server --no-pager
# Check for OOM errors in logs
sudo journalctl -u llama-server | grep -i "out of memory"
# Verify port is listening
sudo ss -tlnp | grep 8080
# Check process status
ps aux | grep llama-server
Step 7: Performance Tuning
Thread Count Optimization
LLM inference scales with thread count up to a point. Test different values:
# Test with different thread counts
for threads in 8 12 16 20 24 28 32; do
echo "Testing with $threads threads:"
./llama-cli -m model.gguf -p "Benchmark prompt" -t $threads -n 128 --verbose
done
Typical Results:
- 16 cores (32 threads): Best for 7B-14B models
- 24-28 threads: Optimal for 35B models
- 32+ threads: Diminishing returns for most models
Memory Mapping
For large models, use memory mapping to avoid loading the entire file into RAM:
./llama-cli -m model.gguf -p "Prompt" --mlock # Lock in RAM (faster but uses more)
./llama-cli -m model.gguf -p "Prompt" --no-mmap # Load entirely (slower startup)
Recommendation: Use --mlock if you have enough RAM. It prevents swapping during inference.
Batch Size Tuning
./llama-cli -m model.gguf -p "Prompt" -b 512 # Default batch size
./llama-cli -m model.gguf -p "Prompt" -b 2048 # Larger batch (faster but more VRAM)
Increase -b until you hit VRAM limits, then reduce.
Troubleshooting
OOM Errors
Symptoms: Model fails to load, “out of memory” errors
Fixes:
- Reduce
-ngl(fewer GPU layers) - Use a more quantized model (Q4 instead of Q8)
- Increase UMA Frame Buffer in BIOS
- Close other GPU-intensive applications
Slow Inference
Symptoms: Less than 5 tokens/second on 7B model
Fixes:
- Verify GPU offloading:
./llama-cli -m model.gguf -p "test" -ngl 999 - Check thermal throttling:
sensors(look for high temps) - Disable power saving: Set CPU governor to
performancesudo cpupower frequency-set -g performance - Verify IOMMU settings:
dmesg | grep iommu
Model Not Recognizing GPU
Symptoms: “No GPU found” or “falling back to CPU”
Fixes:
- Rebuild llama.cpp with correct flags
- Check ROCm/CUDA installation:
rocminfoornvidia-smi - Verify kernel parameters:
cat /proc/cmdline - Update GPU drivers:
sudo dnf upgrade --refresh
Memory Not Recognized
Symptoms: System reports 64GB instead of 128GB
Fixes:
- Add
memmap=128G$0to GRUB parameters - Check BIOS memory settings
- Reseat RAM modules
- Update BIOS to latest version
Example: Running Qwen3.5-122B-A10B
For very large models like Qwen3.5-122B-A10B, use the systemd service configuration above. The model requires:
- 70GB disk space (Q4_K_XL quantization, 3-part GGUF)
- ~40-50GB RAM when loaded (with partial GPU offloading)
- 2GB+ UMA in BIOS for reasonable performance
- Context window: 128K tokens
Optimization Tips:
- Quantization: Q4_K_XL balances quality and memory for 122B models
- GPU Offloading: Start with 20-40 layers, adjust based on VRAM
- KV Cache: Use
--cache-type-k q8_0to reduce memory pressure - Flash Attention: Enable with
--flash-attn onfor faster inference - Batch Size:
-b 2048works well; increase if you have headroom
API Usage Example:
Once the service is running, interact via API:
# Simple completion
curl http://localhost:8080/completion \
-H "Content-Type: application/json" \
-d '{
"prompt": "Explain quantum entanglement in simple terms.",
"n_predict": 1024,
"temperature": 0.7,
"stop": ["</s>"]
}'
# With thinking enabled (Qwen3.5 feature)
curl http://localhost:8080/completion \
-H "Content-Type: application/json" \
-d '{
"prompt": "Solve this math problem step by step.",
"n_predict": 2048,
"temperature": 0.5,
"chat_template_kwargs": {"enable_thinking": true}
}'
Monitor Resource Usage:
# Watch VRAM usage
watch -n 2 rocm-smi
# Check service logs
sudo journalctl -u llama-server -f
# Monitor memory pressure
htop # Look for llama-server process
Next Steps
Once your system is configured:
- Benchmark different quantizations to find your quality/speed sweet spot
- Set up a model registry with your most-used models
- Explore Ollama modelfiles for custom model configurations
- Consider Docker containers for isolated model environments
- Monitor thermal performance during extended inference sessions
Resources
- llama.cpp Documentation: https://github.com/ggerganov/llama.cpp
- Ollama Documentation: https://ollama.com/docs
- GGUF Model Repository: https://huggingface.co/TheBloke
- AMD ROCm Documentation: https://rocm.docs.amd.com/
- Nobara Linux: https://nobara-project.org/
This guide was created for the LivingOnLinux YouTube series. The accompanying video covers unboxing, physical setup, and live demonstrations of these commands.