尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Ollama CPU 推理大提示词优化实测报告(细致化数据版)

Ollama CPU 推理大提示词优化实测报告(细致化数据版) Ollama CPU 推理大提示词优化实测报告细致化数据版测试日期2026-08-08关键词Ollama / llama.cpp / CPU 推理 / 大上下文 / KV Cache 量化 / Prompt Cache数据来源真实服务器实测全部原始测量数据附后摘要TL;DR结论一反直觉CPU 推理下开启 KV Cache 量化q8_0是严重负优化——同一提示词预填充从 84 秒恶化到 208 秒慢 2.5 倍。GPU 场景的优化手段不能照搬到 CPU。结论二手动设置线程数32 / 64与默认无差异——预填充瓶颈是内存带宽而非核心数SMT 虚核收益互相抵消。结论三正解将OLLAMA_KEEP_ALIVE从默认 5 分钟拉长至 24 小时让模型常驻内存llama.cpp 的 Prompt Cache 对相同前缀提示词实现缓存命中 99.99%11,055 token 的预填充从 84 秒降至 0.05 秒请求总耗时 1.6 秒。适用场景固定系统提示词 固定文档上下文 尾部变化问题RAG / 长文档问答 / 多轮对话的标准形态。一、测试环境项目参数CPUAMD Ryzen Threadripper PRO 9975WXZen5核心32 核 / 64 线程单 NUMA 节点内存128 GB DDR5实测 125 GiB交换分区 8 GiBGPU96 GB 显存 NVIDIA 专业卡一块未参与本模型推理仅系统显示占用OSLinuxsystemd 管理服务推理引擎Ollama 0.30.8内置 llama.cpp模型MoE 架构 GGUF 模型总参数 29.9B / 激活约 3BQ4_K_M 量化文件 31.16 GB上下文窗口202,752 tokens启动参数-c 202752GPU offload0 层-ngl 0纯 CPU 推理其他 llama.cpp 参数--mlock --no-mmap --flash-attn auto -b 2048 -ub 2048 -np 1服务监听0.0.0.0:11434OpenAI 兼容端点/v1/chat/completions二、问题现象客户端通过/v1/chat/completions提交 18,730 token 的大提示词系统提示 文档上下文 问题后CPU 占用飙至28 核满负荷约 2800%持续 3 分 14 秒期间客户端一个 token 都不返回表现与死循环/卡死无异预填充完成后才开始生成生成阶段 17.06 tok/sCPU 水平。诊断结论不是死循环。Ollama 日志显示prompt processing进度持续推进progress 0.11 → 0.99说明引擎正在执行预填充prefill——逐 token 消化提示词。预填充阶段本就不产生任何输出大提示词 CPU 推理 数分钟假死。关键日志证据基线18,730 tokensslot print_timing: id 0 | task 0 | prompt processing, n_tokens 2048, progress 0.11, t 7.02 s / 291.56 tokens per second slot print_timing: id 0 | task 0 | prompt processing, n_tokens 4096, progress 0.22, t 16.56 s / 247.29 tokens per second slot print_timing: id 0 | task 0 | prompt processing, n_tokens 6144, progress 0.33, t 28.89 s / 212.67 tokens per second slot print_timing: id 0 | task 0 | prompt processing, n_tokens 8192, progress 0.44, t 44.14 s / 185.57 tokens per second slot print_timing: id 0 | task 0 | prompt processing, n_tokens 10240, progress 0.55, t 62.41 s / 164.08 tokens per second slot print_timing: id 0 | task 0 | prompt processing, n_tokens 12288, progress 0.66, t 83.51 s / 147.14 tokens per second slot print_timing: id 0 | task 0 | prompt processing, n_tokens 14336, progress 0.77, t 107.39 s / 133.49 tokens per second slot print_timing: id 0 | task 0 | prompt processing, n_tokens 16384, progress 0.87, t 134.02 s / 122.25 tokens per second slot print_timing: id 0 | task 0 | prompt eval time 10963 ms / 187 tokens (17.06 tok/s) ← 预填充完成后进入生成 slot print_timing: id 0 | task 0 | stop processing: n_tokens 18916, truncated 0 ← 正常结束未截断三、实验设计控制变量法固定提示词19,125 字符中文 ≈ 11,055 tokens固定生成上限max_tokens32只测预填充阶段每组只改一个变量每次修改后systemctl daemon-reload systemctl restart ollama冷却 45 秒排除热降频干扰Threadripper 满载后 boost 频率回落已验证冷却后频率恢复 3.9~5.3 GHz。实验组变更项对照目的基线改前现场调用方真实请求 18,730 tokens默认配置f16 KV、自动线程建立参考曲线A-1OLLAMA_KV_CACHE_TYPEq8_0OLLAMA_NUM_THREADS64KV 量化 全线程A-2OLLAMA_KV_CACHE_TYPEq8_0OLLAMA_NUM_THREADS32KV 量化 物理核A-3OLLAMA_KV_CACHE_TYPEq8_0 默认线程KV 量化单独作用Bf16 KV默认 默认线程回归基线与 A 组对照Cf16 KV OLLAMA_KEEP_ALIVE24h同提示词第二次请求Prompt Cache 验证四、完整测量数据4.1 预填充速度轨迹对比表tok/s按已处理 token 数已处理 tokens基线 18.7K (f16)A-1 q864线程A-2 q832线程A-3 q8默认B f16 默认2,048291.56172.84172.45169.92290.174,096247.29116.90117.17117.32247.336,144212.6789.1689.3089.28212.678,192185.5771.5771.5071.46184.8510,240164.0860.1260.0359.99163.9412,288147.14————14,336133.49————16,384122.25————总耗时11,055 tokens—197.4 s207.8 s207.8 s84.1 s注A-1/A-2/A-3 三组轨迹逐项几乎一致差异 2%说明线程设置对预填充无影响A 组整体比 B 组慢约 2.5 倍唯一变量是 KV 量化 →q8_0 是负优化元凶。4.2 关键单点对比10,240 tokens 处q8_0: prompt eval 170.57 s / 10240 tokens (60.03 tok/s) f16 : prompt eval 62.46 s / 10240 tokens (163.94 tok/s) 差 2.73 倍4.3 Prompt Cache 验证C 组决定性数据第一轮模型冷加载后首个请求全量预填充: prompt eval 71451.11 ms / 11055 tokens (154.72 tok/s) → 请求总耗时 84.1 s 第二轮相同提示词Keep-Alive 生效缓存命中: cached n_tokens 11054, memory_seq_rm [11054, end) ← 跳过 11054/11055 个 token prompt eval 47.99 ms / 1 tokens ← 仅计算尾部新增 1 token → 请求总耗时 1.6 s指标第一轮第二轮提升预填充耗时71,451 ms48 ms99.93% ↓请求总耗时含 32 token 生成84.1 s1.6 s98.1% ↓缓存命中率0%11,054 / 11,055 99.99%—4.4 生成阶段速度供参考场景生成速度长文本生成187 tokens 实测17.06 tok/s短回复32 tokens 实测22.67 tok/s五、机理分析5.1 为什么预填充随上下文衰减291 → 122 tok/s注意力计算量平方级增长每处理一个新 token 需与前面全部 KV 做注意力运算上下文 2,048 → 16,384计算量增 8 倍内存带宽是 CPU 推理的第一瓶颈权重 31 GB 持续增长的 KV 缓存全部走内存总线纯 CPU 推理-ngl 0时上述开销完全由内存子系统承担核心数再多也救不了。5.2 为什么 q8 KV 在 CPU 上是负优化维度GPUCPU本实验内存带宽极高~1 TB/s 级有限百 GB/s 级KV 量化收益省带宽 → 明显加速省下的带宽有限dequant 开销并行计算单元消化每次注意力计算都要反量化开销 ≥ 收益实测结果未测慢 2.73 倍结论KV Cache 量化OLLAMA_KV_CACHE_TYPEq8_0是为 GPU 显存/带宽场景设计的手段CPU 上反量化开销吃掉了全部带宽收益还倒贴。CPU 推理保持默认 f16 KV。5.3 为什么线程数无效预填充受内存带宽约束而非计算核心数约束Threadripper 的 SMT 虚核64 逻辑核共享同一内存带宽多线程争抢时收益互相抵消。Ollama/llama.cpp 自动检测的线程数已经是最优。5.4 为什么 Keep-Alive Prompt Cache 是质变llama.cpp 会缓存已计算前缀的 KV 状态cached n_tokens请求前缀一致时直接复用只对增量部分做预填充。默认OLLAMA_KEEP_ALIVE5min时模型频繁卸载缓存每次归零基线日志cached n_tokens 0拉长到 24h 后模型常驻缓存跨请求存活——这正是 RAG 场景的标准形态固定 system 固定文档 尾部变化问题。六、结论与最佳实践优先级手段收益备注★★★OLLAMA_KEEP_ALIVE24h模型常驻同前缀请求预填充提速 99.9%前提调用方提示词前缀稳定★★★提示词结构化前缀固定、变更放尾部激活 Prompt Cache 的前提调用方可改造时★★☆保持 f16 KV不开OLLAMA_KV_CACHE_TYPE避免 2.7 倍退化CPU 推理★★☆保持默认线程不设OLLAMA_NUM_THREADS避免无效操作自动检测即最优☆☆☆KV 量化 / 线程调优CPU 场景负收益 / 零收益实测使用前提与边界Prompt Cache 收益的前提是提示词前缀一致若每次提示词完全随机无公共前缀缓存不命中回到全量预填充CPU 物理极限11K token ≈ 84 s模型常驻增加约 31 GB 内存占用本机 128 GB 无压力小内存机器需权衡生成阶段decoding不受上述优化影响CPU 上约 17~23 tok/s。排查口诀遇到CPU 拉满但模型不输出先看日志中prompt processing的progress是否推进——在推进 预填充正常等它完成停滞 才是真卡死。附录 A测试方法可复现生成固定长度中文提示词19,125 字符 ≈ 11,055 tokensPOST/v1/chat/completionsmax_tokens32隔离生成阶段仅测预填充curl-s-XPOST http://host:11434/v1/chat/completions\-HContent-Type: application/json\-d{model:model,messages:[{role:user,content:11K-token-text}],max_tokens:32,stream:false}每次修改配置systemctl daemon-reload systemctl restart ollama冷却 45 s 消除热降频从journalctl -u ollama提取prompt processing轨迹与cached n_tokens对照组每项只改一个变量。附录 B配置变更记录systemd drop-in# /etc/systemd/system/ollama.service.d/override.conf最终生效版 [Service] EnvironmentOLLAMA_KV_CACHE_TYPEq8_0 # ❌ 已移除实测负优化 2.7x EnvironmentOLLAMA_NUM_THREADS64 # ❌ 已移除实测无差异 EnvironmentOLLAMA_KEEP_ALIVE24h # ✅ 保留Prompt Cache 收益来源修改流程先备份原 drop-in 目录 → 追加 Environment 行勿覆盖原 OLLAMA_MODELS/OLLAMA_HOST/OLLAMA_ORIGINS→daemon-reload→restart→ 基准复测。免责声明本文数据为单机单次实测每配置一组基准轨迹逐点记录个体差异以复测为准。测试期间系统负载 33 → 1.4清理异常任务后冷却 45 秒后频率恢复正常3.9~5.3 GHz再测量。
返回列表