Ascend-SACT/Qwen3-235B-A22B
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

Qwen3-235B-A22B模型vLLM多实例及组合并行策略部署实践

概述

本案例给出Qwen3-235B-A22B模型基于vLLM实现多节点、组合并行策略部署的实践。

设备支持

基于x86 CPU+昇腾910B NPU。

环境依赖

  安装关键软件及依赖,各组件之间版本号须匹配。  1)、验证 Ascend NPU 固件和驱动程序是否正确安装,本案例每个节点16张NPU卡。如下命令查看NPU状态。

npu-smi info

2)、安装CANN,版本>=8.2.1RC1,本案例版本为8.3.1RC1,如下命令查看CANN版本号。

more /usr/local/Ascend/ascend-toolkit/latest/x86_64-linux/ascend_toolkit_install.info

3)、安装torch>=2.7.1、torch-npu>= 2.7.1.dev20250724

pip install torch==2.7.1 pip install torch-npu==2.7.1.dev20250724

验证安装是否成功:

输入:

$ python3 -c "import torch;import torch_npu; a = torch.randn(3, 4).npu(); print(a + a);"

期望输出:

tensor([[ 2.4794e-01, 2.4400e+00, -4.9288e-02, 6.5343e-01], [-8.6331e-01, -2.7357e+00, 5.3075e-04, -1.2020e+00], [ 3.1187e+00, 1.4611e+00, -8.7064e-01, 1.2624e+00]], device='npu:0')

4)、安装transformer=4.57.0

pip install transformers==4.57.0

5)、安装 vllm=v0.11.0rc3 和 vllm-ascend=0.11.0rc0

apt-get update -y && apt-get install -y gcc g++ cmake libnuma-dev wget git curl jq pip config set global.index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple pip config set global.extra-index-url https://download.pytorch.org/whl/cpu/ https://mirrors.huaweicloud.com/ascend/repos/pypi git clone --depth 1 --branch v0.11.0rc3 https://gitcode.com/GitHub_Trending/vl/vllm.git cd vllm pip install -r ./requirements/build.txt #安装vllm依赖 VLLM_TARGET_DEVICE=empty pip install -v -e . cd .. pip install vllm-ascend==0.11.0rc0

说明: VLLM_TARGET_DEVICE=empty 变量作用是安装纯Python的基础版vLLM,跳过所有与特定硬件相关的编译。

下载模型文件

社区下载模型文件到指定路径,以魔搭社区为例。

pip install modelscope modelscope download --model Qwen/Qwen3-235B-A22B --local_dir /xxx/xxxxx

模型部署并行策略

多节点多板卡部署超大参数模型,制定合理的并行策略对模型部署、性能至关重要。

并行策略概念

1)、张量并行(Tensor Parallelism,TP)

   TP是将单个模型层中的大型矩阵运算切分到多个NPU上,实现并行计算。例如注意力层或前馈网络中的矩阵,沿着某一维度(例如列或行)进行切分。每个NPU只负责计算切分后的一小部分,计算结束后,NPU之间会通过HCCL进行同步聚合。MoE模型中,TP用于切分非MoE层(如注意力层),MoE层则使用EP。
   对于超大参数模型,TP是必不可少的,因为它可以将模型权重分布在多个NPU上,突破单NPU显存限制。
  使用VLLM --tensor-parallel-size参数指定单个张量并行组中的NPU数量,也即模型权重被切分的数量。同一TP组内的NPU之间需要进行密集通信,需要高带宽互联,建议在一个物理节点(单台服务器)。

2)、数据并行(Data Parallelism,DP)

   DP在多个NPU组上复制完整的模型副本,每个副本处理独立的请求批次,用来提高整体吞吐量。DP数量就是模型副本的总数量,各DP组实现负载均衡。
  使用VLLM --data-parallel-size参数指定数据并行组数量。多节点时,DP对于高并发和吞吐量有显著提升。

3)、流水线并行(Pipeline Parallelism,PP)

   PP将模型的不同层级切分到多个NPU上,形成一个处理流水线。
  模型被垂直切分为多个阶段,每个阶段由一个NPU或一个TP组负责。
 使用vLLM pipeline-parallel-size参数指定流水线并行数量。PP存在流水线气泡,效率较低,部署MoE模型非必要不启用PP。

4)、专家并行(Expert Parallelism,EP)

   EP将所有专家切分到不同的NPU上,以减少单卡显存,同时只有被激活的专家才进行计算。
  使用VLMM --enable-expert-parallel参数用于启用EP。以Qwen3-235B-A22B为例,模型含专家数量128个,每次激活的专家数量8个,部署在16张NPU卡上,使能EP后,128个专家均匀分配给16张NPU,每个NPU负责8个专家。
  

5)、各策略汇总如下:

并行策略核心思想通信开销主要应用场景
张量并行(TP)将模型单个层的参数横向切分到多个NPU上高(频繁同步)解决超大模型参数无法放入单卡的问题
流水线并(PP)将模型按层深度拆分,不同层放在不同NPU上中(层间传递激活值)模型过大,单节点NPU无法通过TP容纳
数据并行(DP)在多个NPU上复制完整的模型副本,同时处理不同数据低(梯度或输出聚合)通过增加副本数来提升吞吐量和处理并发请求
专家并行(EP)将MoE模型中的不同专家(子网络)分布到不同NPU上取决于模型专门用于混合专家模型

并行策略组合原则

制定并行组合策略通常遵循以下原则:

1)确保 TP×PP×DP等于NPU总数,这样可以确保资源得到充分利用。

2)MoE(混合专家)模型,优先选择专家并行(EP),模型专家总数需要能整除EP数,也即使能EP的NPU卡数。

3)超大模型需要张量并行来分摊显存,TP是必需的。

4)TP通信开销大,优先在节点内使用张量并行(TP),内部互联速度快于节点之间。

5)数据并行可以提高吞吐量,通过增加模型副本增大并发。张量并行通常有助于降低单请求推理时延。

6)原则上禁用PP,规避流水线气泡。

7)追求单个请求时延倾向TP,追求高系统吞吐量倾向DP。

并行策略实施

基于以上并行策略原则,部署Qwen3-235B-A22B模型,以2个节点,每节点16卡为例,推荐的并行策略如下:

1)、策略一:单节点DP=1,双节点DP=2,TP=16, PP=1, EP启用

两个节点作为数据并行(DP)组,每个DP组内部使用16路张量并行(TP),并启用专家并行(EP)。

`--data-parallel-size=2

--tensor-parallel-size=16

--pipeline-parallel-size=1

--enable-expert-parallel`

TP: 每个节点内的16张NPU卡组成一个张量并行组。同一节点内部的NPU互联速度快,可以最大化TP的性能。

DP: 两个节点(每个节点16卡)各自运行一个模型副本。客户端请求会被负载均衡到这两个节点,以提高整体吞吐量。

EP: MoE模型中的专家会在每个节点内的16张NPU中进行平均切分。

2)、策略二:单节点DP=2,双节点DP=4,DP=4, TP=8, PP=1, EP启用

将32张NPU卡划分为4个数据并行组,每个DP组内部进行8路张量并行,并启用专家并行。

`--data-parallel-size 4

--data-parallel-size-local 2

--tensor-parallel-size 8

--pipeline-parallel-size=1

--enable-expert-parallel`

TP: 每个节点内的16张NPU卡被分为2个TP组(每个8卡)。

DP: 每个节点2个DP组,--data-parallel-size-local 2;两个节点共4个DP组,设置--data-parallel-size 4。每个DP组内一个TP组。

EP: MoE模型中的专家会在每个节点内的16张NPU中进行平均切分。

vLLM并行策略实现

以如下并行策略为例:单节点DP=2,双节点DP=4,DP=4, TP=8, PP=1, EP启用。VLLM并行策略实现,其中单个节点日志如下:

`rank 0 in world size 32 is assigned as DP rank 0, PP rank 0, TP rank 0, EP rank 0

rank 1 in world size 32 is assigned as DP rank 0, PP rank 0, TP rank 1, EP rank 1

rank 2 in world size 32 is assigned as DP rank 0, PP rank 0, TP rank 2, EP rank 2

rank 3 in world size 32 is assigned as DP rank 0, PP rank 0, TP rank 3, EP rank 3

rank 4 in world size 32 is assigned as DP rank 0, PP rank 0, TP rank 4, EP rank 4

rank 5 in world size 32 is assigned as DP rank 0, PP rank 0, TP rank 5, EP rank 5

rank 6 in world size 32 is assigned as DP rank 0, PP rank 0, TP rank 6, EP rank 6

rank 7 in world size 32 is assigned as DP rank 0, PP rank 0, TP rank 7, EP rank 7

rank 8 in world size 32 is assigned as DP rank 1, PP rank 0, TP rank 0, EP rank 8

rank 9 in world size 32 is assigned as DP rank 1, PP rank 0, TP rank 1, EP rank 9

rank 11 in world size 32 is assigned as DP rank 1, PP rank 0, TP rank 3, EP rank 11

rank 10 in world size 32 is assigned as DP rank 1, PP rank 0, TP rank 2, EP rank 10

rank 12 in world size 32 is assigned as DP rank 1, PP rank 0, TP rank 4, EP rank 12

rank 13 in world size 32 is assigned as DP rank 1, PP rank 0, TP rank 5, EP rank 13

rank 14 in world size 32 is assigned as DP rank 1, PP rank 0, TP rank 6, EP rank 14

rank 15 in world size 32 is assigned as DP rank 1, PP rank 0, TP rank 7, EP rank 15`

日志展示了vLLM在双节点、每个节点16张卡的硬件配置下,采用DP=4、TP=8、PP=1、启用EP的混合并行策略的具体实现。

1)、world size: 32

双节点总共有32个rank,对应双节点32张NPU卡,每节点16个rank,对应单节点16张卡。

2)、DP rank:每个节点DP=2

rank 0-7 被分配为 DP rank 0。

rank 8-15 被分配为 DP rank 1。

32个进程映射到双节点4个DP组,单节点2个DP组,每个DP组包含8个TP进程,对应每8张卡一个TP组。每个DP组(rank 0-7和rank 8-15)会加载完整的模型副本(不包括EP层),由主控进程EngineCore将请求队列分配给两个DP组,独立处理不同的请求批次。假设节点1的NPU 0-15,节点2的NPU 16-31:

DP组0:NPU 0-7

DP组1:NPU 8-15

DP组2:NPU 16-23

DP组3:NPU 24-31

3)、TP rank:TP=8,每个TP组由8张NPU卡组成。

rank 0-7 分别被分配为 TP rank 0 到 TP rank 7。

rank 8-15 也分别被分配为 TP rank 0 到 TP rank 7。

每张NPU卡都只加载模型权重的一部分,而不是所有权重。用于处理非专家层(例如注意力层)中大的张量计算,解决单个GPU显存不足的问题。

4)、PP rank 0:PP=1

所有进程都被分配为PP rank 0,PP为 1。所有NPU卡都处理模型的所有层级,但每张卡只负责每个层级计算的一部分。该策略未启用PP,简化了执行流程,避免了流水线气泡带来的延迟。

5)、EP rank:

rank 0-15 被分配为 EP rank 0 到 EP rank 15,专家被线性切分到16个NPU中,EP跨越了两个DP组。每次推理时,每个token会被路由到特定的专家,需要All-to-All通信来传递token和结果。专家分配日志如下:

(Worker_DP0_TP0_EP0 pid=631288) INFO 10-29 01:37:26 [layer.py:1052] [EP Rank 0/16] Expert parallelism is enabled. Expert placement strategy: linear. Local/global number of experts: 8/128. Experts local to global index map: 0->0, 1->1, 2->2, 3->3, 4->4, 5->5, 6->6, 7->7.

EP启用的两个必要条件:模型本身是MoE模型,且启动命令中使用了--enable-expert-parallel参数。

并行策略协同推理过程

假设两批请求(Request Batch A和Request Batch B)需要处理,推理过程如下:

1)、请求分发与数据并行(DP)

vLLM的EngineCore将Request Batch A分配给DP组0(rank 0-7),Request Batch B分配给DP组1(rank 8-15)。两个DP组独立处理各自的请求。

2)、层内计算与张量并行(TP)

对于Request Batch A,其处理流程进入TP组0 (rank 0-7)。当模型的一个层(如MLP或注意力层)开始计算时,该层的计算任务被切分到同一个TP组内的8张卡上,每个NPU计算一部分,然后通过通信汇聚结果,得到完整的输出。

3)、专家激活与专家并行(EP)

当计算进行到MoE层时,门控网络会根据输入的特征,决定将数据(Token)发送给哪几个专家处理。由于启用了EP(EP=16),这些专家分布在不同的NPU上,系统通过All-to-All通信将Token路由到持有对应专家的NPU上进行计算,然后将计算结果聚合。

模型部署配置

主节点配置

以单节点DP=2,双节点DP=4,DP=4, TP=8, PP=1, EP启用为例。

`#!/bin/sh nic_name="xxxx" #nic_name is the network interface name corresponding to local_ip of the current node local_ip="xxxx"

export HCCL_IF_IP=$local_ip

export GLOO_SOCKET_IFNAME=$nic_name

export TP_SOCKET_IFNAME=$nic_name

export HCCL_SOCKET_IFNAME=$nic_name

export OMP_PROC_BIND=false

export OMP_NUM_THREADS=100

export VLLM_USE_V1=1

export HCCL_BUFFSIZE=1024

vllm serve /model_path/Qwen3-235B-A22B
--host 0.0.0.0
--port 8000
--api-server-count 2
--data-parallel-size 4
--data-parallel-size-local 2
--data-parallel-address $local_ip
--data-parallel-rpc-port 13389
--seed 1024
--served-model-name Qwen3-235B-A22B
--tensor-parallel-size 8
--enable-expert-parallel
--max-num-seqs 16
--max-model-len 32768
--trust-remote-code
--gpu-memory-utilization 0.8`

环境变量说明:

nic_name="xxxx" 和 local_ip="xxxx":当前节点使用的网络接口名称和 IP 地址,推荐eth、enp等接口及IP地址。确保所有分布式通信使用指定的高速网络接口,避免使用慢速网络。

export HCCL_IF_IP=$local_ip:HCCL使用的IP。

export GLOO_SOCKET_IFNAME=$nic_name:Gloo 库使用的网络接口名称。

export TP_SOCKET_IFNAME=$nic_name:设置TP使用的网络接口名称。

export HCCL_SOCKET_IFNAME=$nic_name:设置 HCCL 使用的网络接口名称。

export OMP_PROC_BIND=false:禁用 OpenMP 进程绑定。

export OMP_NUM_THREADS=100:设置 OpenMP 线程数。

export VLLM_USE_V1=1:强制使用 vLLM 的 V1 版本引擎。

export HCCL_BUFFSIZE=1024:设置 HCCL 的通信缓冲区大小。

参数说明:

llm serve /model_path/Qwen3-235B-A22B:指定模型路径。

--host 0.0.0.0 --port 8000:指定服务端口号。

--api-server-count 2:在主节点上启动API服务器实例数,以处理客户端请求并进行负载均衡,与DP组数量无关。

--data-parallel-size 4:双节点总共有4个数据并行组,和--data-parallel-size-local强依赖,数量为--data-parallel-size-local*节点数。

--data-parallel-size-local 2:单节点运行2个数据并行组。和--data-parallel-size 4强依赖。

--data-parallel-address $local_ip:指定主节点与其他节点上DP组通信的IP。

--data-parallel-rpc-port 13389:DP组之间使用该RPC端口进行通信。

--seed 1024 :随机种子,保证 reproducibility

--tensor-parallel-size 8:TP为8

--enable-expert-parallel:使能EP

--max-num-seqs 16:同时处理的最大序列数,也即并发。

--max-model-len 32768:模型处理的最大上下文长度。

--trust-remote-code:信任远程代码执行

--gpu-memory-utilization 0.8:每个NPU推理部署使用显存的最大比例。

从节点配置

`#!/bin/sh nic_name="xxxx" #nic_name is the network interface name corresponding to local_ip of the current node local_ip="xxxx" #The value of node0_ip must be consistent with the value of local_ip set in node0 (master node) node0_ip="xxxx"

export HCCL_IF_IP=$local_ip

export GLOO_SOCKET_IFNAME=$nic_name

export TP_SOCKET_IFNAME=$nic_name

export HCCL_SOCKET_IFNAME=$nic_name

export OMP_PROC_BIND=false

export OMP_NUM_THREADS=100

export VLLM_USE_V1=1

export HCCL_BUFFSIZE=1024

data_parallel_start_rank=$((index * data_parallel_size_local))

vllm serve /model_path/Qwen3-235B-A22B
--host 0.0.0.0
--port 8000
--headless
--data-parallel-size 4
--data-parallel-size-local 2
--data-parallel-start-rank dataparallelstartrank −−data−parallel−addressdata_parallel_start_rank \ --data-parallel-address datap​arallels​tartr​ank −−data−parallel−addressnode0_ip
--data-parallel-rpc-port 13389
--seed 1024
--tensor-parallel-size 8
--served-model-name Qwen3-235B-A22B
--max-num-seqs 16
--max-model-len 32768
--enable-expert-parallel
--trust-remote-code
--no-enable-prefix-caching
--gpu-memory-utilization 0.8 \ `

关键配置说明:

node0_ip="xxxx":关键环境变量。指定主节点的IP地址。这是从节点与主节点建立通信的地址。

--headless:关键参数。此参数表示该节点是无头节点,不启动 API 服务处理外部请求,只作为集群的工作节点,由主节点统一调度。

data_parallel_start_rank=$((index * data_parallel_size_local)):用于计算当前从节点的DP起始 rank。index代表当前节点在集群中的索引(例如,主节点 index=0,从节点 index=1)。

--data-parallel-start-rank $data_parallel_start_rank:关键参数。指定当前从节点DP组rank起始索引。例如,如果 index=1,则data_parallel_start_rank = 1 * 2 = 2,该从节点将运行DP rank 2和DP rank 3。

--data-parallel-address $node0_ip:关键参数。指定主节点的 IP 地址,所有从节点都通过这个地址与主节点进行通信。

从节点执行该脚本,使用--headless模式启动vLLM,通过--data-parallel-address $node0_ip和--data-parallel-rpc-port 13389连接到主节点,由主节点负责请求分发。