简介:这份实战教程面向希望快速上手检索增强生成系统的开发者与运维人员,围绕DeepSeek模型,系统讲解RAG环境从零搭建的完整流程。内容涵盖技术栈概要、Dify服务器、Rerank与Embedding模型服务器、DeepSeek模型服务器三台ECS的分步部署,并涉及CUDA驱动、vLLM推理库、Docker容器化、xinference框架及bge-reranker-large、bge-large-zh-v1.5等模型的具体安装与配置,帮助读者解决多机协作、环境版本匹配与模型调用等实际问题。资源包为1个docx文档,约580KB,以图文步骤与目录结构呈现,便于按章节查阅。目前已有326人学习。通过这份教程,读者可掌握从服务器环境准备到模型部署验证的完整链路,获得可复用的部署思路与排错参考,适合具备一定Linux与深度学习基础、希望深入RAG系统落地的技术人员。
1. 三台机器、四个模型:这套 RAG 环境搭建方案到底值不值得跑一遍
如果你最近在折腾本地知识库,大概率绕不开一个尴尬:模型能跑起来,但检索结果答非所问;或者检索准了,生成又慢得像挤牙膏。这套基于 DeepSeek 的 RAG 环境搭建教程,核心思路就是把「生成」和「检索」拆到不同机器上,用三台服务器分别扛 Dify 平台、向量化/重排模型、大模型推理,避免一张卡上什么都想干、什么都干不好。它适合手头有两三张卡、想把 RAG 链路完整跑通的人,也适合已经用过现成平台、但想搞清楚底层模型怎么注册、怎么启动的从业者。整套流程覆盖 CUDA 驱动、vLLM 推理、Docker 部署和 Xinference 模型管理,踩坑密度不低,但跑通之后你对 RAG 环境搭建的理解会从「点按钮」变成「知道按钮背后在干什么」。
2. 技术栈选型:为什么是 Dify + Xinference + vLLM 这套组合
2.1 三个模块各管一摊,别混在一台机器上
这套方案最值得先讲清楚的是分工逻辑。Dify 负责应用层编排——知识库管理、对话流程、智能体配置,它本身对显卡没要求,所以放在一台普通 ECS 上跑 Docker 就行。Embedding 和 Rerank 模型放在第二台机器,用 Xinference 统一管理,前者把文档切片转成向量,后者对检索回来的候选段落做二次排序。DeepSeek 蒸馏模型放在第三台机器,用 vLLM 做推理后端,专门负责根据检索结果生成回答。
为什么非要拆开?因为 Embedding 和 Rerank 是高频调用、低延迟需求,而大模型推理是低频调用、高显存占用。混在一起最直接的后果就是显存打架——T4 的 16GB 显存跑 bge-large-zh-v1.5 和 bge-reranker-large 刚好够用,但再塞一个 14B 模型进去必然 OOM。分开之后,每台机器只需要关注自己的资源水位,排查问题也简单得多。
常见做法是至少准备两张卡:一张 T4 或同级别卡给 Embedding/Rerank,一张 V100 32GB 或更高给大模型。如果只有一张卡,这套方案跑起来会非常勉强,建议先砍掉 Rerank 环节或者换更小的模型。
2.2 模型选型:bge 系列 + DeepSeek 蒸馏版的组合逻辑
Embedding 模型选的是BAAI/bge-large-zh-v1.5,输出维度 768,最大 token 数 512。这个模型在中文语义相似度任务上表现稳定,社区验证充分,而且 Xinference 对它的支持比较成熟。Rerank 模型选的是BAAI/bge-reranker-large,它的作用是在向量检索召回一批候选文档后,用交叉编码的方式重新打分排序,把真正相关的段落顶到前面。
大模型选的是deepseek-ai/DeepSeek-R1-Distill-Qwen-14B,基于 Qwen-2.5 系列蒸馏而来。选 14B 而不是更大的版本,主要是显存约束——V100 32GB 用 half 精度加载 14B 模型,权重占用大约 28GB,留给 KV Cache 的空间只剩几个 GB。如果换成 32B 或 70B,单卡基本放不下,需要多卡张量并行,部署复杂度会明显上升。
这里有个容易忽略的点:DeepSeek 蒸馏版对中文知识问答的适配不错,但它的输出风格偏「推理型」,有时候会在回答里带上思考过程。如果下游应用对输出格式有严格要求,可能需要在 Dify 的提示词环节做后处理。
2.3 版本锁定:CUDA 12.1 + Python 3.10 + vLLM 0.4.3
这套教程里版本号不是随便写的。CentOS 7.9 默认的 GCC 版本比较老,直接装 vLLM 0.4.3 会遇到编译错误,所以需要先升级开发工具链。CUDA 选 12.1 是因为 vLLM 0.4.3 官方 wheel 包就是按 cu121 编译的,用 11.x 的驱动跑不起来。Python 选 3.10 是因为 vLLM 0.4.3 不支持 3.12,而 3.8 又缺少一些类型注解特性。
驱动版本选的是 530.30.02,对应 CUDA 12.1。这里有个血泪经验:驱动和 CUDA 版本必须匹配,但安装顺序有讲究。如果先装了 CUDA Toolkit 再装驱动,驱动安装程序可能会覆盖掉 CUDA 的部分库文件,导致nvcc -V和nvidia-smi显示的版本不一致。正确做法是先装驱动,重启验证nvidia-smi正常后,再单独安装 CUDA Toolkit,并且安装时取消勾选驱动选项。
3. 三台服务器实操:从驱动安装到模型注册的完整命令
3.1 ECS-2:Xinference 安装与自定义模型注册
第二台机器是整条链路里最需要耐心的部分,因为 Xinference 的自定义模型注册流程涉及多个配置文件,少一步就会报「模型未找到」。
先装 Xinference:
# 安装完整版,包含所有推理后端依赖 pip install "xinference[all]" # 验证安装是否成功 xinference --help安装完成后,配置环境变量并启动服务。这里端口号建议固定为 9997,因为后续 Dify 配置模型地址时会用到:
# 设置模型存储路径,避免默认路径磁盘空间不足 export XINFERENCE_HOME=/tmp/xinference # 前台启动,方便看日志 xinference-local --host 0.0.0.0 --port 9997 # 如果确认没问题,改用后台启动 nohup xinference-local --host 0.0.0.0 --port 9997 &> nohup.out &参数说明:--host 0.0.0.0让服务监听所有网卡,否则 Dify 服务器无法远程调用;--port 9997是 Xinference 默认端口,改成其他端口的话 Dify 那边也要同步改。
接下来注册 Rerank 模型。先准备config.json:
{ "model_name": "custom-bge-reranker-large", "type": "normal", "language": ["en", "zh"], "model_id": "BAAI/bge-reranker-large", "model_uri": "file:///root/models/bge-reranker-large" }注意model_uri必须用file://前缀加绝对路径,不能用相对路径。模型文件需要提前从 HuggingFace 下载好并上传到服务器,下载时确认包含pytorch_model.bin、config.json、tokenizer.json这几个关键文件。
注册命令:
# 将自定义模型注册到 Xinference xinference register --model-type rerank --file model.json --persist # 检查是否注册成功 xinference registrations --model-type rerank--persist参数的作用是把注册信息持久化到磁盘,否则 Xinference 重启后注册记录会丢失。注册成功后,启动模型:
xinference launch --model-name custom-bge-reranker-large --model-type rerankEmbedding 模型的注册流程类似,但config.json多几个字段:
{ "model_name": "custom-bge-large-zh-v1.5", "dimensions": 768, "max_tokens": 512, "language": ["zh"], "model_id": "BAAI/bge-large-zh-v1.5", "model_uri": "file:///root/models/bge-large-zh-v1.5" }dimensions必须和模型实际输出维度一致,bge-large-zh-v1.5 是 768 维,写错了 Dify 那边建知识库时会报维度不匹配。max_tokens设为 512 是因为这个模型的最大输入长度就是 512,超过部分会被截断。
启动 Embedding 模型:
xinference launch --model-name custom-bge-large-zh-v1.5 --model-type embedding两个模型都启动后,可以用 curl 快速验证服务是否正常:
# 测试 Embedding 接口 curl http://localhost:9997/v1/embeddings \ -H "Content-Type: application/json" \ -d '{"model": "custom-bge-large-zh-v1.5", "input": "测试文本"}'如果返回结果里包含 768 维的向量数组,说明 Embedding 服务正常。Rerank 接口的测试类似,把路径换成/v1/rerank即可。
3.2 ECS-3:vLLM 部署 DeepSeek 蒸馏模型
第三台机器负责大模型推理,环境版本要求更严格:CentOS 7.9 + CUDA 12.1 + Python 3.10 + vLLM 0.4.3。
先处理驱动和 CUDA。驱动选 530.30.02 版本,安装后重启验证:
# 验证驱动是否正常加载 nvidia-smi # 输出应该显示 Driver Version: 530.30.02 和 CUDA Version: 12.1CUDA Toolkit 单独安装,安装时取消勾选驱动组件:
# 下载 CUDA 12.1 runfile wget https://developer.download.nvidia.com/compute/cuda/12.1.0/local_installers/cuda_12.1.0_530.30.02_linux.run # 安装,取消勾选 Driver sh cuda_12.1.0_530.30.02_linux.run安装完成后配置环境变量:
# 编辑 ~/.bashrc vim ~/.bashrc # 在文件末尾添加 export PATH=/usr/local/cuda-12.1/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-12.1/lib64:$LD_LIBRARY_PATH # 刷新环境变量 source ~/.bashrc # 验证 nvcc -Vnvcc -V和nvidia-smi显示的 CUDA 版本可能略有差异,只要主版本号一致(都是 12.x)就没问题。
接下来创建 Python 虚拟环境并安装 PyTorch。这里必须指定 cu121 的 index-url,否则 pip 会默认装 CPU 版本:
# 创建虚拟环境 conda create -n myenv python=3.10 -y conda activate myenv # 安装 PyTorch,版本必须和 vLLM 0.4.3 匹配 pip install torch==2.3.0 torchvision==0.18.0 torchaudio==2.3.0 --index-url https://download.pytorch.org/whl/cu121PyTorch 装完后安装 vLLM:
pip install vllm==0.4.3安装过程中如果报依赖版本冲突,按照报错信息里提示的版本号逐个安装即可。常见的是pydantic和fastapi版本不兼容,手动指定版本后重试。
模型文件提前下载并上传到服务器,然后启动推理服务:
python -m vllm.entrypoints.openai.api_server \ --model /root/work/ds/pretrained \ --dtype half \ --trust-remote-code \ --tensor-parallel-size 1 \ --max-model-len 5120 \ --enforce-eager \ --gpu-memory-utilization 0.95 \ --max-num-batched-tokens 5120 \ --max-num-seqs 5 \ --host 0.0.0.0 \ --served-model-name DeepSeek-R1-14B \ --port 8008 &逐个参数解释:--dtype half用 FP16 精度加载,比 FP32 省一半显存;--tensor-parallel-size 1表示单卡推理,多卡的话改成卡数;--max-model-len 5120限制上下文长度,设太大 KV Cache 会撑爆显存;--enforce-eager禁用 CUDA Graph,虽然损失一点性能但能避免某些驱动兼容性问题;--gpu-memory-utilization 0.95让 vLLM 尽可能多地占用显存,留给 KV Cache 用;--max-num-seqs 5限制并发请求数,防止高并发时 OOM。
启动后验证服务:
curl http://localhost:8008/v1/models返回模型列表里包含DeepSeek-R1-14B就说明服务正常。
3.3 ECS-1:Dify 对接三个模型端点
Dify 用 Docker 部署,官方文档里有 docker-compose 方案,这里不展开。重点讲模型对接环节。
登录 Dify 后台后,进入「设置」→「模型供应商」,分别添加三个模型:
| 模型类型 | 供应商 | 接口地址 | 模型名称 |
|---|---|---|---|
| Embedding | Xinference | http://ECS-2-IP:9997/v1 | custom-bge-large-zh-v1.5 |
| Rerank | Xinference | http://ECS-2-IP:9997/v1 | custom-bge-reranker-large |
| LLM | OpenAI-API-compatible | http://ECS-3-IP:8008/v1 | DeepSeek-R1-14B |
Embedding 和 Rerank 的 API Key 可以随便填,Xinference 默认不校验。LLM 的 API Key 也随便填,vLLM 的 OpenAI 兼容接口同样不校验。
配置完成后,建一个测试知识库,上传一份文档,看能否正常完成向量化和检索。如果检索结果为空,优先检查 Embedding 模型是否正常返回向量。
4. 避坑指南:这套环境搭建最容易翻车的五个地方
4.1 现象:Xinference 注册模型时报「model_uri not found」
原因:config.json里的model_uri路径写错了,或者模型文件没有上传到对应目录。Xinference 不会自动下载模型,必须手动把 HuggingFace 上的文件完整下载后上传。
解决:用ls -la确认模型目录下包含pytorch_model.bin、config.json、tokenizer.json、vocab.txt这几个文件。如果缺少pytorch_model.bin,说明下载的是 LoRA 适配器而不是完整模型。
4.2 现象:vLLM 启动时报「CUDA out of memory」
原因:--gpu-memory-utilization设得太高,或者--max-model-len设得太大导致 KV Cache 占用过多。14B 模型 half 精度权重约 28GB,V100 32GB 只剩 4GB 给 KV Cache,max-model-len设 5120 时如果并发请求多,很容易 OOM。
解决:先把--gpu-memory-utilization降到 0.90,--max-model-len降到 4096,--max-num-seqs降到 3,启动成功后再逐步往上调,找到稳定运行的临界值。
4.3 现象:Dify 调用 Embedding 接口超时
原因:ECS-2 的安全组没有开放 9997 端口,或者 Xinference 启动时--host设的是127.0.0.1而不是0.0.0.0。
解决:检查安全组入方向规则,确保 9997 端口对 ECS-1 的内网 IP 开放。同时确认 Xinference 启动命令里--host 0.0.0.0没有写错。
4.4 现象:Rerank 模型返回的分数全是 0 或负数
原因:输入文本格式不对。bge-reranker-large 期望的输入是 query 和 document 的配对,如果只传了 document 没传 query,或者两个字段顺序反了,打分就会异常。
解决:检查 Dify 里 Rerank 节点的配置,确认 query 字段填的是用户问题,document 字段填的是检索召回的段落。用 curl 单独测试 Rerank 接口时,请求体里必须同时包含query和documents两个字段。
4.5 现象:vLLM 服务启动后 curl 能通,但 Dify 调用报 404
原因:Dify 配置 LLM 时接口地址填的是http://ECS-3-IP:8008,但 vLLM 的 OpenAI 兼容接口路径是/v1,少写了这一层。
解决:把接口地址改成http://ECS-3-IP:8008/v1,模型名称填DeepSeek-R1-14B,和--served-model-name参数保持一致。
5. 跑通之后:怎么验证整条链路真的在工作
环境搭完只是第一步,更关键的是确认「检索→重排→生成」这条链路每个环节都在正常出力。我一般会用一个固定测试集来验证,而不是随便问一句「你好」看有没有回复。
先准备三个测试问题,分别对应知识库里明确有答案、部分相关、完全无关三种情况。然后在 Dify 的对话日志里看每个环节的耗时和输出。
Embedding 环节的验证方法是:在 Dify 知识库里搜一个关键词,看返回的段落是否和关键词语义相关。如果返回结果明显不相关,说明 Embedding 模型没有正确加载,或者知识库文档切片粒度太粗。
Rerank 环节的验证方法是:对比开启 Rerank 前后,同一个 query 返回的 Top-3 段落排序是否变化。如果排序完全没变,可能是 Rerank 模型没生效,或者候选段落数量太少(少于 3 个时 Rerank 没有发挥空间)。
LLM 环节的验证方法是:把检索到的段落和用户问题一起发给 vLLM,看生成的回答是否引用了段落里的内容。如果回答完全脱离检索结果,说明 Dify 的提示词模板里没有正确注入上下文变量。
这里有个我踩过的坑:Dify 默认的提示词模板里,上下文变量名是{{context}},但如果你在知识库配置里改了变量名,提示词里也要同步改,否则 LLM 收到的上下文是空的,生成结果自然和知识库无关。
最后一个技巧是关于模型卸载的。Xinference 启动的模型会一直占用显存,如果只是临时测试,用完记得注销:
# 注销 Rerank 模型 xinference unregister --model-type rerank --model-name custom-bge-reranker-large # 注销 Embedding 模型 xinference unregister --model-type embedding --model-name custom-bge-large-zh-v1.5不注销的话,下次启动同类型模型时 Xinference 会报「模型已存在」,还得手动去删注册记录。从那以后我每次做完测试都强制走一遍注销流程,省得下次启动时对着报错发呆。希望这套流程能帮你少走几个弯路。
本文还有配套的精品资源,点击获取