# Qwen3-4B on llama.cpp with ROCm (AMD BC-250)

> Running **Qwen3-4B-Q8_0** via **llama.cpp** with **ROCm HIP** GPU acceleration on the **AMD BC-250 (gfx1010)**.

---

## Table of Contents

- [System Overview](#system-overview)
- [Prerequisites](#prerequisites)
- [Step 1: Clone llama.cpp](#step-1-clone-llamacpp)
- [Step 2: Build llama.cpp with ROCm HIP](#step-2-build-llamacpp-with-rocm-hip)
- [Step 3: Download the Model](#step-3-download-the-model)
- [Step 4: Run Inference (Interactive Chat)](#step-4-run-inference-interactive-chat)
- [Step 5: Run Inference (One-Shot / Batch)](#step-5-run-inference-one-shot--batch)
- [Step 6: Run as API Server](#step-6-run-as-api-server)
- [Performance Results](#performance-results)
- [VRAM / Memory Breakdown](#vram--memory-breakdown)
- [Useful Parameters Reference](#useful-parameters-reference)
- [Troubleshooting](#troubleshooting)
- [Notes & Tips](#notes--tips)

---

## System Overview

| Component        | Value                                         |
|------------------|-----------------------------------------------|
| **GPU**          | AMD BC-250 (Navi 10, gfx1010)                 |
| **VRAM**         | ~14.4 GiB (14750 MiB)                         |
| **Wave Size**    | 32                                            |
| **ROCm Version** | 7.2.0                                         |
| **HIP Version**  | 7.2.26043-9999                                |
| **HIP Compiler** | AMD clang 22.0.0git (ROCm LLVM)               |
| **OS**           | CachyOS (Arch-based), Kernel 6.18.8-3-cachyos |
| **CPU**          | 12 threads                                    |
| **RAM**          | 14 GiB system + 14 GiB swap                   |
| **llama.cpp**    | Build b8184 (commit `3191462`)                 |
| **CMake**        | 4.2.3                                         |

---

## Prerequisites

Before starting, ensure you have:

1. **ROCm installed and working** — verify with:
   ```bash
   rocm-smi
   rocminfo | grep -E "Name:|gfx"
   ```

2. **Required packages**:
   ```bash
   # Arch/CachyOS
   sudo pacman -S git cmake base-devel aria2

   # Ubuntu/Debian
   sudo apt install git cmake build-essential aria2
   ```

3. **ROCm development libraries** (hipblas, rocblas):
   ```bash
   # Verify they exist
   ls /opt/rocm/lib/libhipblas.so
   ls /opt/rocm/lib/librocblas.so
   ls /opt/rocm/lib/llvm/bin/clang++
   ```

4. **Know your GPU architecture**:
   ```bash
   rocminfo | grep "Name:" | grep gfx
   # Output: gfx1010 (for BC-250)
   ```

---

## Step 1: Clone llama.cpp

```bash
cd ~
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp
```

If already cloned, update:
```bash
cd ~/llama.cpp
git stash    # if you have local changes
git pull
```

---

## Step 2: Build llama.cpp with ROCm HIP

### Configure

```bash
cd ~/llama.cpp
rm -rf build
mkdir build && cd build

cmake .. \
  -DGGML_HIP=ON \
  -DAMDGPU_TARGETS="gfx1010" \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_HIP_COMPILER=/opt/rocm/lib/llvm/bin/clang++ \
  -G "Unix Makefiles"
```

**Key flags explained:**

| Flag | Purpose |
|------|---------|
| `-DGGML_HIP=ON` | Enable HIP/ROCm GPU backend |
| `-DAMDGPU_TARGETS="gfx1010"` | Target GPU architecture (BC-250 = gfx1010) |
| `-DCMAKE_HIP_COMPILER=/opt/rocm/lib/llvm/bin/clang++` | Use ROCm's clang directly (required for CMake ≥ 4.x, `hipcc` wrapper is rejected) |
| `-G "Unix Makefiles"` | Use Make instead of Ninja |

> **Important (CMake 4.x):** Do NOT use `-DCMAKE_HIP_COMPILER=/opt/rocm/bin/hipcc` — CMake 4.x explicitly rejects the hipcc wrapper. You must point to the clang++ binary inside ROCm's LLVM directory.

### Verify Configuration

```bash
grep "GGML_HIP" CMakeCache.txt
# Should show: GGML_HIP:BOOL=ON
```

### Build

```bash
make -j$(nproc)
```

> **Build time:** HIP compilation is slow (~15-25 minutes on 12 threads). Each `.cu` template gets compiled to AMDGPU ISA for gfx1010. Be patient.

### Verify Build Output

```bash
ls -lh build/bin/llama-cli build/bin/llama-server

# Verify HIP linkage
ldd build/bin/llama-cli | grep -i "hip\|rocm"
```

Expected output:
```
libggml-hip.so.0 => .../libggml-hip.so.0
libhipblas.so.3 => /opt/rocm/lib/libhipblas.so.3
librocblas.so.5 => /opt/rocm/lib/librocblas.so.5
libamdhip64.so.7 => /opt/rocm/lib/libamdhip64.so.7
librocsolver.so.0 => /opt/rocm/lib/librocsolver.so.0
libhsa-runtime64.so.1 => /opt/rocm/lib/libhsa-runtime64.so.1
```

---

## Step 3: Download the Model

### Using aria2 (Recommended — Maximum Speed)

```bash
mkdir -p ~/models

aria2c \
  -x 16 \
  -s 16 \
  -k 1M \
  -d ~/models \
  -o Qwen3-4B-Q8_0.gguf \
  "https://huggingface.co/Qwen/Qwen3-4B-GGUF/resolve/main/Qwen3-4B-Q8_0.gguf"
```

| aria2 Flag | Purpose |
|------------|---------|
| `-x 16`    | 16 connections per server |
| `-s 16`    | Split into 16 segments |
| `-k 1M`   | Minimum split size 1MB |

### Using wget (Fallback)

```bash
wget -c \
  "https://huggingface.co/Qwen/Qwen3-4B-GGUF/resolve/main/Qwen3-4B-Q8_0.gguf" \
  -O ~/models/Qwen3-4B-Q8_0.gguf
```

### Verify Download

```bash
ls -lh ~/models/Qwen3-4B-Q8_0.gguf
# Expected: ~4.0 GiB (4,280,404,704 bytes)
```

> **Model Source:** [Qwen/Qwen3-4B-GGUF](https://huggingface.co/Qwen/Qwen3-4B-GGUF) on Hugging Face (official Qwen repo).

---

## Step 4: Run Inference (Interactive Chat)

```bash
cd ~/llama.cpp/build/bin

./llama-cli \
  -m ~/models/Qwen3-4B-Q8_0.gguf \
  -ngl 99 \
  -c 4096 \
  --temp 0.6 \
  --top-k 20 \
  --top-p 0.95
```

**Expected startup output:**
```
ggml_cuda_init: found 1 ROCm devices:
  Device 0: AMD BC-250, gfx1010:xnack- (0x1010), VMM: no, Wave Size: 32

build      : b213-3191462
model      : Qwen3-4B-Q8_0.gguf
modalities : text
```

You'll get an interactive `>` prompt. Type your question and press Enter.

**In-chat commands:**
| Command     | Action                          |
|-------------|---------------------------------|
| `/exit`     | Exit the chat                   |
| `/clear`    | Clear chat history              |
| `/regen`    | Regenerate last response        |
| `/read`     | Load a text file into context   |
| `Ctrl+C`    | Force exit                      |

### Disable Thinking Mode

Qwen3-4B has a "thinking" mode enabled by default (responses start with `[Start thinking]`). To disable it and get direct answers:

```bash
./llama-cli \
  -m ~/models/Qwen3-4B-Q8_0.gguf \
  -ngl 99 \
  -c 4096 \
  --temp 0.7 \
  --top-k 20 \
  --top-p 0.8 \
  --jinja \
  --chat-template-file ~/llama.cpp/models/templates/qwen3.jinja \
  -e
```

Or append `/no_think` to your prompt for per-message control.

---

## Step 5: Run Inference (One-Shot / Batch)

For scripting or single-prompt usage without interactive mode:

```bash
cd ~/llama.cpp/build/bin

./llama-cli \
  -m ~/models/Qwen3-4B-Q8_0.gguf \
  -ngl 99 \
  -p "Explain what ROCm is in 2 sentences." \
  -n 200 \
  --no-display-prompt \
  --no-conversation
```

---

## Step 6: Run as API Server

llama.cpp includes an OpenAI-compatible HTTP API server:

```bash
cd ~/llama.cpp/build/bin

./llama-server \
  -m ~/models/Qwen3-4B-Q8_0.gguf \
  -ngl 99 \
  -c 4096 \
  --host 0.0.0.0 \
  --port 8080
```

### Test with curl

```bash
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-4b",
    "messages": [
      {"role": "user", "content": "What is ROCm?"}
    ],
    "max_tokens": 200,
    "temperature": 0.7
  }'
```

### Web UI

Open `http://localhost:8080` in a browser for the built-in chat UI.

---

## Performance Results

Benchmarked on AMD BC-250 with full GPU offload (`-ngl 99`):

| Metric               | Value          |
|----------------------|----------------|
| **Prompt Processing** | ~84–267 t/s   |
| **Generation Speed**  | ~55–57 t/s    |
| **Context Size**      | 2048–4096      |
| **GPU Offload**       | All 36 layers  |

> Prompt processing speed varies by prompt length (shorter prompts = higher t/s due to overhead ratio). Generation speed is consistently **~56-57 tokens/second**.

---

## VRAM / Memory Breakdown

From `llama_memory_breakdown_print` at exit (context size 2048):

| Location         | Total   | Free   | Model  | Context | Compute |
|------------------|---------|--------|--------|---------|---------|
| **ROCm0 (BC-250)** | 14750 MiB | 8382 MiB | 4076 MiB | 288 MiB | 301 MiB |
| **Host (CPU)**     | —       | —      | 394 MiB | 0 MiB   | 14 MiB  |

- **Model weights**: ~4.0 GiB VRAM (matches the Q8_0 file size)
- **Remaining free VRAM**: ~8.4 GiB (plenty of room for larger context windows)
- **Host RAM**: ~394 MiB for metadata

With context size 4096, VRAM usage for context doubles to ~576 MiB, still well within the 14.4 GiB available.

---

## Useful Parameters Reference

| Parameter | Default | Description |
|-----------|---------|-------------|
| `-m` | — | Path to GGUF model file |
| `-ngl 99` | 0 | Number of layers to offload to GPU (99 = all) |
| `-c` | 4096 | Context window size (in tokens) |
| `-n` | -1 | Max tokens to generate (-1 = unlimited) |
| `-p` | — | Initial prompt text |
| `--temp` | 0.6 | Sampling temperature (lower = more deterministic) |
| `--top-k` | 20 | Top-K sampling |
| `--top-p` | 0.95 | Top-P (nucleus) sampling |
| `--no-display-prompt` | off | Don't echo the prompt in output |
| `--no-conversation` | off | Exit after first response (no interactive loop) |
| `-t` | auto | Number of CPU threads |
| `--host` | 127.0.0.1 | Server bind address |
| `--port` | 8080 | Server port |

---

## Troubleshooting

### CMake Error: "CMAKE_HIP_COMPILER is set to the hipcc wrapper"

**Cause:** CMake ≥ 4.x rejects the `hipcc` wrapper script.  
**Fix:** Point to the ROCm clang directly:
```bash
-DCMAKE_HIP_COMPILER=/opt/rocm/lib/llvm/bin/clang++
```

### Build Error: "No rule to make target 'libserver-context.a'"

**Cause:** Race condition from running multiple `make` processes in the same build directory simultaneously.  
**Fix:** Kill all builds, `rm -rf build`, and rebuild from scratch with a single `make -j$(nproc)`.

### "GGML_HIP:BOOL=OFF" in CMakeCache

**Cause:** ROCm dev libraries not found during cmake configuration.  
**Fix:** Ensure `/opt/rocm/lib/libhipblas.so` and `/opt/rocm/lib/llvm/bin/clang++` exist. Re-run cmake.

### Model file is 0 bytes after download

**Cause:** Incorrect URL (case-sensitive) — Hugging Face returns 404.  
**Fix:** The correct filename is `Qwen3-4B-Q8_0.gguf` (capital Q, capital B). Full URL:
```
https://huggingface.co/Qwen/Qwen3-4B-GGUF/resolve/main/Qwen3-4B-Q8_0.gguf
```

### Slow GPU performance / "low-power state" warning

```
WARNING: AMD GPU device(s) is/are in a low-power state
```
The BC-250 may throttle. Force performance mode:
```bash
sudo sh -c 'echo high > /sys/class/drm/card1/device/power_dpm_force_performance_level'
```

### "Exception caught: map::at" in rocm-smi

Known BC-250 issue with rocm-smi power monitoring. Does not affect inference. Ignore safely.

---

## Notes & Tips

- **Qwen3 Thinking Mode**: By default, Qwen3 wraps responses in `[Start thinking]...[End thinking]` blocks showing its reasoning chain. This is a feature, not a bug. Use `--jinja` with the official template or `/no_think` to disable it.

- **Q8_0 Quantization**: This is the highest quality GGUF quantization (8-bit). The 4B parameter model at Q8_0 uses ~4 GiB VRAM, leaving plenty of headroom on the BC-250's ~14.4 GiB.

- **Full GPU Offload**: With `-ngl 99`, all 36 transformer layers are offloaded to the GPU. No CPU fallback needed for this model size.

- **Other Quant Options**: Qwen also provides Q4_K_M (~2.5 GiB) and Q4_0 (~2.3 GiB) variants on the same Hugging Face repo if you want to save VRAM for larger context windows.

- **Multiple Models**: The BC-250 has enough VRAM to potentially run larger models like Qwen3-8B at Q4_K_M quantization (~5 GiB).

---

## Quick Reference

```bash
# Build (one-time)
cd ~/llama.cpp && rm -rf build && mkdir build && cd build
cmake .. -DGGML_HIP=ON -DAMDGPU_TARGETS="gfx1010" -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_HIP_COMPILER=/opt/rocm/lib/llvm/bin/clang++ -G "Unix Makefiles"
make -j$(nproc)

# Download model (one-time)
mkdir -p ~/models
aria2c -x 16 -s 16 -k 1M -d ~/models -o Qwen3-4B-Q8_0.gguf \
  "https://huggingface.co/Qwen/Qwen3-4B-GGUF/resolve/main/Qwen3-4B-Q8_0.gguf"

# Run interactive chat
~/llama.cpp/build/bin/llama-cli -m ~/models/Qwen3-4B-Q8_0.gguf -ngl 99 -c 4096

# Run API server
~/llama.cpp/build/bin/llama-server -m ~/models/Qwen3-4B-Q8_0.gguf -ngl 99 -c 4096 --host 0.0.0.0 --port 8080
```

---

*Documentation generated on March 1, 2026. Based on llama.cpp build b8184, ROCm 7.2.0, AMD BC-250 (gfx1010).*
