GGUF_INSTALL_AND_TUNING.md
5.57 KB
Qwen3 GGUF 安装与调优手册
本文档只覆盖 qwen3_gguf 后端,目标机器为当前项目实测环境:
- GPU:
Tesla T4 16GB - CUDA:
12.8 - 模型:
DevQuasar/Qwen.Qwen3-Reranker-4B-GGUF - 量化:
Q8_0
1. 结论先看
当前这套代码里,GGUF 后端的主要瓶颈不是“显存没吃满”,而是 llama.cpp 按 doc 顺序逐条打分。因此最有效的优化策略是:
- 让模型层尽可能全部 offload 到 GPU
- 打开
flash_attn/offload_kqv - 把
n_ctx / n_batch / n_ubatch调到一个对短标题重排更合适的高效点
本轮在当前机器上的推荐配置是:
qwen3_gguf:
n_ctx: 512
n_batch: 512
n_ubatch: 512
n_gpu_layers: 999
n_threads: 2
n_threads_batch: 4
flash_attn: true
offload_kqv: true
infer_batch_size: 8
sort_by_doc_length: true
length_sort_mode: "char"
说明:
n_gpu_layers: 999在 llama.cpp 中等价于“尽可能全部层都 offload”- 这台 T4 上,即使全量 offload,当前模型也只占到约
4.5 GiBGPU 显存 - 所以“允许 8G 显存”并不会自动带来更高速度;这个模型/后端在当前工作负载下已经接近“该用到的权重都上 GPU 了”
2. 独立环境
qwen3_gguf 必须使用自己的独立 venv:
qwen3_vllm->.venv-rerankerqwen3_gguf->.venv-reranker-gguf
安装命令:
./scripts/setup_reranker_venv.sh qwen3_gguf
脚本现在会自动做两件事:
- 安装 GGUF 后端所需 Python 依赖
- 在检测到
/usr/local/cuda/bin/nvcc时,把llama-cpp-python重编译成 CUDA 版
3. GPU 版验证
必须验证不是 CPU-only 版:
./.venv-reranker-gguf/bin/python - <<'PY'
import llama_cpp
print("supports_gpu_offload =", llama_cpp.llama_supports_gpu_offload())
PY
正确结果应为:
supports_gpu_offload = True
还可以看动态库:
ldd .venv-reranker-gguf/lib/python3.12/site-packages/llama_cpp/lib/libllama.so | rg 'cuda|cublas|ggml-cuda'
应能看到:
libggml-cuda.solibcudart.solibcublas.so
4. 模型下载
当前使用本地文件优先策略,模型放在:
models/reranker/qwen3-reranker-4b-gguf/Qwen.Qwen3-Reranker-4B.Q8_0.gguf
若本地文件存在,后端会直接加载本地 GGUF,不再依赖启动时在线下载。
为了避免当前机器上 Hugging Face Xet 下载的 416 Range Not Satisfiable 问题,start_reranker.sh 已对 qwen3_gguf 默认设置:
HF_HUB_DISABLE_XET=1
5. 本地调优脚本
新增本地基准脚本:
PYTHONPATH=/data/saas-search ./.venv-reranker-gguf/bin/python \
scripts/benchmark_reranker_gguf_local.py --docs 64 --repeat 1
它会直接实例化 GGUF backend,输出:
- 模型加载耗时
- 当前进程 GPU 显存占用
- 单次 rerank 延迟
6. 本轮实测结果
测试条件:
- Query:
白色oversized T-shirt - Docs:
64条商品标题 - 本地脚本:
scripts/benchmark_reranker_gguf_local.py - 每组 1 次,重点比较相对趋势
结果:
6.1 保守配置
n_ctx=384
n_batch=384
n_ubatch=128
n_gpu_layers=24
- GPU 显存:
2984 MiB - 64 docs 延迟:
74347.91 ms
6.2 全量 offload
n_ctx=384
n_batch=384
n_ubatch=128
n_gpu_layers=999
- GPU 显存:
4338 MiB - 64 docs 延迟:
51401.77 ms
6.3 最优配置
n_ctx=512
n_batch=512
n_ubatch=512
n_gpu_layers=999
- GPU 显存:
4564 MiB - 64 docs 延迟:
49116.10 ms
6.4 其它尝试
n_threads=4 / n_threads_batch=8:
- GPU 显存:
4564 MiB - 64 docs 延迟:
49895.88 ms - 比推荐值略慢
infer_batch_size=64:
- GPU 显存:
4564 MiB - 64 docs 延迟:
50723.36 ms - 也略慢
6.5 API 级验证
在把推荐配置写入 config/config.yaml 并重启服务后,使用:
RERANK_BASE=http://127.0.0.1:6007 \
./.venv/bin/python scripts/benchmark_reranker_random_titles.py 64 --repeat 1 --query '白色oversized T-shirt'
得到:
64 docs:50177.22 ms
再用:
RERANK_BASE=http://127.0.0.1:6007 \
./.venv/bin/python scripts/benchmark_reranker_random_titles.py 153 --repeat 1 --query '白色oversized T-shirt'
得到:
153 docs:115328.60 ms
对比旧日志中的保守配置:
- 旧配置
153 docs:153435.37 ms - 新配置
153 docs:115328.60 ms
改善幅度约:
24.8%
7. 为什么没有吃到 8G
结论很重要:
- 当前最优配置已经是“尽可能全量层 offload”
- 该
Q8_0模型在这套 llama.cpp / T4 / 短文本重排场景下,实测只需要约4.5 GiBGPU 显存 - 继续为了“吃满 8G”去增大
n_ctx,不会明显提升吞吐,反而可能带来额外开销
所以本轮不是“显存太保守”,而是:
- 可 offload 的权重已经基本 offload 完了
- 真正拖慢响应的是 逐 doc 顺序推理 这一后端实现路径
8. 生产建议
8.1 当前建议
保留以下参数:
n_ctx: 512
n_batch: 512
n_ubatch: 512
n_gpu_layers: 999
n_threads: 2
n_threads_batch: 4
flash_attn: true
offload_kqv: true
8.2 如果还嫌慢
优先级建议:
- 缩小
rerank_window - 减少传入 doc 数
- 若业务允许,切换到更适合高吞吐的后端
原因:
- 当前 GGUF 后端是本地单进程、逐 doc 打分
- 对长列表重排,它天然不如 vLLM / 云端 rerank API 擅长吞吐
9. 本轮落地文件
config/config.yamlscripts/setup_reranker_venv.shscripts/start_reranker.shscripts/benchmark_reranker_gguf_local.pyreranker/GGUF_INSTALL_AND_TUNING.md