从零基于 Ollama 部署 DeepSeek 大模型完整实战指南
目标:本文从零开始,手把手带你在本地(Windows / Linux / macOS)使用 Ollama 完成 DeepSeek 大模型的部署、命令行交互、HTTP API 调用、Python 程序化调用、模型自定义、局域网对外暴露、性能调优与 Docker 部署,最终交付一套可用的本地大模型服务。
- 适用系统:Windows 10/11、Ubuntu / Debian / CentOS Linux、macOS(Intel / Apple Silicon)
- 示例模型:DeepSeek-R1 系列(推理版)、DeepSeek-V3 通用对话版、DeepSeek-Coder 代码版
- 难度等级:★★☆☆☆(有基础命令行操作能力即可跟随完成)
第 1 章 项目背景与技术选型
1.1 为什么要在本地部署大模型
本地部署大模型(本地化部署 / 私有化部署)近几年成为企业和开发者关注的热点。相比直接调用云端大模型 API(如各厂商的在线接口),本地部署有以下核心优势:
| 维度 |
本地部署 |
云端 API |
| 数据隐私 |
数据不出内网,完全本地流转 |
数据发送到第三方服务器 |
| 成本 |
一次性硬件投入,长期免费使用 |
按 token 计费,量大成本高 |
| 网络依赖 |
断网可用,延迟低 |
依赖公网,受网络波动影响 |
| 可定制性 |
可微调、可改提示词模板、可深度集成 |
定制能力受限 |
| 运维复杂度 |
需要自己维护环境 |
厂商托管,零运维 |
对于企业内部的敏感业务数据、研发团队内部的代码辅助、以及有强数据合规要求(如金融、医疗、政务)的场景,本地部署几乎是唯一合规的选择。
1.2 DeepSeek 系列模型简介
DeepSeek(深度求索)开源的模型在国际开源大模型社区长期占据领先位置,主要有以下三个系列:
- DeepSeek-R1 系列:推理增强模型,具备强大的思维链(Chain of Thought)能力,在数学、逻辑推理、代码生成任务上表现出色。代表版本有 R1-Distill-Qwen-1.5B / 7B / 14B / 32B、R1-Distill-Llama-8B / 70B 等蒸馏版本,以及原版 DeepSeek-R1。
- DeepSeek-V3 系列:通用对话大模型,主打多轮对话、文本生成、知识问答,是日常使用的主力模型。
- DeepSeek-Coder 系列:代码专用模型,在代码补全、代码生成、代码解释、Debug 方面表现优秀,适合程序员日常使用。
在 Ollama 中,以上模型都可以直接通过模型名拉取,不需要手动下载权重文件。
1.3 为什么选择 Ollama
传统部署大模型的方案有很多,例如直接使用 llama.cpp 编译源码、手动下载 GGUF 格式权重、配置 CUDA / ROCm / Metal 运行环境等,步骤繁琐、容易踩坑。Ollama 的出现把整个过程简化成了几条命令:
|
1
2
3
4
5
6
|
# 1. 下载并运行模型(一行命令搞定下载 + 运行)
ollama run deepseek-r1:7b
# 2. 查看本地已有模型
ollama list
# 3. 通过 REST API 调用
curl http://localhost:11434/api/generate -d '{"model":"deepseek-r1:7b","prompt":"你好"}'
|
Ollama 的核心价值:
- 开箱即用:自动处理模型下载、量化、依赖库、硬件加速(NVIDIA CUDA / AMD ROCm / Apple Metal),不需要手动编译。
- 模型仓库丰富:Ollama 官方模型库(https://ollama.com/library)收录了 DeepSeek、Llama、Qwen、Mistral、Gemma 等几乎所有主流开源模型。
- API 标准:提供本地 REST API,默认监听 11434 端口,兼容 OpenAI 的接口风格,方便程序化对接。
- 轻量高效:底层基于 llama.cpp,内存占用优化好,低配置机器也能运行小参数模型。
- 生态完善:支持 LangChain、LlamaIndex、Open WebUI、Dify 等主流框架,可快速搭建应用。
1.4 Ollama 架构与运行原理
Ollama 的整体架构可以概括为「客户端命令行 + 本地守护服务 + 模型运行时」三层:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
┌─────────────────────────────────────────────┐
│ 你的应用程序 │
│ (curl / Python / LangChain / WebUI ...) │
└──────────────────┬──────────────────────────┘
│ HTTP / REST (默认端口 11434)
┌──────────────────▼──────────────────────────┐
│ Ollama 本地服务 (ollama serve) │
│ - 模型管理、并发调度、上下文缓存 │
└──────────────────┬──────────────────────────┘
│
┌──────────────────▼──────────────────────────┐
│ 模型运行时 (基于 llama.cpp) │
│ - GGUF 权重加载 / 量化推理 │
│ - GPU 加速 (CUDA/ROCm/Metal) 或 CPU │
└─────────────────────────────────────────────┘
|
- 命令行客户端 ollama:负责与用户交互,执行 run、list、pull、create 等命令。
- 守护服务 ollama serve:在后台常驻,接收 HTTP 请求,管理模型的生命周期(加载、缓存、卸载)。
- 模型运行时:加载 GGUF 格式的量化权重进行推理,自动选择 GPU 或 CPU。
1.5 完整部署流程一览
整篇文档的实操流程如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
第3步 安装 Ollama
↓
第4步 验证服务 (ollama serve + 11434 端口)
↓
第5步 拉取 DeepSeek 模型 (ollama pull deepseek-r1:7b)
↓
第6步 命令行对话 (ollama run deepseek-r1:7b)
↓
第7步 HTTP API 调用 (/api/generate / /api/chat)
↓
第8步 Python 程序化调用 (requests / ollama / openai / langchain)
↓
第9步 自定义模型 (Modelfile)
↓
第10步 局域网暴露 (OLLAMA_HOST)
↓
第11步 性能调优 + Docker 部署
|
接下来,我们按步骤一步步执行。
第 2 章 硬件环境评估与模型选型
在开始部署之前,建议先评估自己的硬件条件,选择合适的模型参数规模。大模型推理的核心瓶颈是显存(VRAM)和内存(RAM)。参数量越大,需要的显存/内存越多。
2.1 模型参数量与显存对照表
以下数据为在 4-bit 量化(Q4_K_M) 条件下的大致显存/内存占用估算,实际以运行时 ollama ps 显示为准:
| 模型规模 |
参数量 |
最低显存(4bit量化) |
推荐配置 |
适用场景 |
| deepseek-r1:1.5b |
1.5B |
约 1 GB |
8 GB 内存,纯 CPU 可跑 |
边缘设备、教学演示 |
| deepseek-r1:7b |
7B |
约 5 GB |
8 GB 显存 / 16 GB 内存 |
个人日常使用(推荐) |
| deepseek-r1:8b |
8B |
约 6 GB |
8 GB 显存 |
代码 / 推理任务 |
| deepseek-r1:14b |
14B |
约 10 GB |
12~16 GB 显存 |
高质量推理 |
| deepseek-r1:32b |
32B |
约 22 GB |
24 GB 显存 |
强推理能力 |
| deepseek-r1:70b |
70B |
约 46 GB |
双卡 48GB / 大内存 |
企业级应用 |
| deepseek-v3 |
671B(稀疏) |
不可单卡运行 |
多卡集群 / 大内存 |
云端 / 高并发 |
注意:上面的表格是量化后的估算值。如果显存不足,模型会退化为 CPU 推理,速度会慢很多,但功能可用。
2.2 CPU / 内存 / 磁盘要求
- CPU:任意现代 x86_64 或 ARM64 处理器即可,推理时 CPU 会显著影响生成速度。
- 内存(RAM):至少 16 GB,推荐 32 GB。当显存不足、模型放在 CPU 上跑时,内存要求更高。
- 磁盘:模型文件占用较大,deepseek-r1:7b 的 4bit 量化文件约 4.7 GB,deepseek-r1:14b 约 9 GB,deepseek-r1:32b 约 20 GB。请预留足够磁盘空间。
- 显卡(可选但强烈推荐):
- NVIDIA:要求驱动支持 CUDA 11 及以上(驱动版本 >= 452.39),显存 >= 8 GB。
- Apple Silicon(M1/M2/M3/M4):利用统一内存,16 GB 可流畅运行 7B~14B 模型。
- AMD:Linux 下支持 ROCm;Windows 下支持相对有限。
2.3 如何快速判断自己该用哪个模型
- 只有 CPU、内存 16 GB 以下 → 选择 deepseek-r1:1.5b 或 deepseek-r1:7b(CPU 跑 7B 稍慢但可用)。
- 有 8 GB 显卡 → 推荐 deepseek-r1:7b,这是性价比最高的入门选择。
- 有 16~24 GB 显卡 → deepseek-r1:14b,推理能力明显提升。
- 主要写代码 → 可以尝试 deepseek-coder 系列。
- 追求最佳推理效果且硬件充足 → deepseek-r1:32b 及以上。
本文后续所有示例统一使用 deepseek-r1:7b,你在实际操作时可根据硬件替换成其他版本号。
第 3 章 Ollama 介绍与安装
3.1 Ollama 是什么
Ollama 是一个开源的本地大模型运行工具,官网地址为 https://ollama.com,GitHub 仓库为 https://github.com/ollama/ollama。它把「下载模型 + 量化 + 推理 + API 服务」整合到一条命令中,是目前最流行的本地大模型部署方式之一。
3.2 Windows 安装步骤
方式一:官方安装包(推荐)
- 打开浏览器访问 https://ollama.com/download/windows
- 点击 Download for Windows 下载安装包(文件名类似 OllamaSetup.exe)。
- 双击运行安装程序,一路点击 Next,等待安装完成。
- 安装完成后,打开 PowerShell 或 CMD,输入以下命令验证:
|
1
2
|
# 查看版本号
ollama --version
|
如果输出类似:
|
1
|
ollama version is 0.x.x
|
说明安装成功。安装完成后,Ollama 服务会自动在后台运行,默认监听 127.0.0.1:11434。
提示:Windows 版 Ollama 安装后是一个系统托盘程序,右下角托盘区会有一个羊驼图标。它会在开机时自动启动。
方式二:通过命令行安装(Windows)
也可以通过包管理器安装,例如 winget(Windows 10/11 自带):
|
1
2
|
# 使用 winget 安装
winget install Ollama.Ollama
|
3.3 Linux 安装步骤
方式一:一键脚本安装(推荐)
Linux 下最简安装方式是通过官方脚本,一行命令搞定:
|
1
2
|
# Ubuntu / Debian / CentOS 等通用
curl -fsSL https://ollama.com/install.sh | sh
|
该脚本会自动:
- 下载对应架构(amd64 / arm64)的 Ollama 二进制文件;
- 安装到 /usr/local/bin/ollama;
- 创建系统服务(systemd),并自动启动。
安装完成后验证:
|
1
2
3
4
|
# 查看版本
ollama --version
# 查看服务状态(systemd 方式)
systemctl status ollama
|
如果服务未自动启动,可以手动启动:
|
1
2
3
4
|
# 启动 ollama 服务
sudo systemctl start ollama
# 设置开机自启
sudo systemctl enable ollama
|
方式二:手动下载二进制
如果服务器无法访问官方脚本,可以手动下载:
|
1
2
3
4
5
6
|
# 以下载 amd64 版本为例,arm64 请替换
curl -L https://ollama.com/download/ollama-linux-amd64.tgz -o ollama.tgz
# 解压并安装到 /usr/local/bin
tar -C /usr -xzf ollama.tgz
# 前台启动服务(测试用)
ollama serve
|
3.4 macOS 安装步骤
macOS 用户直接访问官网下载 .zip 安装包解压即可:
- 打开 https://ollama.com/download/mac
- 下载 Ollama-darwin.zip,解压后将 Ollama.app 拖入「应用程序」文件夹。
- 首次启动时,系统可能会提示「是否允许从互联网下载的应用」,在「系统设置 → 隐私与安全性」中点击「仍要打开」。
- 通过 Homebrew 也可以安装:
3.5 安装后的全局验证(三个平台通用)
无论哪个平台,安装完成后请依次执行以下命令确认环境就绪:
|
1
2
3
4
5
|
# 1. 确认版本
ollama --version
# 2. 确认服务运行(Windows 下服务已自动运行;Linux/macOS 需确保 ollama serve 在跑)
# 直接请求本地 API 测试
curl http://localhost:11434/api/version
|
curl 命令如果返回类似下面的 JSON,说明 Ollama 服务已经正常运行:
3.6 Ollama 常用环境变量
Ollama 支持通过环境变量自定义行为,常用变量如下:
| 环境变量 |
作用 |
示例 |
| OLLAMA_HOST |
服务监听地址和端口 |
0.0.0.0:11434 |
| OLLAMA_MODELS |
模型存储目录 |
D:\ollama\models |
| OLLAMA_ORIGINS |
允许的跨域来源 |
* |
| OLLAMA_NUM_PARALLEL |
并发请求数量 |
4 |
| OLLAMA_KEEP_ALIVE |
模型保持加载时长 |
5m |
| OLLAMA_MAX_LOADED_MODELS |
同时加载的最大模型数 |
2 |
| OLLAMA_DEBUG |
是否输出调试日志 |
1 |
以 Windows 为例,设置 OLLAMA_MODELS 将模型存储到其他盘:
|
1
2
3
|
# PowerShell 中临时设置(当前会话有效)
$env:OLLAMA_MODELS = "D:\ollama\models"
# 永久设置:系统设置 -> 高级系统设置 -> 环境变量 -> 新建
|
Linux 下通过 export 或 systemd 配置:
|
1
2
3
4
5
|
# 临时设置
export OLLAMA_HOST="0.0.0.0:11434"
# 永久设置(写入用户配置文件)
echo 'export OLLAMA_HOST="0.0.0.0:11434"' >> ~/.bashrc
source ~/.bashrc
|
注意:Windows 下修改环境变量后需要重启 Ollama(托盘图标 → 退出,再重新打开)。
第 4 章 Ollama 核心命令大全
在拉取模型之前,先熟悉 Ollama 的常用命令,后面每一步都会用到。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# 查看帮助
ollama help
# 查看版本
ollama --version
# 查看本地已下载的模型列表
ollama list
# 从模型库下载模型(示例:拉取 deepseek-r1:7b)
ollama pull deepseek-r1:7b
# 运行模型并进入交互对话
ollama run deepseek-r1:7b
# 查看当前已加载模型的资源占用
ollama ps
# 显示模型详细信息(参数量、量化、上下文等)
ollama show deepseek-r1:7b
# 删除本地模型
ollama rm deepseek-r1:7b
# 复制模型
ollama cp deepseek-r1:7b my-deepseek
# 从 Modelfile 创建自定义模型
ollama create my-model -f ./Modelfile
|
各命令的详细使用会在后续章节逐步展开。
第 5 章 拉取 DeepSeek 模型
5.1 DeepSeek 在 Ollama 中的可用版本
在 Ollama 模型库中,DeepSeek 系列可以通过标签(tag)区分版本。常用版本如下:
| 模型名(model:tag) |
说明 |
文件大小(约) |
| deepseek-r1:1.5b |
R1 蒸馏 1.5B 推理模型 |
1.1 GB |
| deepseek-r1:7b |
R1 蒸馏 7B 推理模型(推荐) |
4.7 GB |
| deepseek-r1:8b |
R1 蒸馏 8B(Llama 基座) |
4.9 GB |
| deepseek-r1:14b |
R1 蒸馏 14B 推理模型 |
9.0 GB |
| deepseek-r1:32b |
R1 蒸馏 32B 推理模型 |
20 GB |
| deepseek-r1:70b |
R1 蒸馏 70B 推理模型 |
43 GB |
| deepseek-v3 |
通用对话模型(原名 deepseek-chat) |
404 GB(需大内存) |
| deepseek-coder |
代码专用模型(旧版) |
由具体 tag 决定 |
| deepseek-coder-v2 |
代码专用 V2 模型 |
由具体 tag 决定 |
你可以在 https://ollama.com/library/deepseek-r1 页面查看完整的可用 tag 列表及说明。
5.2 拉取模型(下载)
执行以下命令拉取 deepseek-r1:7b:
|
1
|
ollama pull deepseek-r1:7b
|
执行后终端会显示下载进度条,类似:
|
1
2
3
4
5
|
pulling manifest
pulling 6f1dc39c72f5... 100% ████████████████████████ 4.7 GB
verifying sha256 digest
writing manifest
success
|
出现 success 表示模型下载完成。下载时间取决于你的网速,4.7 GB 在 100M 宽带下约需 5~10 分钟。
加速技巧:如果官方源下载很慢,可以配置国内镜像源,设置环境变量 OLLAMA_HOST 无帮助,需使用代理或镜像。常见做法是设置 HTTPS 代理:
|
1
2
3
|
# Linux/macOS
export HTTPS_PROXY=http://127.0.0.1:7890
ollama pull deepseek-r1:7b
|
或使用国内镜像站(社区维护的 ollama 镜像),将下载地址替换。最简单可靠的方式是使用网络代理。
5.3 查看本地模型列表
输出示例:
|
1
2
|
NAME ID SIZE MODIFIED
deepseek-r1:7b 0a8c26691023 4.7 GB 2 minutes ago
|
- NAME:模型名称和标签
- ID:模型唯一标识
- SIZE:磁盘占用大小
- MODIFIED:最近使用时间
5.4 查看模型详情
|
1
|
ollama show deepseek-r1:7b
|
输出示例:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
Model
architecture qwen2
parameters 7.6B
context length 131072
embedding length 3584
quantization Q4_K_M
Capabilities
completion true
chat true
vision false
tools true
...
|
可以看到该模型参数量、上下文长度、量化方式(Q4_K_M)、是否支持工具调用等关键信息。
5.5 删除模型
如果不需要某个模型,可以删除以释放磁盘空间:
|
1
|
ollama rm deepseek-r1:7b
|
删除前请确认该模型不再使用,删除后需要重新 pull 才能恢复。
5.6 查看模型运行时的资源占用
当模型被加载运行时,可以用以下命令查看显存/内存占用:
输出示例:
|
1
2
|
NAME ID PROCESSOR UNTIL MODEL SIZE CPU GPU
deepseek-r1:7b ... 100% GPU 4 minutes from now 7.6B 4.7GB 0% 4.7GB
|
- PROCESSOR:100% GPU 表示全部在显卡上运行;100% CPU 表示纯 CPU 推理。
- GPU 列显示显存占用;CPU 列显示 CPU 占用。
第 6 章 命令行交互调用 DeepSeek
6.1 进入交互式对话
模型拉取完成后,最直接的使用方式是进入交互对话模式:
|
1
|
ollama run deepseek-r1:7b
|
此时终端会进入对话界面,输入内容并回车即可与模型对话:
由于 R1 是推理模型,它会在回复前输出一段「思考过程」,再输出最终答案:
|
1
2
3
4
5
|
<think>
用户询问我的身份,需要简洁介绍 DeepSeek 模型的基本信息...
</think>
你好!我是 DeepSeek,一个由深度求索公司开发的开源大语言模型。
我可以帮助你回答问题、编写代码、进行推理分析等。有什么可以帮你的?
|
6.2 交互模式下的常用命令
在交互对话界面中,输入以 / 开头的命令可管理对话:
| 命令 |
作用 |
| /bye |
退出对话界面 |
| /exit |
退出对话界面(同 /bye) |
| /clear |
清空当前对话上下文(重新开始) |
| /show |
显示模型信息 |
| /set parameter |
设置运行参数,如 /set parameter temperature 0.7 |
| /? |
查看帮助 |
示例:
|
1
2
3
|
>>> /set parameter temperature 0.3
Set parameter temperature to 0.3
>>> /bye
|
6.3 一次问答模式(非交互)
如果不进入交互界面,也可以直接通过命令行参数传入问题,执行完即退出:
|
1
2
3
4
|
# 直接提问
ollama run deepseek-r1:7b "用 Python 写一个冒泡排序"
# 一次问答并输出流式结果
ollama run deepseek-r1:7b "1 + 1 等于多少?"
|
这种方式非常适合脚本化调用,例如:
|
1
2
3
4
5
6
7
|
#!/bin/bash
# 批量测试模型
for question in "你好" "什么是大模型" "写一段 Hello World"; do
echo "问题:$question"
ollama run deepseek-r1:7b "$question"
echo "=========================="
done
|
6.4 多轮对话与上下文
交互模式下,Ollama 会自动维护对话历史,把之前的对话作为上下文一起发给模型,从而实现多轮对话:
|
1
2
3
|
>>> 我今年 28 岁
>>> 根据刚才的信息,我多大了?
根据你刚才提到的信息,你今年 28 岁。
|
如果你希望开始一个新话题、不想让模型记住之前的内容,输入 /clear 清空上下文。
6.5 设置系统提示词(System Prompt)
可以通过 --system 参数在启动时指定系统提示词,让模型扮演特定角色:
|
1
|
ollama run deepseek-r1:7b --system "你是一名资深的 Python 后端工程师,回答问题时给出简洁的代码示例"
|
也可以在交互模式中用 /set system 设置:
|
1
2
|
>>> /set system 你是一名耐心的中文老师,回答要循序渐进
Set system message.
|
第 7 章 Ollama HTTP API 完整调用实战
Ollama 自带一个基于 HTTP 的 REST API,默认地址为 http://localhost:11434。通过 API,我们可以让任意编程语言调用 DeepSeek,这是程序化接入的关键。
7.1 API 基础地址与端点
| 端点 |
方法 |
作用 |
| /api/generate |
POST |
生成补全(非对话格式) |
| /api/chat |
POST |
对话补全(带消息格式) |
| /api/tags |
GET |
列出本地模型 |
| /api/show |
POST |
查看模型详情 |
| /api/pull |
POST |
拉取模型 |
| /api/push |
POST |
推送模型 |
| /api/create |
POST |
创建模型 |
| /api/delete |
DELETE |
删除模型 |
| /api/embed |
POST |
生成向量嵌入 |
| /api/version |
GET |
查看服务版本 |
7.2 测试 API 是否可用
|
1
|
curl http://localhost:11434/api/version
|
返回:
7.3 使用 /api/generate 生成文本
|
1
2
3
4
5
|
curl http://localhost:11434/api/generate -d '{
"model": "deepseek-r1:7b",
"prompt": "请用一句话介绍什么是大语言模型",
"stream": false
}'
|
参数说明:
- model:使用的模型名称(必须已 pull)。
- prompt:输入提示词。
- stream:是否流式返回。false 表示一次性返回完整结果。
- system(可选):系统提示词。
- temperature(可选):采样温度,值越高输出越发散,默认 0.8。
- options(可选):更多运行时参数,如 {"num_predict": 200} 限制生成长度。
返回结果示例:
|
1
2
3
4
5
6
7
8
9
|
{
"model": "deepseek-r1:7b",
"created_at": "2026-09-03T10:00:00.000Z",
"response": "大语言模型是一种基于深度学习、在海量文本上训练的模型,能够理解和生成自然语言。",
"done": true,
"total_duration": 1234567890,
"eval_count": 32,
"eval_duration": 987654321
}
|
7.4 流式输出(SSE 格式)
将 stream 设为 true(默认即为 true),API 会以 SSE(Server-Sent Events)格式逐块返回结果:
|
1
2
3
4
5
|
curl http://localhost:11434/api/generate -d '{
"model": "deepseek-r1:7b",
"prompt": "写一首关于秋天的五言绝句",
"stream": true
}'
|
返回示例(每行一个 JSON 对象):
|
1
2
3
4
5
|
{"model":"deepseek-r1:7b","response":"秋","done":false}
{"model":"deepseek-r1:7b","response":"风","done":false}
{"model":"deepseek-r1:7b","response":"起","done":false}
...
{"model":"deepseek-r1:7b","response":"","done":true,"total_duration":...}
|
流式输出的优势是首字延迟低,适合聊天机器人和打字机效果展示。
7.5 使用 /api/chat 进行多轮对话
对话场景推荐使用 /api/chat,它使用 OpenAI 风格的 messages 数组来维护多轮对话:
|
1
2
3
4
5
6
7
8
9
10
|
curl http://localhost:11434/api/chat -d '{
"model": "deepseek-r1:7b",
"messages": [
{"role": "system", "content": "你是一个乐于助人的助手"},
{"role": "user", "content": "你好,请介绍一下自己"},
{"role": "assistant", "content": "你好!我是一个本地部署的大语言模型。"},
{"role": "user", "content": "你刚才说你是本地部署的,请问本地部署有什么好处?"}
],
"stream": false
}'
|
- messages:对话消息数组,支持 system、user、assistant 三种角色。
- 多轮对话时,只需把完整历史消息数组传给接口,模型就能理解上下文。
7.6 列出本地模型 /api/tags
|
1
|
curl http://localhost:11434/api/tags
|
返回:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
{
"models": [
{
"name": "deepseek-r1:7b",
"model": "deepseek-r1:7b",
"size": 4989797124,
"details": {
"parameter_size": "7.6B",
"quantization_level": "Q4_K_M"
}
}
]
}
|
7.7 查看模型信息 /api/show
|
1
|
curl http://localhost:11434/api/show -d '{"model": "deepseek-r1:7b"}'
|
返回模型架构、参数量、上下文长度、量化等级等详细信息,可用于程序化判断模型能力。
7.8 通过 API 拉取模型
|
1
|
curl http://localhost:11434/api/pull -d '{"model": "deepseek-r1:8b"}'
|
7.9 生成向量嵌入 /api/embed
DeepSeek 模型本身不是嵌入模型,但 Ollama 支持其他嵌入模型(如 nomic-embed-text)。如果需要做 RAG(检索增强生成),可以拉取嵌入模型使用:
|
1
2
3
4
5
6
7
|
# 拉取一个嵌入模型
ollama pull nomic-embed-text
# 生成嵌入向量
curl http://localhost:11434/api/embed -d '{
"model": "nomic-embed-text",
"input": "今天天气真不错"
}'
|
第 8 章 Python 多方式调用 DeepSeek
Ollama 提供了多种 Python 调用方式,覆盖从最底层的 requests 到官方 ollama 库、再到 openai 兼容 SDK 和 langchain 框架。下面逐一演示。
8.1 准备 Python 环境
首先确认 Python 版本(建议 3.8+):
安装所需依赖库:
|
1
2
3
4
5
6
7
8
|
# 基础 HTTP 请求库(一般已内置)
pip install requests
# Ollama 官方 Python 库
pip install ollama
# OpenAI 兼容 SDK
pip install openai
# LangChain 框架
pip install langchain-ollama
|
8.2 方式一:使用 requests 直接调用 HTTP API
这是最底层、最透明的方式,不依赖任何第三方 SDK,逻辑完全可控。
8.2.1 非流式调用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# -*- coding: utf-8 -*-
"""使用 requests 调用 Ollama /api/generate 接口(非流式)"""
import requests
import json
OLLAMA_URL = "http://localhost:11434"
MODEL_NAME = "deepseek-r1:7b"
def generate(prompt: str, stream: bool = False) -> str:
"""调用 generate 接口生成文本"""
payload = {
"model": MODEL_NAME,
"prompt": prompt,
"stream": stream,
"options": {
"temperature": 0.7,
"num_predict": 512, # 限制最大生成长度
},
}
resp = requests.post(
f"{OLLAMA_URL}/api/generate",
json=payload,
timeout=300, # 大模型推理较慢,超时设长一些
)
resp.raise_for_status()
data = resp.json()
return data["response"]
if __name__ == "__main__":
answer = generate("用 Python 写一个计算斐波那契数列的函数")
print("回答:")
print(answer)
|
8.2.2 流式调用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
# -*- coding: utf-8 -*-
"""使用 requests 流式调用 Ollama,实现打字机效果"""
import requests
import json
OLLAMA_URL = "http://localhost:11434"
MODEL_NAME = "deepseek-r1:7b"
def generate_stream(prompt: str):
"""流式生成,逐块 yield 文本"""
payload = {
"model": MODEL_NAME,
"prompt": prompt,
"stream": True,
}
with requests.post(
f"{OLLAMA_URL}/api/generate",
json=payload,
stream=True,
timeout=300,
) as resp:
resp.raise_for_status()
# SSE 格式:每行一个 JSON
for line in resp.iter_lines():
if not line:
continue
data = json.loads(line)
chunk = data.get("response", "")
yield chunk
if data.get("done"):
break
if __name__ == "__main__":
print("开始生成:\n")
for piece in generate_stream("请详细解释一下 OOP 的三大特性"):
print(piece, end="", flush=True)
print("\n\n生成完成。")
|
8.2.3 多轮对话(chat 接口)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
# -*- coding: utf-8 -*-
"""使用 requests 调用 /api/chat 实现多轮对话"""
import requests
OLLAMA_URL = "http://localhost:11434"
MODEL_NAME = "deepseek-r1:7b"
# 对话历史,按消息追加即可
messages = [
{"role": "system", "content": "你是一个严谨的技术助手。"},
]
def chat(user_input: str) -> str:
"""发送用户消息并返回模型回复,同时维护历史"""
global messages
messages.append({"role": "user", "content": user_input})
payload = {
"model": MODEL_NAME,
"messages": messages,
"stream": False,
}
resp = requests.post(f"{OLLAMA_URL}/api/chat", json=payload, timeout=300)
resp.raise_for_status()
data = resp.json()
# 把模型回复追加进历史,保持多轮上下文
reply = data["message"]["content"]
messages.append({"role": "assistant", "content": reply})
return reply
if __name__ == "__main__":
while True:
user = input("我(输入 exit 退出):")
if user.strip().lower() == "exit":
break
print("DeepSeek:", chat(user))
|
8.3 方式二:使用 Ollama 官方 Python 库
Ollama 官方提供了 Python 客户端库,语法更简洁:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# -*- coding: utf-8 -*-
"""使用 ollama 官方 Python 库"""
import ollama
MODEL_NAME = "deepseek-r1:7b"
# 1. 简单生成(同步)
response = ollama.generate(
model=MODEL_NAME,
prompt="介绍一下云原生技术",
)
print("生成结果:", response["response"])
print("耗时(ms):", response["eval_count"])
# 2. 多轮对话
messages = [
{"role": "system", "content": "你是一名数据库专家。"},
{"role": "user", "content": "MySQL 和 PostgreSQL 有什么区别?"},
]
response = ollama.chat(model=MODEL_NAME, messages=messages)
print("对话回复:", response["message"]["content"])
# 3. 流式生成
print("\n流式输出:")
stream = ollama.generate(model=MODEL_NAME, prompt="写一首短诗", stream=True)
for chunk in stream:
print(chunk["response"], end="", flush=True)
print()
|
8.4 方式三:使用 OpenAI 兼容 SDK
Ollama 兼容 OpenAI 的 API 格式,因此可以直接使用 openai 官方 Python SDK 调用,只需把 base_url 指向 Ollama 地址,api_key 任意填(Ollama 不做鉴权):
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# -*- coding: utf-8 -*-
"""使用 OpenAI SDK 调用本地 Ollama(DeepSeek)"""
from openai import OpenAI
# 指向本地 Ollama 服务
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama", # Ollama 不校验 key,任意值即可
)
# 普通对话
response = client.chat.completions.create(
model="deepseek-r1:7b",
messages=[
{"role": "system", "content": "你是一个 Python 专家"},
{"role": "user", "content": "如何优化递归函数的性能?"},
],
temperature=0.7,
)
print(response.choices[0].message.content)
# 流式对话
print("\n流式对话:")
stream = client.chat.completions.create(
model="deepseek-r1:7b",
messages=[{"role": "user", "content": "用三句话介绍 Kafka"}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
|
重要:Ollama 的 OpenAI 兼容端点路径是 /v1,即完整地址为 http://localhost:11434/v1。
8.5 方式四:使用 LangChain 集成
LangChain 提供了 ChatOllama 封装,可以直接把 DeepSeek 接入到 LangChain 的 Chain 中:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# -*- coding: utf-8 -*-
"""使用 LangChain 集成 Ollama DeepSeek"""
from langchain_ollama import ChatOllama
from langchain_core.messages import HumanMessage, SystemMessage
# 创建 Ollama 聊天模型
llm = ChatOllama(
model="deepseek-r1:7b",
base_url="http://localhost:11434",
temperature=0.7,
num_predict=512,
)
# 简单调用
response = llm.invoke("什么是依赖注入?")
print(response.content)
# 带系统提示词的多轮调用
messages = [
SystemMessage(content="你是一个简洁的代码评审专家。"),
HumanMessage(content="请评审下面这段代码:\n\ndef add(a,b):\n return a+b"),
]
response = llm.invoke(messages)
print("\n代码评审结果:")
print(response.content)
|
8.6 异步调用(性能优化)
在高并发场景下,推荐使用异步方式调用,避免线程阻塞:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# -*- coding: utf-8 -*-
"""异步调用 Ollama,适合高并发场景"""
import asyncio
import ollama
async def async_generate(prompt: str) -> str:
"""异步生成文本"""
result = await ollama.AsyncClient().generate(
model="deepseek-r1:7b",
prompt=prompt,
)
return result["response"]
async def main():
# 并发执行多个生成任务
prompts = [
"写一段 Python 代码",
"解释什么是 HTTP 协议",
"列出常见的排序算法",
]
tasks = [async_generate(p) for p in prompts]
results = await asyncio.gather(*tasks)
for i, r in enumerate(results):
print(f"任务{i + 1}:{r[:100]}...\n")
if __name__ == "__main__":
asyncio.run(main())
|
8.7 各调用方式对比
| 方式 |
依赖 |
优点 |
适用场景 |
| requests |
无 |
最底层、逻辑可控 |
学习原理、定制化需求 |
| ollama 官方库 |
ollama |
语法简洁、功能完整 |
常规业务开发 |
| openai SDK |
openai |
与云端 API 无缝切换 |
已有 OpenAI 代码迁移 |
| LangChain |
langchain-ollama |
可组合 Chain、Agent |
构建复杂 AI 应用 |
| 异步 |
ollama |
高并发、性能好 |
服务端高并发接口 |
第 9 章 Modelfile 自定义模型
Ollama 支持通过 Modelfile 文件对基础模型进行定制,例如设置系统提示词、固化参数、更改模板等,从而生成属于自己的专属模型。
9.1 Modelfile 基本语法
Modelfile 的常用指令如下:
| 指令 |
作用 |
| FROM |
指定基础模型或 GGUF 文件(必填) |
| SYSTEM |
设置系统提示词 |
| TEMPLATE |
自定义提示模板 |
| PARAMETER |
设置推理参数(temperature、top_p、num_ctx 等) |
| LICENSE |
许可证声明 |
| MESSAGE |
预置对话示例 |
| ADAPTER |
加载 LoRA 微调权重 |
9.2 示例一:创建「中文代码助手」模型
新建一个 Modelfile 文件(注意没有扩展名),内容如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# Modelfile
# 基于 deepseek-r1:7b 定制一个中文代码助手
FROM deepseek-r1:7b
# 系统提示词
SYSTEM """你是一个专业的中文代码助手。
要求:
1. 所有回答一律使用中文;
2. 涉及代码时,必须给出完整可运行的代码块;
3. 优先给出简洁、高效的解决方案;
4. 回答末尾给出关键注意事项。"""
# 推理参数
PARAMETER temperature 0.3
PARAMETER top_p 0.9
PARAMETER num_ctx 8192
PARAMETER stop "</s>"
|
然后使用 ollama create 创建新模型:
|
1
2
|
# 在当前目录执行
ollama create my-deepseek-coder -f ./Modelfile
|
创建完成后,用 ollama list 可以看到新模型:
|
1
2
3
|
NAME ID SIZE MODIFIED
my-deepseek-coder ... 4.7GB 1 second ago
deepseek-r1:7b ... 4.7GB 3 minutes ago
|
运行测试:
|
1
|
ollama run my-deepseek-coder "帮我写一个快速排序"
|
9.3 示例二:创建「专属客服」模型
|
1
2
3
4
5
6
7
8
|
FROM deepseek-r1:7b
SYSTEM """你是XX公司的智能客服小助手。
- 只回答与XX公司产品、服务相关的问题;
- 遇到不确定的问题,礼貌地告知用户会转接人工客服;
- 语气亲切、专业;
- 回复控制在200字以内。"""
PARAMETER temperature 0.5
PARAMETER num_ctx 4096
|
|
1
2
|
ollama create support-assistant -f ./Modelfile
ollama run support-assistant
|
9.4 常用 PARAMETER 参数说明
| 参数 |
默认值 |
作用 |
| num_ctx |
2048 |
上下文窗口长度(token 数) |
| temperature |
0.8 |
采样温度,0~2,越高越发散 |
| top_p |
0.9 |
核采样,越低越保守 |
| top_k |
40 |
采样候选数 |
| num_predict |
128 |
最大生成长度(-1 表示不限制) |
| repeat_penalty |
1.1 |
重复惩罚 |
| stop |
- |
停止符,命中即停止生成 |
| seed |
0 |
随机种子,固定后结果可复现 |
提示:num_ctx 设置过大会显著增加显存占用。7B 模型在 8192 上下文下,显存占用会比 2048 多约 1~2 GB。
9.5 使用 GGUF 权重文件自定义模型
如果你从 HuggingFace 等渠道下载了 GGUF 格式的权重文件,也可以直接作为 FROM:
|
1
2
3
|
# 使用本地 GGUF 文件
FROM ./deepseek-r1-7b.Q4_K_M.gguf
PARAMETER temperature 0.7
|
|
1
|
ollama create my-local-model -f ./Modelfile
|
第 10 章 Ollama 局域网 / 远程访问配置
默认情况下,Ollama 只监听 127.0.0.1(本机回环地址),局域网内其他设备无法访问。如果需要让局域网内其他电脑、手机或服务器访问,需要修改监听地址。
10.1 修改监听地址 OLLAMA_HOST
Windows
设置环境变量 OLLAMA_HOST=0.0.0.0:11434,然后重启 Ollama:
|
1
2
|
# PowerShell 临时设置
$env:OLLAMA_HOST = "0.0.0.0:11434"
|
永久设置:控制面板 → 系统 → 高级系统设置 → 环境变量 → 新建系统变量,变量名 OLLAMA_HOST,值 0.0.0.0:11434,然后重启 Ollama。
Linux / macOS
|
1
2
3
4
|
# 设置监听所有网卡
export OLLAMA_HOST="0.0.0.0:11434"
# 如果是 systemd 服务,编辑服务配置
sudo systemctl edit ollama
|
编辑文件写入:
|
1
2
|
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
|
重启服务:
|
1
2
|
sudo systemctl daemon-reload
sudo systemctl restart ollama
|
10.2 允许跨域访问 OLLAMA_ORIGINS
如果网页前端(浏览器)要直接调用 Ollama API,需要配置跨域:
|
1
2
|
# 允许所有来源(仅限可信环境)
export OLLAMA_ORIGINS="*"
|
10.3 防火墙放行端口
- Windows:首次监听 0.0.0.0 时,Windows 防火墙可能弹出提示,勾选「专用网络」并允许即可。若未弹出,需手动放行 11434 端口。
- Linux(以 UFW 为例):
|
1
2
|
sudo ufw allow 11434/tcp
sudo ufw reload
|
10.4 远程调用测试
修改完成后,在局域网内的另一台设备上测试:
|
1
2
3
4
5
6
7
|
# 在另一台电脑上执行(把 IP 换成服务器 IP)
curl http://192.168.1.100:11434/api/version
curl http://192.168.1.100:11434/api/chat -d '{
"model": "deepseek-r1:7b",
"messages": [{"role":"user","content":"你好"}],
"stream": false
}'
|
Python 远程调用只需把 base_url 改为服务器地址:
|
1
2
3
4
5
|
from openai import OpenAI
client = OpenAI(
base_url="http://192.168.1.100:11434/v1",
api_key="ollama",
)
|
10.5 安全注意事项(重要)
暴露到网络后务必注意安全:
- 不要直接暴露到公网:Ollama 默认无鉴权,任何人都能调用你的模型消耗你的算力。
- 只在内网使用:优先通过局域网 + 防火墙白名单访问。
- 如需公网访问:务必在前面加一层认证网关(如 Nginx + Basic Auth、API 网关、VPN)。
- 控制访问来源:设置防火墙只允许特定 IP 访问 11434 端口。
(安全加固的完整方案见第 15 章。)
第 11 章 性能调优与资源优化
部署完成后,可以通过以下方式提升推理速度、优化资源占用。
11.1 设置上下文长度(num_ctx)
上下文长度越长,模型能记住的历史越多,但显存占用越大。在 Modelfile 或 API 请求中设置:
|
1
2
|
# Modelfile 中设置
PARAMETER num_ctx 8192
|
|
1
2
3
4
5
6
|
# API 中设置
payload = {
"model": "deepseek-r1:7b",
"prompt": "你好",
"options": {"num_ctx": 8192},
}
|
11.2 控制并发与模型常驻
通过环境变量控制模型加载行为:
|
1
2
3
4
5
6
|
# 允许同时加载的模型数量
export OLLAMA_MAX_LOADED_MODELS=2
# 模型保持加载的时间(空闲多久后卸载),5m 表示 5 分钟
export OLLAMA_KEEP_ALIVE=5m
# 每个模型的并发请求数量
export OLLAMA_NUM_PARALLEL=4
|
设置 OLLAMA_NUM_PARALLEL 后,多个并发请求可以共享同一个已加载的模型,显著提升吞吐量,避免频繁加载/卸载。
11.3 选择更低的量化等级
Ollama 支持不同量化等级,量化越低显存占用越少,但精度略有损失:
| 量化等级 |
精度 |
显存占用 |
| Q8_0 |
较高 |
较高 |
| Q5_K_M |
较高 |
中 |
| Q4_K_M(默认) |
均衡 |
推荐 |
| Q3_K_M |
较低 |
较低 |
拉取时通过 tag 指定量化等级:
|
1
2
3
4
|
# 拉取 Q4_K_M 版本(默认)
ollama pull deepseek-r1:7b
# 拉取 Q5 版本(需要该 tag 存在于模型库)
ollama pull deepseek-r1:7b-q5_K_M
|
11.4 检查是否使用 GPU 加速
推理时执行 ollama ps 查看 PROCESSOR 列:
|
1
2
|
NAME ID PROCESSOR UNTIL MODEL SIZE GPU
deepseek-r1:7b ... 100% GPU ... 7.6B 4.7GB 4.7GB
|
- 100% GPU:模型全部加载在显卡上,速度最快。
- 50% GPU / 50% CPU:显存不足,部分层跑在 CPU,速度明显变慢。
- 100% CPU:纯 CPU 推理,速度最慢。
如果出现「CPU/GPU 混合」或「100% CPU」,说明显存不够,建议换小模型、降低量化等级或缩短上下文。
11.5 NVIDIA GPU 环境检查
|
1
2
3
4
|
# 查看 GPU 型号和显存
nvidia-smi
# 查看 CUDA 版本
nvcc --version
|
确保驱动和 CUDA 版本符合 Ollama 要求(CUDA 11 及以上)。
11.6 日志与调试
开启调试日志定位性能问题:
|
1
2
|
export OLLAMA_DEBUG=1
ollama serve
|
日志会输出每次请求的耗时、模型加载时间、token 生成速度等关键指标。
第 12 章 Docker 方式部署 Ollama + DeepSeek
如果你使用 Docker / Kubernetes 环境,或希望隔离部署环境,推荐使用官方 Docker 镜像。
12.1 拉取镜像并运行(CPU)
|
1
2
3
4
|
# 拉取 Ollama 官方镜像
docker pull ollama/ollama
# 运行容器并映射端口(CPU 模式)
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
|
参数说明:
- -d:后台运行
- -v ollama:/root/.ollama:将模型数据持久化到 Docker 卷,避免容器删除后模型丢失
- -p 11434:11434:映射端口
- --name ollama:容器名称
12.2 在容器内拉取并运行模型
|
1
2
3
4
5
6
7
8
9
10
|
# 进入容器执行拉取
docker exec -it ollama ollama pull deepseek-r1:7b
# 运行模型(交互)
docker exec -it ollama ollama run deepseek-r1:7b
# 通过宿主机的 API 调用
curl http://localhost:11434/api/chat -d '{
"model": "deepseek-r1:7b",
"messages": [{"role":"user","content":"你好"}],
"stream": false
}'
|
12.3 启用 NVIDIA GPU 支持
需要安装 NVIDIA Container Toolkit(nvidia-container-toolkit),然后:
|
1
2
3
4
5
6
|
# 使用 GPU 运行容器
docker run -d --gpus all \
-v ollama:/root/.ollama \
-p 11434:11434 \
--name ollama \
ollama/ollama
|
12.4 docker-compose 完整示例
新建 docker-compose.yml:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
version: "3.8"
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
# GPU 环境取消下面注释
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: all
# capabilities: [gpu]
environment:
- OLLAMA_HOST=0.0.0.0:11434
- OLLAMA_KEEP_ALIVE=5m
volumes:
ollama_data:
|
启动:
12.5 Docker 部署注意事项
- 容器内默认端口是 11434,务必映射到宿主机。
- 模型数据务必挂载卷持久化,否则容器重建后模型丢失。
- GPU 直通需要安装对应平台的 Container Toolkit。
- 如需访问宿主机的其他模型文件,可额外挂载目录。
第 13 章 常见报错与解决方案
部署过程中最常遇到的问题及解决办法整理如下。
13.1 报错:Error: could not locate cudart
现象:
|
1
|
Error: could not locate cudart
|
原因:没有安装 NVIDIA CUDA 运行库,或驱动版本过旧。
解决:
|
1
2
3
4
5
|
# 1. 更新 NVIDIA 驱动(>= 452.39)
# 2. 安装 CUDA Toolkit,或确认驱动已包含 CUDA 运行库
# 3. 确认环境变量
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
|
如果没有 GPU,则忽略该报错,Ollama 会退化为 CPU 模式。
13.2 报错:模型加载失败 / 显存不足
现象:
|
1
|
Error: failed to load model ... cudaMalloc failed: out of memory
|
原因:显存不足,模型无法全部加载到 GPU。
解决:
- 换用更小的模型(如 7B → 1.5B);
- 使用更低量化等级;
- 减小 num_ctx 上下文长度;
- 关闭其他占用显存的程序;
- 设置 OLLAMA_MAX_LOADED_MODELS=1 只保留一个模型。
13.3 报错:端口 11434 被占用
现象:
|
1
|
bind: address already in use
|
原因:已有进程占用 11434 端口(可能是重复启动了 Ollama,或端口被其他服务占用)。
解决:
|
1
2
3
4
5
6
7
|
# 查看占用端口的进程
# Windows
netstat -ano | findstr 11434
# Linux
lsof -i :11434
# 杀掉占用进程,或修改 OLLAMA_HOST 换端口
export OLLAMA_HOST="127.0.0.1:11435"
|
13.4 报错:连接被拒绝(Connection refused)
现象:
|
1
|
curl: (7) Failed to connect to localhost port 11434: Connection refused
|
原因:Ollama 服务没有运行。
解决:
|
1
2
3
4
5
6
|
# 启动服务
ollama serve
# Linux systemd
sudo systemctl start ollama
# 确认服务运行后再请求
curl http://localhost:11434/api/version
|
13.5 报错:模型拉取失败 / 网络超时
现象:
|
1
|
Error: pull model manifest: Get "https://registry.ollama.ai/...": dial tcp: i/o timeout
|
原因:网络无法访问 Ollama 官方模型仓库,或网络不稳定。
解决:
- 配置代理:
|
1
2
3
|
export HTTPS_PROXY=http://127.0.0.1:7890
export HTTP_PROXY=http://127.0.0.1:7890
ollama pull deepseek-r1:7b
|
- 切换网络(手机热点、其他网络)重试;
- 使用国内镜像源(社区维护)替换默认仓库地址;
- 多试几次,分时段下载。
13.6 报错:模型不存在
现象:
|
1
|
Error: model 'xxx' not found
|
原因:模型名拼写错误,或该模型尚未拉取。
解决:
|
1
2
3
4
|
# 先查看本地已有哪些模型
ollama list
# 确认官方模型库中的正确名称
ollama pull deepseek-r1:7b
|
13.7 中文乱码问题
现象:终端输出中文乱码或方块。
原因:Windows 终端编码(GBK)与 UTF-8 不一致,或终端字体不支持中文。
解决:
- Windows:在 PowerShell/CMD 中先执行 chcp 65001 切换到 UTF-8;
- 或在 Windows Terminal 设置中把默认编码改为 UTF-8;
- 程序调用时,Python 脚本首行加 # -*- coding: utf-8 -*-,读写文件时指定 encoding="utf-8"。
13.8 推理速度非常慢
原因:没有 GPU 加速,模型在 CPU 上运行,或显存不足导致 CPU/GPU 混合。
解决:
- 确认 ollama ps 的 PROCESSOR 列是否为 100% GPU;
- 换更小模型 / 更低量化;
- 缩短上下文 num_ctx;
- 增加 OLLAMA_NUM_PARALLEL 并发;
- 升级硬件。
13.9 Ollama 命令找不到(command not found)
原因:安装失败或环境变量未配置。
解决:
|
1
2
3
4
5
|
# Linux:重新运行安装脚本
curl -fsSL https://ollama.com/install.sh | sh
# 确认二进制位置
which ollama
# 输出如 /usr/local/bin/ollama
|
第 14 章 生产环境部署建议与安全加固
本地部署后如果要长期对外提供服务,建议按下面的方案进行生产化改造。
14.1 推荐的生产部署架构
|
1
2
3
4
5
6
7
8
|
┌──────────────────────┐
用户/前端 ────? │ 反向代理 / 网关 │
│ (Nginx / API 网关) │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ Ollama 服务 (11434) │
└──────────────────────┘
|
分层职责:
- 反向代理层(Nginx):负责 HTTPS 终止、访问认证、限流、负载均衡。
- 应用层:你的业务服务(FastAPI / Spring Boot 等)只与 Ollama 通信,做鉴权和业务逻辑。
- 模型层:Ollama 只接受内网请求。
14.2 Nginx 反向代理 + Basic Auth 示例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# /etc/nginx/conf.d/ollama.conf
server {
listen 80;
server_name your-domain.com;
# Basic Auth 认证
auth_basic "Ollama Access";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://127.0.0.1:11434;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_buffering off; # 流式输出必须关闭缓冲
proxy_read_timeout 300s;
}
}
|
生成密码文件:
|
1
2
3
4
|
# 安装 htpasswd 工具
sudo apt install apache2-utils
# 创建用户和密码
sudo htpasswd -c /etc/nginx/.htpasswd admin
|
14.3 应用层限流与鉴权
在业务服务中对调用做限流,避免单个用户打爆本地算力。以 FastAPI 为例的简易限流:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
# -*- coding: utf-8 -*-
"""FastAPI 封装 Ollama 并做简易限流"""
import time
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import requests
app = FastAPI()
OLLAMA_URL = "http://localhost:11434"
# 简易令牌桶:每用户每分钟限制 N 次
RATE_LIMIT = {"window": 60, "max_requests": 10}
_user_records = {}
class ChatRequest(BaseModel):
message: str
model: str = "deepseek-r1:7b"
def check_rate_limit(user_id: str):
"""简易限流检查"""
now = time.time()
record = _user_records.get(user_id, [])
# 清理过期记录
record = [t for t in record if now - t < RATE_LIMIT["window"]]
if len(record) >= RATE_LIMIT["max_requests"]:
raise HTTPException(status_code=429, detail="请求过于频繁")
record.append(now)
_user_records[user_id] = record
@app.post("/chat")
def chat(req: ChatRequest, user_id: str = "anonymous"):
check_rate_limit(user_id)
payload = {
"model": req.model,
"messages": [{"role": "user", "content": req.message}],
"stream": False,
}
resp = requests.post(f"{OLLAMA_URL}/api/chat", json=payload, timeout=300)
resp.raise_for_status()
return {"reply": resp.json()["message"]["content"]}
# 启动:uvicorn main:app --host 0.0.0.0 --port 8000
|
14.4 数据安全与合规
- 数据不出内网:确认 Ollama 只监听内网,不暴露公网。
- 日志脱敏:业务层记录日志时,对用户输入中的敏感信息(身份证、手机号、密码)做脱敏处理。
- 输入审计:对发送给模型的提示词做内容安全过滤,防止提示注入攻击。
- 模型许可合规:确认使用的模型(如 DeepSeek)的 License 符合你的商用场景要求。
14.5 监控与高可用
- 资源监控:使用 Prometheus + Grafana 监控 GPU 利用率、显存、内存、请求延迟。
- 日志采集:收集 Ollama 日志和业务层日志,便于排查问题。
- 多实例:高并发场景下部署多个 Ollama 实例,由 Nginx 负载均衡分发。
- 模型预热:提前加载模型(发一次探测请求),避免用户首次请求时等待模型加载。
第 15 章 总结与后续学习路线
15.1 全流程回顾
到这里,我们已经完成了:
- ? 了解本地部署大模型的优势和适用场景
- ? 根据硬件选择合适的 DeepSeek 模型规模
- ? 在 Windows / Linux / macOS 上安装 Ollama
- ? 拉取 deepseek-r1:7b 模型
- ? 通过命令行交互使用 DeepSeek
- ? 通过 HTTP API(/api/generate、/api/chat)调用
- ? 通过 requests / ollama / openai / LangChain 四种 Python 方式调用
- ? 通过 Modelfile 自定义专属模型
- ? 配置局域网远程访问
- ? 性能调优与 Docker 部署
- ? 常见报错排查与生产环境安全加固
15.2 核心命令速查
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 安装
# Windows: 官网安装包 / winget install Ollama.Ollama
# Linux: curl -fsSL https://ollama.com/install.sh | sh
# macOS: 官网安装包 / brew install ollama
# 核心命令
ollama --version # 版本
ollama pull <model> # 拉取模型
ollama run <model> # 运行并对话
ollama list # 查看本地模型
ollama ps # 查看运行中模型
ollama show <model> # 查看模型详情
ollama create -f Modelfile # 创建自定义模型
ollama rm <model> # 删除模型
# API 调用
curl http://localhost:11434/api/version
curl http://localhost:11434/api/chat -d '{"model":"deepseek-r1:7b","messages":[{"role":"user","content":"你好"}],"stream":false}'
|
15.3 后续可以深入的方向
- 搭建 Web 聊天界面:部署 Open WebUI,通过可视化界面与大模型对话(docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main)。
- RAG 知识库问答:使用 Ollama + 向量库(如 Chroma / Milvus)+ LangChain,把私有文档接入问答系统。
- Agent 智能体开发:DeepSeek-R1 支持工具调用,可以结合 Function Calling 构建自动执行任务的 Agent。
- 微调模型:基于 LoRA 对 DeepSeek 进行领域微调,让模型更懂你的业务。
- 模型评估:对比不同参数规模、量化等级的模型在具体任务上的效果和速度,选择最优方案。
15.4 参考资料
- Ollama 官网:https://ollama.com
- Ollama GitHub:https://github.com/ollama/ollama
- DeepSeek-R1 模型页:https://ollama.com/library/deepseek-r1
- Ollama API 文档:https://github.com/ollama/ollama/blob/main/docs/api.md
附录 A:搭建 Web 可视化聊天界面(Open WebUI)
命令行和 API 适合开发者,如果想给普通用户一个图形化的聊天界面,推荐部署 Open WebUI。它是一个开源、自托管的 AI 聊天前端,支持与 Ollama 无缝对接。
A.1 Docker 一键部署
|
1
2
3
4
5
6
7
8
|
# 运行 Open WebUI(默认端口 3000)
docker run -d \
-p 3000:8080 \
--add-host=host.docker.internal:host-gateway \
-v open-webui:/app/backend/data \
--name open-webui \
--restart always \
ghcr.io/open-webui/open-webui:main
|
启动后,浏览器访问 http://localhost:3000,首次访问需要注册一个管理员账号(本地存储,不联网)。注册登录后,在设置中选择模型 deepseek-r1:7b,即可开始图形化对话。
A.2 配置说明
- Open WebUI 默认通过 host.docker.internal 访问宿主机的 Ollama 服务。
- 如果 Ollama 与 Open WebUI 不在同一台机器,可以在设置中修改 Ollama 的 Base URL,例如 http://192.168.1.100:11434。
- 数据持久化目录为 /app/backend/data,对话记录、账号信息都保存在这里,请务必挂载卷。
A.3 核心功能
- 多模型切换、多会话管理
- Markdown 渲染、代码高亮
- 文档上传(配合 RAG 可以做知识库问答)
- 用户管理与权限控制
- 支持 Function Calling 工具调用
附录 B:完整的本地问答服务示例
下面给出一个端到端可运行的最小示例:使用 FastAPI 暴露一个 HTTP 接口,内部调用 Ollama 的 DeepSeek,支持多轮对话和流式输出。你可以直接复制运行,作为生产服务的起点。
B.1 项目结构
|
1
2
3
4
|
chat-service/
├── main.py # FastAPI 服务入口
├── requirements.txt # 依赖
└── config.py # 配置
|
B.2 requirements.txt
|
1
2
3
|
fastapi==0.115.0
uvicorn==0.30.0
requests==2.32.0
|
B.3 config.py
|
1
2
3
4
5
6
|
# -*- coding: utf-8 -*-
"""服务配置"""
OLLAMA_BASE_URL = "http://localhost:11434"
DEFAULT_MODEL = "deepseek-r1:7b"
DEFAULT_TEMPERATURE = 0.7
MAX_CONTEXT_LEN = 4096
|
B.4 main.py
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
# -*- coding: utf-8 -*-
"""基于 FastAPI 的 DeepSeek 问答服务(流式 + 非流式)"""
import json
from typing import Optional
from fastapi import FastAPI, HTTPException
from fastapi.responses import StreamingResponse
from pydantic import BaseModel, Field
import requests
from config import OLLAMA_BASE_URL, DEFAULT_MODEL, DEFAULT_TEMPERATURE
app = FastAPI(title="DeepSeek Chat Service", version="1.0.0")
class ChatMessage(BaseModel):
role: str = Field(description="角色:system/user/assistant")
content: str = Field(description="消息内容")
class ChatRequest(BaseModel):
messages: list[ChatMessage]
model: str = DEFAULT_MODEL
temperature: float = DEFAULT_TEMPERATURE
stream: bool = False
max_tokens: Optional[int] = 512
@app.get("/health")
def health():
"""健康检查:确认 Ollama 服务是否可用"""
try:
resp = requests.get(f"{OLLAMA_BASE_URL}/api/version", timeout=5)
resp.raise_for_status()
return {"status": "ok", "ollama": resp.json()}
except Exception as e:
raise HTTPException(status_code=503, detail=f"Ollama 不可用: {e}")
@app.post("/v1/chat/completions")
def chat(req: ChatRequest):
"""对话接口,兼容 OpenAI 风格,支持流式输出"""
payload = {
"model": req.model,
"messages": [m.model_dump() for m in req.messages],
"stream": req.stream,
"options": {
"temperature": req.temperature,
"num_predict": req.max_tokens,
},
}
# 流式:使用 StreamingResponse 转发 SSE
if req.stream:
def event_stream():
with requests.post(
f"{OLLAMA_BASE_URL}/api/chat",
json=payload,
stream=True,
timeout=300,
) as resp:
resp.raise_for_status()
for line in resp.iter_lines():
if not line:
continue
data = json.loads(line)
if data.get("done"):
yield "data: [DONE]\n\n"
break
content = data["message"]["content"]
yield f"data: {json.dumps({'content': content})}\n\n"
return StreamingResponse(
event_stream(),
media_type="text/event-stream",
headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"},
)
# 非流式
resp = requests.post(f"{OLLAMA_BASE_URL}/api/chat", json=payload, timeout=300)
resp.raise_for_status()
data = resp.json()
return {
"reply": data["message"]["content"],
"usage": {"eval_count": data.get("eval_count", 0)},
}
# 启动命令:
# uvicorn main:app --host 0.0.0.0 --port 8000
|
B.5 测试服务
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 安装依赖
pip install -r requirements.txt
# 启动服务
uvicorn main:app --host 0.0.0.0 --port 8000
# 另开终端测试健康检查
curl http://localhost:8000/health
# 测试非流式对话
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"messages": [{"role": "user", "content": "你好,介绍一下你自己"}],
"stream": false
}'
# 测试流式对话
curl -N http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"messages": [{"role": "user", "content": "用三句话介绍 HTTP"}],
"stream": true
}'
|
这个服务可以直接作为企业内部 AI 应用的后端,也可以配合前端页面使用。
附录 C:模型下载慢 / 无网络环境的离线部署方案
某些企业内网无法访问外网,需要离线部署。步骤如下:
C.1 在可联网机器上下载模型文件
|
1
2
3
4
5
|
# 在有网络的机器上拉取模型
ollama pull deepseek-r1:7b
# 查看模型存储位置
# Linux/macOS: ~/.ollama/models
# Windows: %USERPROFILE%\.ollama\models
|
C.2 打包拷贝到内网
|
1
2
3
4
5
6
|
# 打包整个 models 目录(Linux 示例)
tar -czf deepseek-models.tar.gz ~/.ollama/models
# 拷贝到内网机器后解压
tar -xzf deepseek-models.tar.gz -C ~/.ollama
# 重启 Ollama 服务后即可使用
ollama list # 应该能看到 deepseek-r1:7b
|
C.3 内网离线安装 Ollama
把安装脚本/二进制文件提前下载好,在内网执行:
|
1
2
3
|
# 离线安装(手动解压二进制到 /usr/local/bin)
tar -C /usr -xzf ollama-linux-amd64.tgz
ollama serve &
|
C.4 其他补充
- 模型文件较大(7B 约 4.7 GB),建议使用移动硬盘或企业内网传输。
- 拷贝后如果 ollama list 看不到模型,检查 OLLAMA_MODELS 环境变量是否指向了正确目录。
结束语:本文从零到一完整演示了使用 Ollama 本地部署 DeepSeek 大模型的全过程。只要跟随本文一步步操作,你就能拥有一套完全自主可控、数据不出的本地大模型服务。部署只是开始,后续结合业务场景的深度应用才是价值所在。如果在实践过程中遇到任何问题,欢迎对照第 13 章排查,或查阅官方文档。祝部署顺利!