为什么本地跑 LLM
在 Claude API 和 GPT API 如此好用的今天,为什么还要在本地跑模型?
三个核心理由:
- 数据隐私:敏感数据(医疗记录、法律文件、内部代码)不能发送到第三方 API
- 成本控制:高频调用场景下,API 费用远超本地部署的硬件成本
- 离线可用:飞机上、内网环境、网络不稳定的场景
Ollama 让本地 LLM 从”编译 C++ 依赖地狱”变成了”一行命令搞定”。
安装和快速开始
macOS / Linux
# 一行安装
curl -fsSL https://ollama.com/install.sh | sh
# 拉取并运行模型
ollama run llama3
# 就这样。你现在可以在终端里和 Llama 3 对话了。
验证安装
# 查看已安装的模型
ollama list
# 查看运行状态
ollama ps
# Ollama 自动在后台启动 API 服务
curl http://localhost:11434/api/tags
模型选择策略
Ollama 模型库有 200+ 模型,选择困难症的解药:
按场景选模型
| 场景 | 推荐模型 | 大小 | 说明 |
|---|---|---|---|
| 通用对话 | llama3:8b | 4.7 GB | 综合能力最均衡的入门选择 |
| 中文对话 | qwen2.5:14b | 8.7 GB | 中文理解和生成能力最强 |
| 代码生成 | deepseek-coder-v2:16b | 9.4 GB | 代码补全和生成专精 |
| 数学推理 | qwen2.5-math:7b | 4.4 GB | 数学推理专精模型 |
| 极速响应 | gemma4:2b | 1.6 GB | 最小但够用的模型 |
| 高质量输出 | llama3:70b-q4 | 40 GB | 接近 GPT-4 水平,需大内存 |
| 多模态(图文) | llava:13b | 8.0 GB | 支持图片输入的视觉模型 |
按硬件选模型
8 GB 内存 → gemma4:2b 或 phi4-mini:3.8b
16 GB 内存 → llama3:8b 或 qwen2.5:7b
32 GB 内存 → qwen2.5:14b 或 llama3:8b-q8(高精度)
64 GB 内存 → llama3:70b-q4(需要耐心等待)
拉取模型
# 拉取默认版本(通常是 Q4_K_M 量化)
ollama pull llama3
# 拉取特定大小
ollama pull llama3:8b
ollama pull llama3:70b
# 拉取特定量化版本
ollama pull llama3:8b-q8_0 # 8-bit 高精度
ollama pull llama3:8b-q4_0 # 4-bit 小内存
量化对比:精度 vs 速度 vs 内存
量化是把模型权重从 FP16(16-bit)压缩到更低位数(4-bit、8-bit)的过程。Ollama 使用 GGUF 格式,支持多种量化方式。
Llama 3 8B 在 M4 Pro 36GB 上的实测
| 量化 | 文件大小 | 内存占用 | 速度 (tok/s) | MMLU 精度 |
|---|---|---|---|---|
| Q4_K_M (默认) | 4.7 GB | 5.2 GB | 45 | 63.8 |
| Q5_K_M | 5.3 GB | 5.9 GB | 38 | 65.1 |
| Q6_K | 6.6 GB | 7.1 GB | 32 | 65.6 |
| Q8_0 | 8.5 GB | 9.2 GB | 25 | 65.9 |
| FP16 (无量化) | 16 GB | 17 GB | 14 | 66.2 |
结论:Q4_K_M 是性价比甜点——精度损失仅 3.6%,速度是 FP16 的 3.2 倍。除非你的任务对精度极度敏感(如数学推理),否则 Q4_K_M 足够了。
REST API 使用
Ollama 启动后自动在 localhost:11434 提供 REST API。
基本调用
# 生成文本
curl http://localhost:11434/api/generate -d '{
"model": "llama3",
"prompt": "用 TypeScript 实现一个 retry 装饰器",
"stream": false
}'
# 对话模式
curl http://localhost:11434/api/chat -d '{
"model": "llama3",
"messages": [
{ "role": "system", "content": "你是一个 TypeScript 专家。" },
{ "role": "user", "content": "实现一个类型安全的事件总线" }
],
"stream": false
}'
OpenAI 兼容接口
Ollama 内置了 OpenAI 兼容的 API 端点,你可以直接用 OpenAI SDK 连接:
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "http://localhost:11434/v1",
apiKey: "ollama", // Ollama 不需要真实 key
});
const response = await client.chat.completions.create({
model: "llama3",
messages: [
{ role: "user", content: "解释 TypeScript 的协变和逆变" },
],
});
console.log(response.choices[0].message.content);
这意味着你可以在开发时用 Ollama(免费),生产时切换到 OpenAI/Claude API,代码几乎不用改。
流式响应
const stream = await client.chat.completions.create({
model: "llama3",
messages: [{ role: "user", content: "写一个 Express 中间件" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
LangChain 集成
基础使用
import { ChatOllama } from "@langchain/ollama";
const llm = new ChatOllama({
model: "llama3",
temperature: 0,
baseUrl: "http://localhost:11434",
});
const response = await llm.invoke("什么是 RAG?");
console.log(response.content);
搭配 RAG 使用
import { ChatOllama, OllamaEmbeddings } from "@langchain/ollama";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
// 用 Ollama 的 embedding 模型
const embeddings = new OllamaEmbeddings({
model: "nomic-embed-text",
baseUrl: "http://localhost:11434",
});
// 文档切分
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 200,
});
const docs = await splitter.createDocuments([documentText]);
// 向量存储
const vectorStore = await MemoryVectorStore.fromDocuments(docs, embeddings);
// 检索 + 生成
const retriever = vectorStore.asRetriever(3);
const relevantDocs = await retriever.invoke("如何配置 TypeScript 路径别名?");
const llm = new ChatOllama({ model: "llama3", temperature: 0 });
const response = await llm.invoke([
{
role: "system",
content: `根据以下上下文回答问题:\n${relevantDocs.map(d => d.pageContent).join("\n")}`,
},
{ role: "user", content: "如何配置 TypeScript 路径别名?" },
]);
全程数据不离开你的机器——模型推理、向量化、检索都在本地完成。
自定义模型:Modelfile
Ollama 的 Modelfile 类似 Dockerfile,让你基于现有模型创建定制版本:
# 基于 llama3 创建一个代码审查专用模型
FROM llama3
# 设置系统提示
SYSTEM """
你是一个严格的代码审查员。对每段代码,按以下维度评估:
1. 类型安全
2. 错误处理
3. 性能隐患
4. 安全漏洞
输出格式为 JSON,包含 severity(high/medium/low)和 suggestion 字段。
"""
# 调整参数
PARAMETER temperature 0.1
PARAMETER top_p 0.9
PARAMETER num_ctx 8192
# 构建自定义模型
ollama create code-reviewer -f Modelfile
# 使用
ollama run code-reviewer "审查这段代码:async function fetchUser(id) { ... }"
性能优化
1. GPU 层数控制
Ollama 默认会尽量把所有层加载到 GPU。当 GPU 内存不足时,可以手动控制:
# 指定加载到 GPU 的层数(减少可降低显存使用)
OLLAMA_NUM_GPU=20 ollama run llama3:70b
2. 上下文窗口调整
默认上下文是 2048 token,增大上下文会增加内存占用:
# 临时设置
ollama run llama3 --num-ctx 8192
# 在 Modelfile 中永久设置
PARAMETER num_ctx 8192
上下文窗口每增加 1K token,额外消耗约 100-200 MB 内存(取决于模型大小)。
3. 并发请求
Ollama 默认支持并行请求,但多个请求共享 GPU 资源:
# 设置最大并行请求数
OLLAMA_NUM_PARALLEL=4 ollama serve
# 设置模型在内存中的保留时间(避免频繁加载卸载)
OLLAMA_KEEP_ALIVE=30m ollama serve
4. 多模型管理
如果你需要同时运行多个模型:
# 查看当前加载的模型
ollama ps
# 预加载模型(不启动对话)
curl http://localhost:11434/api/generate -d '{"model": "llama3", "keep_alive": "30m"}'
# 卸载模型释放内存
curl http://localhost:11434/api/generate -d '{"model": "llama3", "keep_alive": "0"}'
生产部署注意事项
安全
# 默认只监听 localhost,生产环境如需外部访问:
OLLAMA_HOST=0.0.0.0:11434 ollama serve
# 务必在前面加反向代理(Nginx/Caddy)做认证
# Ollama 本身没有认证机制
Docker 部署
# docker-compose.yml
services:
ollama:
image: ollama/ollama:latest
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
volumes:
ollama_data:
监控
# 查看实时推理状态
ollama ps
# 查看模型加载时间和内存占用
curl http://localhost:11434/api/ps
Ollama vs 其他本地方案
| Ollama | llama.cpp | vLLM (本地) | LM Studio | |
|---|---|---|---|---|
| 安装难度 | 极低 | 中等 | 高 | 极低 |
| API 支持 | REST + OpenAI 兼容 | 需额外配置 | OpenAI 兼容 | REST |
| 多模型管理 | 内置 | 手动 | 手动 | GUI |
| GPU 支持 | CUDA + Metal | CUDA + Metal | CUDA | CUDA + Metal |
| 性能 | 良好 | 最优 | 最优(批量) | 良好 |
| 适用场景 | 开发/内部工具 | 极致性能 | 高并发服务 | 体验/测试 |
我的建议:个人开发和内部工具用 Ollama,需要极致推理性能用 llama.cpp,面向用户的服务用 vLLM。
什么时候不该用本地 LLM
- 需要顶级智能:本地能跑的最大模型(70B Q4)仍然不如 Claude Opus 或 GPT-5
- 需要长上下文:本地模型的上下文通常限制在 8K-32K,远不如 API 模型的 128K-1M
- 没有合适硬件:8GB 以下内存的机器只能跑 2-3B 的小模型,实用性有限
- 需要多模态:本地多模态模型的质量和 API 模型差距更大
最佳实践:本地模型做开发测试和隐私敏感任务,API 模型做生产推理和复杂任务。两者互补而非替代。