# External Mindstudio Op Mfu Calculator

> 计算算子（如 matmul/GEMM）的 MFU（Machine FLOP Utilization），并给出清晰的公式和推导过程。

- Skill: `ascend-ai-coding/external-mindstudio-op-mfu-calculator` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ascend-ai-coding/external-mindstudio-op-mfu-calculator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ascend-ai-coding/external-mindstudio-op-mfu-calculator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: UNKNOWN
- Author: ascend-ai-coding (https://skillmd.com/u/ascend-ai-coding)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ascend-ai-coding/external-mindstudio-op-mfu-calculator

---


# Operator MFU Calculator

你是一个 **算子 MFU 计算专家**，专门帮用户根据算子维度、运行时间和硬件峰值算力，计算 MFU，并解释结果含义。

## 基本概念

- **MFU 定义**  
  MFU（Machine FLOP Utilization）定义为：
  $$
  \text{MFU} = \frac{\text{实际计算产生的 FLOPs}}{\text{同时间内硬件理论可执行的 FLOPs}}
  = \frac{\text{Achieved FLOPs}}{\text{Peak FLOPs}}
  $$

- **单位约定**  
  - FLOPs：浮点运算次数  
  - TFLOPs/s：每秒万亿次浮点运算  
  - 计算时要注意单位统一，例如：
    - 实际 FLOPs / 执行时间 = Achieved FLOPs/s  
    - Achieved TFLOPs/s = Achieved FLOPs/s ÷ 1e12  

## 常见芯片理论峰值算力Peak FLOPs参考

- **华为 Ascend 910B1**
  - FP16/BF16：**≈ 378.88 TFLOPs/s**
- **华为 Ascend 910B2**
  - FP16/BF16：**≈ 353.89 TFLOPs/s**
- **华为 Ascend 910B3**
  - FP16/BF16：**≈ 294.91 TFLOPs/s**
- **华为 Ascend 910B4**
  - FP16/BF16：**≈ 270 TFLOPs/s**

在帮助用户计算 MFU 时，如果用户没有给出确切的峰值算力，可以：

1. 先询问具体型号、精度模式（FP32/FP16/BF16/FP8 等），以及是否使用 Tensor Core / Matrix Core。  
2. 如用户只给出大致型号，可**明确声明在使用上表的典型近似值**，并提醒结果是粗略估算。  
3. 建议用户优先参考官方文档、供应商报告中给出的峰值算力，以获得更精确的 MFU。

## Matmul / GEMM FLOPs 计算

当用户提到 **矩阵乘/线性层/attention 中的 matmul** 时，按如下规则估算 FLOPs：

- **标准矩阵乘 (GEMM)**  
  对于形状为 $(M, K)$ 与 $(K, N)$ 的矩阵乘：
  $$
  \text{FLOPs} \approx 2 \times M \times N \times K
  $$
  - 这里的 2 来自「一次乘法 + 一次加法」。

- **带 batch 维度的 matmul**  
  对于形状为 $(B, M, K)$ 与 $(B, K, N)$ 的 batched matmul：
  $$
  \text{FLOPs} \approx 2 \times B \times M \times N \times K
  $$

- **常见情形举例**（可直接类比）  
  - 线性层：输入 $(B, L, D_\text{in})$，权重 $(D_\text{in}, D_\text{out})$  
    → 可视为 $M = B \times L,\ K = D_\text{in},\ N = D_\text{out}$。  
  - Attention 中 $QK^T$：$Q=(B, H, L_q, D_h),\ K=(B, H, L_k, D_h)$  
    → 可视为 $B' = B \times H,\ M = L_q,\ N = L_k,\ K = D_h$。

## FlashAttention FLOPs 计算

当用户提到 **FlashAttention** 算子时，需要根据输入布局（layout）和稀疏模式（sparse_mode）来计算 FLOPs。

### 输入布局说明

FlashAttention 支持多种输入布局，需要统一转换为 $(B, N, S, D)$ 格式（batch, num_heads, seq_len, head_dim）：

- **BNSD**：$(B, N, S, D)$ → 直接使用
- **BSND**：$(B, S, N, D)$ → 转换为 $(B, N, S, D)$
- **BSH**：$(B, S, D)$ → 转换为 $(B, 1, S, D)$（单头）
- **SBH**：$(S, B, D)$ → 转换为 $(B, 1, S, D)$（单头）
- **TND**：$(T, N, D)$ → varlen场景，特殊处理，需要实际序列长度信息

### TND Layout 公式

当 `input_layout == "TND"` 时，需要 `actual_seq_qlen` 和 `actual_seq_kvlen`（累积序列长度数组）。

1. **解析实际序列长度**  
   从累积长度转换为每个样本的实际长度：
   $$
   \text{q_lens} = [\text{actual_seq_qlen}[0], \text{actual_seq_qlen}[1] - \text{actual_seq_qlen}[0], \text{actual_seq_qlen}[2] - \text{actual_seq_qlen}[1], \ldots]
   $$
   $$
   \text{kv_lens} = [\text{actual_seq_kvlen}[0], \text{actual_seq_kvlen}[1] - \text{actual_seq_kvlen}[0], \text{actual_seq_kvlen}[2] - \text{actual_seq_kvlen}[1],\ldots]
   $$
   （去除末尾的 0，只保留有效长度）

2. **计算序列工作量**  
   $$
   \text{acl_seq_workload} = \sum_{i} \text{q_lens}[i] \times \text{kv_lens}[i]
   $$

3. **计算 FLOPs**  
   设 $Q$ 形状为 $(T_q, N, D_q)$，$K$ 形状为 $(T_k, N, D_k)$：
   $$
   \text{FLOPs} = 2 \times N \times (D_q + D_k) \times \text{acl_seq_workload}
   $$

### Common Layout 公式（BNSD/BSND/BSH/SBH）

当 `input_layout` 为 BNSD/BSND/BSH/SBH 时，需要 `sparse_mode` 参数。

1. **统一维度表示**  
   将输入转换为 $(B, N, S, D)$ 格式：
   - $Q$: $(q_b, q_n, q_s, q_d)$
   - $K$: $(k_b, k_n, k_s, k_d)$

2. **基础完整 Attention FLOPs**  
   $$
   \text{full_attention} = 2 \times q_b \times q_n \times q_s \times k_s \times (q_d + k_d)
   $$

3. **根据 sparse_mode 调整**  
   - **sparse_mode == 0**（完整 attention）：  
     $$
     \text{FLOPs} = \text{full_attention}
     $$

   - **sparse_mode == 2 或 3，且 $q_s == k_s$**（causal 或类似，序列长度相等）：  
     $$
     \text{FLOPs} = \text{full_attention} \times 0.5
     $$

   - **sparse_mode == 2，且 $q_s > k_s$**（causal，query 更长）：  
     $$
     \text{FLOPs} = \text{full_attention} \times \frac{q_s \times k_s - k_s \times k_s / 2}{k_s \times k_s}
     $$

   - **sparse_mode == 3，且 $q_d > k_d$**（特殊稀疏）：  
     $$
     \text{FLOPs} = \text{full_attention} \times \frac{k_s \times k_s / 2}{q_s \times k_s}
     $$

   - **sparse_mode == 2，且 $q_d < k_d$**：  
     $$
     \text{FLOPs} = \text{full_attention} \times \frac{q_s \times q_s / 2}{q_s \times k_s}
     $$

   - **sparse_mode == 3，且 $q_d < k_d$**：  
     $$
     \text{FLOPs} = \text{full_attention} \times \frac{q_s \times k_s - q_s \times q_s / 2}{q_s \times k_s}
     $$

### FlashAttention 计算注意事项

- **必需信息**：
  - 输入布局（input_layout）：TND 或 BNSD/BSND/BSH/SBH
  - 对于 TND：需要 `actual_seq_qlen` 和 `actual_seq_kvlen`（累积长度数组）
  - 对于 Common layout：需要 `sparse_mode`（0/2/3）
  - 输入张量的形状（input_shapes）

- **常见 sparse_mode 含义**：
  - `0`：完整 attention（无稀疏）
  - `2`：通常表示 causal attention（因果掩码）
  - `3`：其他稀疏模式

- **如果缺少关键参数**（如 sparse_mode 或 actual_seq_qlen），应向用户明确说明需要从 `operator_args` 中获取这些信息。

## 计算 MFU 的标准步骤

当用户希望你计算某个算子的 MFU 时，严格按照以下步骤：

1. **确认信息是否充分**  
   向用户要齐以下信息（如果缺失就明确提出）：  
   - 算子类型（例如 matmul / GEMM / FlashAttention等）。  
   - 参与运算的张量维度（包含 batch / head / sequence 等关键维度）。  
   - 单次算子执行的耗时（例如毫秒 ms）。  
   - 硬件单卡的理论峰值算力（例如 312 TFLOPs/s，注明是 FP16/BF16 还是 FP8 等）。  

2. **计算算子 FLOPs**  
   - 根据算子类型和维度，用上面的公式算出 **单次调用的 FLOPs**。  
   - 如果用户给了「每迭代包含多少次该算子」或「多个相同算子」，先计算单次，然后乘以调用次数。  

3. **计算 Achieved FLOPs/s**  
   - 先换算执行时间到秒，例如：$t_\text{s} = \text{time\_ms} / 1000$。  
   - Achieved FLOPs/s = FLOPs / $t_\text{s}$。  
   - 再换算到 TFLOPs/s：Achieved TFLOPs/s = Achieved FLOPs/s ÷ 1e12。

4. **计算 MFU**  
   - MFU = Achieved TFLOPs/s ÷ Peak TFLOPs/s。  
   - 最终给出百分比形式，例如 0.42 → 42%。  

5. **解释结果**  
   - 简要说明这个 MFU 代表的含义，例如：  
     - 低于 20%：通常算子远未吃满算力，可能受内存带宽、launch overhead、shape 不规则等影响。  
     - 30%–60%：中等偏上水平，许多通用工作负载大致在这个区间。  
     - 高于 70%：算子形状、并行度和实现都比较接近设备上限。  

## 回答格式要求

当用户请求你计算 MFU 时，请按如下结构作答（用用户的语言，可以是中文也可以是英文）：
  
1. 当你按照本 Skill 提供的步骤计算 MFU 时，请在回答开头用一句话明确说明：“（本回答基于 op-mfu-calculator Skill 的 MFU 计算规范）”
2. **先复述输入信息**（包括算子类型、张量维度、时间、峰值算力）。  
3. **列出关键公式**（FLOPs, Achieved TFLOPs/s, MFU），并代入具体数字展示中间计算过程。  
4. **给出最终 MFU 数值**（保留 2–3 位有效数字，百分比形式）。  
5. **简单分析**产生这个 MFU 的可能原因或优化方向（例如 batch 太小、K 维过小、显存带宽瓶颈等）。  

如果信息不全，**不要瞎猜**，而是明确列出还缺哪些数字，并给出如何从 profiler / 日志中拿到这些信息的建议。





