在大模型时代,单节点 GPU 资源往往难以满足大模型(如 7B/13B 参数模型)的部署需求。借助 Ray 分布式框架,我们可以轻松实现跨节点 GPU 资源调度,让大模型在多节点间高效运行。本文将以 DeepSeek-llm-7B-Chat 模型为例,详细讲解如何通过 Ray 搭建跨节点集群,结合 vLLM 实现分布式推理,并解决部署过程中的常见问题。

一、背景与目标

为什么需要跨节点 GPU 调用?

  • 模型规模限制:7B 参数的 DeepSeek 模型单卡可加载,但更大的模型(如 33B)单卡显存不足,需多卡并行。
  • 资源利用率:跨节点调用可整合多台服务器的 GPU 资源,避免单节点资源闲置。
  • 分布式推理优势:通过 Ray 的张量并行(Tensor Parallelism),模型层可拆分到不同节点的 GPU,提升推理效率。

本文目标

  • 搭建包含 1 个主节点、2 个工作节点的 Ray 集群。
  • 跨节点调用 2 张 GPU,用 vLLM 部署 DeepSeek-llm-7B-Chat 模型。
  • 实现 OpenAI 兼容的 API 服务,支持客户端调用。

二、环境准备

硬件要求

  • 节点数量:3 台服务器(1 主 2 从,支持 GPU)。
    • 主节点(master):192.168.2.221,至少 1 张 GPU(本文用 Tesla V100-32GB)。
    • 工作节点 1(worker1):192.168.2.226,至少 1 张 GPU。
    • 工作节点 2(worker2):192.168.2.227,至少 1 张 GPU。
  • 网络:节点间内网互通(推荐 10Gbps 以上带宽),支持 SSH 免密登录。

软件要求

工具 / 库版本作用
Python3.9运行环境
Ray2.9.0分布式集群管理
vLLM0.9.2高效大模型推理引擎
CUDA11.8GPU 加速
DeepSeek-llm-7B-Chat-目标部署模型

三、详细部署步骤

步骤 1:全节点初始化环境(所有节点执行)

1.1 安装系统依赖

解决后续可能出现的Python.h缺失问题(编译 C 扩展时需要):

# 基于CentOS/RHEL的系统
dnf install -y python3-devel gcc gcc-c++# 基于Ubuntu的系统
# apt-get install -y python3-dev gcc g++
1.2 创建虚拟环境

统一环境避免依赖冲突:

# 安装virtualenv
pip3 install virtualenv# 创建并激活虚拟环境
cd /opt
virtualenv vllm_env --python=python3.9
source vllm_env/bin/activate  # 激活环境(后续所有操作均在此环境中执行)
1.3 安装核心依赖
# 安装Ray(包含集群管理和客户端组件)
pip install "ray[default,client]" --upgrade# 安装vLLM(支持分布式推理)
pip install vllm==0.9.2# 安装其他工具(可选,用于测试)
pip install requests  # 用于发送API请求

步骤 2:搭建 Ray 分布式集群

2.1 启动主节点(master:192.168.2.221)
# 启动Ray主节点,指定IP、端口和Dashboard
ray start --head \--node-ip-address 192.168.2.221 \  # 主节点IP--port 6379 \                      # 端口(集群元数据存储)--dashboard-host 0.0.0.0 \         # 允许外部访问Dashboard--dashboard-port 8265 \            # Dashboard端口(用于监控集群)--include-dashboard=True \         # 启用Dashboard

启动成功后,会显示工作节点加入命令(需记录):

To add another node to this Ray cluster, run:ray start --address='192.168.2.221:6379'
2.2 加入工作节点(worker1:192.168.2.226 和 worker2:192.168.2.227)

在两个工作节点分别执行以下命令,加入主节点集群:

# 激活虚拟环境(同主节点路径)
source /opt/vllm_env/bin/activate# 加入集群(使用主节点输出的地址)
ray start \--address '192.168.2.221:6379' \  # 主节点地址--node-ip-address 192.168.2.226   # 当前工作节点IP(worker1填226,worker2填227)
2.3 验证集群状态(主节点执行)
# 查看集群节点信息
ray status

预期输出(显示 3 个节点,2 张 GPU 可用):

Node status
---------------------------------------------------------------
Healthy:1 node_abc... (192.168.2.221)1 node_def... (192.168.2.226)1 node_ghi... (192.168.2.227)
Resources
---------------------------------------------------------------
Total Usage: 0.0/192.0 CPU, 0.0/2.0 GPU  # 2张GPU可用

步骤 3:部署 DeepSeek 模型(主节点执行)

3.1 准备模型

将 DeepSeek-llm-7B-Chat 模型下载到所有节点均可访问的路径(推荐用 NFS 共享,避免多节点重复下载):

# 示例:通过Hugging Face Hub下载(需提前登录hf-cli)
huggingface-cli download deepseek-ai/deepseek-llm-7b-chat --local-dir /data/storage/data/VLLM_MODE/deepseek-llm-7b-chat
3.2 启动 vLLM 服务(支持跨节点 GPU 调用)
# 激活虚拟环境
source /opt/vllm_env/bin/activate# 设置Ray集群地址
export RAY_ADDRESS="192.168.2.221:6379"# 启动OpenAI兼容的API服务
python -m vllm.entrypoints.openai.api_server \--model /data/storage/data/VLLM_MODE/deepseek-llm-7b-chat \  # 模型路径--port 9001 \                                              # API服务端口--host 0.0.0.0 \                                           # 允许外部访问--tensor-parallel-size 2 \                                 # 张量并行数(=总GPU数)--distributed-executor-backend ray \                       # 使用Ray作为分布式后端--gpu-memory-utilization 0.9                               # GPU内存利用率(90%)

启动成功的关键日志:

步骤 4:验证跨节点 GPU 调用

4.1 检查 GPU 使用情况(工作节点执行)

在 worker1(192.168.2.226)和 worker2(192.168.2.227)分别执行nvidia-smi,可看到 GPU 被 vLLM 进程占用:

nvidia-smi

预期输出(关键信息):

+-----------------------------------------------------------------------------+
| Processes:                                                                    |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=============================================================================|
|    0   N/A  N/A    872773      C   ...vllm_env/bin/python                   28511MiB |  # vLLM进程占用
+-----------------------------------------------------------------------------+

说明两个节点的 GPU 均被成功调用(每张卡负载约 28GB,符合 7B 模型 + 90% 内存利用率的预期)。

4.2 测试模型推理(客户端执行)

通过 API 发送请求测试:

# 发送推理请求
curl http://192.168.2.221:9001/v1/chat/completions \-H "Content-Type: application/json" \-d '{"model": "deepseek-llm-7b-chat","messages": [{"role": "user", "content": "介绍一下Ray和vLLM的关系"}]}'

成功响应示例(部分):

json

{"id": "chatcmpl-xxx","object": "chat.completion","created": 1689523456,"model": "deepseek-llm-7b-chat","choices": [{"message": {"role": "assistant","content": "Ray是一个分布式计算框架,可用于管理跨节点的GPU资源...vLLM是高效的大模型推理引擎,通过Ray实现分布式部署..."},"finish_reason": "stop","index": 0}]
}

步骤 5:Ray 集群的停止与清理

当需要更新配置或重启集群时,需彻底停止 Ray 进程并清理残留数据,避免旧会话信息干扰:

# 停止当前节点的 Ray 进程
ray stop# 若 ray stop 无效,直接 kill 残留进程(谨慎使用,确保只 kill Ray 相关进程)
pkill -f ray# 清理 Ray 临时目录(包含Redis数据、会话信息等)
rm -rf /tmp/ray/*

注意:以上命令需在所有节点执行(主节点 + 工作节点),确保集群完全停止。清理完成后,可重新执行步骤 2 和步骤 3 启动新集群。

四、常见问题与解决方案

问题 1:Python.h: No such file or directory

  • 原因:缺少 Python 开发库,编译 C 扩展时失败。
  • 解决:安装python3-devel
    dnf install python3-devel  # CentOS/RHEL
    # 或 apt-get install python3-dev  # Ubuntu
    

问题 2:ModuleNotFoundError: No module named 'vllm'

  • 原因:工作节点未安装 vLLM。
  • 解决:在所有工作节点的虚拟环境中安装 vLLM:
    source /opt/vllm_env/bin/activate
    pip install vllm==0.9.2
    

问题 3:Ray Client 连接超时

  • 原因:6379 端口未开放或 Ray Client 服务未启动。
  • 解决
    # 主节点开放端口
    firewall-cmd --add-port=6379/tcp --permanent
    firewall-cmd --reload# 重启Ray时显式指定Client端口
    ray start --head ... --ray-client-server-port 6379
    

问题 4:GPU 资源不足

  • 原因tensor-parallel-size超过实际 GPU 数量。
  • 解决:确保--tensor-parallel-size等于集群总 GPU 数(本文为 2)。
关键代码
pip install "ray[default]" --upgrade
ray start --head   --node-ip-address 192.168.2.221   --port 6379   --dashboard-host 0.0.0.0    --dashboard-port 8265   --include-dashboard=True  创建master ray主节点
ray start   --address '192.168.2.221:6379'   --node-ip-address 192.168.2.226 
ray start   --address '192.168.2.221:6379'   --node-ip-address 192.168.2.227cd /opt/
source vllm_env/bin/activateexport HF_ENDPOINT=https://hf-mirror.com 
huggingface-cli download --resume-download deepseek-ai/deepseek-llm-7b-chat --local-dir /data/storage/data/VLLM_MODE/deepseek-llm-7b-chatRAY_ADDRESS="192.168.2.221:6379" python -m vllm.entrypoints.openai.api_server   --model /data/storage/data/VLLM_MODE/deepseek-llm-7b-chat   --port 9001 --host 0.0.0.0    --tensor-parallel-size 2   --distributed-executor-backend ray  --gpu-memory-utilization 0.9

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/914872.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914872.shtml
英文地址,请注明出处:http://en.pswp.cn/news/914872.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速了解 HTTPS

1. 引入 在 HTTP 协议 章节的 reference 段,曾提到过 HTTPS。这里对HTTPS进行详细介绍。 HTTPS 是在 HTTP 的基础上,引入了一个加密层 (SSL)。HTTP 是明文传输的 (不安全)。当下所见到的大部分网站都是 HTTPS 的。 起初是拜运营商劫持所赐(…

mysql备份与视图

要求:1.将mydb9_stusys数据库下的student、sc 和course表,备份到本地主机保存为st_msg_bak.sql文件,然后将数据表恢复到自建的db_test数据库中;2.在db_test数据库创建一视图 stu_info,查询全体学生的姓名,性别,课程名&…

【数据结构】 链表 + 手动实现单链表和双链表的接口(图文并茂附完整源码)

文章目录 一、 链表的概念及结构 二、链表的分类 ​编辑 三、手动实现单链表 1、定义单链表的一个节点 2、打印单链表 3、创建新节点 4、单链表的尾插 5、单链表的头插 6、单链表的尾删 7、单链表的头删 8、单链表的查找 9、在指定位置之前插入一个新节点 10、在指…

Go语言时间控制:定时器技术详细指南

1. 定时器基础:从 time.Sleep 到 time.Timer 的进化为什么 time.Sleep 不够好?在 Go 编程中,很多人初学时会用 time.Sleep 来实现时间控制。比如,想让程序暂停 2 秒,代码可能是这样:package mainimport (&q…

C# 转换(显式转换和强制转换)

显式转换和强制转换 如果要把短类型转换为长类型,让长类型保存短类型的所有位很简单。然而,在其他情况下, 目标类型也许无法在不损失数据的情况下容纳源值。 例如,假设我们希望把ushort值转化为byte。 ushort可以保存任何0~65535的…

浅谈自动化设计最常用的三款软件catia,eplan,autocad

笔者从上半年开始接触这三款软件,掌握了基础用法,但是过了一段时间不用,发现再次用,遇到的问题短时间解决不了,忘记的有点多,这里记录一下,防止下次忘记Elpan:问题1QF01是柜安装板上的一个部件&…

网络编程7.17

练习&#xff1a;服务器&#xff1a;#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include &…

c++ 模板元编程

听说模板元编程能在编译时计算出常量&#xff0c;简单测试下看看&#xff1a;template<int N> struct Summation {static constexpr int value N Summation<N - 1>::value; // 计算 1 2 ... N 的值 };template<> struct Summation<1> { // 递归终…

【深度学习】神经网络过拟合与欠拟合-part5

八、过拟合与欠拟合训练深层神经网络时&#xff0c;由于模型参数较多&#xff0c;数据不足的时候容易过拟合&#xff0c;正则化技术就是防止过拟合&#xff0c;提升模型的泛化能力和鲁棒性 &#xff08;对新数据表现良好 对异常数据表现良好&#xff09;1、概念1.1过拟合在训练…

JavaScript的“硬件窥探术”:浏览器如何读取你的设备信息?

JavaScript的“硬件窥探术”&#xff1a;浏览器如何读取你的设备信息&#xff1f; 在Web开发的世界里&#xff0c;JavaScript一直扮演着“幕后魔术师”的角色。从简单的页面跳转到复杂的实时数据处理&#xff0c;它似乎总能用最轻巧的方式解决最棘手的问题。但你是否想过&#…

论安全架构设计(层次)

安全架构设计&#xff08;层次&#xff09; 摘要 2021年4月&#xff0c;我有幸参与了某保险公司的“优车险”项目的建设开发工作&#xff0c;该系统以车险报价、车险投保和报案理赔为核心功能&#xff0c;同时实现了年检代办、道路救援、一键挪车等增值服务功能。在本项目中&a…

滚珠导轨常见的故障有哪些?

在自动化生产设备、精密机床等领域&#xff0c;滚珠导轨就像是设备平稳运行的 “轨道”&#xff0c;为机械部件的直线运动提供稳准导向。但导轨使用时间长了&#xff0c;难免会出现这样那样的故障。滚珠脱落&#xff1a;可能由安装不当、导轨损坏、超负荷运行、维护不当或恶劣环…

机器视觉的包装盒丝印应用

在包装盒丝网印刷领域&#xff0c;随着消费市场对产品外观精细化要求的持续提升&#xff0c;传统印刷工艺面临多重挑战&#xff1a;多色套印偏差、曲面基材定位困难、异形结构印刷失真等问题。双翌光电科技研发的WiseAlign视觉系统&#xff0c;通过高精度视觉对位技术与智能化操…

Redis学习-03重要文件及作用、Redis 命令行客户端

Redis 重要文件及作用 启动/停止命令或脚本 /usr/bin/redis-check-aof -> /usr/bin/redis-server /usr/bin/redis-check-rdb -> /usr/bin/redis-server /usr/bin/redis-cli /usr/bin/redis-sentinel -> /usr/bin/redis-server /usr/bin/redis-server /usr/libexec/red…

SVN客户端(TortoiseSVN)和SVN-VS2022插件(visualsvn)官网下载

SVN服务端官网下载地址&#xff1a;https://sourceforge.net/projects/win32svn/ SVN客户端工具(TortoiseSVN):https://plan.io/tortoise-svn/ SVN-VS2022插件(visualsvn)官网下载地址&#xff1a;https://www.visualsvn.com/downloads/

990. 等式方程的可满足性

题目&#xff1a;第一次思考&#xff1a; 经典并查集 实现&#xff1a;class UnionSet{public:vector<int> parent;public:UnionSet(int n) {parent.resize(n);}void init(int n) {for (int i 0; i < n; i) {parent[i] i;}}int find(int x) {if (parent[x] ! x) {pa…

HTML--教程

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body><h1>我的第一个标题</h1><p>我的第一个段落。</p> </body> </html&g…

Leetcode刷题营第二十七题:二叉树的最大深度

104. 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff…

微信小程序翻书效果

微信小程序翻书效果 wxml <viewwx:for"{{imgList}}" hidden"{{pagenum > imgList.length - index - 1}}"wx:key"index"class"list-pape" style"{{index imgList.length - pagenum - 1 ? clipPath1 : }}"bindtouchst…