DeepSeek部署教程:从Ollama到vLLM的完整路径
简介:这是一份讲解DeepSeek部署的PDF格式文档,面向需要快速上手该工具的开发者与技术人员。教程覆盖部署全流程:先说明CPU、内存、硬盘等硬件要求及操作系统适配,再讲解Python 3.6以上环境与虚拟环境配置,逐步指导安装网络请求、网页解析等常用依赖库;安装部分区分命令行初学者与定制开发者,提供官方安装包和源码编译两种路径;配置环节详述用户代理、请求头、抓取深度及代理IP池等高级选项。通过本教程,读者可掌握部署要点,规避环境或配置不当导致的异常,快速进入实际抓取环节;附带的命令与配置示例亦可直接复用,有助于缩短部署时间。教程以适合快速阅读的篇幅编排,重点步骤配有说明,方便对照操作。资源仅含1个PDF文件,共823KB,便于按需查阅。目前已有327人学习,适合爬虫入门者、运维人员及希望深入了解该技术的算法工程师。
1. DeepSeek部署教程.pdf:把检索词变成一条能跑通的部署路径
搜「DeepSeek部署教程.pdf」的人,大多不是在找一份现成的文档,而是在找一条从零把DeepSeek跑起来的路径。本地部署DeepSeek的价值很清楚:数据不出内网、没有 API 额度焦虑、可以按自己的显存改量化级别和上下文长度,还能把推理服务接到团队已有的工具链里。难点在于选型,Ollama、vLLM、Docker、Dify 四条路各有边界,选错一步后面全是返工。下面按「先选型、再最小可用、后生产化、最后排错」这条我实际落地的顺序展开,覆盖从开发机试跑到给团队提供一个共享推理服务的完整过程。
2. 部署DeepSeek前先定选型:Ollama、vLLM与Dify的路由规则
2.1 三条主流路径的差异与适用边界
很多人一上来就问「用哪个部署DeepSeek」,答案取决于谁在调用、并发有多高、下游要不要工作流编排。先看一张对比表:
| 路径 | 适合场景 | 接口形态 | 生产友好度 | 上手成本 |
|---|---|---|---|---|
| Ollama | 开发机、个人笔记本、小团队共享 | OpenAI兼容 /v1 | 中 | 最低 |
| vLLM | 7×24 服务、高并发、多路复用 | OpenAI兼容 /v1 | 高 | 中 |
| Dify + 推理后端 | 业务应用编排、RAG、Agent对话流 | 可视化编排再转 API | 高 | 中高 |
Ollama 是「本地部署 AI」的快捷方式,一条命令把模型拉下来当服务跑,适合验证模型效果;但它默认不做细粒度的批处理优化,并发上来后延迟和吞吐都不够看。vLLM 是生产环境跑 DeepSeek 的主流选择,PagedAttention 和 continuous batching 让单卡吞吐明显高于朴素实现,这也是为什么「vllm部署大模型」在社区检索里常年排在前列。Dify 解决的是模型之后的事:把知识库、工具调用、工作流编排接到模型上。实际项目里常见组合是 vLLM 当推理引擎、Ollama 在开发期做验证、Dify 做应用入口。
选型之前还有一件事要做:把「AI大模型本地部署配置」里的配置两个字拆开看,显存、量化、上下文长度三项缺一不可,否则模型能拉下来也跑不动。
2.2 先算显存再选模型:量化、上下文与显存预算
部署 DeepSeek 时失误最多的是「卡够大就硬上」,其实量化级别和上下文长度对显存占用差异极大。推理显存大致等于模型权重加 KV Cache 加激活临时区,其中权重占比约等于「参数量 × 量化位宽 ÷ 8」,KV Cache 与上下文长度、并发数线性相关。用一个简化的 Python 脚本在部署前粗算:
# 部署前粗算显存:以 DeepSeek-R1-Distill-Qwen-14B 为例
model_billions = 14
quant_bits = 4 # q4_K_M 级别量化
weight_gb = model_billions * quant_bits / 8 # 约 7GB
max_len = 32768 # 上下文窗口长度
seqs = 4 # 并发序列数
layers = 48 # 隐藏层数,以模型 config 为准
hidden = 5120 # 隐藏层维度,以模型 config 为准
kv_cache_gb = 2 * layers * hidden * max_len * seqs / 1024**3
total_gb = (weight_gb + kv_cache_gb) * 1.2 # 预留 20% 给 CUDA context 和激活值
print(f"粗估显存: {total_gb:.1f} GB")
这段脚本先把权重和 KV Cache 分开算,是因为二者的调优方向完全不同:权重是固定开销,只能靠换更小的量化档位来省;KV Cache 则随并发数和上下文长度增长,单会话不并发时可以把 seqs 设为 1,显存预算立刻降下来。预留的 20% 余量不能省,CUDA context、激活值、临时 buffer 都会吃显存。实际部署时优先调低 max_len 或并发数,而不是一味降低量化等级,因为量化从 Q4 降到 Q3 对输出质量的影响往往比缩上下文更明显。
无并发场景下,14B Q4 模型在 16GB 显存的卡上就能跑;但同一个模型开放给团队使用时,通常需要 40GB 以上显存,否则多路请求很快撞 OOM。
2.3 决策规则:先问四个问题再动手
动手前先回答四个问题:谁在调这个服务,只有自己还是多人共享;最坏的时候同时来几个请求;下游是直接用 OpenAI SDK 调用,还是接 Dify 这类应用平台;手上是单卡还是多卡,卡间是 PCIe 还是 NVLink。前两个问题指向并发规模,第三问决定要不要在模型层之上再加一层编排,第四问影响能不能用多卡并行。
# 确认卡数与可用显存,部署前的硬检查
nvidia-smi --query-gpu=index,name,memory.total,memory.free --format=csv
memory.total 与 memory.free 要一起看,vLLM 启动时按空闲显存分配 KV Cache,如果机器上已有其它进程占用显存,剩余空间不足会导致启动直接失败。判断规则很简单:单用户、低并发走 Ollama;多人共用、API 网关后面挂多个应用走 vLLM;需要在界面上拖拽编排 RAG 和 Agent 流程,再套一层 Dify。多卡环境优先考虑 vLLM 的 --tensor-parallel-size ,比 Ollama 的多卡支持更成熟。
3. 用Ollama在本地跑通DeepSeek的最小命令
3.1 安装与首次拉取模型
Ollama 本地部署的难度不在安装,而在第一次拉模型时的等待。Debian 系系统用官方脚本一条命令装完,然后直接进交互对话验证:
# 安装(Debian/Ubuntu 用官方脚本)
curl -fsSL https://ollama.com/install.sh | sh
# 启动服务并确认版本
systemctl start ollama
ollama --version
# 拉取 DeepSeek 的 R1 蒸馏模型(32B Q4 量化,约 19GB)
ollama pull deepseek-r1:32b
# 进入交互对话验证是否可用
ollama run deepseek-r1:32b "写一段计算CRC32的python代码"
deepseek-r1:32b 是社区里使用率很高的蒸馏模型标签,参数量大意味着推理成本和显存占用都更高;显存紧张可以换 deepseek-r1:14b 或 deepseek-r1:8b ,质量差距在通用任务上可以接受。首次 pull 等待时间是正常的,Ollama 会把模型分成多层存储,之后跨会话复用,不需要重复下载。交互对话能正常回答,说明模型和驱动链路已经通了一半。
3.2 调整上下文长度、并发与监听地址
ollama run 里的临时参数只对当前会话生效,服务级配置要写进环境变量或 Modelfile。最常见的一组配置是监听地址、并发数和上下文长度:
# 让服务监听 0.0.0.0,供局域网内其他机器调用
OLLAMA_HOST=0.0.0.0:11434 ollama serve
# 限制并发数,避免显存被瞬时打满
OLLAMA_NUM_PARALLEL=2 ollama serve
# 设置默认上下文长度,对所有模型生效
OLLAMA_CONTEXT_LENGTH=16384 ollama serve
OLLAMA_HOST 把服务暴露到局域网后,团队其他人不需要在各自机器上重复拉模型,直接把客户端 base_url 指向这台机器即可。 OLLAMA_NUM_PARALLEL 默认串行处理请求,设成 2 意味着同时处理 2 个请求,其余排队,这对多人同时试用本地部署 DeepSeek 的场景很关键。 OLLAMA_CONTEXT_LENGTH 控制模型能记住的 token 数量,显存不足时优先降这个值,而不是换小模型。
| 命令 / 环境变量 | 作用 | 典型值 |
|---|---|---|
| ollama list | 查看本地已拉取的模型 | - |
| ollama show 模型名 | 查看模型配置与参数 | - |
| OLLAMA_CONTEXT_LENGTH | 上下文窗口长度 | 4096 / 8192 / 16384 |
| OLLAMA_NUM_PARALLEL | 并发处理数 | 1 / 2 / 4 |
| /set parameter temperature | 交互式调整随机性 | 0.2 ~ 0.8 |
| /clear | 清空上下文,开启新会话 | - |
3.3 本地模型的常见坑:OOM、对话长度上限与请求失败
「deepseek 达到对话长度上限,请开启新对话」是 Ollama 用户最常撞到的问题,它不是模型故障,而是上下文窗口被打满了。Ollama 默认上下文可能只有 2048 或 4096,连续对话几轮后触发上限,解决办法是在启动服务前设置 OLLAMA_CONTEXT_LENGTH ,同时保证显存能容纳对应的 KV Cache。
另一个高频问题是 CUDA OOM,日志里直接报 out of memory 。先看是不是并发数设置过高, OLLAMA_NUM_PARALLEL 从默认值下降到 1 再测;如果还 OOM,就把 OLLAMA_CONTEXT_LENGTH 降到 8192,或者换成更小的量化模型。还有一个隐蔽问题:服务日志里频繁出现 Rerouting ,说明请求已经排队,但调用方以为服务挂了,此时调高并行数或者让客户端增加超时时间即可。
Ollama 同时暴露了 OpenAI 兼容接口 http://localhost:11434/v1 ,这意味着 Dify、Codex、VS Code 插件等工具都能在配置里直接填这个地址,开发期的联调成本很低。
4. 用vLLM部署DeepSeek到生产环境
4.1 启动vLLM服务的最小参数
vLLM 部署大模型是生产环境的默认选择,它把模型服务化之后暴露的接口与 OpenAI 兼容,切换成本几乎为零。安装和启动命令如下:
pip install vllm
vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-14B \
--served-model-name deepseek-r1 \
--gpu-memory-utilization 0.90 \
--max-model-len 32768 \
--max-num-seqs 8 \
--enable-prefix-caching
--served-model-name 决定对外暴露的模型名,客户端调用时用这个名字而不是 Hugging Face 路径。 --gpu-memory-utilization 设成 0.90,意思是把最多 90% 的显存分配给 vLLM,剩下 10% 留给 CUDA context 和临时显存,设成 1.0 看着效率高,实际很容易在推理中途触发显存分配失败。 --max-num-seqs 控制同一个 batch 里最多容纳的请求数,设大了 KV Cache 快速膨胀,设小了吞吐上不去。 --enable-prefix-caching 在做多轮对话和 RAG 时收益非常明显,尤其是角色设定和系统提示词不变的情况下,命中缓存后首 token 延迟可以降一个量级。
4.2 并发调优与KV Cache的取舍
vLLM 的性能上限由显存里能塞进多少 KV Cache 决定。PagedAttention 的作用是让 KV Cache 按块分配,减少碎片,但它不能改变显存总量。下面这张表是实际调参时我常用的启动参数组合:
| 参数 | 影响 | 试调建议 |
|---|---|---|
| --gpu-memory-utilization | KV Cache 可用量 | 0.85 ~ 0.92 |
| --max-model-len | 单请求上下文上限 | 16K / 32K |
| --max-num-seqs | 同一 batch 的请求数 | 4 ~ 16 |
| --tensor-parallel-size | 多卡并行度 | 与卡数一致 |
| --dtype | 推理精度 | auto 或 bfloat16 |
调参顺序有讲究:先确认 max-model-len 符合业务最坏情况,再根据显存余量定 max-num-seqs 。如果团队实际用不到 32K 上下文,把 --max-model-len 降到 16384,释放出来的显存可以支撑更高的并发。观察 GPU 利用率也有门道,利用率不到 60% 时先提高 batch 而不是换卡,因为此时瓶颈大概率在请求稀疏,而不是算力不足。vLLM 启动日志里的 Avg prompt throughput 和 Avg generation throughput 是判断瓶颈的第一手依据。
4.3 用OpenAI SDK调用本地DeepSeek
vLLM 启动后,客户端一侧的接入方式和调用 OpenAI 没有任何区别:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="local-any-token"
)
resp = client.chat.completions.create(
model="deepseek-r1",
messages=[
{"role": "system", "content": "你是部署在内部网络的DeepSeek服务"},
{"role": "user", "content": "帮我检查这段代码的资源泄漏"},
],
max_tokens=2048,
temperature=0.6,
)
print(resp.choices[0].message.content)
base_url 要写成 vLLM 服务实际监听的地址, model 必须与 --served-model-name 保持一致,否则接口返回模型不存在。这里的 max_tokens 值得特别注意:DeepSeek R1 这类推理模型会把思维链也计入生成 token, max_tokens 设置过小会出现输出为空或突然截断的现象,2048 是相对稳妥的起点。 temperature 在代码生成任务里建议调低到 0.3 左右,通用问答可以保持 0.6 到 0.8。
4.4 用curl验证服务健康状态
# 查询模型列表,确认模型已注册
curl http://localhost:8000/v1/models | python3 -m json.tool
# 快速冒烟请求,验证推理链路
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-r1",
"messages": [{"role": "user", "content": "1+1="}],
"max_tokens": 128
}'
/v1/models 只做连通性检查,返回结果里 id 字段的值就是客户端可用的模型名。冒烟请求显式加了 max_tokens: 128 ,避免测试时输出过长。如果这一步报 DeepSeek request extension preparation failed 一类错误,多半是请求上下文超过了 --max-model-len ,或者客户端传了 vLLM 不支持的扩展参数,排错方向后面单讲。
5. 用Docker镜像部署DeepSeek并联通开发工具链
5.1 docker安装部署前的基础要求
用 Docker 部署 DeepSeek 之前要明确一件事:GPU 驱动装在宿主机,容器里只带 CUDA 库,NVIDIA Container Toolkit 是宿主机到容器的桥梁。先检查环境:
# 确认宿主机驱动可用
nvidia-smi
# 确认 container toolkit 已安装
dpkg -l | grep nvidia-container-toolkit
第一条命令没有输出,说明驱动没装好,容器里跑什么都是白搭。第二条没有输出,需要先安装对应发行版的 toolkit,否则 Docker 启动时即使加了 gpus 参数也会静默降级为 CPU 推理,模型能加载但速度慢到不可用。docker 安装部署最容易被忽略的就是这一层,GPU 直通正常后再谈编排。
5.2 用docker compose编排一个可复用的DeepSeek服务
我一般把 vLLM 推理服务写进一个 docker-compose.yml ,好处是重启策略、GPU 申请和端口映射都能跟着配置走:
# docker-compose.yml:带 GPU 的 vLLM 推理服务
services:
deepseek-vllm:
image: vllm/vllm-openai:latest
container_name: deepseek-vllm
ports:
- "8000:8000"
volumes:
- ~/.cache/huggingface:/root/.cache/huggingface
environment:
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-}
command:
- "--model"
- "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B"
- "--served-model-name"
- "deepseek-r1"
- "--max-model-len"
- "32768"
- "--gpu-memory-utilization"
- "0.90"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
restart: unless-stopped
volumes 把 Hugging Face 缓存挂进容器,模型只在首次启动时下载,之后重启容器不需要重新拉取。 HUGGING_FACE_HUB_TOKEN 通过 .env 文件注入,公开模型可以留空,私有模型必须填写。 command 段逐项对应 vLLM 的启动参数,与命令行写法完全一致。 deploy.resources 段是关键,告诉 Docker 编排器要申请 GPU 资源,少了这一段容器会在无 GPU 状态下启动。最后 restart: unless-stopped 保证机器重启后推理服务自动拉起。
5.3 接入Dify工作流与Codex/VSCode扩展
Dify 本地部署完成之后,要把 DeepSeek 配置为模型供应商。在 Dify 后台的「模型供应商」里选择 OpenAI-API-compatible 类型,基础 API 地址填 http://宿主机IP:8000/v1 ,模型名填 deepseek-r1 ,API Key 随意填一个非空值。Dify 本身依赖 Postgres 和 Redis,可以用独立的 docker compose 管理,不必和推理服务混在一个文件里。
VS Code 插件和 Codex 接入本地 DeepSeek 的方式类似,这类工具普遍支持自定义 OpenAI 兼容端点:
{
"name": "deepseek-on-vllm",
"apiBaseUrl": "http://localhost:8000/v1",
"apiKey": "local-any",
"model": "deepseek-r1"
}
这里的 apiBaseUrl 要写客户端机器能访问到的地址,如果 IDE 和推理服务不在同一台机器,把 localhost 换成服务所在机器的 IP,而不是写 Docker 容器名。 model 字段同样要与 --served-model-name 一致,这是配置里最容易出错的点。
| 对接对象 | 配置位置 | 填写内容 |
|---|---|---|
| Dify | 模型供应商 > OpenAI-API-compatible | API Base URL 填 http://host:8000/v1 |
| Dify | 模型供应商 > 模型名称 | deepseek-r1 |
| Codex / Continue | agent 配置 apiBaseUrl | http://localhost:8000/v1 |
| Codex / Continue | agent 配置 model | deepseek-r1 |
6. 部署DeepSeek后的压测与四个排错技巧
6.1 一分钟快速压测:吞吐与首Token延迟
模型部署完先别急着接业务,用一段 8 请求的并发压测确认服务能扛住真实负载:
import time
from concurrent.futures import ThreadPoolExecutor
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="x")
def one_call(i):
t0 = time.time()
client.chat.completions.create(
model="deepseek-r1",
messages=[{"role": "user", "content": f"请输出第{i}段技术说明"}],
max_tokens=200
)
return time.time() - t0
with ThreadPoolExecutor(4) as ex:
times = list(ex.map(one_call, range(8)))
print(times)
4 个并发线程发 8 个请求,观察平均时延和是否有报错。vLLM 会把并发请求连续批处理,平均时延会上升但总吞吐可以接受;如果出现连接超时,先查客户端到服务端的网络,而不是怀疑模型。更正式的压测可以用 --metrics 参数把指标暴露给 Prometheus 监控部署,再配 Grafana 看板观察长期趋势。
6.2 四个高频排错对照
| 报错现象 | 根因 | 处理方法 |
|---|---|---|
| DeepSeek request extension preparation failed | 请求上下文超过 --max-model-len ,或客户端传了不支持的扩展参数 | 调大 max-model-len;检查请求里是否携带未知参数 |
| 达到对话长度上限,请开启新对话 | 上下文窗口已满,旧会话无法继续 | 调高 max-model-len 或 OLLAMA_CONTEXT_LENGTH,让客户端开启新会话 |
| CUDA out of memory | KV Cache 或权重超出显存 | 调低 gpu-memory-utilization、max-num-seqs |
| 调用超时或连接拒绝 | 网络不通或服务未启动 | 用 curl 检查 8000 端口连通性 |
最后留一个判断习惯:vLLM 日志里的 Avg generation throughput 持续偏低,优先怀疑并发参数设置,而不是模型本身; Avg prompt throughput 偏低时,检查每个请求的上下文是否都不同,导致 prefix cache 命中率上不去。把这两个指标盯住,本地推理服务的性能底细基本就清楚了。
更多推荐


所有评论(0)