已合并
增加verl qwen3+dapo+A3单机脚本,优化了A3单机性能,平均单卡吞吐290TPS #794
imzhengwei创建于 2025年12月5日
增加verl qwen3+dapo+A3单机脚本,优化了A3单机性能,平均单卡吞吐290TPS #794
已合并
imzhengwei创建于 2025年12月5日
2 个文件变更+217-0
@@ -0,0 +1,138 @@
1+set -xeuo pipefail
张健翔2025年12月8日

建议脚本和配置文件的名称可以带上节点数量, 例如: test_dapo_qwen3_32b_fsdp2_A3_1_node.sh

likedislike
imzhengwei
2025年12月10日 评论:
2+ 
ZVermouth
Zzhoubeirong2025年12月8日

贴一下精度和性能的验证报告

likedislike
VermouthVermouth2025年12月11日

精度和性能链接打不开,请开通访问权限!

likedislike
3+project_name='DAPO'
4+exp_name='DAPO-Qwen3-32B'
5+ 
6+adv_estimator=grpo
7+ 
8+use_kl_in_reward=False
9+kl_coef=0.0
10+use_kl_loss=False
11+kl_loss_coef=0.0
12+ 
13+clip_ratio_low=0.2
14+clip_ratio_high=0.28
15+ 
Z
Zzhoubeirong2025年12月8日

目前正在版本迭代,这两天verl和vllm会升级到新版本,在新版本上验证完直接上新版本吧

likedislike
16+max_prompt_length=$((1024 * 2))
17+max_response_length=$((1024 * 10))
18+enable_overlong_buffer=True
19+overlong_buffer_len=$((1024 * 4))
20+overlong_penalty_factor=1.0
21+ 
22+loss_agg_mode="token-mean"
23+ 
24+use_token_level_loss=True
25+enable_filter_groups=False
26+filter_groups_metric=acc
27+max_num_gen_batches=10
28+train_prompt_bsz=32
29+gen_prompt_bsz=$((train_prompt_bsz * 1))
30+n_resp_per_prompt=16
31+train_prompt_mini_bsz=32
32+ 
33+# Ray
34+WORKING_DIR=${WORKING_DIR:-"${PWD}"}
35+RUNTIME_ENV=${RUNTIME_ENV:-"${WORKING_DIR}/verl/trainer/runtime_env.yaml"}
Vermouth
VermouthVermouth2025年12月11日

此条代码评论区间+34+35

这两个参数后续没有用到,建议删除。

likedislike
36+NNODES={NNODES:-1}
37+NPUS_PER_NODE={NPUS_PER_NODE:-16}
38+ 
39+# Paths
40+MODEL_PATH=./ckpt/Qwen3-32B
41+CKPTS_DIR=./ckpt/Qwen3-32B-save
42+TRAIN_FILE=./data/dapo-math-17k.parquet
43+TEST_FILE=./data/dapo-math-17k.parquet
44+ 
45+# Algorithm
46+temperature=1.0
47+top_p=1.0
48+top_k=-1 # 0 for HF rollout, -1 for vLLM rollout
49+val_top_p=0.7
50+ 
51+# Performance Related Parameter
52+sp_size=4
53+use_dynamic_bsz=True
54+actor_ppo_max_token_len=$(((max_prompt_length + max_response_length) / sp_size))
55+infer_ppo_max_token_len=$(((max_prompt_length + max_response_length) / sp_size))
56+offload=True
57+gen_tp=4
58+ 
59+python3 -m recipe.dapo.main_dapo \
60+ data.train_files="${TRAIN_FILE}" \
61+ data.val_files="${TEST_FILE}" \
62+ data.prompt_key=prompt \
63+ data.truncation='left' \
64+ data.max_prompt_length=${max_prompt_length} \
65+ data.max_response_length=${max_response_length} \
66+ data.gen_batch_size=${gen_prompt_bsz} \
67+ data.train_batch_size=${train_prompt_bsz} \
68+ actor_rollout_ref.rollout.n=${n_resp_per_prompt} \
69+ algorithm.adv_estimator=${adv_estimator} \
70+ algorithm.use_kl_in_reward=${use_kl_in_reward} \
71+ algorithm.kl_ctrl.kl_coef=${kl_coef} \
72+ actor_rollout_ref.actor.use_kl_loss=${use_kl_loss} \
73+ actor_rollout_ref.actor.kl_loss_coef=${kl_loss_coef} \
74+ actor_rollout_ref.actor.clip_ratio_low=${clip_ratio_low} \
75+ actor_rollout_ref.actor.clip_ratio_high=${clip_ratio_high} \
76+ actor_rollout_ref.actor.clip_ratio_c=10.0 \
77+ algorithm.filter_groups.enable=${enable_filter_groups} \
78+ algorithm.filter_groups.max_num_gen_batches=${max_num_gen_batches} \
79+ algorithm.filter_groups.metric=${filter_groups_metric} \
80+ actor_rollout_ref.model.use_remove_padding=True \
81+ actor_rollout_ref.actor.use_dynamic_bsz=${use_dynamic_bsz} \
82+ actor_rollout_ref.ref.log_prob_use_dynamic_bsz=${use_dynamic_bsz} \
83+ actor_rollout_ref.rollout.log_prob_use_dynamic_bsz=${use_dynamic_bsz} \
84+ actor_rollout_ref.actor.ppo_max_token_len_per_gpu=${actor_ppo_max_token_len} \
85+ actor_rollout_ref.ref.log_prob_max_token_len_per_gpu=${infer_ppo_max_token_len} \
86+ actor_rollout_ref.rollout.log_prob_max_token_len_per_gpu=${infer_ppo_max_token_len} \
87+ actor_rollout_ref.model.path="${MODEL_PATH}" \
88+ actor_rollout_ref.model.enable_gradient_checkpointing=True \
89+ actor_rollout_ref.actor.optim.lr=1e-6 \
90+ actor_rollout_ref.actor.optim.lr_warmup_steps=10 \
91+ actor_rollout_ref.actor.optim.weight_decay=0.1 \
92+ actor_rollout_ref.actor.ppo_mini_batch_size=${train_prompt_mini_bsz} \
93+ actor_rollout_ref.actor.fsdp_config.param_offload=${offload} \
94+ actor_rollout_ref.actor.fsdp_config.optimizer_offload=${offload} \
95+ actor_rollout_ref.actor.entropy_coeff=0 \
96+ actor_rollout_ref.actor.grad_clip=1.0 \
97+ actor_rollout_ref.rollout.name=vllm \
98+ actor_rollout_ref.actor.loss_agg_mode=${loss_agg_mode} \
99+ actor_rollout_ref.actor.ulysses_sequence_parallel_size=${sp_size} \
100+ actor_rollout_ref.rollout.gpu_memory_utilization=0.85 \
101+ actor_rollout_ref.rollout.tensor_model_parallel_size=${gen_tp} \
102+ actor_rollout_ref.rollout.enable_chunked_prefill=True \
103+ actor_rollout_ref.rollout.max_num_batched_tokens=$((max_prompt_length + max_response_length)) \
104+ actor_rollout_ref.rollout.temperature=${temperature} \
105+ actor_rollout_ref.rollout.top_p=${top_p} \
106+ actor_rollout_ref.rollout.top_k="${top_k}" \
107+ actor_rollout_ref.rollout.val_kwargs.temperature=${temperature} \
108+ actor_rollout_ref.rollout.val_kwargs.top_p=${val_top_p} \
109+ actor_rollout_ref.rollout.val_kwargs.top_k=${top_k} \
110+ actor_rollout_ref.rollout.val_kwargs.do_sample=True \
111+ actor_rollout_ref.rollout.val_kwargs.n=1 \
112+ actor_rollout_ref.ref.fsdp_config.param_offload=${offload} \
113+ actor_rollout_ref.ref.ulysses_sequence_parallel_size=${sp_size} \
114+ actor_rollout_ref.actor.fsdp_config.fsdp_size=-1 \
115+ actor_rollout_ref.ref.strategy=fsdp2 \
116+ actor_rollout_ref.actor.strategy=fsdp2 \
117+ reward_model.reward_manager=dapo \
118+ reward_model.overlong_buffer.enable=${enable_overlong_buffer} \
119+ reward_model.overlong_buffer.len=${overlong_buffer_len} \
120+ reward_model.overlong_buffer.penalty_factor=${overlong_penalty_factor} \
121+ trainer.logger='["console"]' \
122+ trainer.project_name="${project_name}" \
123+ trainer.experiment_name="${exp_name}" \
124+ trainer.n_gpus_per_node="${NPUS_PER_NODE}" \
125+ trainer.nnodes="${NNODES}" \
126+ trainer.val_before_train=False \
127+ trainer.save_freq=100 \
128+ trainer.test_freq=100 \
129+ trainer.total_epochs=10 \
130+ trainer.default_local_dir="${CKPTS_DIR}" \
131+ trainer.resume_mode=auto \
132+ trainer.balance_batch=True \
133+ actor_rollout_ref.rollout.enforce_eager=False \
134+ actor_rollout_ref.actor.use_torch_compile=False \
135+ actor_rollout_ref.ref.use_torch_compile=False \
136+ actor_rollout_ref.actor.fsdp_config.forward_prefetch=True \
137+ actor_rollout_ref.actor.entropy_from_logits_with_chunking=True \
138+ trainer.device=npu 2>&1 | tee "logs/verl_qwen3_32b_$(date +%Y%m%d_%H%M).log"
@@ -0,0 +1,79 @@
1+pkill -9 python
2+ray stop --force
3+rm -rf /tmp/ray
4+ 
5+export RAY_DEDUP_LOGS=0
6+export HYDRA_FULL_ERROR=1
7+ 
8+# ------------- HCCL优化 -------------#
9+export HCCL_ASYNC_ERROR_HANDLING=0
10+export HCCL_EXEC_TIMEOUT=3600
11+export HCCL_CONNECT_TIMEOUT=3600
12+export HCCL_OPEXPANSION_MODE=AIV
13+export HCCL_BUFFSIZE=256
14+export ATB_LLM_HCCL_ENABLE=1
15+ 
16+# TASK_QUEUE_ENABLE,下发优化,图模式设置为1,非图模式设置为2
17+export TASK_QUEUE_ENABLE=1
18+# 使能vllm V1 Engine
19+export VLLM_USE_V1=1
20+# 请确认该文件存在(可通过 find /usr -name libjemalloc.so.2 确认)
21+export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2
22+ 
23+#修改为当前需要跑的用例路径
24+DEFAULT_SH="./test_dapo_qwen3_32b_fsdp2_A3_1_node.sh"
25+echo "Use $DEFAULT_SH"
26+ 
27+ulimit -n 32768
28+mkdir logs
29+ 
30+NNODES=1
31+NPUS_PER_NODE=16
32+#修改为对应主节点IP
33+MASTER_ADDR="IP FOR MASTER NODE"
34+#修改为当前节点的通信网卡
35+SOCKET_IFNAME="Your SOCKET IFNAME"
36+export HCCL_SOCKET_IFNAME="SOCKET IFNAME FOR CURRENT NODE"
37+export GLOO_SOCKET_IFNAME="SOCKET IFNAME FOR CURRENT NODE"
38+#获取当前节点IP
39+CURRENT_IP=$(ifconfig $SOCKET_IFNAME | grep -Eo 'inet (addr:)?([0-9]{1,3}\.){3}[0-9]{1,3}' | awk '{print $NF}')
40+if [ "$MASTER_ADDR" = "$CURRENT_IP" ]; then
41+ # 主节点启动
42+ ray start --head --port 6766 --dashboard-host=$MASTER_ADDR --node-ip-address=$CURRENT_IP --dashboard-port=8260 --resources='{"NPU": '$NPUS_PER_NODE'}'
43+ 
44+ while true; do
45+ ray_status_output=$(ray status)
46+ npu_count=$(echo "$ray_status_output" | grep -oP '(?<=/)\d+\.\d+(?=\s*NPU)' | head -n 1)
47+ npu_count_int=$(echo "$npu_count" | awk '{print int($1)}')
48+ device_count=$((npu_count_int / $NPUS_PER_NODE))
49+ 
50+ # 判断 device_count 是否与 NNODES 相等
51+ if [ "$device_count" -eq "$NNODES" ]; then
52+ echo "Ray cluster is ready with $device_count devices (from $npu_count NPU resources), starting Python script."
53+ ray status
54+ bash $DEFAULT_SH
55+ break
56+ else
57+ echo "Waiting for Ray to allocate $NNODES devices. Current device count: $device_count"
58+ sleep 5
59+ fi
60+ done
61+else
62+ # 子节点尝试往主节点注册ray直到成功
63+ while true; do
64+ # 尝试连接 Ray 集群
65+ ray start --address="$MASTER_ADDR:6766" --resources='{"NPU": '$NPUS_PER_NODE'}' --node-ip-address=$CURRENT_IP
66+ 
67+ # 检查连接是否成功
68+ ray status
69+ if [ $? -eq 0 ]; then
70+ echo "Successfully connected to the Ray cluster!"
71+ break
72+ else
73+ echo "Failed to connect to the Ray cluster. Retrying in 5 seconds..."
74+ sleep 5
75+ fi
76+ done
77+fi
78+ 
79+sleep 600