ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于DeepSeek的RAG环境搭建:三台机器部署Dify、xinference与vLLM实战

基于DeepSeek的RAG环境搭建:三台机器部署Dify、xinference与vLLM实战

简介:这份文档面向希望快速上手检索增强生成系统的开发者与运维人员,围绕基于DeepSeek搭建RAG环境这一目标,系统梳理了从技术栈认知到多机部署的完整路径。内容涵盖CUDA并行计算、vLLM大模型推理、Docker容器化等关键工具,并按Dify服务器、Rerank与Embedding模型服务器、DeepSeek模型服务器三台ECS实例逐步展开,涉及xinference安装、bge-reranker-large与bge-large-zh-v1.5部署、环境版本选定及Python依赖配置等实操细节。资源包为1个docx文档,约580KB,目录结构清晰,便于按模块查阅。目前已有326人学习。读者可借此掌握多节点RAG系统的环境搭建思路、模型选型依据与常见配置要点,适合作为深度学习模型部署与检索增强应用的入门实战参考。

1. 三台机器、三个模型:这套 RAG 环境为什么总在第二步翻车

RAG 系统环境搭建这件事,说难不难,说简单也真不简单。我见过太多人卡在同一个地方:Dify 用 Docker 两行命令就跑起来了,心里正美,结果到 Rerank 和 Embedding 模型部署那一步,xinference 注册完模型死活加载不出来,或者 vLLM 启动直接报 CUDA 版本不匹配。这套基于 DeepSeek 的 RAG 环境,核心就三台机器——ECS-1 跑 Dify 做应用编排,ECS-2 用 xinference 挂 Rerank 和 Embedding 模型,ECS-3 用 vLLM 起 DeepSeek-R1-Distill-Qwen-14B 做生成。三台机器的系统、CUDA 版本、Python 版本全不一样,装错一个环节,后面全得推倒重来。这篇笔记适合正在搭 RAG 环境、被模型部署和版本兼容折腾过的开发者,我会把每台机器的安装步骤、参数取舍和踩过的坑都摊开讲。

2. 环境规划与版本选型:三台 ECS 的系统、CUDA 和 Python 怎么定

2.1 三台服务器的角色划分与硬件要求

这套 RAG 环境把负载拆到三台机器上,每台只干一件事,互不干扰。ECS-1 跑 Dify,对显卡没要求,用 Docker 部署就行,系统选 CentOS 7.5 64bit。ECS-2 负责 Rerank 和 Embedding 两个模型,显卡用 1 张 NVIDIA Tesla T4(16GiB 显存),镜像选 Ubuntu 20.04 server 64bit,自带 Tesla Driver 470.223.02 和 CUDA 11.4,Python 用 3.8。ECS-3 跑 DeepSeek 大模型,显卡是 1 张 NVIDIA Tesla V100(32GiB 显存),系统 CentOS 7.9 64bit,CUDA 11.4,Python 3.8。

这里有个容易忽略的点:ECS-2 和 ECS-3 虽然都写着 CUDA 11.4,但 ECS-3 后面要装 vLLM 0.43,实际需要把 CUDA 升到 12.1,Python 也要换成 3.10。所以 ECS-3 的最终环境版本是 CentOS 7.9 + CUDA 12.1 + Python 3.10 + vLLM 0.43。这个版本组合不是随便定的,vLLM 0.43 对 CUDA 和 PyTorch 的版本要求很死,装错了就是一堆编译报错。

提示:如果你的 ECS-2 和 ECS-3 用的是同一批机器,建议先把 ECS-3 的 CUDA 升级做完再装 ECS-2 的 xinference,避免驱动版本互相干扰。

2.2 模型选型与显存占用估算

三个模型各司其职。DeepSeek-R1-Distill-Qwen-14B 是生成模型,源自 Qwen-2.5 系列蒸馏而来,14B 参数用 half 精度加载,显存占用大概 28GB 左右,V100 的 32GiB 刚好够用,但要把--gpu-memory-utilization设到 0.95 才能吃满。BAAI/bge-reranker-large 是检索结果重排序模型,参数量小,T4 的 16GiB 绰绰有余。BAAI/bge-large-zh-v1.5 是文本向量化模型,输出 768 维向量,max_tokens 512,也是轻量级。

选型上有个取舍:bge-reranker-large 和 bge-large-zh-v1.5 都是 BAAI 出的中文优化模型,在中文 RAG 场景下比通用模型效果好不少。DeepSeek-R1-Distill-Qwen-14B 选 14B 而不是 7B 或 32B,是因为 14B 在 V100 单卡上刚好能跑,7B 效果不够,32B 显存装不下。如果你的显卡是 A100 40G 或 80G,可以考虑上更大的模型,但 14B 对大多数知识库问答场景已经够用了。

2.3 版本兼容性对照表

把三台机器的环境版本列成一张表,装之前先对一遍,能省掉后面很多返工。

服务器系统CUDAPython关键工具显卡
ECS-1CentOS 7.5无要求无要求Docker + Dify无要求
ECS-2Ubuntu 20.0411.43.8xinferenceTesla T4 16GiB
ECS-3CentOS 7.912.13.10vLLM 0.43Tesla V100 32GiB

这张表里最容易出问题的是 ECS-3 的 CUDA 12.1 和驱动版本。驱动要选 530.30.02,这个版本对应 CUDA 12.1,装的时候注意把驱动和 CUDA Toolkit 分开装,不然会冲突。

3. ECS-2 部署实战:xinference 挂载 Rerank 与 Embedding 模型

3.1 xinference 安装与环境变量配置

ECS-2 上先装 xinference。官方推荐用 pip 装全量包,命令如下:

# 安装 xinference 全量包,包含所有推理后端依赖 pip install "xinference[all]"

装完之后配置环境变量,指定模型缓存目录,避免默认路径占满系统盘:

# 设置 xinference 的模型存储路径 export XINFERENCE_HOME=/tmp/xinference # 启动 xinference 本地服务,监听所有网卡,端口 9997 xinference-local --host 0.0.0.0 --port 9997

这里XINFERENCE_HOME我一般会设到数据盘挂载的目录,比如/data/xinference,因为模型文件动辄几个 GB,放/tmp重启就没了。端口 9997 是 xinference 的默认端口,后面 Dify 配置模型时要填这个地址,所以不要随便改。

验证安装是否成功:

# 查看 xinference 命令行帮助,确认安装完整 xinference --help

如果这条命令能正常输出帮助信息,说明基础环境没问题。接下来启动服务,测试阶段可以直接前台跑,方便看日志:

# 前台启动,方便观察日志输出 xinference-local --host 0.0.0.0 --port 9997

生产环境用后台启动:

# 后台启动,日志重定向到 nohup.out nohup xinference-local --host 0.0.0.0 --port 9997 &> nohup.out &

注意:端口号 9997 在 xinference 启动后不可变,如果这个端口被占用,要么杀掉占用进程,要么重新配置。我遇到过用 9997 端口跑其他服务的,启动直接报Address already in use,查了半天才发现是之前测试留下的进程没关。

3.2 注册 bge-reranker-large 自定义模型

xinference 内置了一些模型,但 bge-reranker-large 需要手动注册。先从 huggingface 下载模型文件到本地,再上传到服务器。下载这一步和 xinference 安装可以同步进行,节省时间。

模型文件放好之后,写一个 config.json:

{ "model_name": "custom-bge-reranker-large", "type": "normal", "language": ["en", "zh"], "model_id": "BAAI/bge-reranker-large", "model_uri": "file:///path/to/bge-reranker-large" }

几个参数说明一下。model_name是自定义名称,后面启动模型时用这个名称,可以随便取,但建议带上custom-前缀方便区分。type固定写normal。language指定支持的语言,中英文都写上。model_id是模型在 huggingface 上的原始 ID,xinference 用它来识别模型架构。model_uri是本地模型文件的绝对路径,file://前缀不能少。

注册命令:

# 将自定义 rerank 模型注册到 xinference,--persist 表示持久化注册信息 xinference register --model-type rerank --file model.json --persist

--persist这个参数很关键,不加的话重启 xinference 后注册信息就丢了,又得重新注册一遍。注册完检查一下:

# 列出所有已注册的 rerank 模型 xinference registrations --model-type rerank

如果输出里能看到custom-bge-reranker-large,说明注册成功。启动模型:

# 启动自定义 rerank 模型 xinference launch --model-name custom-bge-reranker-large --model-type rerank

启动过程会加载模型到显存,T4 加载这个模型大概十几秒。如果卡住不动,先看日志里有没有报错,常见的是模型路径写错或者文件不完整。

3.3 注册 bge-large-zh-v1.5 自定义模型

Embedding 模型的注册流程和 Rerank 几乎一样,区别在 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:///path/to/bge-large-zh-v1.5" }

这里多了两个参数:dimensions是向量维度,bge-large-zh-v1.5 输出 768 维,这个值必须和模型实际输出一致,写错了 Dify 那边检索会报维度不匹配。max_tokens是单次输入的最大 token 数,512 是模型的上限,超过会被截断。

注册和启动命令:

# 注册 embedding 模型 xinference register --model-type embedding --file model.json --persist # 检查注册结果 xinference registrations --model-type embedding # 启动 embedding 模型 xinference launch --model-name custom-bge-large-zh-v1.5 --model-type embedding

两个模型都启动后,xinference 会分别分配端口,在启动日志里能看到。记下这两个端口,Dify 配置模型服务时要用。

3.4 模型注销与重新注册

调试阶段经常需要改 config.json 重新注册,这时候要先注销旧模型:

# 注销 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

注销之后重新走一遍注册和启动流程。注意如果模型已经 launch 了,要先在 xinference 的 Web UI 里停掉或者用 API 停掉,不然注销会报模型正在使用中。

4. ECS-3 部署实战:CUDA 12.1 与 vLLM 跑 DeepSeek-14B

4.1 驱动与 CUDA 安装的先后顺序

ECS-3 的驱动和 CUDA 安装有个坑:如果你在装 CUDA Toolkit 的时候勾选了安装驱动,会和之前单独装的驱动冲突,导致nvidia-smi和nvcc -V显示的版本对不上。正确做法是先单独装驱动,再单独装 CUDA Toolkit,装 CUDA 的时候取消勾选驱动。

驱动选 530.30.02 版本,这个版本对应 CUDA 12.1。去 NVIDIA 官网下载 x86_64 架构的 runfile,安装:

# 给 runfile 加执行权限 chmod +x NVIDIA-Linux-x86_64-530.30.02.run # 安装驱动,-no-opengl-files 避免覆盖系统 OpenGL 库 ./NVIDIA-Linux-x86_64-530.30.02.run -no-opengl-files

装完驱动后装 CUDA Toolkit 12.1,同样用 runfile,安装时在组件选择界面把 Driver 那一项的勾去掉:

# 安装 CUDA Toolkit,不安装驱动 ./cuda_12.1.0_530.30.02_linux.run --toolkit --silent --override

配置环境变量:

# 编辑 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

验证:

# 查看 CUDA 编译器版本 nvcc -V # 查看驱动和 GPU 状态 nvidia-smi

nvcc -V输出 CUDA 12.1,nvidia-smi右上角显示 CUDA Version 12.1,两者一致就对了。如果不一致,大概率是环境变量没生效或者装 CUDA 时把驱动覆盖了。

4.2 Python 3.10 虚拟环境与 PyTorch 依赖

用 conda 创建 Python 3.10 环境:

# 创建名为 myenv 的虚拟环境,Python 版本 3.10 conda create -n myenv python=3.10 -y # 激活环境 conda activate myenv

装 PyTorch 的时候要注意版本匹配。vLLM 0.43 对 torch 版本有要求,直接pip install torch装最新版会报错。指定 torch 2.3.0 和 CUDA 12.1 的索引:

# 安装指定版本的 PyTorch,匹配 CUDA 12.1 pip install torch==2.3.0 torchvision==0.18.0 torchaudio==2.3.0 --index-url https://download.pytorch.org/whl/cu121

这三个包的版本必须一起指定,torch、torchvision、torchaudio 之间有版本对应关系,单独升级其中一个会导致依赖冲突。--index-url指向 PyTorch 官方的 CUDA 12.1 仓库,不加这个参数会从默认源装 CPU 版本。

4.3 vLLM 0.43 安装与依赖冲突处理

装 vLLM:

# 安装 vllm 0.43 版本 pip install vllm==0.43

安装过程中大概率会遇到依赖版本报错,比如transformers版本不兼容、pydantic版本冲突等。我的做法是看报错信息里提示的版本要求,手动装指定版本。常见的有:

# 根据报错提示,手动安装指定版本的依赖 pip install transformers==4.42.0 pip install pydantic==2.7.0

装完之后用pip check检查依赖完整性:

# 检查已安装包的依赖冲突 pip check

如果有冲突,根据提示逐个解决。vLLM 的依赖链比较长,耐心点一个个装,别想着一次性搞定。

4.4 启动 DeepSeek-R1-Distill-Qwen-14B 服务

模型文件提前下载好上传到服务器,比如放在/root/work/ds/pretrained。启动命令:

# 启动 vLLM OpenAI 兼容 API 服务 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 &

逐个参数解释。--model指定模型路径。--dtype half用半精度加载,省显存。--trust-remote-code允许加载模型自带的代码,DeepSeek 系列模型需要这个。--tensor-parallel-size 1单卡推理,如果是多卡就改成卡数。--max-model-len 5120最大上下文长度,设太大显存不够,5120 是 14B 模型在 V100 上的安全值。--enforce-eager禁用 CUDA graph,虽然损失一点性能,但能避免一些显存碎片问题。--gpu-memory-utilization 0.95显存利用率,V100 32G 跑 14B half 精度刚好够,设低了浪费显存。--max-num-batched-tokens 5120和--max-num-seqs 5控制并发,单卡场景下不要设太高,不然容易 OOM。--served-model-name是 API 里调用的模型名称,Dify 配置时填这个。--port 8008服务端口。

启动后看到Uvicorn running on http://0.0.0.0:8008就说明服务起来了。第一次加载模型会花几分钟,耐心等。

5. 避坑排查:这套环境最容易翻车的五个地方

5.1 xinference 注册模型后 launch 报模型不存在

现象:xinference register显示成功,xinference registrations也能看到,但xinference launch报Model not found。

原因:注册时--persist没加,或者 config.json 里的model_name和 launch 时--model-name不一致。还有一种情况是 xinference 服务重启后注册信息丢失。

解决:注册时务必加--persist,launch 前先用xinference registrations确认模型在列表里,名称逐字核对。

5.2 vLLM 启动报 CUDA 版本不匹配

现象:RuntimeError: CUDA error: no kernel image is available for execution on the device或者torch.cuda.is_available()返回 False。

原因:PyTorch 装的是 CPU 版本,或者 CUDA 版本和 PyTorch 编译时的 CUDA 版本不一致。常见于pip install torch没加--index-url。

解决:卸载 torch 重新装,指定--index-url https://download.pytorch.org/whl/cu121。装完用python -c "import torch; print(torch.version.cuda)"确认输出 12.1。

5.3 nvcc 和 nvidia-smi 显示的 CUDA 版本不一致

现象:nvcc -V显示 12.1,nvidia-smi显示 11.4,或者反过来。

原因:装 CUDA Toolkit 时勾选了安装驱动,把之前的驱动覆盖了。或者环境变量PATH里指向了旧版 CUDA。

解决:重装驱动,再重装 CUDA Toolkit 并取消驱动勾选。检查~/.bashrc里的PATH和LD_LIBRARY_PATH是否指向正确的 CUDA 目录。

5.4 Dify 调用 Embedding 模型报维度不匹配

现象:Dify 知识库检索时报Vector dimension mismatch。

原因:config.json 里的dimensions写错了,或者 Dify 里配置的向量维度与模型实际输出不一致。bge-large-zh-v1.5 输出 768 维,写 512 或 1024 都会报错。

解决:确认 config.json 里dimensions为 768,Dify 模型配置里也填 768。

5.5 vLLM 启动后 OOM 或推理极慢

现象:启动时显存不足报错,或者启动成功但推理速度极慢。

原因:--gpu-memory-utilization设太高导致显存碎片,或者--max-model-len设太大。--enforce-eager没加的话 CUDA graph 可能占用额外显存。

解决:把--gpu-memory-utilization降到 0.90,--max-model-len降到 4096,加上--enforce-eager。如果还是 OOM,考虑量化加载或者换更大显存的卡。

6. 装完怎么验证:从 xinference 到 vLLM 的连通性检查

环境装完不算完,得验证三台机器之间的调用链路是通的。我一般按这个顺序走一遍。

先验证 ECS-2 的 xinference 服务。浏览器打开http://ECS-2-IP:9997,能看到 xinference 的 Web UI 就说明服务正常。在 UI 里找到已启动的 rerank 和 embedding 模型,分别点进去看状态是不是 running。也可以用 curl 直接测:

# 测试 xinference 的 rerank 接口 curl -X POST http://ECS-2-IP:9997/v1/rerank \ -H "Content-Type: application/json" \ -d '{"model": "custom-bge-reranker-large", "query": "测试查询", "documents": ["文档1", "文档2"]}'

返回结果里包含每个文档的 relevance score 就说明 rerank 模型工作正常。embedding 模型类似,调/v1/embeddings接口,看返回的向量维度是不是 768。

再验证 ECS-3 的 vLLM 服务:

# 测试 vLLM 的 OpenAI 兼容接口 curl http://ECS-3-IP:8008/v1/models

返回 JSON 里能看到DeepSeek-R1-14B这个模型 ID 就对了。再发一个对话请求:

# 测试模型推理 curl http://ECS-3-IP:8008/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model": "DeepSeek-R1-14B", "messages": [{"role": "user", "content": "你好"}]}'

能正常返回生成内容,说明 vLLM 服务没问题。

最后在 ECS-1 的 Dify 里配置模型。进入 Dify 的设置页面,模型供应商选 OpenAI-API-compatible,分别填 ECS-3 的 vLLM 地址和 ECS-2 的 xinference 地址。配置完在 Dify 里建一个测试知识库,上传一个文档,看能不能正常向量化、检索和生成回答。这一步走通,整套 RAG 环境就算跑起来了。

有个细节值得注意:Dify 调用 xinference 的 embedding 模型时,如果知识库文档比较多,建议把max_tokens设成 512 以下,避免单次请求超时。我一般会在 Dify 的模型配置里把超时时间调到 60 秒,给 embedding 留足处理时间。

从那以后我每次搭完这套环境,都会先跑一遍 curl 验证三台机器的接口,再进 Dify 做端到端测试,确认没问题才交给业务方用。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进