Ollama — 本地跑 LLM 的工具
已复核Ollama 是本地大语言模型的“Docker”。日常类比:以前想在自己电脑跑一个 LLM,要装 Python、装 CUDA、装推理框架、对齐一堆依赖版本;Ollama 把这些打包成一个 Go 编写的服务加一行命令。
实际操作长这样:
ollama pull llama3.1 # 下载模型ollama run llama3.1 # 进入对话服务默认监听 127.0.0.1:11434。更关键的是:固定 v0.33.1 在同一个端口上同时提供三套 HTTP API——自家原生 /api/*、OpenAI 兼容 /v1/chat/completions 等、以及 Anthropic Messages 兼容 /v1/messages。你之前写给 OpenAI 或 Claude 的客户端代码,把 base URL 一改就能打到本地模型。
不理解 Ollama 的分层,下面这些事说不清:
- 为什么“本地跑 LLM”从一件需要工程师折腾环境的事,变成了一行命令的事——变化在安装与分发工程,不在模型本身
- 为什么 LangChain / LlamaIndex 这类框架都默认支持 Ollama——它同时讲 OpenAI 和 Anthropic 两种“方言”,存量客户端零改动
- 为什么
ollama create基于已有模型做定制几乎不占额外磁盘——和 Docker layer 复用是同一招 - 为什么模型第一次请求慢、过几分钟再问又要重新加载——服务、调度器与推理子进程是三层
固定 v0.33.1 的架构可以拆成三层:
-
Modelfile(Dockerfile 风格的模型配置 DSL):parser 接受
FROM、PARAMETER、TEMPLATE、SYSTEM、ADAPTER、LICENSE、MESSAGE、RENDERER等指令。写一个声明文件“基于 llama3.1,加一段 system prompt,温度 0.7”,ollama create出一个新名字的模型。类比:Dockerfile 基于基础镜像加几层。 -
内容寻址存储:模型数据放在
<models>/blobs/sha256-<摘要>,名字与版本由<models>/manifests/里的清单指向这些 blob——和 Docker/Git 一样“内容定址、清单引用”。所以ollama create不复制权重,只新建一份 manifest 复用既有 blob;同一权重被多个自定义模型共享。 -
服务与推理引擎分离:HTTP 层(原生 + OpenAI + Anthropic 三套 API)→ 调度器(按
OLLAMA_NUM_PARALLEL、OLLAMA_KEEP_ALIVE管理加载与并发)→ 推理子进程。该版本源码明确:所有 GGML/GGUF 模型由上游llama-server子进程推理(仓库根LLAMA_CPP_VERSION锁定 b10630);Apple MLX 路径走独立的--mlx-enginerunner。Ollama 不再自己重写推理循环,而是把上游引擎当成可替换的子进程。
三个关键默认值(envconfig):监听 127.0.0.1:11434;OLLAMA_NUM_PARALLEL=1(单模型并发请求数);OLLAMA_KEEP_ALIVE=5m(模型空闲 5 分钟后卸载)。
案例 1:两行命令 + 一个 curl
Section titled “案例 1:两行命令 + 一个 curl”ollama pull llama3.1curl http://localhost:11434/api/chat -d '{ "model": "llama3.1", "messages": [{"role": "user", "content": "用一句话解释相对论"}]}'逐部分:pull 把模型 blob 下载进内容寻址存储并写 manifest;/api/chat 是原生对话端点,默认流式返回。首次请求会触发模型加载(调度器拉起推理子进程),空闲超过 keep-alive 后卸载,下次请求再加载。
案例 2:用 Modelfile 做个“古文先生”
Section titled “案例 2:用 Modelfile 做个“古文先生””cat > Modelfile <<'EOF'FROM llama3.1SYSTEM "你是一位读过四书五经的先生。无论问什么都用古文回答,每句不超过 12 字。"PARAMETER temperature 0.6EOF
ollama create sage -f Modelfileollama run sage "如何学好编程?"逐部分:FROM 指向已有模型;SYSTEM 与 PARAMETER 是 parser 支持的指令。create 不会重新下载 llama3.1 的权重——它复用既有 blob,只新建一份 manifest 指向同一文件,这就是“像 Docker”的 layer 复用。
案例 3:OpenAI / Anthropic 客户端零改动打到本地
Section titled “案例 3:OpenAI / Anthropic 客户端零改动打到本地”from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")resp = client.chat.completions.create( model="llama3.1", messages=[{"role": "user", "content": "Go 的 channel 一句话讲清"}],)逐部分:/v1/chat/completions、/v1/completions、/v1/embeddings、/v1/models、/v1/responses 是 OpenAI 兼容层;同版本还挂了 Anthropic Messages 兼容的 /v1/messages——两大主流客户端生态的存量代码都只改 base URL。api_key 本地不校验,但多数 SDK 要求非空。
-
内存由模型大小决定:模型文件多大,加载进内存/显存就大致要多大,超了就加载失败或落到极慢路径。下载前用
ollama list看体积,跑起来用ollama ps看实际占用,别靠经验数字猜。 -
量化档位是质量 vs 体积的取舍:同一模型有 Q2/Q4/Q5/Q8 等量化版本,位宽越低体积越小、质量损失越大。具体损失多少因模型与任务而异——本轮未做量化质量测量,选档位要自己对任务试。
-
并发默认是 1,不是“开箱高并发”:固定 v0.33.1 的
OLLAMA_NUM_PARALLEL默认值是1,同一模型同时只处理一个请求,其余排队。小团队共用要显式调大,生产高并发场景该看 vllm 这类专职 serving 引擎。 -
keep-alive 让“第二次请求变快”也让“闲置后变慢”:模型空闲 5 分钟(默认)后卸载,下次请求重新加载。演示前先热身一次,或调
OLLAMA_KEEP_ALIVE。 -
模型必须是 GGUF(走 llama-server 路径):HuggingFace 上的 safetensors 权重要先转换成 GGUF 才能导入;Apple 侧另有 MLX 引擎路径。转换工具链在 Ollama 之外,新手容易卡在这一步。
适用 vs 不适用场景
Section titled “适用 vs 不适用场景”适用:
- 个人本地试模型、调 prompt——不烧云端 token,数据不出本机
- 小团队内部共享一个推理服务——OpenAI/Anthropic 双兼容层接现有客户端
- LLM 应用开发期的本地 mock 与离线演示
- 用 Modelfile 把“模型 + system prompt + 参数”打包成可版本化、可分享的配置
不适用:
- 生产高并发推理——默认单请求并发的调度模型不是为千 QPS 设计的,选 vLLM / 专职 serving
- 需要直接控制推理引擎细节——那不如直接用 llama-cpp 的
llama-server,少一层管理面 - 完全不碰命令行的用户——GUI 优先的桌面工具更合适
- 训练 / fine-tune——Ollama 只做推理与分发,训练在别处完成后转 GGUF 导入
固定版本边界
Section titled “固定版本边界”- 本文绑定
ollama/ollama@13f2fb8c...,即 release tagv0.33.1(lightweight tag,Ollama 不发 npm 包)。 - 推理引擎:GGML/GGUF 模型统一由上游
llama-server子进程服务(LLAMA_CPP_VERSION锁b10630);MLX 引擎(MLX_VERSION c793734e...)经--mlx-engine独立入口,面向 Apple 平台。 - API 面:原生
/api/*(含 experimentalweb_search/web_fetch/model-recommendations)、OpenAI 兼容/v1/*(含/v1/responses)、Anthropic 兼容/v1/messages;cloud passthrough 可把 cloud 模型转发到 ollama.com。 - 默认值:
OLLAMA_HOST=127.0.0.1:11434、OLLAMA_NUM_PARALLEL=1、OLLAMA_KEEP_ALIVE=5m、OLLAMA_MODELS可配置。 - 本文未运行 Ollama 服务、未拉取模型、未做推理速度或量化质量测量;registry 上各模型默认量化档位以其页面为准,本文不绑定。状态保持
UNVERIFIED。
- 易用性本身是产品力——把“装环境”变成“拉二进制”,这层分发工程与模型能力无关,却决定了普及速度
- 兼容层是采纳策略——同时讲 OpenAI 与 Anthropic 两种 API 方言,存量生态零改动迁移,比“更好的自有 API”更有效
- content-addressed storage 是通用套路——Docker、Git、Nix、Ollama 都是“blob 定址 + 清单引用”,配置变更不复制数据
- 子进程边界让引擎可替换——把上游
llama-server当子进程用并锁版本,上游演进与管理面解耦,MLX 这类新引擎也能并排挂
- 固定 v0.33.1 里,同一个模型默认能同时处理几个请求?
ollama create sage -f Modelfile(FROM llama3.1)会把 llama3.1 的权重复制一份吗?- 一个 GGUF 模型的推理发生在 Ollama 主进程里吗?
检查点:
- 1 个(
OLLAMA_NUM_PARALLEL默认 1),其余排队;要并发得显式调大。 - 不会。只新建 manifest 指向既有
blobs/sha256-*,权重 blob 被复用。 - 不在。由上游
llama-server子进程服务(llama.cpp 锁 b10630),主进程负责 HTTP、调度与存储。
- 官方安装与 Quick Start:ollama.com
- 固定源码:ollama/ollama —— 本文绑定提交
13f2fb8c99278469b954429d5541019f4d83a4d0 - Modelfile 参考:仓库内
docs/目录 - llama-cpp —— 上游推理引擎,Ollama 把它的
llama-server当子进程用 - mcp-ts-sdk —— agent 栈的协议层;Ollama 是其下的本地推理层
- llama-cpp —— GGUF 模型的实际推理引擎(
llama-server子进程,版本被锁定) - langchain —— 上层应用框架,经 OpenAI 兼容层对接 Ollama
- vllm —— 生产 serving 引擎,与 Ollama 形成“个人/小团队 vs 生产”分工
- transformers —— HuggingFace 训练与推理库,权重多经 GGUF 转换后进 Ollama
- mcp-ts-sdk —— 协议层与推理层:agent 栈两块互补地基