[feat] A5 deep fused moe supported - #661
Conversation
3972f03 to
ee33ec3
Compare
| @@ -0,0 +1,53 @@ | |||
| ## DeepEP-DeepFusedMoE | |||
There was a problem hiding this comment.
这块融合算子是有相关的文档,a5只需要在a3的基础修改即可,无需新启文件。
| uint64_t shareX1MxScaleNum = x1MxScaleNum; | ||
| uint64_t x2MxScaleNum = CeilUp(Ceil(gmm2HLen, 32), 2); | ||
| uint64_t shareX2MxScaleNum = CeilUp(Ceil(shareGmm2HLen, 32), 2); | ||
| ; |
There was a problem hiding this comment.
有孤立分号;同一函数还保留了注释掉的 workspace 计算。
| size_t x1TokenSize = MxActStorageBytes(shareExpertTokenNum * h + maxTokenNum * h, isMxFp4); | ||
| size_t x2TokenSize = MxActStorageBytes(shareExpertTokenNum * shareGmm2HLen + maxTokenNum * gmm2HLen, isMxFp4); | ||
| size_t maxTokenSize = CeilUp(x1TokenSize < x2TokenSize ? x2TokenSize : x1TokenSize, GM_ALIGN_SIZE); | ||
| // size_t tokenScaleSize = CeilUp((shareExpertTokenNum + maxTokenNum) * sizeof(float), GM_ALIGN_SIZE); |
| @@ -0,0 +1,295 @@ | |||
| #ifndef DEEPEP_OP_KERNEL_PROFILING_COMMON_PROFILE_PROTOCOL_COMMON_H | |||
There was a problem hiding this comment.
profiling 协议被复制两份,已出现漂移
Host 和 kernel 分别维护近乎相同的协议头:
csrc/deepep/profiling/common/profile_protocol_common.h
csrc/deepep/ops/op_kernel/profiling/common/profile_protocol_common.h
当前两者已经存在 API 差异,后续字段布局或常量变更很容易导致 host/kernel 静默不兼容。
建议:抽取唯一共享协议头;若受编译环境限制,至少加入构建期一致性校验或由同一模板生成。
| static_cast<bool>(EXEC_FLAG & EXEC_FLAG_SMOOTH_QUANT), | ||
| false, EXEC_FLAG> | ||
| dispatcher; | ||
| dispatcher.Init(gmX_, gmexpertIds_, gmSmoothScales_, gmShareSmoothScales_, xActiveMask_, gmShareX1, gmX1, |
There was a problem hiding this comment.
Init 签名(cam_moe_distribute_dispatch.h)第 5/6 参数为 shareX1Token / xActiveMask,但调用处写反:
dispatcher.Init(gmX_, gmexpertIds_, gmSmoothScales_, gmShareSmoothScales_, xActiveMask_, // ← 实参5 传入 shareX1Token 位 gmShareX1, // ← 实参6 传入 xActiveMask 位 gmX1, ...);
QuantForShareExpert() 把量化后的 shared-expert token 写进 xActiveMask 缓冲(破坏掩码);TokenActiveMaskCal() 从 gmShareX1 读掩码得到垃圾activeMaskBsCnt_
触发条件: moeExpertNumPerRank == 1(tiling 仅在 != 1 时置 EXEC_FLAG_DEEP_FUSE)。PR 测试用 64 experts / EP8 = 8 experts/rank,未覆盖此路径。
修复: 交换两个实参为 gmShareX1, xActiveMask_。
| if constexpr ((EXEC_FLAG & EXEC_FLAG_DEEP_FUSE) == 0) { | ||
| if constexpr (g_coreType == AscendC::AIV) { | ||
| AscendC::TPipe tpipe; | ||
| MoeDistributeDispatchImpl::CamMoeDistributeDispatch<ExpandXType, int8_t, false, true, |
There was a problem hiding this comment.
非 deep-fuse 分支实例化 CamMoeDistributeDispatch<ExpandXType, int8_t, false, true, ...>,其 QuantProcess() 产出普通 int8 对称量化 + float per-token scale。但下游 GMM1 kernel(dispatch_mx_gmm1_swiglu.h:70-76)的 static_assert 强制 ElementA 为 float8_e4m3_t/ float8_e5m2_t,scale 为 fp8_e8m0_t(per-32-group MX 格式)。int8_t 被重解释为 float8_e4m3_t 数值含义完全不同。
后果: expert/rank 配置下 GMM1 计算结果错误。
修复: 要么让独立 dispatcher 也走 MX 量化(QuantDynamicMx),要么在 tiling 阶段对 moeExpertNumPerRank == 1 报错拒绝。
| return ge::GRAPH_SUCCESS; | ||
| } | ||
|
|
||
| static ge::graphStatus GetAttrAndSetTilingData(const gert::TilingContext &context, const char *nodeName, |
There was a problem hiding this comment.
fused_deep_moe_tiling.cpp 的GetAttrAndSetTilingData 从未给这两个字段赋值,而 kernel 侧 cam_moe_distribute_combine.h:251/259 与 cam_moe_distribute_dispatch.h:235 会读取。当前零初始化且暂未用于计算/边界检查,属潜在 0 值隐患。建议填充或删除字段。
| } | ||
|
|
||
| AscendC::PipeBarrier<PIPE_ALL>(); | ||
| Arch::CrossCoreFlag gmm1AivFinished{0}; |
There was a problem hiding this comment.
fused_deep_moe_a5.h:425 和 :445 均用 flag ID {0}。非 deep-fuse 路径下两次 SetFlag/WaitFlag 中间虽有 PipeBarrier<PIPE_ALL>(),但若 flag 需显式 clear 则第二次等待可能受残留状态影响。建议用不同 ID 或确认自动清除语义。
| return; | ||
| } | ||
| const auto *calibration = GetTimeCalibration(rank); | ||
| exporter::ExportAggregatedTrace(sources, rank, manager.profileTraceDir, calibration, manager.numRanks); |
There was a problem hiding this comment.
profile_session.cpp:ExportAggregatedTrace() 返回值未检查,随后 manager.Reset() 清空所有 buffer。磁盘满/权限错→整轮 profiling 静默丢失。建议检查返回值,失败时保留 session 可重试。
There was a problem hiding this comment.
profling风险不大,无需dfx逻辑
| } | ||
|
|
||
| CATLASS_DEVICE | ||
| uint32_t SendToMoeExprt(GM_ADDR gmX, GM_ADDR gmExpandIdx, GM_ADDR gmMoeSmoothScales) |
There was a problem hiding this comment.
拼写 SendToMoeExprt → Expert
| // MM1/GMM1-Swiglu output | ||
| int64_t shareSwigluOffset; | ||
| int64_t swigluOffset; | ||
| // MM2/GMM2 input |
|
|
||
| uint64_t profWeightSumStart = 0; | ||
|
|
||
| do { |
There was a problem hiding this comment.
do{...}while(false) 无 break,等价普通 {},建议简化
| int64_t launchCountCaptured{0}; | ||
| }; | ||
|
|
||
| void ExportBufferToTrace(const at::Tensor &profileBuffer, int64_t rank, const std::string &profileTraceDir, |
There was a problem hiding this comment.
ExportBufferToTrace 完整实现但无调用方,dead code
| num_experts: int, | ||
| quant_mode: int = 1, | ||
| fuse_mode: FuseMode = FuseMode.FUSED_DEEP_MOE, | ||
| ) -> Tuple[torch.Tensor, torch.Tensor] |
There was a problem hiding this comment.
Python API 签名漏掉 profile_enable
| auto profileBufferBytesPtr = attrs->GetAttrPointer<int64_t>(ATTR_PROFILE_BUFFER_BYTES_INDEX); | ||
| auto profileLaunchIdPtr = attrs->GetAttrPointer<int64_t>(ATTR_PROFILE_LAUNCH_ID_INDEX); | ||
|
|
||
| uint32_t epRankSize = static_cast<uint32_t>(*epRankSizePtr); |
There was a problem hiding this comment.
Tiling 在校验前解引用属性并做除法,非法输入会崩溃而不是报错在检查 epRankSizePtr、epRankIdPtr、moeExpertNumPtr 是否为空、epRankSize 是否大于零之前,已经解引用并执行 moeExpertNum / epRankSize。
建议:先完整检查全部指针和 epRankSize > 0,再转换类型与相除。
* origin/main: release A5 image (sgl-project#683) add minimax m3 attention ops on A3 (sgl-project#668) [Attentions][CI][Fix] Add attentions to build-and-release CI and build module bugfix (sgl-project#571)
2b38637 to
bbb1170
Compare
Motivation
This PR introduces the corresponding implementation updates in csrc/ and synchronizes the related examples.
Modifications
Host
Dispatch + GMM + Combine.Kernel
Dispatch,GMM, andCombineinto a unified execution flow.Tiling
Testing
Benchmarking and Profiling
Checklist