AI · #llm#ollama#open-webui#local-ai

使用 Ollama 在本地跑大语言模型

2024.02.23 2 min 986
// 目录 · contents

大概是 2024 年初,公司有个需求:做内部代码辅助工具,但代码不能传到 OpenAI。本地部署模型这条路于是变成了必选项。折腾了一周之后,Ollama 成了我日常用得最顺手的方案,这篇文章记录一下过程。

为什么是 Ollama

当时看了几个方案,llama.cpp 太底层,LM Studio 有 GUI 但 API 不好用,Ollama 的定位很准——用起来像 Docker,ollama pull 拉模型,ollama run 跑模型,命令简单,API 兼容 OpenAI 格式,现有代码改一行 base_url 就能接。

我用的是 M2 MacBook Pro 16GB,跑 7B 的模型没什么压力,13B 会有点吃力,70B 就别想了。

装起来

1
2
brew install ollama
ollama serve # macOS 安装后会自动注册 launchd,通常不需要手动起

拉一个模型跑起来:

1
ollama run mistral

第一次会自动下载,Mistral 7B 大概 4GB。下完之后直接进了交互对话界面。

几个常用的模型选择:中文场景用 qwen:7b(通义千问),代码用 codellama,通用任务我现在主要用 mistral,质量和速度比 llama2 都要好一些。

用 Modelfile 定制

这是 Ollama 比较好用的地方。可以写一个 Modelfile 固定 system prompt 和参数,然后 ollama create 生成一个”定制版本”:

1
2
3
4
5
6
7
8
9
10
11
FROM mistral

SYSTEM """
你是一个 Java 后端开发助手。
回答用中文,代码示例用 Java 17+。
直接给代码,不需要解释废话。
如果涉及性能问题,给出量化的对比。
"""

PARAMETER temperature 0.5
PARAMETER num_ctx 4096
1
2
ollama create java-helper -f ./Modelfile
ollama run java-helper

我给不同的场景做了几个版本:代码审查、SQL 优化、技术方案评审。每次开对话直接选对应的模型,比每次手写 system prompt 方便。

API 调用

Ollama 暴露了两套接口,原生的和兼容 OpenAI 格式的,我基本只用后者:

1
2
3
4
5
6
7
8
9
10
11
12
from openai import OpenAI

client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="whatever", # 本地不验证
)

resp = client.chat.completions.create(
model="mistral",
messages=[{"role": "user", "content": "用 Java 写个 LRU 缓存"}],
)
print(resp.choices[0].message.content)

真的就只改了一行 base_url,把原来接 OpenAI 的代码直接跑本地了。

搭 Open WebUI

命令行对话用久了还是不太方便,搭了个 Open WebUI,有类似 ChatGPT 的界面,支持多模型切换、对话历史保存。

1
2
3
4
5
6
7
docker run -d \
-p 3000:8080 \
-v open-webui:/app/backend/data \
--add-host=host.docker.internal:host-gateway \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
--name open-webui \
ghcr.io/open-webui/open-webui:main

host.docker.internal 这个很关键,容器里访问不到宿主机的 localhost,一开始没加这个参数一直连不上 Ollama,后来才想明白。

踩过的坑

内存压力导致冷启动变慢

跑 13B 模型时,系统内存压力大的时候 macOS 会把模型从内存里踢出去,下次对话第一条消息得等二三十秒重新加载。最后还是换回了 7B,速度快一倍,质量差了一点,但可以接受。

中文效果问题

Llama 2 的中文真的很差,说的是人话但经常驴唇不对马嘴。换成 Qwen 之后好了很多,中文理解和生成都明显提升。Mistral 的中文比 Llama 2 好,但还是不如 Qwen。

批处理任务超时

用 API 跑批处理,长文本生成时客户端默认超时会报错。加上超时配置就好了:

1
2
3
4
5
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="whatever",
timeout=120.0,
)

整体下来,本地模型对于数据敏感的场景已经够用了。代码辅助、内部文档问答这两块用 7B 的模型基本满足需求。复杂推理、长上下文分析还是得上云端的大模型。

作者 · authorzt
发布 · date2024-02-23
篇幅 · length986 字 · 2 min
许可 · licenseCC BY-SA 4.0
$ echo "comments" · 评论