Skip to content

perf(megakernel): MK-KDA 2라운드 -- gates bf16 mma GEMM, p1+p2 병합, split-K 상한, conv 언롤: 스팬 199 → 176 µs - #230

Merged
choiceoh merged 1 commit into
mainfrom
feat/kda-round2
Sep 2, 2026
Merged

perf(megakernel): MK-KDA 2라운드 -- gates bf16 mma GEMM, p1+p2 병합, split-K 상한, conv 언롤: 스팬 199 → 176 µs#230
choiceoh merged 1 commit into
mainfrom
feat/kda-round2

Conversation

@choiceoh

@choiceoh choiceoh commented Sep 2, 2026

Copy link
Copy Markdown
Owner

요약

KDA 커널 스팬(L2 배수, acc=3) 199 → 176 µs, 벤치 MK-KDA 320 → 280 µs(stock 640650). 수치는 모든 단계에서 동일 급(out 56e-4, conv_state 0, rec_state 1.6e-6), VERDICT PASS. GEMM 형상은 불변(n=1024 첫 발사 32.7→30.7).

항목 조치 µs
gates 워프당 내적(5단 셔플)을 cp.async 32행 타일 + mma.sync m16n8k16 bf16 GEMM 으로 14.5 → 6.2
p1+p2 conv 는 p0 의 qkv 만 읽으므로 gates 뒤 배리어 제거 대기 3.4 → 0
split-K o_proj(k=2048) 스윕 r=3 40.8 / r=2 33.4 / r=1 35.5 / r=4 43.8 → 슬라이스 ≥ 8 k-블록 상한(파이프라인 채움 비용) p5 39.7 → 35.1
conv 런타임 인덱스 람다(로컬 메모리) → 스펙 창 8 로 언롤한 선택식; 호스트가 mql ≤ 8 검사 6.6 → 4.7
(기각) L2 예열 노는 16 블록이 delta 동안 o_proj 팩을 prefetch.global.L2 p5 −5.6 이지만 delta +12, 벤치 280 → 309

최종 176 = in_proj 76 + gates 6 + conv 4 + delta 34 + norm 0.5 + o_proj 35 + 배리어 ~17. in_proj·o_proj 는 W4 스트림의 DRAM 속도 그 자체(~190 GB/s 유효)라 커널 안에서 더 줄일 것이 거의 없습니다.

  • 프로브 노브 VLLM_GLM53_MK_KSR_IN/OUT(split-K 강제, 진단 전용). 계약 테스트: mma GEMM, 배리어 4개, split-K 상한, conv 언롤·mql 검사.
  • MEASUREMENTS.md 10차, README 단계 예산.

🤖 Generated with Claude Code


Note

Medium Risk
Megakernel KDA changes alter synchronization, conv state handling under speculative decode, and GEMM split-K heuristics—high impact if drift slips past shadow/contract tests. Removing build-time async-dflash and indexer split-K paths is lower risk if serving no longer depended on those artifacts.

Overview
MK-KDA in glm53_megakernel.cu is the main change: kernel span 199 → 176 µs and bench 320 → ~280 µs, with the same numerical gates (out/rec_state, VERDICT PASS).

The gates phase is rewritten from per-warp dot products to a bf16 tensor-core GEMM (mma.sync m16n8k16) with cp.async-staged 32-row weight tiles and stricter 16 B alignment checks. Phase 1 and conv (phase 2) no longer sit behind an extra grid barrier because both only read p0 qkv. Short conv uses a compile-time spec window (KDA_NQ_MAX = 8) with unrolled token/history selection instead of runtime-indexed local arrays, and the host rejects mql above that limit. mk_choose_ksr caps split-K when k-slices are shorter than ~8 k-blocks (favoring r=2 on o_proj), with optional VLLM_GLM53_MK_KSR_IN/OUT overrides for sweeps.

Docs record the 10th megakernel round in MEASUREMENTS.md and trim campaign material: RUNBOOK megakernel examples use EXTRA_ENV="...", and long EXP-7/8/9 (prep fused, dflash async, indexer split-K) sections are removed from the runbook and kernel map supplements.

Removed from build/glm53/: the vendored glm53_config_vllm.py fork (dflash async allowlist) and glm53_indexer_gate.py split-K helper; glm53_prefill_fastpath.py goes back to stock torch.mm for the fp32 head-gate.

Reviewed by Cursor Bugbot for commit 7a287e0. Bugbot is set up for automated code reviews on this repo. Configure here.

…split-K 상한, conv 언롤, o_proj L2 예열

스팬 199 → SPAN_FINAL µs(배수 진단, acc=3), 벤치 320 → BENCH_FINAL µs.
- p1 gates: 워프당 내적(행 재사용, 5단 셔플)을 cp.async 32행×128 타일
  (8 KB, 동적 smem 이중 버퍼) + mma.sync m16n8k16 bf16 GEMM 으로: 14.5 → 6.2
  (하한 4.5, 가중치 1 MB).
- p1+p2 병합: conv 는 p0 의 qkv 만 읽으므로 gates 뒤 배리어 제거(대기 3.4 → 0).
- split-K 상한: o_proj(k=2048) 스윕 r=3 40.8 / r=2 33.4 / r=1 35.5 / r=4 43.8
  → 슬라이스 ≥ 8 k-블록(비용 모델의 "라운드 수"는 파이프라인 채움 비용을
  모른다). p5 39.7 → 35.1; GEMM 형상 불변(n=1024 첫 발사 32.7 → 30.7).
- conv: 런타임 인덱스 람다(st/kept 가 로컬 메모리)를 스펙 창 8 로 언롤한
  선택식으로: 6.6 → 4.7. 호스트가 mql ≤ 8 을 검사.
- delta 동안 노는 16 블록이 o_proj 팩 4.5 MB 를 prefetch.global.L2 로
  예열: p5 PREFETCH_RESULT.
- 프로브 노브 VLLM_GLM53_MK_KSR_IN/OUT(split-K 강제, 진단 전용).
수치는 모든 단계에서 동일 급(out 5~6e-4, conv_state 0, rec_state 1.6e-6),
VERDICT PASS. MEASUREMENTS.md 10차, README 단계 예산.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 2, 2026 13:18
@choiceoh
choiceoh merged commit 0a57e1b into main Sep 2, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T13:19:48.380944Z 7a287e0 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

It introduces launch-breaking RUNBOOK commands (profile keys passed via EXTRA_ENV), contains a README/code inconsistency about L2 prefetch, and needs a stricter KDA mql contract to avoid incorrect conv_state writes under narrower query lengths.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates the GLM-5.3 megakernel KDA implementation to reduce per-layer decode latency (notably by reworking the gates path and tightening KDA split-K/conv behavior), and concurrently removes previously-added experimental overlay modules and associated probes/docs that are no longer shipped in the glm53 profile.

Changes:

  • MK-KDA perf work: gates rewritten as cp.async + bf16 tensor-core MMA GEMM, phase barrier removed between gates/conv, split-K capped to keep ≥8 k-blocks per slice, conv unrolled to the spec window with an mql guard and split-K probe knobs.
  • Contract updates: tests/test_logic.py updated to assert the new KDA kernel invariants/text signatures.
  • Cleanup/revert: remove glm53_prep_fused, glm53_async_dflash, and glm53_indexer_gate_splitk overlays plus related probes/docs, and drop them from profiles/glm53.env and the composed build/glm53/manifest.tsv.
File summaries
File Description
tools/trace_step_timeline.py Removed trace analysis helper script.
tools/trace_step_composition.py Removed trace analysis helper script.
tests/test_logic.py Updates overlay symbol contract checking and adds/updates KDA megakernel contract assertions.
STEP_KERNEL_MAP.md Removes previously-added supplemental trace decomposition sections.
RUNBOOK_KERNEL_CAMPAIGN2.md Updates megakernel experiment commands (shadow/arm) and removes EXP-7/8/9 docs.
profiles/glm53.env Drops removed experimental modules and their VLLM_* knobs from the profile.
probes/run_prep_fused_check.sh Removed prep-fused probe wrapper.
probes/prep_fused_check.py Removed prep-fused probe implementation.
probes/moe_gate_tile_sweep.py Removed MoE gate tile sweep probe.
probes/indexer_gate_check.py Removed indexer head-gate split-K probe.
overlay/modules/glm53_prep_fused/requires Removed prep-fused module dependency list.
overlay/modules/glm53_prep_fused/README.md Removed prep-fused module documentation.
overlay/modules/glm53_prep_fused/manifest.tsv Removed prep-fused module manifest.
overlay/modules/glm53_model_wiring/glm5next_model.py Removes prep-fused import/install hook from model wiring.
overlay/modules/glm53_model_wiring/glm53_prefill_fastpath.py Removes indexer head-gate helper indirection; uses stock torch.mm directly.
overlay/modules/glm53_megakernel/README.md Updates MK-KDA phase budget narrative and adds split-K probe knob mention.
overlay/modules/glm53_megakernel/glm53_megakernel.cu Core MK-KDA changes: gates MMA GEMM, barrier removal, conv unroll, split-K cap, alignment + mql checks, ksr probe knobs.
overlay/modules/glm53_indexer_gate_splitk/requires Removed indexer-gate split-K module dependency list.
overlay/modules/glm53_indexer_gate_splitk/README.md Removed indexer-gate split-K module documentation.
overlay/modules/glm53_indexer_gate_splitk/manifest.tsv Removed indexer-gate split-K module manifest.
overlay/modules/glm53_indexer_gate_splitk/glm5next_attention.py Removed indexer-gate split-K attention overlay file.
overlay/modules/glm53_indexer_gate_splitk/glm53_indexer_gate.py Removed indexer-gate split-K kernel file.
overlay/modules/glm53_async_dflash/README.md Removed async-dflash module documentation.
overlay/modules/glm53_async_dflash/manifest.tsv Removed async-dflash module manifest.
MEASUREMENTS.md Adds MK-KDA “10차” measurement section; removes large EXP-7/8/9 writeups.
build/glm53/manifest.tsv Removes composed rows for the deleted experimental overlays.
build/glm53/glm5next_model.py Mirrors removal of prep-fused install hook in composed build output.
build/glm53/glm5next_attention.py Removed composed attention overlay file for indexer-gate split-K.
build/glm53/glm53_prep_fused.py Removed composed prep-fused implementation.
build/glm53/glm53_prefill_fastpath.py Mirrors removal of indexer head-gate helper indirection in composed build output.
build/glm53/glm53_megakernel.cu Mirrors MK-KDA kernel changes in composed build output.
build/glm53/glm53_indexer_gate.py Removed composed indexer-gate split-K kernel file.
Review details
  • Files reviewed: 33/36 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +231 to 239
EXTRA_ENV="VLLM_GLM53_MEGAKERNEL=1 VLLM_GLM53_MK_KDA_SHADOW=1" \
bash launchers/start-glm53-nvfp4-tp4.sh
# bench-tp4 1회 내내 [megakernel] kda shadow 로그에 DRIFT 0 확인

# 4. 브래킷 — 세그먼트별 개별 암(MHC와 GEMM은 별도 부팅으로 분리)
VLLM_GLM53_MEGAKERNEL=1 VLLM_GLM53_MK_MHC=1 \
EXTRA_ENV="VLLM_GLM53_MEGAKERNEL=1 VLLM_GLM53_MK_MHC=1" \
bash launchers/start-glm53-nvfp4-tp4.sh # cand A
VLLM_GLM53_MEGAKERNEL=1 VLLM_GLM53_MK_GEMM=1 \
EXTRA_ENV="VLLM_GLM53_MEGAKERNEL=1 VLLM_GLM53_MK_GEMM=1" \
bash launchers/start-glm53-nvfp4-tp4.sh # cand B (MHC 합침은 그 다음)
Comment on lines 2182 to +2184
a.mql = (int)ints[2];
TORCH_CHECK(a.mql <= KDA_NQ_MAX,
"kda: max_query_len over the unrolled conv window (KDA_NQ_MAX)");
Comment thread tests/test_logic.py
Comment on lines +391 to +413
owners = {} # dotted module path -> (module dir, source path)
for manifest in sorted(glob.glob(
os.path.join(REPO, "overlay", "modules", "*", "manifest.tsv"))):
moddir = os.path.dirname(manifest)
for raw in open(manifest, encoding="utf-8"):
line = raw.rstrip("\n")
if not line or line.startswith("#"):
continue
source, target = line.split("\t")[:2]
if not source.endswith(".py"):
continue
# Targets are absolute for image-bound overlays and relative to the
# package root for portable ones, so anchoring on "/vllm/" silently
# skipped every portable module -- including moe_gate_sm121, the one
# this check exists for.
if target.startswith("vllm/"):
rel = target
elif "/vllm/" in target:
rel = "vllm/" + target.split("/vllm/", 1)[1]
else:
continue
dotted = rel[:-3].replace("/", ".")
owners[dotted] = os.path.join(moddir, source)
Comment on lines +190 to +195
cp.async + `mma.sync m16n8k16 bf16` GEMM over 32-row weight tiles; the
conv is unrolled to the 8-token spec window (the host refuses a wider
`max_query_len`); the delta rule runs two blocks per head (rows split, S
register-resident, per-token state stores staged through smem) while the
16 head-less blocks warm L2 with the o_proj pack (`prefetch.global.L2`);
p4 emits the o_proj's fp8 A tiles itself so p5 starts without a prologue;
choiceoh added a commit that referenced this pull request Sep 2, 2026
fix(repo): main 복구 -- #230 이 되돌린 다른 세션의 작업 33 파일 복원 + KDA 2라운드 재적용
choiceoh pushed a commit that referenced this pull request Sep 2, 2026
…라운드는 유지

#230 의 커밋(7a287e0)은 0bd06b7 에서 갈라졌으면서 glm53_prep_fused·glm53_async_dflash·
glm53_indexer_gate_splitk 모듈, probes/tools 5개, glm5next_model.py 의 prep-fused 훅,
프로필 MODULES/노브, 테스트 419줄, 원장·RUNBOOK·커널맵 항목을 삭제했다(#224 와 같은
패턴: 오래된 작업 트리로 add -A). 유지한 것 = #230 이 실제로 작성한 것: 메가커널
.cu/README(KDA 2라운드), 테스트의 KDA 계약 2 hunk, 원장 10차 항목. 나머지는 이 브랜치
(0bd06b7 + 리뷰 처리분) 그대로. 41,247 checks OK.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@choiceoh

choiceoh commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

이 PR 의 커밋 7a287e00bd06b7 에서 갈라졌는데 glm53_prep_fused·glm53_async_dflash·glm53_indexer_gate_splitk 모듈, probes/tools 5개, glm5next_model.py 의 prep-fused 훅, 프로필 MODULES/노브, 테스트·원장·RUNBOOK 항목(#226~#229)을 삭제했습니다 (36 파일, −11,145줄; #224 와 같은 패턴 — 오래된 작업 트리에서 git add -A). #231 에서 복원했고, 이 PR 이 실제로 작성한 MK-KDA 2라운드(.cu/README, KDA 계약 테스트 2 hunk, 원장 10차 항목)는 그대로 유지했습니다. 다음부터는 브랜치를 만들 때 git checkout -b <branch> origin/main 로 최신 main 에서 갈라 주세요.

@choiceoh

choiceoh commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

정정: 복원은 #232 (다른 세션) 가 먼저 했고, #231 은 그 위에 리뷰 처리분을 다시 얹어 머지했습니다. main 5ac66fa 기준 세 모듈·probes·tools·훅 모두 있습니다.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a non-blocking comment: Cursor Bugbot was still pending after the 8-minute wait, so this PR is not approved. Human review is needed; a reviewer will be requested if assignment succeeds.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7a287e0. Configure here.

#pragma unroll
for (int j = 0; j < NQ_MAX; ++j) v = (q == j) ? xin[j] : v;
}
a.conv_state[sbase + i] = v;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conv state write drops older history

Medium Severity

The unrolled conv state write only keeps three prior values (kept[0..2]) and maps every i >= 2 onto kept[2]. keep is conv_width - nq_tok (10 minus the request length), so any spec-verify sequence shorter than 7 tokens writes the wrong prefix into conv_state. Later steps then convolve from a corrupted window. Host code only checks mql <= 8, and _kda_eligible still admits those shorter cu_seqlens spans.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7a287e0. Configure here.

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.

2 participants