# RX 5700 XT + ROCm 7.0.2 + llama.cpp 部署 Fin-R1-7B 完整教程
## 环境
| 项目 | 配置 |
|------|------|
| 系统 | Ubuntu 24.04.3 LTS (Kernel 6.8.0) |
| GPU | AMD Radeon RX 5700 XT (gfx1010, 8GB VRAM) |
| ROCm | 7.0.2 |
| 推理引擎 | llama.cpp (HIP/ROCm backend) |
| 模型 | SUFE-AIFLM-Lab/Fin-R1 (Q4_K_M, 7.62B, 4.4GB) |
---
## 一、前置准备
### 1.1 开启 root SSH
```bash
sudo passwd root # 设置 root 密码
sudo sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
sudo systemctl restart sshd
```
### 1.2 确认硬件
```bash
lspci | grep VGA # 应看到 RX 5700 XT (Navi 10)
lsblk # 确认目标安装盘
```
---
## 二、安装 ROCm 7.0.2
```bash
# 添加 AMD 官方源
wget https://repo.radeon.com/amdgpu-install/latest/ubuntu/noble/amdgpu-install.deb
sudo apt install ./amdgpu-install.deb
# 安装 ROCm 7.0.2 到 /opt/rocm-7.0.2
sudo amdgpu-install --usecase=rocm,hip,rocmdev --rocmrelease=7.0.2 --no-dkms
# 添加到 PATH
echo 'export PATH=/opt/rocm-7.0.2/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
```
### 2.1 验证安装
```bash
rocminfo | grep -E "Name:|gfx"
# 应显示: Name: gfx1010, Marketing Name: AMD Radeon RX 5700 XT
```
---
## 三、⚠️ 关键修复:IOMMU 直通
这是本次部署的**核心发现**。默认的 IOMMU 会将 GPU 的 DMA 操作限制在安全映射区,导致 ROCm 7.0.2 无法正常工作,VRAM 被锁住约 4.3GB。
问题表现:
- `rocminfo` 正常但 `llama.cpp` 加载模型时卡死
- dmesg 出现 `DMAR: PTE Write access is not set`
- VRAM 只有约 3.8GB 可用(总共 8GB)
修复:
```bash
# 编辑 GRUB
sudo sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT=""/GRUB_CMDLINE_LINUX_DEFAULT="iommu=pt"/' /etc/default/grub
sudo update-grub
sudo reboot
```
修复后效果:
- VRAM 从 3.8GB → 8.1GB 可用
- 无任何 IOMMU/DMA 故障
- GPU 计算正常工作
---
## 四、⚠️ 关键修复:编译 gfx1010 目标
这是第二个核心发现。ROCm 7.0.2 的 rocBLAS 库**只包含 gfx1030+ 的内核**,不再支持 gfx1010(RDNA1)。必须将 llama.cpp 编译为 gfx1010 目标。
### 4.1 错误的做法
```bash
# ❌ 这会导致 "invalid device function" 错误
cmake .. -DGGML_HIP=ON -DAMDGPU_TARGETS=gfx1030
```
即使设置 `HSA_OVERRIDE_GFX_VERSION=10.3.0` 骗过设备检测,实际推理时 GPU 内核会崩溃。
### 4.2 正确的做法
```bash
git clone 网页链接 /opt/llama.cpp
cd /opt/llama.cpp
mkdir build && cd build
# ✅ 直接编译为 gfx1010
cmake .. -DGGML_HIP=ON -DAMDGPU_TARGETS=gfx1010 -DCMAKE_BUILD_TYPE=Release
cmake --build . --target llama-cli llama-server -j$(nproc)
```
编译后的二进制**不需要** `HSA_OVERRIDE_GFX_VERSION`,原生 gfx1010 直接跑。
---
## 五、下载模型
```bash
mkdir -p /opt/models
# 从 HuggingFace 下载 Fin-R1 Q4_K_M (推荐,8GB 卡最佳选择)
pip install huggingface_hub
huggingface-cli download SUFE-AIFLM-Lab/Fin-R1-GGUF Fin-R1-Q4_K_M.gguf \
--local-dir /opt/models
```
---
## 六、启动服务
### 6.1 命令行测试
```bash
/opt/llama.cpp/build/bin/llama-cli \
-m /opt/models/Fin-R1-Q4_K_M.gguf \
-c 4096 --n-gpu-layers 28 \
-p "你好,介绍一下你自己" -n 128 --simple-io
```
### 6.2 API 服务(推荐)
```bash
# 生成 API Key
python3 -c "import secrets; print(secrets.token_hex(32))" > /opt/llama-api-key
chmod 600 /opt/llama-api-key
# 启动服务
/opt/llama.cpp/build/bin/llama-server \
-m /opt/models/Fin-R1-Q4_K_M.gguf \
-c 4096 \
--n-gpu-layers 28 \
--api-key-file /opt/llama-api-key \
--host 0.0.0.0 \
--port 8080 &
```
### 6.3 调用示例
```bash
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"messages":[{"role":"user","content":"你好"}],"max_tokens":128}'
```
### 6.4 systemd 自启动
```ini
# /etc/systemd/system/fin-r1.service
[Unit]
Description=Fin-R1-7B API Server
After=network.target
[Service]
Type=simple
ExecStart=/opt/llama.cpp/build/bin/llama-server \
-m /opt/models/Fin-R1-Q4_K_M.gguf \
-c 4096 --n-gpu-layers 28 \
--api-key-file /opt/llama-api-key \
--host 0.0.0.0 --port 8080
Restart=on-failure
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
```
```bash
systemctl daemon-reload
systemctl enable --now fin-r1
```
---
## 七、性能实测
### 7.1 推理速度
| 指标 | 数值 |
|------|------|
| 生成速度 | 37-43 tokens/s |
| 提示处理 | 200-250 tokens/s |
| 1000 token 长文本 | ~25 秒完成 |
| Context 上限 | 32768 (VRAM 余量 1.8GB) |
### 7.2 VRAM 占用
| Context | VRAM 占用 | 剩余 |
|---------|----------|------|
| 4096 | 4803 MiB | 3373 MiB |
| 8192 | 5018 MiB | 3158 MiB |
| 16384 | 5451 MiB | 2725 MiB |
| 32768 | 6314 MiB | 1862 MiB |
### 7.3 温度表现(1000 token 连续生成)
| 指标 | 空闲 | 负载峰值 |
|------|------|---------|
| Hotspot (结温) | 48°C | 77°C |
| 边缘 | 42°C | 63°C |
| 显存 | 48°C | 68°C |
峰值 77°C,远超安全阈值(AMD 官方上限 110°C),且任务结束后 5 秒内回落至 48°C。
---
## 八、常见问题排查
| 现象 | 原因 | 解决 |
|------|------|------|
| `invalid device function` | 编译目标错误 (gfx1030≠gfx1010) | 重编译为 gfx1010 |
| 模型加载卡死/无输出 | IOMMU 锁住 VRAM | 添加 `iommu=pt` 内核参数 |
| `out of memory` | VRAM 不够 | 降低 `--n-gpu-layers` 或 context |
| 401 Unauthorized | 未传 API Key | 请求头加 `Authorization: Bearer <key>` |
| 中文乱码 | Qwen2 tokenizer | 使用 `--simple-io` 去除交互式界面干扰 |
---
## 九、关键总结
1. IOMMU 直通是命门 — `iommu=pt` 释放了被锁的 4.3GB VRAM
2. 编译目标必须匹配硬件 — gfx1010 卡必须编译 gfx1010,不能靠 `HSA_OVERRIDE_GFX_VERSION` 硬骗
3. 不需要 Docker — 原生部署完全可行,Docker 不解决底层兼容性问题
4. 不需要 `HSA_OVERRIDE_GFX_VERSION` — gfx1010 原生编译后直接跑