云端大模型按 token 计费,一个月对话量上来后账单吓人,而且内部工单数据走公网总归不踏实。同事安利了 Ollama,说本地能跑开源模型。我半信半疑地试了,结论是:本地模型不是云端替代品,而是特定场景的划算补充。
模型量化:显存决定你能跑多小
Ollama 拉模型时就要选量化版本。以 Qwen2-7B 为例,不同量化对显存和效果影响很大:
| 量化 | 大致显存 | 中文效果 | 推理速度(token/s) |
|---|---|---|---|
| q8_0 | 约 8GB | 接近原版 | 22 |
| q4_K_M | 约 4.5GB | 可接受 | 41 |
| q2_K | 约 3GB | 明显退化 | 58 |
我们的机器是单卡 16GB,一开始贪效果用 q8_0 跑 7B,剩的显存不够并发第二个模型。切到 q4_K_M 后,显存省下近一半,速度翻倍,中文问答在内部知识库场景上差别不大(人工评测 0.82 vs 0.78)。量化是本地部署最值得抠的旋钮。
Java 侧怎么调
Ollama 提供 HTTP API,Java 用普通 HttpClient 就能调,不用重依赖:
HttpClient c = HttpClient.newHttpClient();
String body = """
{"model":"qwen2:7b-q4_K_M","prompt":"总结这段工单:%s","stream":false}
""".formatted(ticket);
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("http://ollama:11434/api/generate"))
.POST(BodyPublishers.ofString(body)).build();
HttpResponse<String> r = c.send(req, BodyHandlers.ofString());
// 解析 json 拿 response 字段
若要流式,把 stream 设为 true,响应是逐行 JSON,自己按行读。我们封装了一层 OllamaClient,统一处理超时(设 30 秒)和重试。
推理性能与并发
本地模型的两个硬伤:首 token 慢、并发低。我们测过,7B-q4 在单卡上:
- 单请求首 token 约 300ms,之后 41 token/s,一段 200 字回答约 5 秒;
- 并发超过 4 路,显存争抢,速度掉到 15 token/s,且易 OOM。
所以本地模型不适合"高并发公开服务",更适合"内部低频、批量、隐私敏感"的任务,比如每晚批量总结工单、给知识库打标签。这些不要求实时,本地跑正好省云费用。
与云端模型的混合使用
我们的策略是分层:
- 简单、批量、含敏感数据的:走本地 Ollama,零成本、数据不出内网;
- 复杂推理、实时交互、要效果的:走云端大模型(如 GPT-4o 级别或国内大模型 API);
- 路由层按"任务类型 + 数据敏感度"决定走哪条路,对用户透明。
比如客服实时对话走云端,但对话里提取的"用户订单号、手机号"做脱敏时,用本地模型处理,敏感字段不外泄。
成本对比(月度)
| 方案 | 费用 | 适用 |
|---|---|---|
| 全云端 | 约 1.2 万元/月 | 全场景 |
| 混合(本地批处理+云端实时) | 约 3800 元/月 | 我们现状 |
小结
Ollama + Java 把"本地大模型"的门槛降到了一个 HTTP 调用。关键是量化选对(我们 7B 用 q4_K_M 性价比最高),并认清它的边界:不适合高并发实时,适合隐私敏感、可批量的内部任务。和云端模型做混合路由,既省了七成成本,又守住了数据不出网的底线。别指望本地模型全面替代云端,把它放在该在的位置,它就很香。