在 Ascend NPU 上微调和预训练 LLM

使用基于 Workbench 的配方,在带有 Huawei Ascend NPU 的 arm64 节点上运行全参数 SFT 和预训练。这些 notebook 直接在附加了多个 NPU 的单个 Workbench 容器中运行训练(不使用 VolcanoJob)。

NotebookWorkbench 镜像工作负载
qwen3_finetune_verify.ipynbPyTorch CANNQwen3-8B 的全参数 SFT(MindSpeed-LLM)
qwen25_pretrain_verify.ipynbPyTorch CANNQwen2.5-7B 的预训练(MindSpeed-LLM)
qwen3_0.6b_finetune_verify.ipynbMindSpore CANNQwen3-0.6B 的全参数 SFT(捆绑 MindSpeed-Core-MS 和 MindSpeed-LLM)

三个 notebook 都采用验证优先的方式:默认使用较短的序列和较少的迭代次数,以便在扩展规模前确认运行时、模型加载、预处理和分布式启动路径。PyTorch CANN 镜像捆绑了 Python 3.12、CANN 8.5.0、PyTorch 2.9.0 和 torch_npu 2.9.0。

开始之前

  • 已安装 Ascend 驱动、CANN 运行时和 Kubernetes device plugin;你的 Workbench 可以调度到 arm64 Ascend 节点。
  • PyTorch 示例需要至少 4 个 NPU;MindSpore notebook 针对 2× Ascend 910B 32G 进行了调优,使用 TP=1、PP=1、MBS=2。
  • 工作区使用持久化存储,并为 HuggingFace 模型和转换后的 Megatron / MCore 权重预留足够空间。
  • 网络:PyTorch notebook 运行时从 https://gitcode.com/ascend/MindSpeed-LLM.git 克隆 MindSpeed-LLM。如果 Workbench 无法访问该仓库,请将本地副本放入工作区,并更新第一个单元格中的路径。MindSpore notebook 使用 /opt/app-root/share/MindSpeed-Core-MS 下捆绑的目录树,不会进行克隆。

按照创建 Workbench创建 Workbench(PyTorch CANN 或 MindSpore CANN),然后通过 JupyterLab 文件浏览器上传 notebook。

准备基础模型

每个 notebook 都需要在以下位置提供 HuggingFace 格式的模型:

NotebookHF_MODEL_DIR 默认值
微调/opt/app-root/src/models/Qwen3-8B
预训练/opt/app-root/src/models/Qwen2.5-7B
MindSpore SFT/opt/app-root/src/models/Qwen3-0.6B

将模型文件放到该位置,或在第一个参数单元格中更改 HF_MODEL_DIR。对于有版本控制且可复用的模型,请将 artifact 存储在 S3、PVC 或 OCI registry 中。请参阅使用 Workbench 上传模型;然后在Model Registry中单独注册生成的 URI。

三个 notebook 都会在训练前将 HF 转换为 Megatron / MCore;请预留磁盘空间以存放第二个大型权重目录。

准备数据集

微调数据(Alpaca 风格 JSONL)

两个微调 notebook 都需要:

  • ALPACA_PARQUET = /opt/app-root/src/datasets/alpaca/train-00000-of-00001-a09b74b3ef9c3b56.parquet
  • RAW_DATA_FILE = .../finetune_dataset/alpaca_sample.jsonl(位于 notebook 的工作目录下)

如果 parquet 文件存在,notebook 会自动将其转换为 JSONL。如果已有 JSONL,请将其放置在 RAW_DATA_FILE,或更新该变量。记录格式如下:

{ "instruction": "...", "input": "...", "output": "..." }

通过更改参数单元格中的 handler,可以替换为 ShareGPT 和 Pairwise 格式。

预训练数据(原始文本)

MindSpeed-LLM 预处理接受 .parquet、.json、.jsonl 和 .txt。结构化格式需要 text 字段;纯文本则需要每行一个片段。默认路径为同一个 ALPACA_PARQUET;如果该路径不存在,notebook 会回退到内置示例,因此你仍可验证整个流程。

对于更大的数据集,请挂载 PVC 或从平台数据集仓库拉取——请参阅使用 Workbench 微调 LLM。

运行 notebook

每个 notebook 的流程结构相同:

  1. 环境检查——确认 torch_npu(或 mindspore + msadapter)、MindSpeed 和 MindSpeed-LLM 可导入,并确认可用 NPU 数量与 TP × PP 匹配。
  2. 数据集准备——将 parquet 转换为 JSONL(或在预训练中回退到内置示例)。
  3. HF → MCore 权重转换——将权重写入特定于 TP/PP 的输出目录。
  4. 数据预处理——生成 MindSpeed 所需的 .bin / .idx 文件。
  5. 训练——SFT 使用 posttrain_gpt.py,预训练使用 pretrain_gpt.py。MindSpore notebook 使用 msrun 和 --ai-framework mindspore --ckpt-format msadapter,并将日志写入 .../logs。
  6. 验证——检查 latest_checkpointed_iteration.txt,列出 iter_* 目录,并(对于 PyTorch SFT)运行快速推理冒烟测试。

MindSpore SFT notebook 与上游 Qwen3 路径保持一致:

  • examples/mindspore/qwen3/ckpt_convert_qwen3_hf2mcore.sh
  • examples/mindspore/qwen3/data_convert_qwen3_instruction.sh
  • examples/mindspore/qwen3/tune_qwen3_0point6b_4K_full_ms.sh

默认 MindSpore 参数:TP=1、PP=1、MBS=2、SEQ_LENGTH=2048、TRAIN_ITERS=100、ENABLE_THINKING=true。

需要查看的参数

各 notebook 通用:

  • HF_MODEL_DIR、OUTPUT_DIR
  • ALPACA_PARQUET 或 RAW_DATA_FILE
  • TP、PP(MindSpore 还包括 MBS)
  • SEQ_LENGTH、TRAIN_ITERS
  • ENABLE_THINKING(Qwen3)
  • MASTER_ADDR、MASTER_PORT、NNODES、NODE_RANK(MindSpore 多节点)

对于实际运行,请将 SEQ_LENGTH 提高到模型的上下文窗口,将 TRAIN_ITERS 提高到生产值,并调整并行度 / batch size 以适应可用 NPU 数量和数据集大小。如果更改 TP 或 PP,请重新运行权重转换,使 checkpoint 布局保持匹配。

输出路径

Notebook默认输出
qwen3_finetune_verify.ipynb/opt/app-root/src/Qwen3-8B-work-dir/output/qwen3_8b_finetuned
qwen25_pretrain_verify.ipynb/opt/app-root/src/Qwen2.5-7B-work-dir/output/qwen25_7b_pretrained
qwen3_0.6b_finetune_verify.ipynb/opt/app-root/src/Qwen3-0.6B-work-dir/output/qwen3_0.6b_finetuned

请将这些路径保存在持久化存储上。训练后,使用使用 Workbench 上传模型将结果上传到 S3、PVC 或 OCI registry,然后使用Model Registry将其 Model URI 注册为新的 Model Registry 版本。

注意事项

  • notebook 运行的是全参数 SFT,而非 LoRA。请将默认值视为冒烟测试配置,在正式运行前进行调优。
  • MindSpore notebook 仅验证 checkpoint 生成,不包含稳定的推理步骤。
  • 对于离线或受限集群:请在工作区预先准备 MindSpeed-LLM 仓库以及模型 / 数据集文件(PyTorch notebook)。MindSpore notebook 仅使用捆绑的源代码树。