跳转至

Qwen3-30B-A3B SFT训练

#!/bin/bash                          # 指定脚本使用 bash 解释器执行

set -x                              # 打印执行的每一条命令(调试用)

source /root/.bashrc                # 加载当前用户的环境变量配置

MEGATRON_PATH=${MEGATRON_PATH:-"/workspace/AIAK-Megatron"}   # Megatron代码路径(默认值)
AIAK_TRAINING_PATH=${AIAK_TRAINING_PATH:-"/workspace/AIAK-Training-LLM"}  # 训练框架路径

DATA_PATH=${DATA_PATH:-"/data/dataset/alpaca_data_en_52k.json"}  # 训练数据路径
DATA_CACHE_PATH=${DATA_CACHE_PATH:-"/data/qwen3/dataset/sft_aplaca_en_data_cache"}  # 数据缓存路径
DATASET_CONFIG_PATH=${DATASET_CONFIG_PATH:-"/workspace/AIAK-Training-LLM/configs/sft_dataset_config.json"}  # 数据集配置文件路径

TOKENIZER_PATH=${TOKENIZER_PATH:-"/data/Qwen3-30B-A3B/"}     # tokenizer路径(HF模型目录)
CHECKPOINT_LOAD_PATH=${CHECKPOINT_LOAD_PATH:-"/data/Qwen3_30B_mcore_tp2pp2ep2"}  # 加载模型权重路径
CHECKPOINT_SAVE_PATH=${CHECKPOINT_SAVE_PATH:-"/data/Qwen3_30B_mcore_tp2pp2ep2_save"}  # 保存模型路径
TENSORBOARD_PATH=${TENSORBOARD_PATH:-"/data/tensorboard-log/qwen3-30b.sft.xpu"}  # tensorboard日志路径
mkdir -p ${TENSORBOARD_PATH}      # 创建tensorboard目录(如果不存在)
GPUS_PER_NODE=8                   # 每个节点使用8张卡

export CUDA_VISIBLE_DEVICES="0,1,2,3,4,5,6,7"  # 指定可见GPU
#export DIST_MULTI_STREAM=false   # 是否开启多流(未启用)
export CUDA_DEVICE_MAX_CONNECTIONS=1  # 控制CUDA连接数(优化通信)

######################kunlun##########################
# bf16类型专用(megatron相关变量参考<百舸megatron专用>)
export USE_FAST_BF16_FC=true                    # 使用bf16加速全连接层
export FORCE_DISABLE_INPLACE_BF16_CAST=false    # 是否关闭inplace bf16转换

export BKCL_RDMA_NICS="eth1,eth1,eth2,eth2,eth3,eth3,eth4,eth4" # RDMA网卡绑定(多机通信)
export BKCL_SOCKET_IFNAME=eth0                  # 指定socket网卡
export BKCL_TREE_THRESHOLD=0                    # BKCL树通信阈值
export BKCL_FORCE_L3_RDMA=0                     # 是否强制L3 RDMA
export BKCL_ENABLE_XDR=1                        # 启用XDR优化
export BKCL_ALL_TO_ALL_OPT=1                    # all-to-all优化
export BKCL_RING_HOSTID_USE_RANK=1              # 用rank作为host id
#export BKCL_FORCE_SYNC=1                       # 强制同步(关闭)
#export BKCL_DEBUG=1                            # debug模式(关闭)
export BKCL_RDMA_VERBS=1                        # 启用verbs(多机pp4必须)

export XMLIR_PARALLEL_SAVE_MEMORY=true         # 节省显存(但性能下降)
export XMLIR_BATCH_PARALLEL=false               # batch并行关闭
export SAVE_LOG_FILE_WITH_RANK_ID=false         # 日志是否按rank分文件
export XMLIR_LOG_PATH="log-path"                # 日志路径
export XMLIR_LOG_PREFIX="log-file-prefix"       # 日志前缀
export P800_DEBUG=false                         # debug模式(nan检测)
export P800_DUMP_DIR="ckpt-dump-dir-path"       # dump路径
export XMLIR_DIST_ASYNC_ISEND_IRECV=true        # 异步通信
export XMLIR_CUDNN_ENABLED=1                    # 启用cuDNN

# LINEAR 开关
export XMLIR_ENABLE_LINEAR_FC_FUSION=1          # linear融合开关
export XDNN_FC_GEMM_DTYPE=int32_with_ll         # GEMM计算类型
export XMLIR_MEGATRON_CORE_AIAK_PLUGIN=1        # 启用AIAK插件

XFLAGS --disable megatron_core_aiak             # 禁用某些插件
XFLAGS --disable transformer_engine_1_7         # 禁用TE 1.7
XFLAGS --disable transformer_engine_1_13        # 禁用TE 1.13
######################################################

# Change for multinode config
MASTER_ADDR=${MASTER_ADDR:-"localhost"}       ## master节点地址
MASTER_PORT=${MASTER_PORT:-"6000"}            ## master端口
NNODES=${WORLD_SIZE:-"1"}                     ## 总节点数
NODE_RANK=${RANK:-"0"}                        ## 当前节点编号

DISTRIBUTED_ARGS=(
    --nproc_per_node $GPUS_PER_NODE           # 每个节点进程数(=GPU数)
    --nnodes $NNODES                          # 节点数
    --node_rank $NODE_RANK                    # 当前节点rank
    --master_addr $MASTER_ADDR                # 主节点IP
    --master_port $MASTER_PORT                # 主节点端口
)

MODEL_ARGS=(
    --model-name qwen3-30b-a3b                # 模型名称
    --rotary-base 1000000                     # RoPE基数
    --rotary-seq-len-interpolation-factor 1   # RoPE插值因子
)

DATA_ARGS=(
    --tokenizer-type HFTokenizer              # tokenizer类型
    --hf-tokenizer-path $TOKENIZER_PATH       # tokenizer路径
    --data-path $DATA_PATH                    # 数据路径
    --split 100,0,0                           # 数据划分(全训练)
)

SFT_ARGS=(
    --chat-template alpaca                    # 使用alpaca模板
    --sft-num-preprocess-workers 8            # 数据预处理线程数
    --no-check-for-nan-in-loss-and-grad       # 不检查nan
    --packing-sft-data                        # 启用packing
)

TRAINING_ARGS=(
    --training-phase sft                      # 训练阶段:SFT
    --seq-length 2048                         # 序列长度
    --max-position-embeddings 2048            # 最大位置编码
    --init-method-std 0.006                   # 初始化标准差
    --micro-batch-size 1                      # 单卡batch
    --global-batch-size 128                   # 全局batch
    --lr 1.0e-5                               # 学习率
    --min-lr 1.0e-6                           # 最小学习率
    --clip-grad 1.0                           # 梯度裁剪
    --weight-decay 0.1                        # 权重衰减
    --optimizer adam                          # 优化器
    --adam-beta1 0.9                          # Adam参数
    --adam-beta2 0.95
    --adam-eps 1e-08
    --norm-epsilon 1e-6                       # 层归一化epsilon
    --train-iters 50                          # 训练步数(很小,测试用)
    --lr-decay-iters 5000                     # 学习率衰减步数
    --lr-decay-style cosine                   # cosine衰减
    --lr-warmup-fraction 0.002                # warmup比例
    --initial-loss-scale 65536                # bf16 loss scale
    --bf16                                    # 使用bf16
    --load $CHECKPOINT_LOAD_PATH              # 加载模型
    --save $CHECKPOINT_SAVE_PATH              # 保存模型
    --save-interval 500                       # 保存间隔
    --eval-interval 100                       # 评估间隔
    --eval-iters 10                           # 评估步数
    --no-load-optim                           # 不加载优化器状态
    --no-load-rng                             # 不加载随机状态
)

MOE_ARGS=(
    --moe-router-load-balancing-type aux_loss # MoE负载均衡方式
    --moe-router-topk 8                       # top-k专家
    --moe-aux-loss-coeff 1e-2                 # 辅助loss系数
)

MODEL_PARALLEL_ARGS=(
    --tensor-model-parallel-size 2            # 张量并行
    --pipeline-model-parallel-size 2          # pipeline并行
    --expert-model-parallel-size 2            # expert并行
    --sequence-parallel                       # 序列并行
    --use-distributed-optimizer               # 分布式优化器
    --distributed-backend nccl                # 通信后端
)

LOGGING_ARGS=(
    --log-interval 1                          # 日志间隔
    --tensorboard-dir ${TENSORBOARD_PATH}     # tensorboard路径
    --log-timers-to-tensorboard               # 记录性能指标
)

if [ -n "${WANDB_API_KEY}" ]; then
    LOGGING_ARGS+=(
        --wandb-project ${WANDB_PROJECT}      # wandb项目
        --wandb-exp-name ${WANDB_NAME}        # wandb实验名
    )
fi

PYTHONPATH=$MEGATRON_PATH:$AIAK_TRAINING_PATH:$PYTHONPATH \  # 设置python路径
    torchrun ${DISTRIBUTED_ARGS[@]} \                      # 启动分布式训练
    $AIAK_TRAINING_PATH/aiak_training_llm/train.py \       # 训练脚本
    ${MODEL_ARGS[@]} \                                     # 模型参数
    ${DATA_ARGS[@]} \                                      # 数据参数
    ${TRAINING_ARGS[@]} \                                  # 训练参数
    ${SFT_ARGS[@]} \                                       # SFT参数
    ${MODEL_PARALLEL_ARGS[@]} \                            # 并行参数
    ${LOGGING_ARGS[@]}                                     # 日志参数

Megatron是什么

Megatron 是一个“训练超大语言模型的分布式引擎”


一、它到底是什么?

Megatron-LM 是由 NVIDIA 开源的一个框架,用来:

在很多GPU/加速卡上,高效训练像 GPT 这种超大模型(几十亿~万亿参数)


二、为什么需要它?

你可以这样理解:

  • 你本地训练一个小模型 → 一张卡就够
  • 但像 Qwen3-30B / GPT-3 这种模型:
  • 参数:300亿+
  • 显存需求:几百GB

一张卡根本装不下 所以必须“拆开训练”

Megatron 就是专门干这个的:

把一个大模型拆成很多份,让多张卡一起算


三、它核心做了什么?

Megatron最核心就是三种“并行”👇

1️⃣ Tensor Parallel(张量并行)

👉 把一层里的矩阵拆开

比如:

一个大矩阵 → 分给 8 张卡分别算

2️⃣ Pipeline Parallel(流水线并行)

👉 把模型按层拆

GPU1:前几层
GPU2:中间层
GPU3:后几层

像流水线一样一层层传


3️⃣ Data Parallel(数据并行)

👉 多份模型,同时吃不同数据

卡1:训练样本A
卡2:训练样本B

👉 你脚本里这几行就是它的核心:

--tensor-model-parallel-size 2
--pipeline-model-parallel-size 2
--expert-model-parallel-size 2

意思是:

👉 你在用 Megatron 把模型拆成 2×2×2 = 8 份,在 8 张卡上跑


四、它和 PyTorch 什么关系?

  • PyTorch:基础框架(会写模型)
  • Megatron:高级加速器(帮你“分布式训练大模型”)

👉 类比:

角色 类比
PyTorch 发动机
Megatron 涡轮增压 + 变速箱

五、你现在这个脚本在干嘛(结合你)

你现在不是“写模型”,而是在:

👉 用 Megatron 做:

  • Qwen3-30B
  • SFT微调
  • 8卡训练
  • 多并行(TP+PP+EP)

👉 本质就是:

用工业级方式训练大模型,而不是玩具级训练

AIAK是什么

👉 AIAK = 一套“让大模型在特定国产/异构硬件上跑得更快”的增强层(插件 + 运行时 + 适配层)


它和 Megatron 的关系

你现在的技术栈其实是:

Megatron(训练框架)
   ↓
AIAK(加速/适配层)
   ↓
底层硬件(GPU / 昆仑芯 XPU 等)

👉 类比一下:

层级 作用
Megatron 负责“怎么训练模型”
AIAK 负责“怎么在这块硬件上跑得更快”

二、AIAK到底干了什么?

从你脚本里其实已经暴露了很多👇

1️⃣ 算子加速(最核心)

比如你看到这些:

export USE_FAST_BF16_FC=true
export XMLIR_ENABLE_LINEAR_FC_FUSION=1
export XDNN_FC_GEMM_DTYPE=int32_with_ll

👉 本质是在干:

把 PyTorch / Megatron 的算子 👉 替换成 更快的底层实现(xblas / xdnn / 自研算子)


2️⃣ 图编译 / IR优化

export XMLIR_***

👉 XMLIR = 一种中间表示(类似编译器)

作用:

把计算图重新编译 → 更高效执行

类似:

  • TensorRT(推理)
  • XLA(Google)
  • TorchInductor

3️⃣ 通信优化(重点)

你脚本里一堆:

export BKCL_***

👉 这是:

  • 类似 NCCL
  • 但用于国产/自研硬件(比如昆仑芯)

作用:

多卡之间传数据更快(AllReduce / AllToAll)


4️⃣ 分布式调度增强

export XMLIR_DIST_ASYNC_ISEND_IRECV=true

👉 作用:

通信异步化 → 减少等待 → 提升吞吐


5️⃣ 显存优化

export XMLIR_PARALLEL_SAVE_MEMORY=true

👉 本质:

用性能换显存(你现在很可能就靠这个在撑)


三、为什么会有 AIAK?

因为:

👉 Megatron 本来是为 NVIDIA GPU 写的(CUDA生态)

但现实是:

  • 有昆仑芯(XPU)
  • 有昇腾
  • 有其他AI芯片

👉 这些硬件:

  • 指令不一样
  • 通信库不一样
  • 算子实现不一样

所以必须有一层:

👉 “兼容 + 加速 + 重写算子”的中间层

👉 这就是 AIAK


四、你可以这样理解(非常重要)

👉 Megatron:

“我要训练一个大模型”

👉 AIAK:

“我帮你把这个训练,在这台机器上跑到极限性能”


五、为什么你现在会遇到很多奇怪问题?

因为你现在用的是:

Megatron + AIAK + XPU + MoE + 多并行

👉 这是一个:

复杂度指数级爆炸的组合

常见问题来源:

  • BKCL通信挂
  • XMLIR编译问题
  • 算子不兼容
  • 并行策略冲突
  • checkpoint格式不一致

六、你脚本里最关键的一行

export XMLIR_MEGATRON_CORE_AIAK_PLUGIN=1

👉 意味着:

你启用了 AIAK 对 Megatron 的深度接管

不是简单加速,而是:

👉 很多核心执行路径已经被 AIAK 替换了


七、总结一句话

👉 AIAK = Megatron 的“硬件适配 + 极致加速外挂”