# llama.cpp 编译 Qwen3.5-4B GPU 推理全记录

> **硬件**:GTX 1660 6GB | i5-12600K 16GB  
> **系统**:Windows 10 | CUDA 13.1 | MSVC 2022  
> **模型**:Qwen3.5-4B-Q4_0 (2.5GB) | 全层 GPU | 45 tok/s  
> **耗时**:从零到可用 installer,踩坑 12 小时

---

## 一、环境选择:GCC 还是 MSVC?

### 尝试 1:GCC 14.2.0 (MinGW) — ❌ CUDA 不兼容

```
cmake -G "MinGW Makefiles" -DGGML_CUDA=ON ..
# 编译通过,产物不含 ggml-cuda.dll
```

**问题**:MinGW 的 ABI 与 CUDA 不兼容。CUDA 在 Windows 上只支持 MSVC 工具链。

**解决**:必须用 Visual Studio 生成器。

---

### 尝试 2:安装 MSVC Build Tools

```powershell
winget install Microsoft.VisualStudio.2022.BuildTools
# 网络受限 → 多次超时
```

**踩坑**:winget 在特定网络环境下载极慢。绕路方案:

```powershell
# 直下离线包
curl -L -o vs_buildtools.exe "https://aka.ms/vs/17/release/vs_buildtools.exe"
vs_buildtools.exe --quiet --add Microsoft.VisualStudio.Workload.VCTools
```

选装组件清单:
- MSVC v143 编译器
- Windows 10 SDK
- CMake 工具
- C++ ATL/MFC

---

### 安装 CUDA Toolkit 13.1

```powershell
# winget 同样不可靠 → 手动下载
curl -L -o cuda_13.1.exe "https://developer.download.nvidia.com/compute/cuda/13.1.0/..."
cuda_13.1.exe -s
```

**致命坑**:CUDA 安装后 VS 找不到 `crt` 头文件!

```
fatal error C1083: 无法打开包括文件: "crtdefs.h"
```

**解决**:CUDA 安装程序没正确注册 VS 集成。补装 CRT 头文件 + 手动复制到 VS Include 目录:

```powershell
# 从 Windows SDK 复制缺失的 CRT headers
copy "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt\*" ^
     "C:\Program Files\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.44.34823\include\"
```

---

## 二、编译 cmake 配置

```bash
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp && mkdir build-cuda && cd build-cuda

cmake .. -G "Visual Studio 17 2022" -A x64 ^
  -DGGML_CUDA=ON ^
  -DCMAKE_CUDA_ARCHITECTURES="75" ^     # GTX 1660 = SM 7.5
  -DGGML_CUDA_FORCE_MMQ=OFF ^
  -DGGML_CUDA_FORCE_CUBLAS=ON ^
  -DLLAMA_BUILD_UI=OFF                  # UI 另建,见下文

cmake --build . --config Release -j 8
```

### 关键参数解释

| 参数 | 值 | 原因 |
|------|-----|------|
| `GGML_CUDA` | ON | 启用 CUDA 加速 |
| `CMAKE_CUDA_ARCHITECTURES` | 75 | GTX 1660 的 SM 版本。**填错会编译成功但运行崩溃** |
| `GGML_CUDA_FORCE_MMQ` | OFF | 让 CUDA 优先走 cuBLAS |
| `LLAMA_BUILD_UI` | OFF | Web UI 需要 node/npm,网络不好时单独构建 |

### 查自己 GPU 的 SM 版本

| GPU | SM | `CMAKE_CUDA_ARCHITECTURES` |
|-----|-----|---------------------------|
| GTX 1060 | 6.1 | 61 |
| GTX 1660 | 7.5 | 75 |
| RTX 2060 | 7.5 | 75 |
| RTX 3060 | 8.6 | 86 |
| RTX 4090 | 8.9 | 89 |

---

## 三、Web UI 构建

llama.cpp 的 CMake 提供 `LLAMA_BUILD_UI=ON`,需要联网下载 node_modules。**网络受限时必超时**。

### 本地构建方案

```bash
cd llama.cpp/tools/ui
npm install     # svelte + vite + tailwind
npm run build   # 产物 → dist/
```

产物:
```
dist/
├── index.html     (4 KB)
├── bundle.js      (148 KB)
├── bundle.css     (12 KB)
└── loading.html   (1 KB)
```

用 `--path` 参数让 llama-server 直接提供静态文件:

```bash
llama-server.exe --path ./dist --ui -m model.gguf
```

无需 Python 代理,一个进程搞定 API + UI。

---

## 四、启动命令 & 踩坑日记

### 最优命令(经过多次崩溃修正)

```bash
llama-server.exe ^
  -m Qwen3.5-4B-Q4_0.gguf ^
  --host 0.0.0.0 ^
  --port 8080 ^
  --path ./ui ^
  --ui ^
  -ngl 999 ^                # 全层 GPU
  -c 16384 ^                # 16K 上下文
  -t 8 ^                    # 8 线程
  --cache-type-k q4_0 ^     # K 缓存量化
  --cache-type-v q4_0 ^     # V 缓存量化
  --keep 20 ^               # 保留前 20 token
  --alias "Qwen3.5-4B-Q4_0"
```

### 坑 1:`--no-flash-attn` 导致启动崩溃

```
# ❌ 错误
--no-flash-attn --cache-type-v q4_0

# 报错:
E llama_init_from_model: V cache quantization requires flash_attn
```

**原因**:`q4_0` 量化 V 缓存依赖 flash attention 的算子。  
**解决**:去掉 `--no-flash-attn`,保持默认 `auto`(= `on`)。

### 坑 2:`-c 262144` 导致 OOM

```
# 262K 上下文 × q4_0 KV cache = 256MB → 超出 GTX 1660 6GB 余量
```

**解决**:降低到 `-c 16384`(16K),足够日常开发。

### 坑 3:bat 脚本中 `|` 被解析为管道

```batch
# ❌ echo 1660 (6GB) | 16K ctx | 全层GPU
# → '16K' is not recognized as an internal or external command

# ✅ echo 1660 6GB   16K ctx   全层GPU
```

### 坑 4:PyInstaller `--noconsole` 打包后子进程异常

用 PyInstaller 把 Python 代理 + 子进程管理打包成 EXE:
- 多次点击产生 10+ 个实例互相抢端口
- 子进程 `llama-server` 在 PyInstaller 环境中 stderr 丢失
- 最终放弃 PyInstaller,改用纯 bat + 快捷方式

---

## 五、性能实测

```
llama_perf_context_print:        load time =    2983.86 ms
llama_perf_context_print: prompt eval time =      61.01 ms /    20 tokens (    3.05 ms per token,   327.77 tokens per second)
llama_perf_context_print:        eval time =     400.37 ms /    18 tokens (   22.24 ms per token,    44.97 tokens per second)
```

| 模式 | 速度 |
|------|------|
| 全 GPU (`-ngl 99`) | **45 tok/s** |
| 混合 (19 GPU + 14 CPU) | 15 tok/s |

纯 GPU 推理比混合模式快 **3 倍**。GTX 1660 6GB 跑 4B 模型毫无压力。

---

## 六、Windows 安装包制作

### 最终方案:bat + zip 自解压

放弃了 PyInstaller(子进程不稳定)、放弃了 VBS(路径兼容差)、放弃了 NSIS/Inno Setup(未安装)。

**最简方案**:

```
Qwen-4B-Setup.zip
├── install.bat     → 复制文件 + 创建快捷方式 + 开始菜单
├── uninstall.bat   → 删除文件 + 清理快捷方式
└── app/
    ├── Qwen-4B.bat  → llama-server 启动脚本(相对路径)
    ├── bin/          → llama-server.exe + CUDA DLLs
    ├── model/        → Qwen3.5-4B-Q4_0.gguf
    └── ui/           → 网页界面
```

`install.bat` 核心逻辑:

```batch
:: 让用户选择安装路径
set /p "INSTALL_DIR=安装路径 [%ProgramFiles%\Qwen-4B]: "

:: 复制文件
xcopy /E /Y app\* "%INSTALL_DIR%\"

:: 创建快捷方式(桌面 + 开始菜单)
powershell -Command "$ws = New-Object -ComObject WScript.Shell; ..."

:: 注册卸载入口
copy uninstall.bat "%INSTALL_DIR%\"
```

`Qwen-4B.bat` 用 `%~dp0` 实现相对路径:

```batch
set "APPDIR=%~dp0"
"%APPDIR%bin\llama-server.exe" -m "%APPDIR%model\Qwen3.5-4B-Q4_0.gguf" ...
```

---

## 七、模型显存占用分析

```
Qwen3.5-4B-Q4_0.gguf 本体:   1.0 GB  (模型参数)
16K KV Cache (q4_0):          0.13 GB (K=64MB + V=64MB)
Prompt Cache:                 0.5 GB  (缓存池)
─────────────────────────────────────
合计:                        ~1.6 GB
GTX 1660 总显存:              6.0 GB
富余:                         4.4 GB ✅
```

6GB 显存跑 4B 模型 + 16K 上下文非常宽松。理论可跑 32K 上下文(KV Cache ≈ 256MB)。

---

## 八、OpenClaw 对接

```json
{
  "models": {
    "providers": {
      "local-qwen4b": {
        "baseUrl": "http://127.0.0.1:8080/v1",
        "api": "openai-completions",
        "apiKey": "not-needed",
        "models": [{
          "id": "Qwen3.5-4B-Q4_0",
          "contextWindow": 16384,
          "maxTokens": 4096
        }]
      }
    }
  },
  "agents": {
    "defaults": {
      "model": { "primary": "local-qwen4b/Qwen3.5-4B-Q4_0" }
    }
  }
}
```

**注意**:OpenClaw 的 `"api"` 字段必须用 `"openai-completions"` 而非 `"openai"` 或 `"openai-compatible"`,后者会在 validate 时报错。

---

## 九、总结:一条命令从零到可用

```bash
# 1. 装 MSVC Build Tools + CUDA Toolkit
# 2. 编译
git clone https://github.com/ggml-org/llama.cpp && cd llama.cpp
mkdir build-cuda && cd build-cuda
cmake .. -G "Visual Studio 17 2022" -A x64 -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=75
cmake --build . --config Release -j 8

# 3. 下载模型
# https://huggingface.co/Qwen/Qwen2.5-3B-Instruct-GGUF → Q4_0 量化版

# 4. 启动
build-cuda\bin\Release\llama-server.exe -m model.gguf -ngl 999 -c 16384 --port 8080

# 5. 打开 http://127.0.0.1:8080 → 开始对话
```

---

> 作者:侠心论道  
> 日期:2026-05-19  
> 许可:CC BY 4.0  
> 模型:Qwen3.5-4B · 推理引擎:llama.cpp · GPU:NVIDIA GTX 1660
 

更多推荐