资讯动态

三台机器搭建RAG系统:Dify+Xinference+vLLM实战指南

发布时间:2026/10/16 12:42:20 来源:尧图企业网站定制
简介这份实战教程面向希望快速上手检索增强生成系统的开发者与运维人员聚焦基于DeepSeek模型搭建RAG系统的完整环境部署流程。内容从技术栈概要切入依次讲解Dify服务器、Rerank与Embedding模型服务器、DeepSeek模型服务器的分步安装部署并覆盖CUDA驱动、vLLM推理框架、Docker容器化、xinference推理工具及bge-reranker-large、bge-large-zh-v1.5等中文模型的落地配置帮助读者解决多机环境下的版本兼容与部署排错问题。资源包为1个docx文档约580KB以图文步骤与目录结构组织便于按模块查阅。目前已有326人学习。读者可据此掌握从服务器环境准备、模型选型到推理服务启动的完整链路获得可直接参照的多节点部署经验与实操思路。1. 三台机器、三个模型、一条链路这套 RAG 环境到底怎么搭很多人第一次搭 RAG 系统习惯把 Dify、Embedding、Rerank、大模型全塞进一台机器结果显存被抢爆、端口互相打架、Docker 和 conda 的环境变量互相污染最后连日志都看不懂。这份教程的价值就在于它把链路拆成了三台服务器ECS-1 只跑 Dify 做应用编排ECS-2 用 Xinference 托管 bge-reranker-large 和 bge-large-zh-v1.5 两个检索侧模型ECS-3 用 vLLM 单独拉起 DeepSeek-R1-Distill-Qwen-14B 做生成。三台机器各司其职显存不打架排查问题时也能快速定位是哪一段断了。如果你手里正好有 1 到 2 张 T4 或 V100又不想在环境上反复翻车这套拆分思路值得照着走一遍。2. 技术栈选型为什么是 Dify Xinference vLLM 这套组合2.1 三个组件各自解决什么问题RAG 的完整链路是「文档向量化 → 检索 → 重排序 → 拼上下文 → 大模型生成」。这条链路上每个环节对硬件和框架的要求完全不同硬凑在一台机器上只会互相拖累。Dify 负责的是最上层知识库管理、应用编排、对话界面、API 暴露。它本身对显卡没要求用 Docker 部署在 ECS-1 上就行CentOS 7.5 加 Docker 足够跑起来。真正吃显存的是下面两层。Embedding 和 Rerank 是检索侧的两个模型。bge-large-zh-v1.5 负责把文档切块后转成 768 维向量存进向量库bge-reranker-large 负责在召回之后对候选段落做精排。这两个模型参数量不大一张 T4 16GiB 就能同时托管用 Xinference 统一管理的好处是它支持自定义模型注册不用改框架源码就能把本地下载的模型挂上去。生成侧用 vLLM 部署 DeepSeek-R1-Distill-Qwen-14B。这个模型源自 Qwen-2.5 系列14B 参数用半精度加载大约需要 28GB 显存所以 ECS-3 选了 V100 32GiB。vLLM 的 PagedAttention 和连续批处理能把吞吐拉起来比直接用 HuggingFace transformers 推理快不少而且它自带 OpenAI 兼容的 API ServerDify 那边填个地址就能接上。2.2 版本锁定别让 CUDA 和驱动成为黑匣子这套教程里版本选得很死ECS-2 用 Ubuntu 20.04 Tesla Driver 470.223.02 CUDA 11.4 Python 3.8ECS-3 用 CentOS 7.9 CUDA 12.1 Python 3.10 vLLM 0.43。为什么要卡这么细因为 vLLM 对 CUDA 版本和 PyTorch 版本极其敏感装错一个小版本就是一堆undefined symbol报错。ECS-3 上驱动选的是 530.30.02对应 CUDA 12.1。注意教程里特别强调了一点驱动和 CUDA Toolkit 要分开装。如果你在已经装了驱动的机器上直接跑 CUDA 的.run安装包并勾选驱动选项大概率会把原有驱动覆盖掉然后nvidia-smi直接失联。正确做法是安装时取消勾选驱动只装 Toolkit再手动配环境变量。服务器系统镜像CUDAPython显卡核心组件ECS-1CentOS 7.5 64bit无要求无要求无要求Dify (Docker)ECS-2Ubuntu 20.04 Driver 47011.43.8T4 16GiBXinference bge 系列ECS-3CentOS 7.912.13.10V100 32GiBvLLM DeepSeek-14B提示三台机器的安全组要提前放行对应端口——Dify 的 Web 端口、Xinference 的 9997、vLLM 的 8008否则服务起来了但外部访问不通会浪费大量时间在排查网络上。3. ECS-2 实战用 Xinference 托管 Embedding 和 Rerank 模型3.1 安装 Xinference 并配置环境变量Xinference 是这一层的关键工具它把模型加载、推理接口、模型注册都统一了。安装本身不复杂但环境变量不配好模型文件会默认下到系统盘很容易把磁盘撑满。# 安装 xinference 完整版包含所有推理后端 pip install xinference[all] # 配置模型存储路径避免默认下到系统盘 export XINFERENCE_HOME/tmp/xinference # 验证安装是否成功 xinference --helpXINFERENCE_HOME这个变量建议写进~/.bashrc不然每次重启终端都要重新 export。/tmp/xinference只是教程里的示例路径实际部署时换成数据盘挂载点更稳妥比如/data/xinference。启动 Xinference 有两种方式调试阶段用前台启动方便看日志正式跑用后台启动# 前台启动方便观察日志 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 的默认端口教程里标注了「端口号不可变」因为 Dify 那边配置模型连接时默认指向这个端口。如果你非要改Dify 的模型配置里也要同步改否则连不上。3.2 注册并启动 bge-reranker-largeRerank 模型的作用是在向量检索召回一批候选文档后用交叉编码器对每个「问题-文档」对做相关性打分把最相关的排到前面。bge-reranker-large 在中文场景下表现稳定是很多 RAG 项目的默认选择。第一步是把模型文件下载到本地再上传服务器。HuggingFace 下载可以用huggingface-cli或者git lfs clone模型文件大概 1.3GB 左右。上传到服务器后需要写一个 config.json 告诉 Xinference 这个模型在哪、是什么类型{ 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是自定义的注册名后面启动和调用都用这个名字。model_uri必须用file://前缀加绝对路径写相对路径会找不到模型。language字段声明支持中英文不影响推理但影响 Xinference 的模型分类展示。注册和启动的命令如下# 注册自定义 rerank 模型--persist 表示持久化注册信息 xinference register --model-type rerank --file model.json --persist # 检查是否注册成功 xinference registrations --model-type rerank # 启动模型 xinference launch --model-name custom-bge-reranker-large --model-type rerank--persist这个参数很关键。不加的话Xinference 重启后注册信息就丢了又得重新注册一遍。启动成功后Xinference 会输出一个 model_uidDify 配置 rerank 模型时需要填这个 uid。3.3 注册并启动 bge-large-zh-v1.5Embedding 模型负责把文本转成向量是知识库构建的基础。bge-large-zh-v1.5 输出 768 维向量最大输入 512 token中文语义相似度任务上表现不错。config.json 的写法和 rerank 略有不同多了dimensions和max_tokens两个字段{ 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必须和模型实际输出维度一致写错了 Dify 那边建知识库时向量维度对不上检索会直接报错。max_tokens是单次输入的最大 token 数超过会被截断所以文档切块时每块不要超过 512 token。# 注册 embedding 模型 xinference register --model-type embedding --file model.json --persist # 检查注册结果 xinference registrations --model-type 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 维的向量数组说明模型正常工作。如果返回 404检查 model_uid 是否填对如果返回 500看 Xinference 日志里是不是显存不够。4. ECS-3 实战vLLM 部署 DeepSeek-R1-Distill-Qwen-14B4.1 驱动与 CUDA 安装的先后顺序ECS-3 的环境配置是整套流程里最容易翻车的一步。教程里明确写了先装 NVIDIA 驱动 530.30.02再单独装 CUDA Toolkit 12.1安装 CUDA 时取消勾选驱动选项。# 验证驱动是否安装成功 nvidia-smi # 验证 CUDA Toolkit 是否安装成功 nvcc -V这两条命令输出的 CUDA 版本要一致。如果nvidia-smi显示 12.1 而nvcc -V显示 11.x说明系统里存在多个 CUDA 版本环境变量指向了旧版本。这时候需要检查~/.bashrc里的 PATH 和 LD_LIBRARY_PATH# 编辑环境变量 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 ~/.bashrcLD_LIBRARY_PATH里写lib64还是lib取决于系统架构x86_64 一般是lib64。写错了会导致编译时找不到 CUDA 库。4.2 Python 环境与 PyTorch 版本匹配vLLM 0.43 对 PyTorch 版本有硬性要求教程里指定的是 torch 2.3.0 cu121。用 conda 创建独立环境避免和系统 Python 冲突# 创建 Python 3.10 虚拟环境 conda create -n myenv python3.10 -y # 激活环境 conda activate myenv # 安装指定版本的 PyTorch索引指向 cu121 pip install torch2.3.0 torchvision0.18.0 torchaudio2.3.0 \ --index-url https://download.pytorch.org/whl/cu121--index-url这个参数不能省。默认的 PyPI 源里 torch 是 CPU 版本装上去 vLLM 启动时会报「no CUDA-capable device detected」。指定 cu121 索引才能拉到 GPU 版本。4.3 安装 vLLM 并启动模型服务vLLM 安装本身一条命令但过程中会出现依赖版本冲突按报错提示逐个装指定版本即可# 安装 vLLM 0.43 pip install vllm0.43模型文件提前下载好上传到服务器14B 模型半精度大约 28GB上传需要一些时间。启动命令参数比较多逐个解释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指定半精度加载14B 模型用 float32 会直接 OOM。--tensor-parallel-size 1表示单卡推理如果你有两张卡可以改成 2 做张量并行。--max-model-len 5120限制上下文长度设太大 KV Cache 会吃掉大量显存。--enforce-eager关闭 CUDA Graph 捕获启动更快但推理稍慢调试阶段建议开着。--gpu-memory-utilization 0.95让 vLLM 占用 95% 显存留一点给系统。--max-num-seqs 5限制并发序列数T4 或 V100 上设太高会排队。启动成功后用 curl 测试 OpenAI 兼容接口curl http://localhost:8008/v1/chat/completions \ -H Content-Type: application/json \ -d { model: DeepSeek-R1-14B, messages: [{role: user, content: 你好}], max_tokens: 100 }能正常返回生成结果说明 ECS-3 这一层通了。回到 Dify 的管理后台在模型供应商里添加 OpenAI 兼容接口Base URL 填http://ECS-3内网IP:8008/v1模型名填DeepSeek-R1-14B保存后就能在应用里调用了。5. 避坑排查这套环境里最容易翻车的五个地方5.1 Xinference 注册模型后重启丢失现象注册完自定义模型Xinference 服务重启后xinference registrations列表空了Dify 那边报模型不存在。原因注册时没加--persist参数注册信息只存在内存里进程退出就没了。解决重新注册时加上--persist注册信息会写入XINFERENCE_HOME下的配置文件重启后自动加载。5.2 vLLM 启动报 CUDA out of memory现象--gpu-memory-utilization 0.95启动后报 OOM但nvidia-smi看显存明明够。原因--max-model-len设太大KV Cache 预分配吃掉了大量显存。14B 模型在 5120 上下文下 KV Cache 大约需要 4-6GB如果设成 32768光 KV Cache 就要 20GB 以上。解决先把--max-model-len降到 4096 或 5120 试跑确认能起来后再逐步往上调。同时--gpu-memory-utilization可以降到 0.90 留更多余量。5.3 Dify 连接 Xinference 报超时现象Dify 里配置 Embedding 模型时填了 ECS-2 的地址和 9997 端口保存时提示连接超时。原因ECS-2 的安全组没放行 9997 端口或者 Xinference 启动时--host写的是127.0.0.1而不是0.0.0.0。解决检查安全组入方向规则确认 9997 端口对 ECS-1 的内网 IP 开放。同时确认 Xinference 启动命令里--host 0.0.0.0绑定到所有网卡。5.4 CUDA 版本不一致导致 vLLM 编译失败现象pip install vllm0.43过程中报nvcc fatal: Unsupported gpu architecture或编译到一半失败。原因系统里存在多个 CUDA 版本nvcc指向了旧版本和 PyTorch 编译时用的 CUDA 版本不匹配。解决which nvcc确认当前使用的 CUDA 路径检查~/.bashrc里 PATH 的顺序确保/usr/local/cuda-12.1/bin在最前面。必要时用update-alternatives切换默认 CUDA 版本。5.5 模型文件路径写错导致加载失败现象Xinference 启动模型时报FileNotFoundError或model_uri not accessible。原因config.json 里model_uri写的是相对路径或者路径拼写有误或者模型文件权限不对Xinference 进程用户没有读权限。解决model_uri必须用file://加绝对路径比如file:///data/models/bge-large-zh-v1.5。确认路径下确实有config.json、pytorch_model.bin等模型文件。用chmod -R 755确保 Xinference 运行用户有读权限。6. 验证链路是否真正打通从一条 query 看完整数据流环境搭完之后怎么确认三台机器真的串起来了我一般会构造一条测试 query从 Dify 的日志和 vLLM 的日志两头对照着看。先在 Dify 里建一个最简单的知识库应用上传一份测试文档然后提一个问题。正常情况下Dify 的日志会显示先调用 ECS-2 的 embedding 接口把 query 转向量然后检索向量库召回候选段落再调用 ECS-2 的 rerank 接口对候选做精排最后把 top-k 段落拼进 prompt 发给 ECS-3 的 vLLM 接口生成回答。如果中间某一步断了日志会停在对应的位置。比如 embedding 调用失败日志里会看到Connection refused指向 ECS-2 的 9997 端口如果 rerank 返回空结果检查 Xinference 那边模型是否还在运行如果 vLLM 返回超时看 ECS-3 的 GPU 利用率是不是打满了。一个实用的技巧是在 ECS-2 和 ECS-3 上分别开一个终端跑watch -n 1 nvidia-smi提问题时观察显存和 GPU 利用率的变化。正常流程下ECS-2 的显存会在 embedding 和 rerank 调用时短暂上升ECS-3 的 GPU 利用率会在生成阶段飙到 80% 以上。如果某台机器全程没动静说明请求根本没到那一层。还有一点值得注意Dify 默认的 rerank 超时时间比较短如果 ECS-2 的 T4 同时跑 embedding 和 rerank并发高的时候 rerank 可能来不及返回。可以在 Dify 的模型配置里把超时时间从默认的 10 秒调到 30 秒给 T4 留够推理时间。从那以后我每次搭完 RAG 环境都会先用一条 query 把三台机器的日志和 GPU 状态对一遍确认数据流完整走通再开始灌知识库。这个习惯帮我省了很多「以为配好了其实没通」的返工时间。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑