杨覃娟、师炜文、周键淇、杨蕾蕾、刘芮金、谢艺言
DeepSeek-V4系列包括V4-Pro(1.6T 参数,49B 激活)和V4-Flash(284B 参数,13B 激活)两个模型,开创了一种全新的注意力机制,在token维度进行压缩,结合DSA稀疏注意力(DeepSeek Sparse Attention),实现了全球领先的长上下文能力,并且相比于传统方法大幅降低了对计算和显存的需求。
V4-Pro与V4-Flash最大上下文长度为1M,均同时支持非思考模式与思考模式,其中思考模式支持 reasoning_effort参数设置思考强度(high/max)。对于复杂的Agent场景建议使用思考模式,并设置强度为 max。
得益于DeepSeek-V4架构强大的CSA+HCA,我们可以在A2单机上跑1M上下文!
**1. 权重:**官方发布的权重是FP4+FP8混合量化类型,我们用的910B算力,该算力不支持浮点量化。所以模型权重用的昇腾官方发布的W8A8(INT8)。可以直接从modelscope下载:
**2. 镜像:**可以直接从镜像仓库ascend/vllm-ascend 拉取预构建镜像并运行。我们用的是v0.13.0rc3.tar.gz(为什么不是v0.18.0xxx?因为昇腾提前在v0.13版本适配的,预计节前发布适配v0.18.0的版本)。
export IMAGE_ID=quay.io/ascend/vllm-ascend:v0.13.0rc3 # for dsk-v4
export NAME=vllm_0130rc3
docker run -it -d \
--name $NAME --net=host \
--shm-size=500g \
--privileged=true \
--device=/dev/davinci0 \
--device=/dev/davinci1 \
--device=/dev/davinci2 \
--device=/dev/davinci3 \
--device=/dev/davinci4 \
--device=/dev/davinci5 \
--device=/dev/davinci6 \
--device=/dev/davinci7 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v /root/.cache:/root/.cache \
-v /etc/hccn.conf:/etc/hccn.conf \
-v /usr/bin/hccn_tool:/usr/bin/hccn_tool \
-v /mnt/esfs:/home/models \ # 换成自己的权重路径就行
--entrypoint=bash $IMAGE_ID \
docker exec -it $NAME bash#!/bin/sh
# this obtained through ifconfig
# nic_name is the network interface name corresponding to local_ip of the current node
nic_name="enp67s0f5"
local_ip="机器的IP"
# The value of node0_ip must be consistent with the value of local_ip set in node0 (master node)
node0_ip="机器的IP"
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 ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
export HCCL_BUFFSIZE=1024
export VLLM_ASCEND_BALANCE_SCHEDULING=1
export HCCL_INTRA_PCIE_ENABLE=1
export HCCL_INTRA_ROCE_ENABLE=0
export VLLM_USE_V1=1
export LD_PRELOAD=/usr/local/Ascend/ascend-toolkit/latest/aarch64-linux/lib64/libjemalloc.so:/usr/local/Ascend/ascend-toolkit/latest/arm64-linux/lib64/libjemalloc.so:$LD_PRELOAD
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE=AIV
# 这些参数要设置,不然会报Transformers的版本错误
# 暂时还没测具体是哪个参数,反正都配上
export USE_MULTI_BLOCK_POOL=1
export OMP_PROC_BIND=false
export OMP_NUM_THREADS=10
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export ACL_OP_INIT_MODE=1
export TRITON_ALL_BLOCKS_PARALLEL=1
# 相比官方的参数,我们修改了
# 1. max-num-batched-tokens调整为32K
# 2. max-model-len调大到1M
# 3. num_speculative_tokens调大到3
nohup vllm serve "/home/models/DeepSeek-V4-Flash-w8a8-mtp/" \
--host 0.0.0.0 \
--port 8080 \
--block-size 128 \
--tensor-parallel-size 8 \
--enable-expert-parallel \
--quantization ascend \
--seed 1024 \
--served-model-name dskv4_flash \
--max-num-seqs 16 \
--max-model-len 1024K \
--max-num-batched-tokens 32768 \
--trust-remote-code \
--gpu-memory-utilization 0.93 \
--async-scheduling \
--tokenizer-mode deepseek_v4 \
--tool-call-parser deepseek_v4 \
--enable-auto-tool-choice \
--reasoning-parser deepseek_v4 \
--additional-config '{"enable_cpu_binding":true, "multistream_overlap_shared_expert": true}' \
--speculative-config '{"num_speculative_tokens": 3, "method": "deepseek_mtp"}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' >log_$(date +%Y%m%d_%H%M%S) 2>&1 &A2双机部署参考了其他模型的经验,采用了TP8DP2EP16的方案(但其实可以不用双机,毕竟单机都能跑1M了,双机会影响通信)。具体的启动参数如下:
#!/bin/sh
# this obtained through ifconfig
# nic_name is the network interface name corresponding to local_ip of the current node
nic_name="enp67s0f5"
local_ip="机器的IP"
# The value of node0_ip must be consistent with the value of local_ip set in node0 (master node)
node0_ip="master节点的IP"
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 HCCL_BUFFSIZE=1024
export VLLM_ASCEND_BALANCE_SCHEDULING=1
export HCCL_INTRA_PCIE_ENABLE=1
export HCCL_INTRA_ROCE_ENABLE=0
export VLLM_USE_V1=1
export LD_PRELOAD=/usr/local/Ascend/ascend-toolkit/latest/aarch64-linux/lib64/libjemalloc.so:/usr/local/Ascend/ascend-toolkit/latest/arm64-linux/lib64/libjemalloc.so:$LD_PRELOAD
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE=AIV
# for dskv4
export USE_MULTI_BLOCK_POOL=1
export OMP_PROC_BIND=false
export OMP_NUM_THREADS=10
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export ACL_OP_INIT_MODE=1
export TRITON_ALL_BLOCKS_PARALLEL=1
flags=()
if [[ "$local_ip" == "$node0_ip" ]]; then
flags=()
else
flags+=(--headless)
flags+=(--data-parallel-start-rank=1)
fi
nohup vllm serve "/home/models/DeepSeek-V4-Flash-w8a8-mtp/" \
--host 0.0.0.0 \
--port 8080 \
"${flags[@]}" \
--data-parallel-size 2 \
--data-parallel-size-local 1 \
--data-parallel-address $node0_ip \
--data-parallel-rpc-port 8082 \
--block-size 128 \
--tensor-parallel-size 8 \
--quantization ascend \
--seed 1024 \
--served-model-name dskv4_flash \
--enable-expert-parallel \
--max-num-seqs 16 \
--max-model-len 131072 \
--max-num-batched-tokens 32768 \
--trust-remote-code \
--gpu-memory-utilization 0.93 \
--async-scheduling \
--additional-config '{"enable_cpu_binding":true, "multistream_overlap_shared_expert": true}' \
--speculative-config '{"num_speculative_tokens": 3, "method": "mtp"}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' >log_$(date +%Y%m%d_%H%M%S) 2>&1 &官方有A3的方案可以参考一下:2P1D,64K,P:TP1DP16EP16,D:TP1DP32EP32。资源有限,我们只有三台机器,采用的方案是2P1D,128K,P:TP8DP1EP8,D:TP1DP8EP8。
部署步骤参考官方的就行,这里只说一下跟官方文档不一样的地方:
P节点的脚本run_dp_template.sh,由于我们使用了TP8DP1策略,所以删掉了--data-parallel-rank这个参数。
proxy的启动方式如下:
cd /vllm-workspace/vllm-ascend/examples/disaggregated_prefill_v1
python load_balance_proxy_layerwise_server_example.py \
--host X.XXX.XXX.XX0 \ # proxy部署在第一个prefill节点上
--port XXXX \ # 端口为XXXX
--prefiller-hosts \
X.XXX.XXX.XX0 \
X.XXX.XXX.XX1 \
--prefiller-port \
XXX0 \
XXX0 \
--decoder-hosts \ # 多少个DP就要写多少个ip地址
X.XXX.XXX.XX2 \
X.XXX.XXX.XX2 \
X.XXX.XXX.XX2 \
X.XXX.XXX.XX2 \
X.XXX.XXX.XX2 \
X.XXX.XXX.XX2 \
X.XXX.XXX.XX2 \
X.XXX.XXX.XX2 \
--decoder-ports \
XXX0 \
XXX1 \
XXX2 \
XXX3 \
XXX4 \
XXX5 \
XXX6 \
XXX7
目前tool-call还不支持,因为上游vllm还不支持,但是已经有PR,但是仅适配vllm-main分支。 对于v0.13.0rc3版本,小巧灵有一个对应的补丁,可以试一试,不过不建议直接用于生产环境。
昇腾还在适配中,会采用W4A8数据类型。