本地运行模型
之前直接使用 LM-studio,好用、无脑。本地用足够了。但是放在服务器上才是正道,本地运行无法长时间开启保持运行,而且 Ollama 推出了并行 GPU 计算之后可用性大幅提升,可用性很高。今天研究下如何用 Ollama 如何在本地来使用这些 HF 的开源模型,后面把它搬到服务器上。
设置
设置很简单,先在电脑上创建一个文件夹,比如我会把我的模型放到一个雷电 3 外接的 nvme 硬盘上,路径是 /Volumes/RD/Modules。然后在这里直接创建,格式可以参考 Ollama 的文档。
touch lmstudio-ai/Meta-Llama-3-8B-Instruct-GGUF/Modelfile
从 HuggingFace 下载模型
1. 使用 HuggingFace
从 HuggingFace 下载模型需要挑选下。这里我先以 Meta-Llama-3-8B-Instruct 为例子,我之前下载了 lmstudio-ai/Meta-Llama-3-8B-Instruct-GGUF。如果网络存在问题可以选择国内镜像站,当然也可以去国内的下载。下载可以选择镜像站,但是你还是需要梯子的,因为比如 Meta 的 Llama3 或者 Google 的 Gemma 等模型都是需要申请的,通过了才能用。不过给大家提个醒,申请 Token 的时候尽量别填写中国,否则你会遇到跟我一样的情况。
遇到这种情况你可以选择三种方案:
- 使用搜索引擎搜资源,看看有人共享模型网盘地址没有。
- 直接搜索模型名称,有一些有志人士会讲这些模型重传到自己仓库中让大家使用。
- 直接在 HuggingFace 中查找下载。
OK,知道在哪下载了之后你要知道用什么样的模型。
2. 应该下载什么样的模型
本地运行模型在不写代码的情况对于模型格式还是需要一些要求的。你会遇到两种格式 GGUF 和 Safetensor。
GGUF(General Graphical User Interface Format)是一种用于存储和共享开源机器学习模型的格式。
Safetensors 是一种专为机器学习模型设计的文件格式。
简单说,GGUF 把模型权重和结构统一存储了,方便传输和扩展。Safetensors 是二进制格式,安全高效,可以通过量化转换为 GGUF,可以参考的官方文档。它们的细节差别,以及具体如何将 safetensor 量化转换我会再写一篇文章细说。
那么我们最好挑 GGUF 格式模型,主机配置高的可以 Q6、Q8,配置不行的自行尝试小的吧。我自己平时用 Q6 的就足够了(M2 Ultra, 192G)。GGUF 格式的所有的模型都可以被 Ollama 直接加载,也可以在 LM-studio 中直接使用,比较推荐。
而 Safetensor 格式的 Ollama 支持了三种架构的也可以直接加载:
- LlamaForCausalLM
- MistralForCausalLM
- GemmaForCausalLM
这里以 GGUF 为例介绍一下怎么用。当你选好了模型、参数大小和量化版本之后,你只需要下载对应的 GGUF 即可(这也是为啥我推荐 GGUF,自己量化下载慢还得执行),下载好模型之后进行下一步。
使用 Modelfile 加载模型
最简单的使用
- 指定模型
FROM Meta-Llama-3-8B-Instruct-Q6_K.gguf
- 导入模型文件
ollama create randy-model -f Modelfile
输出显示 transferring model data... success。
- 运行导入的模型后进入命令行交互模式
ollama run randy-model
>>> 介绍一下你自己
Nice to meet you! I'm LLaMA, an AI assistant developed by Meta AI...
经过上面三步已经可以用命令行跟大模型沟通了,但是为了作为生产力给各个软件提供能力,你还需要继续折腾一下。
- 很多模型对中文是不友好的,比如这个 Meta 的 Llama3 和 3.1。我们可以在导入 Model 的时候要求 Ollama 增加 TEMPLATE、SYSTEM、PARAMETER。
- 为了对接使用模型的应用,需要后台运行模型暴露 API 接口。
稍微进阶一下
1. 修改一下 Modelfile
通过上面的内容大家也看得出,其实 Ollama 的 Modelfile 跟 Docker 的 Dockerfile 格式很相似,我们需要添加几个内容改成这个样子,有一部分是来自 Ollama 的官方文档,一部分来自网上找的,简单解释下含义。
FROM Meta-Llama-3-8B-Instruct-Q6_K.gguf
# sets the temperature to 1 [higher is more creative, lower is more coherent]
PARAMETER temperature 1
# sets the context window size to 4096, this controls how many tokens the LLM can use as context to generate the next token
PARAMETER num_ctx 4096
TEMPLATE """{{ if .System }}<|start_header_id|>system<|end_header_id|> {{ .System }}<|eot_id|>{{ end }}{{ if .Prompt }}<|start_header_id|>user<|end_header_id|> {{ .Prompt }} <|eot_id|>{{ end }}<|start_header_id|>assistant<|end_header_id|> {{ .Response }}<|eot_id|>"""
SYSTEM """尽你的最大可能和能力回答用户的问题。不要重复回答问题。不要说车轱辘话。语言要通顺流畅。不要出现刚说一句话,过一会又重复一遍的愚蠢行为。
RULES:- Be precise, do not reply emoji.- Always response in Simplified Chinese, not English."""
PARAMETER stop "<|start_header_id|>"
PARAMETER stop "<|end_header_id|>"
PARAMETER stop "<|eot_id|>"
PARAMETER stop "<|reserved_special_token"
参数说明:
- PARAMETER:指定模型的一些参数,包括常见的 temperature、top-p、tok-k 等。这里说下 stop,stop 其实是要设置模型的停止符。当遇到 stop 的 value 值时,LLM 将停止生成文本并返回。可以通过在模型文件中指定多个单独的
stop 参数来设置多个停止模式。
- SYSTEM:预设的 System message。
- TEMPLATE:这个重点说一下,这个模板是定义的是真正传递给 LLM 的 input 内容。通过这个模板的定义我们可以完整的控制到底如何传递给大模型,也能配合 stop 标记来管理。由于 Ollama 使用 go 语言开发,所以模板语法也是 go 的规则。
2. 创建一个新版本的 model 镜像
ollama create randy-model:v1 -f Modelfile
ollama list
可以看到新版本已创建。
3. 再试试吧
ollama run randy-model:v1
>>> 介绍一下你自己
Bonjour! 您好!我是一个人工智能语言模型,我被设计用于回答问题、生成文本和进行自然语言处理...
可以看到中文响应更自然了。
试试 API
到此为止我们的模型已经在本地运行了,想要建立后台任务可以尝试 mac 的后台进程或者 linux 的 screen 命令等,根据实际情况处理即可。关于 Ollama 的 API 官方文档有说明。这里只做简单的一个测试。如果你不确定 ollama 服务运行的端口可以用 ollama serve 来试一下,没启动的话会尝试启动,在运行的话会告诉你运行在哪。
curl --location --request POST 'http://127.0.0.1:11434/api/generate' \
--header 'User-Agent: Apifox/1.0.0' \
--header 'Content-Type: application/json' \
--data-raw '{
"stream": false,
"system": "你是一个中文助手",
"model": "randy-model",
"prompt": "介绍一下你自己"
}'
生产环境如何使用
Ollama 的 API 和 OpenAI 的 API sdk 还是有差别的,如果想无缝切换到 OpenAPI 的 sdk 中最简单的方式就是做代理,感谢开源,有些项目已经可以帮我们完成这个目标了,推荐使用作为中间代理。
常见问题与优化
- 显存不足:如果运行过程中发现显存爆满,建议降低量化等级(如从 Q8 降至 Q4),或减少
num_ctx 上下文窗口大小。
- 响应速度慢:检查 GPU 是否被正确识别,确保 Ollama 版本较新以利用最新的 CUDA 加速特性。
- 中文乱码:确保 Modelfile 中的 SYSTEM 提示词明确指定输出简体中文,并使用合适的 Template 防止特殊字符解析错误。
总结
Ollama 还是比较适合作为中间层的,运行效率已经基本能满足服务使用。经过测试在 0.2 以上的版本性能在我的主机上 llama3 8B 的性能并不低与 GPT 3.5,比 4o-mini 稍微慢一点。当然推理能力和生成质量稍有不及,不过只要主机够多,搭建私域强大的 LLM 不是问题。