Skip to content

feat: embedding 第二平台 Cambricon MLU590 接入 - #9

Merged
TruNcat3 merged 2 commits into
mainfrom
feat/embedding-cambricon-mlu
Oct 7, 2026
Merged

TruNcat3 merged 2 commits into
mainfrom
feat/embedding-cambricon-mlu

Conversation

@TruNcat3

Copy link
Copy Markdown
Collaborator

Summary

把 ops/embedding 从 P800 单平台扩展为 P800/Kunlunxin + Cambricon MLU590 双平台,按仓库既有的「三层实现 + 黄金数据」标准交付。kernel/p800_kunlunxin.py 逐字节未改动。

平台命名沿用仓库既有约定 cambricon(与 13 个 MLU 算子、configs/devices/cambricon.yaml、perf/baselines/cambricon.json、flag_gems vendor 同名),别名 mlu / mlu590 / cambricon-mlu590 归一。

实现

文件 内容
ops/embedding/kernel/cambricon.py(新增) MLU 后端:前向委托原生 aten::index_select,反向委托原生 aten::embedding_backward
ops/embedding/kernel/platform.py(新增) 按 tensor.device.type 路由的门面 + dispatch_key_for / synchronize(复用 ops/sdpa/kernel/triton_level.py 的 facade 写法)
ops/embedding/{register,_profile,example}.py 注册守卫与 profile 支持 cambricon;perf case 用平台标签(P800 仍叫 ops.embedding.p800.forward,不改名)
ops/embedding/test/*、script/* 改为走门面,两平台同一套测试/基准

关键决策(均有实测依据,详见 ops/embedding/reports/cambricon.md):

  • MLU 原生 embedding_backward 是完整的:padding_idx + scale_grad_by_freq 与 CPU 参考 6/6 组合 err=0,因此不做 P800/XPU 那套 inverse-frequency 补偿,MLU 后端是零补偿纯委托(原生缺口只在 XPU)。
  • sparse=True 前向接受、反向显式 NotImplementedError:torch_mlu 对 sparse=True 反向会返回 COO 稀疏梯度而不是报错,必须自己拦;守卫用例覆盖。
  • A1 dispatch key = AutogradPrivateUse1:PrivateUse1 与 AutogradPrivateUse1 实测都能命中,但 PrivateUse1 会覆盖 functorch 的 batch rule(BatchRulesModules.cpp 报 Overriding warning);Autograd key 同时与 p800 AutogradCUDA 同构。
  • 平台门面保持扁平结构,不引入子目录;p800_kunlunxin.py 不动。

验证(MLU590-M9,MLU_VISIBLE_DEVICES=7,卡 mlu:0)

层 结果
kernel 前向 20/20、反向 6/6 err=0;哨兵、守卫 2 项通过
黄金 174/174 PASS,worst=0.000e+00(同一套黄金、同一逐位判据)
A1 op 拦截 5 次;注册=直调逐位;dense/scale 梯度 err=0;sparse fwd OK / bwd rejected
应用层 拦截 8 次;logits diff=0;greedy 1.00;两级梯度 diff=0;flag_gems.only_enable(['gelu']) 生效
一键 python3 example.py cambricon 三层 PASS
单测 pytest tests/unit -q 20 passed

性能

ops/embedding/reports/perf_fp16_cambricon.json(warmup=20 / iters=100,每次读回一个输出元素强制完成,speedup = native/ours):

shape ours native Triton ours/native
1k×D128 0.0681ms 0.0445ms 0.2995ms 0.654x
16k×D128 0.0612ms 0.0451ms 2.3029ms 0.736x
131k×D128 0.0819ms 0.0662ms 失败(grid 65536>65535) 0.809x
16k×D512 0.0550ms 0.0617ms 10.5459ms 1.123x
vocab128k 16k×D128 0.0525ms 0.0404ms 2.3306ms 0.769x

backward 16k×D128:dense 0.2651 / 0.2497ms(0.942x),scale_grad_by_freq 0.2944 / 0.2796ms(0.950x,原生分支仅 +11%,P800 手写补偿 +47%)。

perf gate:ops.embedding.cambricon.forward 0.060ms / 142.8 GB/s、ops.embedding.native.forward 0.045ms / 187.9 GB/s,FAIL 0 · WARN 0 · NEW 0;perf/baselines/cambricon.json 增至 33 条 case(P800 基线不动)。

顺带修的 bench 缺陷(影响历史数字)

bench_dispatch.py 的 a1 分支原来裸调 register_a1(...):返回的 torch.library.Library 没有引用时会被 GC,析构即反注册,于是 a1 子进程实际测的是「未注册状态」(F.embedding 落回原生)。

  • 已改为持有 _a1_lib 并断言;全仓扫描确认这是唯一裸调用点(sdpa 与各测试都持有 lib)。
  • P800 a1 数字作废:历史 A1−native ≈ 0.024ms、"A1 与 direct 同档/略快" 不可用,需在有 torch_xmlir 的环境复跑(本机无 torch_xmlir,ModuleNotFoundError)。native / direct 两行不受影响。
  • 三层精度结论不受影响(测试持有 lib,拦截计数 5/8 均 > 0)。
  • MLU 修复后实测(3 轮稳定):native 0.0450 / direct 0.0600 / a1 0.1041ms,A1 − native ≈ +0.059ms、A1 − direct ≈ +0.044ms。

另修 bench_perf.py 反向分支:原是 XPU 专用的 if not scale: 跳过,MLU 拿不到 native 对照 → 改为按平台 try/except。

文档

  • 新增 ops/embedding/reports/cambricon.md(环境 · 实现选择 · 平台命名 · dispatch key · 验证 · 性能 · dispatch 与 Library-GC 缺陷 · 关键发现 · 复现命令)
  • REPORT.md:硬件平台 1→2、双 key 路线、实现矩阵 +2 行、P800/cambricon 两套验证矩阵与关键数字、交付物 +4 项、遗留 +1 条
  • README.md:标题 / 一页看全 / 快速开始(两平台)/ backward 与 Triton 章节 / 边界
  • reports/{accuracy,test-report,performance,development}.md:补 cambricon 结果,标注作废的 0.024ms
  • ops/README.md:embedding 行 1→2 平台,并修正既有错误「黄金 117/117」→ 174/174;库级汇总句同步
  • CHANGELOG.md:Unreleased 新增 embedding 第二平台条目 + Fixed(Library GC、native scale 对照)

校验

本地复现 CI 全部 5 步:Markdown 链接与锚点 0 错误 · Python ast.parse 通过 · YAML 通过 · scripts/intake_validate.py --validate-only 0 错误 · 性能基线结构检查通过;另 pytest tests/unit -q 20 passed。

已知但非本 PR 引入:scripts/check_env.py --device cambricon 报 6 项不符,是 d5c7a3d 写锁的容器镜像(torch 2.12.1 / torch_mlu 1.34.1 / flag_gems 5.0.2 …)与本机 torch2.11 实测栈的既有漂移;--device mlu590 为 OK。

FlagOS Dev and others added 2 commits October 7, 2026 10:36
按既有「三层实现 + 黄金数据」标准把 ops/embedding 从 P800 单平台扩展到
p800-kunlunxin + cambricon 双平台;p800_kunlunxin.py 逐字节未改动。

实现
- 新增 kernel/cambricon.py:前向委托原生 aten::index_select,反向委托
  原生 aten::embedding_backward。MLU 原生 padding_idx + scale_grad_by_freq
  完整(6/6 组合 err=0),因此不需要 P800/XPU 的 inverse-frequency 补偿
- sparse=True 前向接受、反向显式 NotImplementedError(torch_mlu 会返回
  COO 稀疏梯度而不是报错,必须自己拦)
- 新增 kernel/platform.py:按 tensor.device.type 路由的门面,附
  dispatch_key_for / synchronize;测试、bench、A1 注册共用一条路径
- A1 key = AutogradPrivateUse1:两个 key 都命中,但 PrivateUse1 会覆盖
  functorch 的 batch rule;Autograd key 同时与 p800 AutogradCUDA 同构
- 平台/profile/门禁命名统一 cambricon(别名 mlu/mlu590 归一)
- register_a1 增加 MLU 侧注册守卫;_profile 支持 cambricon 与自动探测

验证(MLU590-M9 / mlu:0)
- kernel 20/20 前向 + 6/6 反向 err 0;黄金 174/174 逐位 worst=0
- A1 op 拦截 5 次、注册=直调逐位;应用层拦截 8 次、logits/梯度 0 diff、
  greedy 1.00、flag_gems gelu 生效;example.py 三层 PASS;20 单测通过
- perf gate:ops.embedding.cambricon.forward 0.060ms/142.8GB/s、
  native.forward 0.045ms/187.9GB/s,FAIL 0 · WARN 0 · NEW 0(基线 33 case)

修复
- bench_dispatch.py a1 分支裸调 register_a1:返回的 torch.library.Library
  无引用即被 GC 并反注册,历史 a1 数字(P800 A1−native ≈0.024ms)测的是
  未注册状态,已作废并标注待复测;native/direct 与三层精度结论不受影响
- bench_perf.py 反向原生 scale 改为按平台 try/except,MLU 反向表补 native 对照

文档
- 新增 reports/cambricon.md(环境/实现选择/dispatch key/验证/性能/Library-GC
  缺陷与复现);REPORT、README、四件套、ops/README、CHANGELOG 同步双平台口径,
  并修正 ops/README 的黄金 117/117 → 174/174
@TruNcat3
TruNcat3 force-pushed the feat/embedding-cambricon-mlu branch from 63066db to ea0f721 Compare October 7, 2026 02:46
@TruNcat3
TruNcat3 merged commit 3c1a8c6 into main Oct 7, 2026
2 checks passed
@TruNcat3

TruNcat3 commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

📦 后续维护提示(rebase 合入后补记):

本 PR 合入后 ops/ 做了全库审计整改(#16),与你相关的变化:

  1. 你的算子目录现在有 __init__.py(13 个社区算子统一补齐)——多算子同进程消费时请用包态导入 from ops.embedding import register_a1,顶层名不再互相遮蔽(根因见 sdpa/reports/e2e_mini_llm.md)
  2. embedding 新增 PLATFORM.md + MERGE.md——你的 cambricon 平台绑定项(Autograd key vs PrivateUse1 的选择,reports/cambricon.md §4)已沉淀进 PLATFORM.md §4;后续第四平台接入照 MERGE.md 七步走
  3. 合并前自查:templates/operator/README 新增「交付自查清单」,新算子/新平台合并前照单打勾;python3 ops/test_packaging.py(现覆盖全 16 算子导入)是最后一道门

另:rebase 后的合并版本在 MLU 机器上建议复跑一次 EMBEDDING_PROFILE=cambricon python3 example.py(rebase 改动了 facade/register 结构,本机无 MLU 无法代验)。

zzy2039 pushed a commit to zzy2039/FlagOS-OP that referenced this pull request Oct 11, 2026
FLAG-OP#9 rebase 并列策略遗留: embedding 索引双行/平台合计注记双条 → 单行
三平台终态; sdpa_math 双平台已有 PLATFORM.md, 补齐 MERGE.md 七步。

# wt <wangt635@ustc.edu.cn>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant