Administrator
发布于 2024-07-26 / 4468 阅读
113

本地大模型部署:Ollama + Java 的实践

云端大模型按 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 性价比最高),并认清它的边界:不适合高并发实时,适合隐私敏感、可批量的内部任务。和云端模型做混合路由,既省了七成成本,又守住了数据不出网的底线。别指望本地模型全面替代云端,把它放在该在的位置,它就很香。

参考