1. 项目背景与目标
最近在部署Qwen3-235B大语言模型时,遇到了一个颇具挑战性的任务:如何在两台昇腾910B服务器上实现分布式部署。这个2350亿参数的模型对计算资源的需求极高,单台服务器难以承载,因此分布式部署成为必然选择。
我选择使用vllm-ascend 0.11.0镜像进行部署,这是一个专门为昇腾NPU优化的vLLM版本。与传统的单机部署不同,分布式部署需要考虑节点间通信、资源分配、模型并行等多个复杂因素。特别是在没有共享存储的情况下,模型权重需要分别传输到两台服务器中,这增加了部署的复杂度。
2. 环境准备与验证
2.1 硬件配置检查
在开始部署前,必须确保两台昇腾910B服务器的硬件状态正常。每台服务器配备8个NPU,我们需要验证这些NPU的连通性和健康状态。
bash复制# 检查NPU链路状态
for i in {0..7}; do hccn_tool -i $i -lldp -g | grep Ifname; done
# 获取以太网端口链路状态
for i in {0..7}; do hccn_tool -i $i -link -g; done
# 检查网络健康状态
for i in {0..7}; do hccn_tool -i $i -net_health -g; done
执行这些命令后,如果发现NPU没有配置IP(输出显示netdetect address为0.0.0.0),就需要进行下一步的IP配置。
2.2 NPU网络配置
为了实现节点间通信,我们需要为每台服务器的NPU分配专用IP地址。这里采用192.168.100.0/24网段,服务器1使用1-8,服务器2使用9-16。
服务器1配置脚本:
bash复制# NPU0-7配置为192.168.100.1-8
for i in {0..7}; do
ip=$((i+1))
hccn_tool -i $i -ip -s address 192.168.100.$ip netmask 255.255.255.0
done
# 配置对端检测地址(指向服务器2的NPU IP)
for i in {0..7}; do
peer_ip=$((i+9))
hccn_tool -i $i -netdetect -s address 192.168.100.$peer_ip
done
服务器2的配置类似,只是IP地址范围不同。配置完成后,需要验证网络连通性:
bash复制# 等待30秒让HCCL网络初始化
sleep 30
# 检查网络健康状态
for i in {0..7}; do
result=$(hccn_tool -i $i -net_health -g)
echo "NPU${i}: ${result}"
done
# 跨节点NPU通信测试
for i in {0..7}; do
peer_ip=$((i+9)) # 服务器2的NPU IP
result=$(hccn_tool -i $i -ping -g address 192.168.100.$peer_ip 2>&1)
echo "NPU${i} -> 192.168.100.$peer_ip: ${result}"
done
注意:如果网络健康状态显示为"Init"而不是"Healthy",可能需要检查物理连接或重新配置NPU IP。
3. 容器部署与问题排查
3.1 启动vllm-ascend容器
使用以下命令启动容器:
bash复制docker run --rm \
--name qwen3_235B \
--net=host \
--privileged \
--shm-size=512g \
--ulimit nproc=65535:65535 \
--device /dev/davinci0 \
...(省略其他设备映射)...
-it quay.io/ascend/vllm-ascend:v0.11.0-openeuler bash
这里有几个关键点:
--privileged参数是必须的,否则容器内无法访问NPU设备--shm-size=512g设置了大共享内存,适合大模型运行--ulimit nproc=65535:65535解决了OpenBLAS线程创建问题
3.2 常见问题与解决方案
在实际部署中,我遇到了几个典型问题:
问题1:OpenBLAS警告
code复制OpenBLAS blas_thread_init: pthread_create failed for thread 1 of 64: Operation not permitted
解决方案:添加--ulimit nproc=65535:65535参数。
问题2:容器内找不到NPU
code复制dcmi module initialize failed. ret is -8005
解决方案:确保使用--privileged参数,并验证宿主机NPU状态正常。
问题3:版本不匹配
如果容器内dcmi库版本与宿主机驱动不匹配,会导致NPU无法识别。解决方法是确保容器镜像版本与宿主机驱动版本兼容。
4. Ray集群搭建
4.1 主节点配置
在服务器1的容器内执行:
bash复制export NIC_NAME=bond1.2001 # 根据实际网卡名称修改
export LOCAL_IP=节点1IP
export HCCL_IF_IP=${LOCAL_IP}
export GLOO_SOCKET_IFNAME=${NIC_NAME}
export TP_SOCKET_IFNAME=${NIC_NAME}
ray start --head \
--port=6379 \
--node-ip-address=${LOCAL_IP} \
--num-gpus=8
4.2 子节点配置
在服务器2的容器内执行:
bash复制export NIC_NAME=bond1.2001
export LOCAL_IP=节点2IP
export HEAD_IP=主节点IP
ray start \
--address="${HEAD_IP}:6379" \
--node-ip-address=${LOCAL_IP} \
--num-gpus=8
4.3 防火墙配置
如果遇到连接问题,可能是防火墙阻止了Ray通信。在两台服务器的宿主机上执行:
bash复制# 开放同网段所有流量
iptables -I INPUT -s XX.XX.XX.0/24 -j ACCEPT
iptables -I OUTPUT -d XX.XX.XX.0/24 -j ACCEPT
或者更精确地只开放Ray所需端口:
bash复制iptables -I INPUT -s XX.XX.XX.XX -p tcp --dport 6379 -j ACCEPT # GCS
iptables -I INPUT -s XX.XX.XX.XX -p tcp --dport 8265 -j ACCEPT # Dashboard
iptables -I INPUT -s XX.XX.XX.XX -p tcp --dport 10001 -j ACCEPT # Client
iptables -I INPUT -s XX.XX.XX.XX -p tcp --dport 20000:30000 -j ACCEPT # Worker ports
5. 模型服务启动与优化
5.1 启动vLLM服务
在服务器1的容器内执行:
bash复制export HCCL_SOCKET_IFNAME=bond1.2001
export HCCL_BUFFSIZE=1024
export OMP_NUM_THREADS=10
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
nohup vllm serve /root/models/Qwen/Qwen3-235B-A22B-Instruct-2507 \
--host 0.0.0.0 \
--port 1025 \
--tensor-parallel-size 8 \
--pipeline-parallel-size 2 \
--max-model-len 87000 \
--trust-remote-code \
--distributed-executor-backend ray \
--dtype bfloat16 \
> vllm_serve.log 2>&1 &
关键参数说明:
--tensor-parallel-size 8:使用8路张量并行--pipeline-parallel-size 2:使用2路流水线并行(对应两台服务器)--max-model-len 87000:设置最大模型长度--dtype bfloat16:使用bfloat16精度减少内存占用
5.2 性能优化建议
-
内存优化:
- 设置
--gpu-memory-utilization 0.95尽可能利用NPU内存 - 使用
--swap-space 0禁用交换空间,避免性能下降
- 设置
-
吞吐量优化:
- 调整
--max-num-batched-tokens 32768增加批处理大小 - 设置
--block-size 128优化内存块分配
- 调整
-
延迟优化:
- 启用
--enable-prefix-caching缓存注意力前缀 - 使用
--enable-chunked-prefill分块预填充减少延迟
- 启用
6. API测试与监控
6.1 测试API接口
使用curl测试模型服务:
bash复制curl --location 'http://xx.xx.xx.xx:1025/v1/chat/completions' \
--header 'Content-Type: application/json' \
--data '{
"model": "/root/models/Qwen/Qwen3-235B-A22B-Instruct-2507",
"messages": [{"role": "user", "content": "你好,请介绍一下你自己"}],
"max_tokens": 85000,
"temperature": 0.7
}'
6.2 监控与维护
-
服务管理:
- 停止服务:
pkill -f "vllm serve" - 查看日志:
tail -f vllm_serve.log
- 停止服务:
-
资源监控:
- NPU状态:
npu-smi info - 内存使用:
free -h - Ray集群状态:
ray status
- NPU状态:
-
性能分析:
- 使用
ascend-dmi工具分析NPU利用率 - 通过Ray Dashboard(端口8265)监控任务分布
- 使用
7. 经验总结与注意事项
在实际部署过程中,我积累了一些宝贵经验:
-
网络配置要点:
- NPU间的网络延迟对性能影响很大,确保使用专用网络连接
- HCCL通信超时设置要足够长(我使用了7200秒)
-
容器部署陷阱:
- 容器内NPU访问需要特权模式
- 设备映射必须完整,包括davinciX、davinci_manager等
-
模型并行策略:
- 235B模型适合8路张量并行+2路流水线并行的组合
- 更大的模型可能需要调整并行策略
-
性能调优技巧:
- bfloat16在昇腾910B上性能表现良好
- 适当增加OMP线程数可以提高效率
-
稳定性保障:
- 长时间运行需要监控内存泄漏
- 定期检查Ray工作节点状态
这个部署方案已经稳定运行了一段时间,能够充分发挥两台昇腾910B服务器的计算能力,为Qwen3-235B大模型提供了高效的推理服务。对于需要部署类似大模型的团队,这份经验应该能帮助避开不少坑。
