跟着这篇走完,本机就能把 DeepSeek-R1 跑起来。先用命令行跟它聊一轮热热手,再调 /api/chat 发请求,让响应里 message.thinking(推理思考过程)和 message.content(最终回答)分两个字段给你。
整个流程 5 步,每步结尾都附一条 curl 或 ollama 命令验证你这步有没有走对。localhost:11434 是 Ollama 的默认监听端口,模型本文固定用 deepseek-r1:8b(即 5.2 GB 的 Q4_K_M 蒸馏版,基座是 Qwen3-8B,和 deepseek-r1:latest 指向同一份权重)。
如果你换了端口,或者改用 1.5b / 14b / 32b / 70b 这些 tag,把示例值替换掉就行,整套命令照样能跑。还没装过 Ollama 的,先去从零跑通 Ollama + Qwen3 本地对话把服务拉起来再回来。

前置条件
| 项 | 要求 | 说明 |
|---|---|---|
| Ollama | 0.34.4 或更高 | 0.40.0 仍是预发布版,不要用 |
| 磁盘 | 6 GB 以上空闲 | deepseek-r1:8b 是 DeepSeek-R1-0528-Qwen3-8B 蒸馏版,Q4_K_M 量化 5.2 GB |
| 内存 | 16 GB 以上(8b 推理)/ 32 GB+(14b)/ 64 GB+(32b)/ 96 GB+(70b) | 8B 加载后常驻约 5 GB;大模型按 tag 推 |
| 网络 | 能访问 ollama.com | 首次拉模型需下载 5.2 GB,之后可完全离线 |
先跑这条确认版本。
ollama --version
看到 ollama version is 0.34.4 就满足条件。命令报 command not found 说明 Ollama 没装成功,先解决再往下走。
第一步:安装并启动 Ollama
macOS 和 Linux 用同一条安装脚本,Windows 用 PowerShell。不想跑脚本的话,去官方下载页拿各平台的图形安装包。
# macOS / Linux
curl -fsSL https://ollama.com/install.sh | sh
# Windows(PowerShell)
irm https://ollama.com/install.ps1 | iex
装完之后 macOS 和 Windows 上 Ollama 会常驻菜单栏并自动拉起服务,Linux 上安装脚本会注册 systemd 服务并立即启动。这一步不用你手动跑 ollama serve,除非你跑在 Docker 或纯命令行环境里,那才需要自己起进程。
验证服务在监听默认端口。
curl http://localhost:11434/api/version
返回 {"version":"0.34.4"} 说明服务在跑,可以进入下一步。返回 curl: (7) Failed to connect to localhost port 11434 是服务没起 / OLLAMA_HOST 被改到别的地址 / 容器内 localhost 指自己,看 常见问题 第 1 项。
第二步:拉 deepseek-r1:8b
Ollama 的模型不会随安装包一起下发,要单独 pull 到本地。deepseek-r1 是仓库名,8b 是规格 tag,写全了才能避开歧义。
ollama pull deepseek-r1:8b
下载 5.2 GB,速度看网络。deepseek-r1 是仓库名,8b 是规格 tag——写全了才能避开歧义。
这里的 8b 实际是 DeepSeek-R1-0528-Qwen3-8B(arch=qwen3、parameters=8.19B、Q4_K_M 量化、128K 上下文),跟 deepseek-r1:latest 指向同一份 blob。
deepseek-r1 仓库下还有更小和更大的规格,按机器内存挑一档:
| tag | 磁盘 | 上下文 | 适合 |
|---|---|---|---|
deepseek-r1:1.5b |
1.1 GB | 128K | 只验证链路 |
deepseek-r1:8b |
5.2 GB | 128K | 本文用 |
deepseek-r1:14b |
9.0 GB | 128K | 32 GB 内存 |
deepseek-r1:32b |
20 GB | 128K | 64 GB 内存 |
deepseek-r1:70b |
43 GB | 128K | 96 GB+ 内存 |
验证模型是否真的落到本地。
ollama list
输出里出现一行 deepseek-r1:8b、SIZE 列显示 5.2 GB,就算拉好了。列表里没它,说明前面的 pull 中途失败。报 Error: pull model manifest: file does not exist 一般是 tag 写错或大小写错(比如 deepseek-r1:8B),看 常见问题 第 2 项。
第三步:用命令行完成一次 thinking 会话
ollama run 会拉起模型并进入交互提示符,这是最快确认「模型到底能不能答」的方式。
ollama run deepseek-r1:8b
首次执行要把权重加载进内存,会等几秒到几十秒——第一次跑这种规模模型基本都有这一步等加载的耐心挑战,别误以为进程卡死了。加载完出现 >>> 提示符,直接敲问题回车即可。
DeepSeek-R1 跟一般聊天模型不一样:会先输出 thinking(推理过程),再输出 content(正式回答)。CLI 默认就开着 thinking,不用额外开关。
在 >>> 下输入:
>>> 用一句话解释什么是栈溢出
>>> /bye
能看到先出一段 thinking 再给最终答案;/bye 干净退出回到 shell,这一步就算成了。如果进程被 kill 或报 Error: model requires more system memory,多半是上一个模型还在 keep-alive 缓存里没释放,看 常见问题 第 3 项。
第四步:用 REST API 发一次带 thinking 的请求
Ollama 服务同时暴露了一套 HTTP 接口,端口就是刚才验证过的 11434。先发一条单轮请求确认接口通,同时验证 think 参数能让响应里出现 message.thinking 字段。
curl http://localhost:11434/api/chat -d '{
"model": "deepseek-r1:8b",
"messages": [
{ "role": "user", "content": "用一句话说明 /api/chat 的 stream 和 think 参数区别" }
],
"think": true,
"stream": false
}'
think: true 显式开启思考输出(默认值其实就是 true,写出来主要为了明确);stream: false 一次性拿完整 JSON,便于对照字段。
注意一个容易踩的点:Ollama 响应里用 message.thinking 装思考过程,用 message.content 装最终回答——这跟 DeepSeek 云 API 的 message.reasoning_content 不是同一个字段,把云 SDK 搬过来直接读 reasoning_content 会拿到 undefined。
返回体同时满足四条就算通了:"done": true、message.thinking 非空、message.content 非空、eval_count > 0。
eval_count 是这次实际生成的 token 数——它为 0 就说明模型啥都没吐出来,多半是模型名写错或者显存不够加载失败。
message.thinking 是空或字段缺失,那基本是按 DeepSeek 云 SDK 在 message.reasoning_content 取值、拿到 undefined 的问题了,看 常见问题 第 4 项。
第五步(可选进阶):流式看 thinking 实时回流
把 stream 打开,给 curl 加 -N 关掉输出缓冲,让 /api/chat 一边生成一边返回。
curl -N http://localhost:11434/api/chat -d '{
"model": "deepseek-r1:8b",
"messages": [
{ "role": "user", "content": "从 1 数到 5" }
],
"think": true,
"stream": true
}'
流式响应里 message.thinking 增量分片出现在 message.content 之前——这是肉眼能看到“思考过程一个字一个字地往外冒”的唯一方式。done: true 只在最后一行出现,前面每一行都是中间分片。
关掉 thinking 有几种写法,按你的场景挑:
- 请求体里把
think改成false,或者干脆不写——简单粗暴。 - 会话内
/set notthink,CLI 默认开启 thinking,临时切到notthink。 - CLI 启动时加
--hidethinking,适合脚本里想隐藏思考过程、但仍允许模型内部推理的场景。
核心概念
这张架构图就是整条调用链路的走向——从左到右走一遍,一次带 thinking 的请求的完整路径就看清楚了。

| 概念 | 是什么 | 类比 |
|---|---|---|
| Ollama | 把权重文件、运行参数和推理引擎(llama.cpp / MLX)打包成本地常驻服务的运行时 | 像本地的数据库服务,装好就有一个进程守在 11434 端口 |
| DeepSeek-R1 / 蒸馏版 | DeepSeek-R1 本身是 671B MoE 推理模型;Ollama 上常见的是蒸馏版(1.5b/8b/14b/32b/70b),默认 8b 即 DeepSeek-R1-0528-Qwen3-8B(Q4_K_M 量化,5.2 GB,128K 上下文) |
像 GitHub 仓库里的 release tag,同一个仓库下不同规格,挑机器够得动的那个 |
thinking 字段 |
/api/chat 响应里 message.thinking 装推理思考过程,message.content 装最终回答;通过请求体 "think": true/false 或 CLI 的 /set think//set nothink 切换 |
像 LLM 的 inner monologue / 草稿区,思考在前面、答案在后面 |
num_ctx |
一次请求能看到的 token 上限,Ollama 默认 4096,超出历史会被截断;DeepSeek-R1 蒸馏版模型上限 128K,671b 主模型 160K | 像工作台面积,放得下的材料在工作台上用,放不下的就推到地上 |
keep_alive |
模型在内存里停留的时间,默认 5m(5 分钟);超出后自动卸载,下一次请求触发重新加载 |
像酒店退房时间,超过时间房间就释放,下一个客人来再重新办入住 |
常见问题
curl: (7) Failed to connect to localhost port 11434
现象:命令行 curl 或客户端连不上 11434,报 Connection refused,不是超时。
原因:Ollama 服务没起来;或者只绑在别的地址上(容器里最常见,容器内的 localhost 不是宿主机);或者被 HTTP_PROXY/HTTPS_PROXY/NO_PROXY 没设 localhost/127.0.0.1 劫持。
Error: pull model manifest: file does not exist(或 model "deepseek-r1:8B" not found, try pulling it first)
现象:ollama pull deepseek-r1:8b 直接报 file does not exist,没下任何东西;或者 /api/chat 调用时回 model not found。
原因:tag 是 exact string;常见错例 deepseek-r1:8B(大写)、deepseek-r1:8b-v2(不存在的量化档)、OLLAMA_HOST 指向了别的机器。
相关文章:ollama pull deepseek-r1:8B 报 pull model manifest: file does not exist
CUDA error: out of memory(或进程被 kill / Linux dmesg 报 oom-kill)
现象:拉完后第一次推理直接被 kill;Linux 上 dmesg 报 OOM;有时换更小 tag 反而没事。
原因:模型超过 VRAM/RAM;num_ctx=4096 默认推高 KV cache;上一个模型还在 keep-alive(默认 5 分钟)缓存里没释放。
响应里 message.thinking 字段缺失,或按 message.reasoning_content 取值拿到 undefined
现象:调 /api/chat 返回 JSON 里 message.content 正常但没有 message.thinking;或者按云 SDK 写法在 message.reasoning_content 取值,拿到 undefined/null。
原因:Ollama API 字段名是 message.thinking,不是 DeepSeek 云 API 的 message.reasoning_content;且需要请求体显式 "think": true(不传则按模型 thinking.default,多数情况下仍是 true,但写出来最稳)。
