8GB显存跑Qwen2.5-7B:Ollama和vLLM实测对比,我把num_ctx砍到2048后才稳

🔑 关键词:Ollama, vLLM, Qwen2.5-7B, 8GB显存, 本地大模型

📖 摘要:RTX 4060 8GB + i5-12400 实测 Qwen2.5-7B-Instruct:Ollama 0.5.7 与 vLLM 0.6.6 的显存、tok/s、TTFT、并发对比,附可复现 Modelfile、环境变量和踩坑步骤。

先交代机器和版本,免得说我云评测

图片

手上这台是矿渣拆机的 RTX 4060 8GB,不是 Ti。CPU i5-12400,B660M 迫击炮,32GB DDR4 3200,1TB SN570。系统 Ubuntu 22.04.4,内核 6.5.0-41,NVIDIA 550.107.02,CUDA 12.4。Ollama 0.5.7,llama.cpp b4458,vLLM 0.6.6。模型是 Qwen2.5-7B-Instruct,不是 7B-Coder。Q4_K_M GGUF 文件 4.68GB,Q5_K_M 5.44GB,Q8_0 8.10GB,AWQ 4bit 约 5.5GB。测试问题用固定 512 token 的《三体》摘要 + 5 个追问,温度 0.7,top_p 0.9,repeat_penalty 1.1。别拿“写个贪吃蛇”测,那个测不出 prefill。

问题不是装不上,是 Open WebUI 一传 4096 就 OOM

图片

一开始我用 Open WebUI 连 Ollama,默认请求 num_ctx=4096。nvidia-smi 看权重刚加载 5.8GB,感觉稳。结果粘贴 3000 字文档后,日志蹦 CUDA error: out of memory,ollama ps 显示 runner 占 7.9GB。我以为是 Q4 量化不够狠,差点去下 Q3_K_S。后来用 ollama psnvidia-smi --query-gpu=memory.used --format=csv -l 1 盯了 10 分钟,发现真正变化的是 prefill 阶段:512 token 请求时显存从 5.8GB 跳到 7.2GB,4096 token 直接顶到 7.9GB。Qwen2.5-7B 是 GQA,28 层、4 个 KV heads、head_dim 128,2048 上下文 f16 KV cache 大约 112MiB,4096 约 224MiB,8192 约 448MiB。KV cache 不是大头,大头是 Ollama 默认并行槽和 prefill 激活。我这边 0.5.7 默认跑了 4 个 parallel,显存预分配直接多出 1.5GB。把 OLLAMA_NUM_PARALLEL=1OLLAMA_MAX_LOADED_MODELS=1 写进 systemd 后,同样 4096 上下文从 7.9GB 降到 6.4GB。

图片

Ollama 我的可用配置:Modelfile + 环境变量

/etc/systemd/system/ollama.service.d/override.conf 里加:

[Service]
Environment=OLLAMA_FLASH_ATTENTION=1
Environment=OLLAMA_KV_CACHE_TYPE=q8_0
Environment=OLLAMA_NUM_PARALLEL=1
Environment=OLLAMA_MAX_LOADED_MODELS=1
Environment=OLLAMA_HOST=0.0.0.0:11434

然后 sudo systemctl daemon-reload && sudo systemctl restart ollama。Modelfile 我写这样:

FROM qwen2.5:7b-instruct-q4_K_M
PARAMETER num_ctx 2048
PARAMETER num_gpu 99
PARAMETER num_thread 6
PARAMETER temperature 0.7
PARAMETER repeat_penalty 1.1

ollama create qwen25-8g -f Modelfile,跑 ollama run qwen25-8g --verbose。固定 512 token 输入、生成 256 token,结果:num_ctx=2048 时 eval rate 38.4 tok/s,prefill 0.62s,显存 6.1GB;num_ctx=4096 时 34.1 tok/s,prefill 0.71s,显存 6.4GB;num_ctx=8192 时没跑完,7.9GB 后 OOM。把 KV cache 从 f16 换成 q8_0,4096 下省了约 180MB,速度只掉 0.8 tok/s。Q5_K_M 我也试了,同上下文显存多 0.76GB,eval 36.9 tok/s,回答质量在中文总结上我没盲测出差别。所以 8GB 卡上我不推荐 Q5 以上,Q4_K_M 是甜点,Q3 别碰,长文档里人名会开始乱。

图片

vLLM 我也装了,单用户真没必要硬上

图片

vLLM 0.6.6 装完,模型用 Qwen/Qwen2.5-7B-Instruct-AWQ。启动命令:

vllm serve Qwen/Qwen2.5-7B-Instruct-AWQ --quantization awq --max-model-len 4096 --gpu-memory-utilization 0.92 --max-num-seqs 4 --enforce-eager --port 8000

注意 --enforce-eager 我加了,不然 CUDA graph 会多占 300-400MB,8GB 卡很容易在启动时 OOM。单请求 512 输入、256 输出,vLLM 跑 44.2 tok/s,TTFT 0.42s,显存 7.3GB。Ollama 同条件 38.4 tok/s,TTFT 0.51s,显存 6.1GB。看起来 vLLM 快 15%,但我把 --max-num-seqs 开到 4 并发后,总吞吐 82 tok/s,TTFT 最慢到 2.3s;Ollama 因为 OLLAMA_NUM_PARALLEL=1,4 个请求排队,总吞吐只有 41 tok/s,最后一个 TTFT 4.8s。结论很直接:如果你一个人用,Ollama 更省显存、更好装;如果你要给 3-5 个人做内部问答,vLLM 的连续批处理才值。8GB 卡上 vLLM 的 PagedAttention 省的是显存碎片,不是总量,权重 + CUDA context + 激活已经吃掉 7GB,留给你的余量只有 500MB 左右。

我的独立观点:8GB 卡别追长上下文,先砍并行槽

图片

现在很多人一提 8GB 跑 7B 就问“能不能 32K 上下文”。我的答案是:能加载,不能用。Qwen2.5-7B 在 Q4_K_M 下权重 4.68GB,CUDA context 约 300-500MB,prefill 到 4096 时激活另占 1GB 左右,再算上桌面环境 200-300MB,8GB 卡实际安全线是 2048-3072 上下文。你要真需要长文档,两个方案:一是把 num_ctx 设 2048,用 RAG 切片,每片 800-1200 字,重叠 150 字;二是换 3060 12GB 或 P40 24GB。4060 的 272GB/s 带宽和 8GB 显存,跑 7B 生成会先撞带宽墙再撞显存墙;3060 12GB 虽然老,但 360GB/s 带宽和 12GB 显存,二手 900-1100 元,比换 4060 Ti 16GB 划算。别问我怎么知道,我抽屉里还有一张 P40,驱动和散热能把人折腾疯。最后一句:把 OLLAMA_NUM_PARALLEL 从 4 改 1,比你从 Q4 换 Q3 有用得多。

🏷️ 标签: