moe OJ教程更新 #46
|
|
@ -155,14 +155,11 @@ EOF
|
|||
**命令示例:**
|
||||
|
||||
```apl
|
||||
cd /root/Project/fused_moe # 这里需要替换成自己的项目路径
|
||||
#克隆代码仓库
|
||||
git clone https://gitlink.org.cn/metax-maca/op_optimization.git
|
||||
#切换到fused moe目录下benchmark项目
|
||||
cd op_optimization/基于AI\ Agent开发范式的国产GPU大模型推理算子库优化/operator_task_package/fused_moe_task_package/benchmark
|
||||
```
|
||||
|
||||
**预期结果:**
|
||||
|
||||
终端提示符路径显示为 fused\_moe 项目路径:
|
||||
|
||||
* (base) root@0a5a9d0c0f06:~/Project/fused\_moe#
|
||||
|
||||
|
||||
### 步骤 3:pybind 编译
|
||||
|
|
@ -326,371 +323,23 @@ bash scripts/run_fused_moe_i8_tn_benchmark.sh --backend all --warmup 5 --iters 2
|
|||
| 终端长时间无输出 | Kernel 死锁或 MACA 驱动异常 | 减小测试 shape;重启容器或设备 |
|
||||
| avg\_ms 异常抖动(±50%) | 其他进程占用 GPU | 关闭其他占用显存的进程,单机单任务运行 |
|
||||
|
||||
## 六、项目实践2-Kernel Swift 智能算子迁移系统自动调优
|
||||
## 六、XPU-OJ 冒烟提交
|
||||
|
||||
系统链接:[https://deeplink.org.cn/kernelswift/task](https://deeplink.org.cn/kernelswift/task)
|
||||
### 6.1 目标
|
||||
|
||||
**项目目标:**基于 KernelSwift 智能算子迁移系统,对 Fused MoE 算子进行在线自动调优。通过输入算子的 PyTorch 代码,一键生成适配沐曦硬件的高性能实现,高效完成算子优化与全流程追踪。
|
||||
在完成前文的本地验证后,本节将带你把实现提交到 XPU-OJ,并确认评测环境能够正确调用 `run_kernel(...)`。
|
||||
|
||||
### 步骤1:复用算子广场的Fused MoE 算子进行二次优化
|
||||
完成本节后,你应能够完成一次最小 OJ 提交,查看评测结果,并据此进入正确性修复或后续性能优化。
|
||||
|
||||
**目标:**通过提交算子广场的 fused\_moe 算子代码发起自动优化流程,实现二次优化
|
||||
本节的冒烟提交只用于验证函数接口、索引逻辑和提交流程;性能优化请在正确性通过后再进行。
|
||||
|
||||
**操作:**
|
||||
### 6.2 前置准备
|
||||
|
||||
1. 进入算子广场:点击左侧导航栏 【算子广场】,进入算子列表页
|
||||
|
||||
搜索 fused\_moe 算子,复制 `input_code.py` 代码,也可直接复制以下代码:
|
||||
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
|
||||
|
||||
class Model(nn.Module):
|
||||
"""
|
||||
Reference PyTorch MoE forward (no fused kernels).
|
||||
Expects inputs:
|
||||
hidden_states: (M, in_size)
|
||||
w1: (E, hidden_size, in_size) where hidden_size = 2 * up_dim
|
||||
w2: (E, out_size, up_dim)
|
||||
topk_weights: (M, top_k)
|
||||
topk_idx: (M, top_k)
|
||||
top_k: int
|
||||
renormalize: bool
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def forward(
|
||||
self,
|
||||
hidden_states: torch.Tensor,
|
||||
w1: torch.Tensor,
|
||||
w2: torch.Tensor,
|
||||
topk_weights: torch.Tensor,
|
||||
topk_idx: torch.Tensor,
|
||||
top_k: int,
|
||||
renormalize: bool = True,
|
||||
) -> torch.Tensor:
|
||||
if renormalize:
|
||||
topk_weights = topk_weights / topk_weights.sum(dim=-1, keepdim=True)
|
||||
|
||||
seq_len = hidden_states.size(0)
|
||||
out_size = w2.size(1)
|
||||
output = hidden_states.new_zeros(seq_len, out_size)
|
||||
num_experts = w1.size(0)
|
||||
|
||||
# Accumulate expert contributions
|
||||
for eid in range(num_experts):
|
||||
token_idx, k_idx = torch.where(topk_idx == eid)
|
||||
if token_idx.numel() == 0:
|
||||
continue
|
||||
gate_proj, up_proj = w1[eid].chunk(2, dim=0)
|
||||
down_proj = w2[eid]
|
||||
tmp = F.linear(hidden_states[token_idx], gate_proj)
|
||||
tmp = F.silu(tmp) * F.linear(hidden_states[token_idx], up_proj)
|
||||
tmp = F.linear(tmp, down_proj)
|
||||
tmp = tmp * topk_weights[token_idx, k_idx, None]
|
||||
output.index_add_(0, token_idx, tmp.to(output.dtype))
|
||||
return output
|
||||
|
||||
|
||||
# Hyperparameters
|
||||
seq_len = 128
|
||||
in_size = 128
|
||||
hidden_size = 256 # 2 * up_dim
|
||||
out_size = 128
|
||||
num_experts = 32
|
||||
top_k = 4
|
||||
|
||||
dtype = torch.float16
|
||||
|
||||
def get_inputs():
|
||||
hidden_states = (torch.rand(seq_len, in_size, dtype=dtype) - 0.5) / 2
|
||||
w1 = (torch.rand(num_experts, hidden_size, in_size, dtype=dtype) - 0.5) / 2
|
||||
w2 = (torch.rand(num_experts, out_size, hidden_size//2, dtype=dtype) - 0.5) / 2
|
||||
routing_logits = (torch.rand(seq_len, num_experts, dtype=dtype) - 0.5) / 2
|
||||
routing_weights = torch.softmax(routing_logits, dim=-1, dtype=torch.float32)
|
||||
topk_weights, topk_idx = torch.topk(routing_weights, top_k, dim=-1)
|
||||
return [hidden_states, w1, w2, topk_weights, topk_idx, top_k, True]
|
||||
|
||||
def get_init_inputs():
|
||||
return []
|
||||
```
|
||||
|
||||
2. 进入新建任务页:点击左侧导航栏【新建任务】 ,进入算子提交页面。
|
||||
|
||||
3. 编写算子代码:在 `model.py` 编辑器中输入刚刚复制的 fused\_moe 算子代码。
|
||||
|
||||
如果想自行编写算子代码,需严格遵循标准格式规范:输入代码必须包含 `class Model` 定义算子实现,`get_init_inputs` 和 `get_inputs` 定义测试用例,确保优化过程可验证算子正确性。
|
||||
|
||||
4. 配置优化参数
|
||||
|
||||
* 指定任务名称:支持字母、下划线、数字组合,示例:fused\_moe\_01
|
||||
|
||||
* 选择适配硬件:算子需要适配的目标硬件厂商及型号,建议:沐曦
|
||||
|
||||
* 最大演化轮次:优化算法迭代次数,取值范围40-400,建议默认40,复杂算法可提高至100+
|
||||
|
||||
5. 提交优化任务:点击右下角 \[优化\] 按钮,系统将提交任务并进入 \[生成中\] 状态
|
||||
|
||||
|
||||
[](https://www.picgo.net/image/image1.4SHrb4)
|
||||
|
||||
完成上述步骤将看到如下界面:
|
||||
|
||||
[](https://www.picgo.net/image/image2.4SHscu)
|
||||
|
||||
### 步骤2:任务查看与结果管理
|
||||
|
||||
**目标:**在新建优化任务后可追踪任务进度,获取优化结果
|
||||
|
||||
**操作:**
|
||||
|
||||
1. 查看任务列表:点击左侧【任务查看】,可看到所有提交的优化任务
|
||||
|
||||
* 任务状态:排队中、环境初始化、算子预编译、精度验证、性能调优、已完成、失败
|
||||
|
||||
* 任务信息:任务名称、进度、创建时间、适配硬件
|
||||
|
||||
* 操作按钮:查看详情、删除任务
|
||||
|
||||
|
||||
[](https://www.picgo.net/image/image3.4SHDeY)
|
||||
|
||||
2. 追踪任务进度:当前任务状态为【运行中】时,点击任务列表中的【查看详情】按钮,追踪任务进度:
|
||||
|
||||
* 左侧:原始算子代码(输入的 `input_code.py`)
|
||||
|
||||
* 右侧:任务进度条,包含以下阶段:
|
||||
|
||||
1. 环境初始化:准备目标硬件编译环境
|
||||
|
||||
2. 算子预编译:验证算子代码是可正常编译
|
||||
|
||||
3. 精度验证:验证优化后算子输出与原始算子误差的可接受范围
|
||||
|
||||
4. 性能调优:按设定的演化轮次迭代优化算子性能
|
||||
|
||||
|
||||
* 顶部:任务名称、创建/更新时间、适配硬件、当前轮次进度
|
||||
|
||||
|
||||
[](https://www.picgo.net/image/image4.4SHVpp)
|
||||
|
||||
3. 获取优化结果:当前任务状态为【已完成】时,可在详情页查看优化结果:
|
||||
|
||||
* 优化后算子代码支持一键复制
|
||||
|
||||
* 算子加速比(基准耗时 / 优化后耗时)、性能数据(如延迟、吞吐量)
|
||||
|
||||
* 可点击【Diff 对比】查看优化前后代码差异,理解性能提升逻辑
|
||||
|
||||
|
||||
[](https://www.picgo.net/image/image5.4ScbBr)
|
||||
|
||||
4. 任务异常处理
|
||||
|
||||
* 任务失败:查看错误日志,常见原因包括代码不符合规范、测试用例错误、硬件适配问题,修改后重新提交任务;
|
||||
|
||||
* 排队时间长:可调整提交时间,或联系平台管理员确认资源状态。
|
||||
|
||||
|
||||
## 七、Agent使用说明
|
||||
|
||||
在本模块中,Agent可以帮助你完成以下任务:
|
||||
|
||||
1. **环境检查**
|
||||
|
||||
```plaintext
|
||||
我正在算力平台进行 Fused MoE 的 Benchmark 验证。
|
||||
需要的环境信息如下:
|
||||
- Python 3.12
|
||||
- g++ 13.3.0
|
||||
- mxcc 已安装
|
||||
- numpy / torch / triton 已安装
|
||||
|
||||
请帮我确认:
|
||||
1. 当前环境是否满足编译与运行要求?
|
||||
2. 是否有潜在的不兼容风险(如 Python 与 libpython 版本)?
|
||||
```
|
||||
|
||||
2. **运行测试**
|
||||
|
||||
```plaintext
|
||||
请帮我运行 scripts/run_fused_moe_i8_tn_pybind_test.sh 脚本
|
||||
```
|
||||
|
||||
3. **分析结果**
|
||||
|
||||
```plaintext
|
||||
这是性能测试结果:
|
||||
pybind: avg_ms=0.30, TOPS=0.027
|
||||
triton: avg_ms=19.01, TOPS=0.0004
|
||||
reference: avg_ms=1685, TOPS=0.000005
|
||||
|
||||
请分析:
|
||||
1. 为什么 pybind 比 Triton 快这么多?
|
||||
2. TOPS 指标是否可信?
|
||||
3. 当前结果是否已经具备提交价值?
|
||||
```
|
||||
|
||||
4. **报错检查**
|
||||
|
||||
```plaintext
|
||||
编译 pybind 时出现以下错误:
|
||||
/usr/bin/ld: cannot find -lpython3.10
|
||||
|
||||
已知:
|
||||
- 使用的是 Conda Python 3.10
|
||||
- mxcc 编译正常
|
||||
|
||||
请一步一步告诉我:
|
||||
1. 错误原因是什么?
|
||||
2. 如何用 find 命令定位 libpython3.10.so?
|
||||
3. 如何在 build_fused_moe_i8_tn_pybind.sh 中正确指定路径?
|
||||
```
|
||||
|
||||
5. **代码理解**
|
||||
|
||||
```plaintext
|
||||
请帮我梳理释 benchmark_fused_moe_i8_tn.py 代码整体框架
|
||||
```
|
||||
|
||||
6. **KernelSwift 系统搜索算子**
|
||||
|
||||
|
||||
```plaintext
|
||||
请帮我在算子广场检索 fused_moe 算子
|
||||
```
|
||||
|
||||
## 八、常见问题与注意事项
|
||||
|
||||
### 8.1 算力平台进行 Benchmark 验证:
|
||||
|
||||
1. 环境准备与依赖问题
|
||||
|
||||
* 确保算力平台已正确安装 Python 和 C++、MACA 编译器及相关运行时库,避免因环境缺失导致编译失败;
|
||||
|
||||
* 镜像环境使用 Conda Python 作为默认运行环境,避免系统 Python 与 Conda Python 混用,防止 `Python.h`或 `libpython`路径错误。
|
||||
|
||||
2. pybind 编译与链接
|
||||
|
||||
* 若`Python.h not found`,请检查脚本中`PYTHON_INCLUDE`是否指向当前 Python 的 `include`目录;
|
||||
|
||||
* 若`libpython not found`,请直接指定 Conda 下的`**libpython3.x.so**`绝对路径,避免链接系统静态库;
|
||||
|
||||
* 编译 `pybind`模块时,务必开启 `-fPIC`,否则会出现 `recompile with -fPIC`错误。
|
||||
|
||||
3. 性能测试建议
|
||||
|
||||
* benchmark 应在关闭其他占用 GPU 的任务后执行,避免干扰性能数据;
|
||||
|
||||
* 多次运行取平均值,避免单次抖动影响结果;
|
||||
|
||||
* 性能对比应基于相同随机种子、相同 shape、相同 TopK、相同 batch size的条件下进行,降低误差。
|
||||
|
||||
|
||||
### 8.2 Kernel Swift 智能算子迁移系统自动调优项目:
|
||||
|
||||
1. 代码规范问题
|
||||
|
||||
输入代码需符合以下标准格式:
|
||||
|
||||
* `class Model`,表示待优化的算子实现;
|
||||
|
||||
* `def get_init_inputs`,表示 module init 的输入测试样例;
|
||||
|
||||
* `def get_inputs`,表示 module forward 的输入测试样例。
|
||||
|
||||
2. 性能优化建议
|
||||
|
||||
* 对于复杂算子,可适当提高最大演化轮次(如 100-200),获得更高加速比;
|
||||
|
||||
* 优先选择算子广场中已有优化案例的算子类型,降低适配失败概率。
|
||||
|
||||
3. 硬件适配问题
|
||||
|
||||
* 提交任务前确认目标硬件支持的算子类型;
|
||||
|
||||
* 优化失败时,可尝试更换适配硬件,或调整算子实现逻辑。
|
||||
|
||||
|
||||
## 九、XPU-OJ 冒烟提交:从 Benchmark 验证到评测结果
|
||||
|
||||
### 9.1 教程定位
|
||||
|
||||
前面的Benchmark 验证教程主要帮助你完成三件事:
|
||||
|
||||
1. 看懂 Fused MoE 算子的输入、输出和计算逻辑;
|
||||
|
||||
2. 在模力方舟环境里跑通本地编译、测试和 benchmark 脚本;
|
||||
|
||||
3. 得到一组本地性能基线,方便后续判断优化是否真的有效。
|
||||
|
||||
|
||||
需要特别说明:
|
||||
|
||||
* Benchmark 不是最终提交物。
|
||||
|
||||
* XPU-OJ 才是最终评测入口。
|
||||
|
||||
* XPU-OJ 不会直接运行前面的 benchmark 脚本,而是会调用你提交代码里的 `run_kernel(...)` 函数。
|
||||
|
||||
|
||||
简单理解:
|
||||
|
||||
| 内容 | 作用 |
|
||||
| --- | --- |
|
||||
| Benchmark | 帮你理解算子和建立性能基线 |
|
||||
| Agent | 帮你读代码、写初版、定位错误、迭代优化 |
|
||||
| XPU-OJ | 按统一测试数据评测你的 `run_kernel(...)` |
|
||||
| Candidate | 每一版可提交、可复现的代码结果 |
|
||||
|
||||
完成本节后,你应该能完成一次最小 OJ 提交,确认自己的提交链路是通的。
|
||||
|
||||
### 9.2 学习目标
|
||||
|
||||
完成本模块后,你将能够:
|
||||
|
||||
1. 理解 benchmark 和 XPU-OJ 提交之间的区别;
|
||||
|
||||
2. 找到 Fused MoE GEMM 题目的接口约定;
|
||||
|
||||
3. 准备一个可以提交到 OJ 的 `run_kernel(...)` 文件;
|
||||
|
||||
4. 在 XPU-OJ 页面提交代码并查看结果;
|
||||
|
||||
5. 根据 OJ 返回的 `Wrong Answer`、`Runtime Error`、`Accepted` 等状态判断下一步动作。
|
||||
|
||||
|
||||
### 9.3 适用对象
|
||||
|
||||
本模块适合已经完成以下准备的参赛者:
|
||||
|
||||
* 已经进入模力方舟赛事镜像;
|
||||
|
||||
* 已经上传或准备好 Fused MoE 源码;
|
||||
|
||||
* 已经可以在终端里运行基础命令;
|
||||
|
||||
* 已经配置好 Agent 工具,例如 OpenCode;
|
||||
|
||||
* 已经拿到组委会发放的 XPU-OJ 账号。
|
||||
|
||||
|
||||
如果你还没有做过 GPU kernel 优化,也可以先照着本节完成一次冒烟提交。这里的目标不是马上拿高分,而是先确认“我能提交、OJ 能调用我的函数、反馈能回来”。
|
||||
|
||||
### 9.4 前置准备
|
||||
|
||||
#### 9.4.1 代码准备
|
||||
#### 6.2.1 代码准备
|
||||
|
||||
建议在工作目录下保留一个候选版本目录,例如:
|
||||
|
||||
```bash
|
||||
cd /data/fusedmoe_v2.1
|
||||
mkdir -p oj/problem_1_fused_moe
|
||||
```
|
||||
|
||||
|
|
@ -702,7 +351,7 @@ oj/problem_1_fused_moe/solution001.py
|
|||
|
||||
真正提交时,只需要把这个文件里的内容复制到 XPU-OJ 提交框。
|
||||
|
||||
#### 9.4.2 账号准备
|
||||
#### 6.2.2 账号准备
|
||||
|
||||
XPU-OJ 账号由组委会统一发放。登录入口:
|
||||
|
||||
|
|
@ -712,9 +361,9 @@ https://xpuoj.com/
|
|||
|
||||
如果登录后看不到比赛或题目,请联系助教或赛事运营确认账号是否已经加入对应比赛或用户组。
|
||||
|
||||
### 9.5 知识预备
|
||||
### 6.3 知识预备
|
||||
|
||||
#### 9.5.1 什么是 OJ
|
||||
#### 6.3.1 什么是 OJ
|
||||
|
||||
OJ 可以理解为“自动评测机”。
|
||||
|
||||
|
|
@ -735,7 +384,7 @@ OJ 可以理解为“自动评测机”。
|
|||
|
||||
所以,OJ 不是让你提交 benchmark 日志,也不是让你提交本地运行截图,而是让你提交一份符合接口约定的代码。
|
||||
|
||||
#### 9.5.2 什么是 Candidate
|
||||
#### 6.3.2 什么是 Candidate
|
||||
|
||||
Candidate 就是一次可复现的候选方案。
|
||||
|
||||
|
|
@ -751,7 +400,7 @@ Candidate 就是一次可复现的候选方案。
|
|||
|
||||
这样后续多次打榜时,不会忘记哪一版代码对应哪一次提交结果。
|
||||
|
||||
### 9.6 项目实践:Fused MoE GEMM OJ 冒烟提交
|
||||
### 6.4 项目实践:Fused MoE GEMM OJ 冒烟提交
|
||||
|
||||
本节以当前 XPU-OJ 题目 **1. Fused MoE GEMM** 为例。
|
||||
|
||||
|
|
@ -999,7 +648,7 @@ cp oj/problem_1_fused_moe/solution001.py oj/problem_1_fused_moe/solution002.py
|
|||
|
||||
然后让 Agent 基于 `solution002.py` 继续改。
|
||||
|
||||
### 9.7 Agent 使用说明
|
||||
### 6.5 Agent 使用说明
|
||||
|
||||
本模块中,Agent 主要用来做三件事:
|
||||
|
||||
|
|
@ -1063,7 +712,7 @@ OJ 返回 Runtime Error。
|
|||
只给出最小修复方案。
|
||||
```
|
||||
|
||||
### 9.8 常见问题
|
||||
### 6.8 常见问题
|
||||
|
||||
#### Q1:为什么本地能跑,OJ 上却 Runtime Error?
|
||||
|
||||
|
|
@ -1127,7 +776,7 @@ Access to torch.Tensor is not allowed
|
|||
|
||||
不要只看单次结果。每轮都记录,后面才知道 Agent 的修改到底有没有带来收益。
|
||||
|
||||
### 9.9 从 Benchmark 验证到参赛作品的路径回顾
|
||||
### 6.9 从 Benchmark 验证到参赛作品的路径回顾
|
||||
|
||||
建议按下面顺序推进:
|
||||
|
||||
|
|
@ -1146,8 +795,299 @@ Access to torch.Tensor is not allowed
|
|||
7. 用 OJ 分数和耗时判断优化是否有效。
|
||||
|
||||
|
||||
一句话总结:
|
||||
|
||||
```text
|
||||
Benchmark 验证代码用来学习,OJ 用来评分,Candidate 用来管理每一轮结果。
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
## 七、项目实践2-Kernel Swift 智能算子迁移系统自动调优
|
||||
|
||||
系统链接:[https://deeplink.org.cn/kernelswift/task](https://deeplink.org.cn/kernelswift/task)
|
||||
|
||||
**项目目标:**基于 KernelSwift 智能算子迁移系统,对 Fused MoE 算子进行在线自动调优。通过输入算子的 PyTorch 代码,一键生成适配沐曦硬件的高性能实现,高效完成算子优化与全流程追踪。
|
||||
|
||||
### 步骤1:复用算子广场的Fused MoE 算子进行二次优化
|
||||
|
||||
**目标:**通过提交算子广场的 fused\_moe 算子代码发起自动优化流程,实现二次优化
|
||||
|
||||
**操作:**
|
||||
|
||||
1. 进入算子广场:点击左侧导航栏 【算子广场】,进入算子列表页
|
||||
|
||||
搜索 fused\_moe 算子,复制 `input_code.py` 代码,也可直接复制以下代码:
|
||||
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
|
||||
|
||||
class Model(nn.Module):
|
||||
"""
|
||||
Reference PyTorch MoE forward (no fused kernels).
|
||||
Expects inputs:
|
||||
hidden_states: (M, in_size)
|
||||
w1: (E, hidden_size, in_size) where hidden_size = 2 * up_dim
|
||||
w2: (E, out_size, up_dim)
|
||||
topk_weights: (M, top_k)
|
||||
topk_idx: (M, top_k)
|
||||
top_k: int
|
||||
renormalize: bool
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def forward(
|
||||
self,
|
||||
hidden_states: torch.Tensor,
|
||||
w1: torch.Tensor,
|
||||
w2: torch.Tensor,
|
||||
topk_weights: torch.Tensor,
|
||||
topk_idx: torch.Tensor,
|
||||
top_k: int,
|
||||
renormalize: bool = True,
|
||||
) -> torch.Tensor:
|
||||
if renormalize:
|
||||
topk_weights = topk_weights / topk_weights.sum(dim=-1, keepdim=True)
|
||||
|
||||
seq_len = hidden_states.size(0)
|
||||
out_size = w2.size(1)
|
||||
output = hidden_states.new_zeros(seq_len, out_size)
|
||||
num_experts = w1.size(0)
|
||||
|
||||
# Accumulate expert contributions
|
||||
for eid in range(num_experts):
|
||||
token_idx, k_idx = torch.where(topk_idx == eid)
|
||||
if token_idx.numel() == 0:
|
||||
continue
|
||||
gate_proj, up_proj = w1[eid].chunk(2, dim=0)
|
||||
down_proj = w2[eid]
|
||||
tmp = F.linear(hidden_states[token_idx], gate_proj)
|
||||
tmp = F.silu(tmp) * F.linear(hidden_states[token_idx], up_proj)
|
||||
tmp = F.linear(tmp, down_proj)
|
||||
tmp = tmp * topk_weights[token_idx, k_idx, None]
|
||||
output.index_add_(0, token_idx, tmp.to(output.dtype))
|
||||
return output
|
||||
|
||||
|
||||
# Hyperparameters
|
||||
seq_len = 128
|
||||
in_size = 128
|
||||
hidden_size = 256 # 2 * up_dim
|
||||
out_size = 128
|
||||
num_experts = 32
|
||||
top_k = 4
|
||||
|
||||
dtype = torch.float16
|
||||
|
||||
def get_inputs():
|
||||
hidden_states = (torch.rand(seq_len, in_size, dtype=dtype) - 0.5) / 2
|
||||
w1 = (torch.rand(num_experts, hidden_size, in_size, dtype=dtype) - 0.5) / 2
|
||||
w2 = (torch.rand(num_experts, out_size, hidden_size//2, dtype=dtype) - 0.5) / 2
|
||||
routing_logits = (torch.rand(seq_len, num_experts, dtype=dtype) - 0.5) / 2
|
||||
routing_weights = torch.softmax(routing_logits, dim=-1, dtype=torch.float32)
|
||||
topk_weights, topk_idx = torch.topk(routing_weights, top_k, dim=-1)
|
||||
return [hidden_states, w1, w2, topk_weights, topk_idx, top_k, True]
|
||||
|
||||
def get_init_inputs():
|
||||
return []
|
||||
```
|
||||
|
||||
2. 进入新建任务页:点击左侧导航栏【新建任务】 ,进入算子提交页面。
|
||||
|
||||
3. 编写算子代码:在 `model.py` 编辑器中输入刚刚复制的 fused\_moe 算子代码。
|
||||
|
||||
如果想自行编写算子代码,需严格遵循标准格式规范:输入代码必须包含 `class Model` 定义算子实现,`get_init_inputs` 和 `get_inputs` 定义测试用例,确保优化过程可验证算子正确性。
|
||||
|
||||
4. 配置优化参数
|
||||
|
||||
* 指定任务名称:支持字母、下划线、数字组合,示例:fused\_moe\_01
|
||||
|
||||
* 选择适配硬件:算子需要适配的目标硬件厂商及型号,建议:沐曦
|
||||
|
||||
* 最大演化轮次:优化算法迭代次数,取值范围40-400,建议默认40,复杂算法可提高至100+
|
||||
|
||||
5. 提交优化任务:点击右下角 \[优化\] 按钮,系统将提交任务并进入 \[生成中\] 状态
|
||||
|
||||
|
||||
[](https://www.picgo.net/image/image1.4SHrb4)
|
||||
|
||||
完成上述步骤将看到如下界面:
|
||||
|
||||
[](https://www.picgo.net/image/image2.4SHscu)
|
||||
|
||||
### 步骤2:任务查看与结果管理
|
||||
|
||||
**目标:**在新建优化任务后可追踪任务进度,获取优化结果
|
||||
|
||||
**操作:**
|
||||
|
||||
1. 查看任务列表:点击左侧【任务查看】,可看到所有提交的优化任务
|
||||
|
||||
* 任务状态:排队中、环境初始化、算子预编译、精度验证、性能调优、已完成、失败
|
||||
|
||||
* 任务信息:任务名称、进度、创建时间、适配硬件
|
||||
|
||||
* 操作按钮:查看详情、删除任务
|
||||
|
||||
|
||||
[](https://www.picgo.net/image/image3.4SHDeY)
|
||||
|
||||
2. 追踪任务进度:当前任务状态为【运行中】时,点击任务列表中的【查看详情】按钮,追踪任务进度:
|
||||
|
||||
* 左侧:原始算子代码(输入的 `input_code.py`)
|
||||
|
||||
* 右侧:任务进度条,包含以下阶段:
|
||||
|
||||
1. 环境初始化:准备目标硬件编译环境
|
||||
|
||||
2. 算子预编译:验证算子代码是可正常编译
|
||||
|
||||
3. 精度验证:验证优化后算子输出与原始算子误差的可接受范围
|
||||
|
||||
4. 性能调优:按设定的演化轮次迭代优化算子性能
|
||||
|
||||
|
||||
* 顶部:任务名称、创建/更新时间、适配硬件、当前轮次进度
|
||||
|
||||
|
||||
[](https://www.picgo.net/image/image4.4SHVpp)
|
||||
|
||||
3. 获取优化结果:当前任务状态为【已完成】时,可在详情页查看优化结果:
|
||||
|
||||
* 优化后算子代码支持一键复制
|
||||
|
||||
* 算子加速比(基准耗时 / 优化后耗时)、性能数据(如延迟、吞吐量)
|
||||
|
||||
* 可点击【Diff 对比】查看优化前后代码差异,理解性能提升逻辑
|
||||
|
||||
|
||||
[](https://www.picgo.net/image/image5.4ScbBr)
|
||||
|
||||
4. 任务异常处理
|
||||
|
||||
* 任务失败:查看错误日志,常见原因包括代码不符合规范、测试用例错误、硬件适配问题,修改后重新提交任务;
|
||||
|
||||
* 排队时间长:可调整提交时间,或联系平台管理员确认资源状态。
|
||||
|
||||
|
||||
## 八、Agent使用说明
|
||||
|
||||
在本模块中,Agent可以帮助你完成以下任务:
|
||||
|
||||
1. **环境检查**
|
||||
|
||||
```plaintext
|
||||
我正在算力平台进行 Fused MoE 的 Benchmark 验证。
|
||||
需要的环境信息如下:
|
||||
- Python 3.12
|
||||
- g++ 13.3.0
|
||||
- mxcc 已安装
|
||||
- numpy / torch / triton 已安装
|
||||
|
||||
请帮我确认:
|
||||
1. 当前环境是否满足编译与运行要求?
|
||||
2. 是否有潜在的不兼容风险(如 Python 与 libpython 版本)?
|
||||
```
|
||||
|
||||
2. **运行测试**
|
||||
|
||||
```plaintext
|
||||
请帮我运行 scripts/run_fused_moe_i8_tn_pybind_test.sh 脚本
|
||||
```
|
||||
|
||||
3. **分析结果**
|
||||
|
||||
```plaintext
|
||||
这是性能测试结果:
|
||||
pybind: avg_ms=0.30, TOPS=0.027
|
||||
triton: avg_ms=19.01, TOPS=0.0004
|
||||
reference: avg_ms=1685, TOPS=0.000005
|
||||
|
||||
请分析:
|
||||
1. 为什么 pybind 比 Triton 快这么多?
|
||||
2. TOPS 指标是否可信?
|
||||
3. 当前结果是否已经具备提交价值?
|
||||
```
|
||||
|
||||
4. **报错检查**
|
||||
|
||||
```plaintext
|
||||
编译 pybind 时出现以下错误:
|
||||
/usr/bin/ld: cannot find -lpython3.10
|
||||
|
||||
已知:
|
||||
- 使用的是 Conda Python 3.10
|
||||
- mxcc 编译正常
|
||||
|
||||
请一步一步告诉我:
|
||||
1. 错误原因是什么?
|
||||
2. 如何用 find 命令定位 libpython3.10.so?
|
||||
3. 如何在 build_fused_moe_i8_tn_pybind.sh 中正确指定路径?
|
||||
```
|
||||
|
||||
5. **代码理解**
|
||||
|
||||
```plaintext
|
||||
请帮我梳理释 benchmark_fused_moe_i8_tn.py 代码整体框架
|
||||
```
|
||||
|
||||
6. **KernelSwift 系统搜索算子**
|
||||
|
||||
|
||||
```plaintext
|
||||
请帮我在算子广场检索 fused_moe 算子
|
||||
```
|
||||
|
||||
## 九、常见问题与注意事项
|
||||
|
||||
### 9.1 算力平台进行 Benchmark 验证
|
||||
|
||||
1. 环境准备与依赖问题
|
||||
|
||||
* 确保算力平台已正确安装 Python 和 C++、MACA 编译器及相关运行时库,避免因环境缺失导致编译失败;
|
||||
|
||||
* 镜像环境使用 Conda Python 作为默认运行环境,避免系统 Python 与 Conda Python 混用,防止 `Python.h`或 `libpython`路径错误。
|
||||
|
||||
2. pybind 编译与链接
|
||||
|
||||
* 若`Python.h not found`,请检查脚本中`PYTHON_INCLUDE`是否指向当前 Python 的 `include`目录;
|
||||
|
||||
* 若`libpython not found`,请直接指定 Conda 下的`**libpython3.x.so**`绝对路径,避免链接系统静态库;
|
||||
|
||||
* 编译 `pybind`模块时,务必开启 `-fPIC`,否则会出现 `recompile with -fPIC`错误。
|
||||
|
||||
3. 性能测试建议
|
||||
|
||||
* benchmark 应在关闭其他占用 GPU 的任务后执行,避免干扰性能数据;
|
||||
|
||||
* 多次运行取平均值,避免单次抖动影响结果;
|
||||
|
||||
* 性能对比应基于相同随机种子、相同 shape、相同 TopK、相同 batch size的条件下进行,降低误差。
|
||||
|
||||
|
||||
### 9.2 Kernel Swift 智能算子迁移系统自动调优项目
|
||||
|
||||
1. 代码规范问题
|
||||
|
||||
输入代码需符合以下标准格式:
|
||||
|
||||
* `class Model`,表示待优化的算子实现;
|
||||
|
||||
* `def get_init_inputs`,表示 module init 的输入测试样例;
|
||||
|
||||
* `def get_inputs`,表示 module forward 的输入测试样例。
|
||||
|
||||
2. 性能优化建议
|
||||
|
||||
* 对于复杂算子,可适当提高最大演化轮次(如 100-200),获得更高加速比;
|
||||
|
||||
* 优先选择算子广场中已有优化案例的算子类型,降低适配失败概率。
|
||||
|
||||
3. 硬件适配问题
|
||||
|
||||
* 提交任务前确认目标硬件支持的算子类型;
|
||||
|
||||
* 优化失败时,可尝试更换适配硬件,或调整算子实现逻辑。
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue