ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

MiniMax M2.7 / M3 NPU 迁移实战:基于 PyPTO-Gym 的 MoE 融合 Grouped-GEMM 与 E2E 生成基准

MiniMax M2.7 / M3 NPU 迁移实战:基于 PyPTO-Gym 的 MoE 融合 Grouped-GEMM 与 E2E 生成基准 MiniMax M2.7 / M3 NPU 迁移实战基于 PyPTO-Gym 的 MoE 融合 Grouped-GEMM 与 E2E 生成基准【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址: https://gitcode.com/cann/pypto-gym本文以 PyPTO-Gym 仓库中 MiniMaxM2.7 / M3迁移工作为核心讲解如何用同一套推理 / 基准脚本、通过--variant {m27,m3}参数切换两个模型变体在 Ascend 910B 上把 MoE 专家 FFN 路由到 PyPTO 融合 grouped-GEMM 算子并完成单提示词推理、三段式prefill / decode / 端到端E2E 生成基准与 NPUGraph 捕获回放基准。读完本文你将掌握 MiniMax 两代 MoE 模型在 NPU 上的完整迁移链路模型下载与补丁、FP8 权重流式反量化、融合算子开关与 tile 参数、四臂基准驱动与 JSON 报告解析以及算子层的循环结构、权重布局与精度校验方式。迁移架构总览MiniMax M2.7 与 M3 在仓库中共享同一套 bench / runner 脚本模型选择完全由--variant {m27,m3}决定见 ask_minimax.py 与 bench_minimax.py。两条迁移路径的核心思路一致MoE 专家 FFN 路由到共享的 PyPTO 融合 grouped-GEMM 算子一次 kernel 调用完成所有被路由专家的mm1 → activation → mm2替代原先逐 expert 的 Python 循环路由专家权重在 host 侧保持 FP8按层流式反量化dequant到 BF16再送入 kernel--streaming默认开启使完整的大模型权重能够装入单 die路由gating、共享专家、注意力、RMSNorm、RoPE 等留在 host 侧由 PyTorch 执行PyPTO 只接管计算密集的专家 FFN 段。从源码结构看两变体的差异被刻意收敛到极小范围bench_minimax.py 中_VARIANTS字典只有display模型名、activation传给融合 kernel 的激活名M2.7 为siluM3 为swigluoai、vec_tileUB 适配的向量 tileM2.7 为 128M3 为 256三处ask_minimax.py 的_VARIANTS更是只有display与vec_tile。参数解析、环境准备、warmup、输入构造、generate 循环、计时与报告全部走共享代码路径。模型信息与运行环境两个变体的关键模型超参对比如下来自 modeling/transformers/minimax/README.md字段M2.7--variant m27M3--variant m3hidden_size (H)30726144moe_intermediate_size (I)15363072num_experts (E)256128top_k84专家激活SiLU-SwiGLUsiluclamped GLUswigluoai代码来源仓库内置无需trust_remote_code仓库内置无需trust_remote_code权重精度FP8 block-quant流式反量化到 BF16FP8MXFP8流式反量化到 BF16补充模型背景MiniMax-M2.7 为 228.7B 的 MoE 语言模型256 专家、top-8、sigmoid e_score_correction_bias路由MiniMax-M3 为约 428B 总量 / 约 23B 激活的原生视觉-语言 MoE 模型本文只加速其文本骨干的 MoE 专家 FFN128 路由专家、top-4、swigluoai激活。这些信息均可在 minimax_m27 集成说明 与 minimax_m3 集成说明 中核实。迁移所依赖的软件栈同上 README 的 Environment 表以当前仓库实际内容为准字段版本torch_npu2.10transformers4.57.1pypto0.2.1pto-isav9.1.0CANN9.1.0NPUAscend 910B3其中 transformers 4.57.1 是代码基线仓库内置的MiniMaxM2/MiniMaxM3建模代码即从该版本复制而来因此运行时不需要trust_remote_code建模代码见 src/pypto_gym/transformers/minimax_m27/ 与 src/pypto_gym/transformers/minimax_m3/。仓库代码与归档映射README 给出了迁移产物的归档映射目标路径均为仓库根下的相对位置源目标{pypto_gym_repo}/动作ask_minimax.py/bench_minimax.py/bench_minimax.shmodeling/transformers/minimax/覆盖modeling_minimax_m27.pysrc/pypto_gym/transformers/minimax_m27/覆盖modeling_minimax_m3.pysrc/pypto_gym/transformers/minimax_m3/覆盖grouped-GEMM / MSA 算子src/pypto_gym/ops/pypto_tensor/minimax/覆盖算子测试tests/ops/minimax_m27/、tests/ops/minimax_m3/新增当前仓库实际布局与之一致推理 / 基准脚本位于 modeling/transformers/minimax/含ask_minimax.py、bench_minimax.py、bench_minimax.sh与共享加载入口_variant.py算子实现位于 src/pypto_gym/ops/pypto_tensor/minimax/测试位于 tests/ops/minimax_m27/ 与 tests/ops/minimax_m3/。环境准备与模型下载从 README 的 Usage 出发完整流程分三步# --- M2.7 --- export MODEL_PATH/path/to/MiniMax-M2.7 python3 ../download_hf_model.py --model-id MiniMaxAI/MiniMax-M2.7 --output-dir $MODEL_PATH python3 ../runtime_patch.py --model-family minimax_m27 --model-path $MODEL_PATH # --- M3 --- export MODEL_PATH/path/to/MiniMax-M3 python3 ../download_hf_model.py --model-id MiniMaxAI/MiniMax-M3 --output-dir $MODEL_PATH python3 ../runtime_patch.py --model-family minimax_m3 --model-path $MODEL_PATH其中download_hf_model.py与runtime_patch.py位于 modeling/transformers/ 目录由各模型目录共用仓库中亦有 download_hf_model.py 与 runtime_patch.py 源文件。对于 M3若使用 FP8 checkpoint如MiniMaxAI/MiniMax-M3-MXFP8同样通过--model-id指定即可。注意--model-path命令行参数会覆盖$MODEL_PATH环境变量见 ask_minimax.py 与 bench_minimax.py 中defaultos.environ.get(MODEL_PATH)的默认值逻辑。单提示词推理ask_minimax.py推理入口 ask_minimax.py 用于在单 die 上跑一次文本生成通过--variant选择模型与激活MODEL_PATH/path/to/MiniMax-M2.7 python3 ask_minimax.py --variant m27 --device NPU MODEL_PATH/path/to/MiniMax-M3 python3 ask_minimax.py --variant m3 --device NPU --use_pypto常用参数源码 parse_args参数默认值说明--variant必填m27或m3选择模型变体--model-path$MODEL_PATHcheckpoint 路径缺省时报错退出--device$TILE_FWK_DEVICE_ID或 0NPU 设备号--promptExplain mixture-of-experts routing in one paragraph.输入提示词--max-new-tokens128生成的最大新 token 数--max-layersNone只加载前 N 层smoke test--streaming/--no-streamingTrue路由专家 FP8 留 host、逐层反量化默认开--use_pyptoFalse将 MoE FFN 路由到 PyPTO 融合 kernel脚本内部会做三件关键事见 main根据变体设置PYPTO_VEC_TILEos.environ.setdefaultM2.7128 / M3256这是 UB 适配的向量 tile开启torch_npu.npu.config.allow_internal_format True通过共享入口_variant.load_variant_model(args, dev, streaming...)构建模型——M2.7 会先设置USE_PTO_GROUPED_GEMM True再走build_model → load_streaming_state_dict → attach_expert_fp8 → materialize_meta_buffers → patch_moe五步装配M3 则直接调用其load_model入口见 _variant.py。加载完成后日志会打印patched N MoE block(s) with the PyPTO kernelN即为被融合算子接管的 MoE 块数量。E2E 生成基准bench_minimax.pybench_minimax.py 是真实生成式token-generating基准不是重复 forward 的微基准它运行真正的model.generate()自回归循环、统计实际产出的 token 数并对--iters次生成取平均值mean ± std而非 best-of。吞吐按服务基准常用的三段式分解prefillgenerate(max_new_tokens1)摄取提示词并吐出首个 token即 TTFTtok/s prompt_len / prefill_timedecode稳态逐 token 循环total - prefill对应剩余N-1个 tokentok/s (N-1) / decode_timeboth完整端到端生成tok/s N / total_time。四臂arms设计一个进程跑一个臂bench_minimax.sh负责串联并汇总 JSON 报告臂说明eager原生逐专家 MoE FFN 循环仅 M3 提供M2.7 始终走融合 kernelpypto路由专家 FFN 走 PyPTO 融合 grouped-GEMM流式 FP8 专家graphvecgraphNPUGraph 捕获固定窗口、逐生成 token 回放NPU 友好的向量化 FFNpyptographpyptographNPUGraph 捕获 融合 grouped-GEMM图臂的静态 MoE 路由会把每个 token 都送到前top_k个专家因此只有这些专家会被反量化FP8→BF16到 die 上一次并被捕获。融合 kernel 的kernel 级收益Eager vs PyPTO由本地算子微基准单独测量WARMUP5 / ITERS20不随仓库分发kernel 正确性则由仓库内测试 tests/ops/minimax_m27/ 与 tests/ops/minimax_m3/ 覆盖。关键参数参数默认值说明--variant必填m27/m3--max-new-tokens64每次生成的目标 token 数 N--max-layersNone只加载前 N 层M3 需 ≥4 才能覆盖 MoE 层--warmup2warmup 生成次数吸收 JIT 编译--iters5计时生成次数取平均--streamingTrueFP8 留 host 逐层反量化FP8 ckpt 必需--use_pyptoFalseMoE FFN 走 PyPTO kernel--graphFalse启用 NPUGraph 捕获/回放--graph-window32图捕获的固定窗口 W--report-fileNoneJSON 报告输出路径--moe-impl/--seq/--route/--active/--prompt-text—兼容旧版 m27 8-die shell 参数当前版本会归一化为共享开关--moe-impl pypto等价--use_pypto对 m3 为 no-op图臂实现的工程要点图臂通过_install_static_moe_m27/_install_static_moe_m3见 bench_minimax.py把每个 MoE 块的 forward 替换为静态路由版本M2.7 先将前top_k个专家反量化到设备并拍平成w13_flat/w2_flatM3 强制所有注意力走稠密 GQA绕过 MSA indexer使整个 decoder 可被 NPUGraph 捕获。回放循环在 host 侧做 argmax 选 token 与窗口滑动。源码注释里还记录了踩坑经验expert_cumsum声明为 host-ready若在捕获区域内重建它arangehost 端读取会强制一次捕获中途的 device→host 同步导致回放调度过期、触发 aicore 507011 错误——因此静态路由下expert_cumsum必须在捕获前缓存一次并复用持久 tensorM3 侧对应block.experts.static_cumsum_cache True。Shell 驱动bench_minimax.shbench_minimax.sh 是统一驱动脚本变体通过VARIANT环境变量或第一个位置参数传入MODEL_PATH/path/to/MiniMax-M3 VARIANTm3 DEVICE0 bash bench_minimax.sh MODEL_PATH/path/to/MiniMax-M2.7 bash bench_minimax.sh m27支持的 env 配置变量默认值说明VARIANT第一个位置参数或m27m27/m3MODEL_PATH必填checkpoint 路径DEVICETILE_FWK_DEVICE_ID或 0NPU 设备号LAYERS4适配单 die 的层切片M3 ≥4 才含 MoE 层置空表示全部层NEW_TOKENS32每次测量生成的 token 数 NWARMUP1warmup 次数ITERS5计时次数WINDOW32图臂固定捕获窗口PROMPTHello.输入文本ARMSm27:pypto,vecgraph,pyptographm3:eager,pypto,vecgraph,pyptograph要跑的臂子集REPORT_DIR脚本所在目录JSON 报告输出目录脚本固定导出的环境包括PYPTO_VEC_TILE默认 128、TE_PARALLEL_COMPILER1、PYTORCH_NPU_ALLOC_CONFexpandable_segments:True并把PYTHONPATH指向仓库src。当指定LAYERS时会给公共参数追加--max-layers与--no-streaming。各臂输出bench_latest_{eager,pypto,vecgraph,pyptograph}.json最后由内嵌 Python 打印汇总表arm prefill decode e2e (tok/s) -------------------------------------------------- eager ... ... ... pypto ... ... ... vecgraph ... ... ... pyptograph ... ... ...若vecgraph与pyptograph都产出了 decode 吞吐还会额外打印PyPTOgraph / vecgraph x.xx x的端到端图臂比值。算子层原理融合 Grouped-GEMM 与 MSAminimax_moe_grouped_gemm核心算子 minimax_grouped_gemm_impl.py经init.py 以grouped_gemm名字导出在一次 kernel 调用中完成所有专家的mm1 → activation → mm2BF16 输入输出、FP32 累加。两个变体仅activation参数不同详见 ops README变体activation激活公式tile 默认值VEC_TILE / CUBE_NBUF / VEC_NBUF / L1M2.7siluSiLU(gate) * up128 / 2 / 2 / 2M3swigluoai(clamp(up) 1) * (gate * sigmoid(alpha * gate))256 / 4 / 1 / 3M3 的 swigluoai 参数来自其 configalpha 1.702、limit 7.0。所有 tile 旋钮与 alpha/limit 均可用环境变量覆盖PYPTO_VEC_TILE、PYPTO_CUBE_NBUFFER、PYPTO_VEC_NBUFFER、PYPTO_L1_REUSE、PYPTO_MM*、PYPTO_SWIGLU_ALPHA、PYPTO_SWIGLU_LIMIT。循环结构pypto.loop遍历 expert、pypto.loop_unroll遍历 tokenEXPERT_LOOP — 遍历 expert偏移从 expert_cumsum 动态获取 LOOP_TOKEN (unroll)— 每个 expert 的 token 按 unroll_list 分块 mm1: tile_x w13_e → gate_up [tile_batch, 2*I] FP32 activation (silu/swigluoai) → cast BF16 mm2: sw w2_e → down [tile_batch, H] FP32 → cast BF16 assemble → result权重布局上F.linear约定的gate_up_proj [E, 2*I, H]与down_proj [E, H, I]经convert_minimax_weights转换为 direct-matmul 格式的w13_flat [E*H, 2*I]与w2_flat [E*I, H]。Dtype 流转为输入/权重 BF16 → mm1 到 FP32 → 激活全程 FP32 → 中间 cast 回 BF16 → mm2 到 FP32 → 输出 cast 回 BF16。Kernel 签名minimax_moe_grouped_gemm( sorted_tokens, # [N_total, H] BF16 — 按 expert 预排序的 tokens weights, # (w13_flat, w2_flat) BF16 — 转换后的权重 expert_cumsum, # [E1] INT32 — 各 expert 累计 token 数 result, # [N_total, H] BF16 — 输出缓冲 dims, # MoeDims(num_experts, hidden_size, intermediate_size, activation) )M3 MSA 稀疏注意力算子补充背景M3 文本骨干的稀疏注意力在 ops README 中另有三个 PyPTO kernelminimax_m3_msa_indexerlightning indexer4 个 index-query head 打分、128-token block max-pool、top-k 选 16 个 block 并强制保留最近 local block、minimax_m3_msa_sparse_decode在选中 block 上做 block-sparse online-softmax flash attention、msa_main_branchGQA-batched flash attention16 个 Q head 共享 1 个 KV head 并 batch 进 cube M 轴。它们服务于长上下文稀疏路径与本文聚焦的文本推理 / 基准主流程属于同一迁移工程但当前推理基准默认走稠密 GQA 路径M3 图臂即显式is_sparseFalse。README 同时注明对 M3 decode 形状原生npu_fused_infer_attention_scorepaged block-sparse目前比该 PyPTO kernel 快约 5x该 kernel 为 PyPTO-native MSA 路径原生算子为性能目标。模型集成与权重加载开关变量USE_PTO_GROUPED_GEMM定义于 src/pypto_gym/ops/pypto_tensor/minimax/init.py是唯一控制 MoE FFN 是否走融合 kernel 的开关默认Falseopt-in与 llada2_moe / gemma4_31b_it 的接入方式一致由入口脚本按次开启。patch_moeM3 侧通过is_minimax_m3_moeduck-type 检查遍历每个 MoE 块在开启时把专家容器的 forward 重绑到 PyPTO 路径。两条权重路径prebuilt预构建一次性把全部专家反量化为 BF16 平铺权重MoE 显存约 1xstreaming流式专家权重保持 FP8 于 host每次 forward 只把被路由的专家反量化到设备——这是完整 62 层 M2.7 单 die 装下与M3 单 die 只装约一层激活专家的关键机制见 minimax_m27 README 与 minimax_m3 README。M3 的量化约束M3 全 BF16 checkpoint 约 856 GB无法装入单颗 910B die因此基准使用FP8 weight-onlycheckpoint如MiniMaxAI/MiniMax-M3-MXFP8kernel 是 BF16 计算weight-only FP8 经 block 反量化复用_dequant_fp8_block到 BF16 即可把专家显存减半且无需激活量化——由于没有 INT8 kernelW8A8 的A8在此处无收益。M3 加载器会剥离language_model.前缀并跳过 vision / projector / MSA-indexer / MTP 张量其 key 重映射与真实 checkpoint 的 22665/22665 个文本张量完全对齐0 missing / 0 unexpected。测试与精度校验算子正确性由仓库内测试覆盖M2.7 grouped-GEMMsilutests/ops/minimax_m27/test_minimax_m27_grouped_gemm.py用例case_001E8, H3072, I1536counts 含零 token 专家M3 grouped-GEMMswigluoaitests/ops/minimax_m3/test_minimax_m3_grouped_gemm.py用例case_smoke_edgeE4, H256, I128counts[1,0,3,4]覆盖不均匀路由与 clampMSA indexer sparse decodetests/ops/minimax_m3/test_minimax_m3_msa_pypto.py含短上下文保护nb≤TOPK 时返回arange(nb)与 indexer→attention 端到端用例。运行方式export TILE_FWK_DEVICE_ID0 python3 -m pytest tests/ops/minimax_m27/ python3 -m pytest tests/ops/minimax_m3/精度判据见 ops READMEGrouped-GEMM 用numpy.testing.assert_allclosertol 0.008~0.015、atol 0.008~0.5视变体与 clamp 覆盖而定MSA indexer 选中的 block id 集合与 torch reference完全一致MSA sparse decode / main branch 的 max_diff 5e-2。使用注意事项M3 层结构layers 0–2 为稠密层、layer 3 起才是 MoE因此--max-layers至少设为 4 才能触达 grouped-GEMM 路径——脚本在m3 use_pypto n_patched0时会打印显式警告见 bench_minimax.pyM2.7 无 eager 臂M2.7 始终流式走融合 kernel只有 M3 提供完整的四臂集合bench_minimax.sh 中DEFAULT_ARMS即体现了这一差异FP8 checkpoint 前提M3 跑完整层数需要 FP8MXFP8checkpoint--max-layers较小层数可用于 BF16 快速 smoke testkernel 级与 E2E 级的分层验证Kernel 半Eager vs PyPTO的微基准保持在本地WARMUP5 / ITERS20仓库内以算子测试保证正确性E2E 半由本 README 对应的脚本产出运行环境前提脚本强依赖torch_npu缺失时直接ImportError并假设 Ascend 910B 类环境PYPTO_VEC_TILE取值即按 910B 的 192 KB UB 设计M3 的 H6144 使PYPTO_VEC_TILE256成为必要的上限。【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址: https://gitcode.com/cann/pypto-gym创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表