Skip to content

feat(glm53): 인덱서 fp32 head-gate split-K (glm53_indexer_gate_splitk, opt-in, EXP-9) - #227

Merged
choiceoh merged 1 commit into
feat/glm53-prep-fused-v2from
feat/glm53-indexer-gate-splitk
Sep 2, 2026
Merged

feat(glm53): 인덱서 fp32 head-gate split-K (glm53_indexer_gate_splitk, opt-in, EXP-9)#227
choiceoh merged 1 commit into
feat/glm53-prep-fused-v2from
feat/glm53-indexer-gate-splitk

Conversation

@choiceoh

@choiceoh choiceoh commented Sep 2, 2026

Copy link
Copy Markdown
Owner

#226 (feat/glm53-prep-fused-v2) 위에 쌓인 브랜치 — #226 머지 후 base 를 main 으로 바꾸거나 함께 머지.

무엇

Indexer.forward 의 fp32 head-gate torch.mm(hidden.float(), _wp_fp32) ([M,4096]×[4096,16], 층당 1회 × 11) 을 cuBLAS 가 2블록 gemmSN 커널로 답한다 (48 SM 중 2개): 유휴 GB10 47 us, 9월 1일 트레이스(CUPTI) 86 us. (행, K-슬라이스 512) 마다 프로그램 하나를 띄우고 fp32 atomic 으로 모으는 split-K Triton 커널이 같은 곱을 10 us 에 낸다. M<=16(디코드) 만 이 경로, 프리필·C>=3 은 stock 그대로.

M stock torch.mm split-K(8) 경로
1 15.5 us 8.5 us split-K
8 (C=1) 50.0 us 9.9 us split-K
16 (C=2) 50.1 us 11.7 us split-K
32 (C=4) 15.9 us 17.4 us torch.mm 유지

(GB10, CUDA 그래프 리플레이, probes/indexer_gate_check.py)

수치 — bit-exact 아님

양쪽 다 fp32 누적, 합산 순서만 다르다. 300회/2,480행: max|diff| 2.4e-6 절대, 행 최대 대비 6.7e-7, top-1 뒤집힘 0, top-4 집합 변화 0. bf16 게이트가 순위를 뒤집는 오차(1e-2)보다 네 자릿수 아래지만 품질 브래킷(9/9, 한국어 0/16) 대상.

천장과 게이트

11 × ~40 us ≈ 0.44 ms/스텝 = C=1 66 ms 스텝의 ~0.65% — 원장 1% 규칙에 걸려 단독 부팅 금지. EXP-7/EXP-8 과 독립이라 그 부팅에 얹어 같이 잰다 (RUNBOOK EXP-9).

VLLM_GLM53_INDEXER_GATE_SPLITK=1 bash launchers/start-glm53-nvfp4-tp4.sh   # 프로필 선언 키: caller env

켜진 증거는 트레이스에서 gemmSN 11개 → _gate_splitk_kernel 11개 (부팅 로그 줄 없음 — 그래프 안에서 층마다 호출). 기본 0 = stock 과 같은 torch.mm 호출. 롤백 env 한 줄.

파일

  • overlay/modules/glm53_indexer_gate_splitk/attention.py 오버레이 (플릿 preimage a0870c31…, fi618 동일; 변경은 import 1줄 + 호출 1줄) + glm53_indexer_gate.py (커널·헬퍼) + manifest/requires/README
  • glm53_model_wiring/glm53_prefill_fastpath.pyVLLM_GLM53_FUSED_K_GATE=1 팔의 융합 인덱서도 같은 헬퍼 (모듈 미탑재 시 stock 으로 폴백)
  • profiles/glm53.env — MODULES 추가, VLLM_GLM53_INDEXER_GATE_SPLITK=0
  • probes/indexer_gate_check.py — 수치(순위 뒤집힘 포함) + 그래프 리플레이 타이밍
  • tests/test_logic.py — 계약 테스트; test_overlay_symbol_contracts 를 프로필 단위로 (dsv4 mla_indexer 와 glm53 glm53_tail_slot_persistentmla/indexer.py 를 각자 소유하는데 전역 "마지막 매니페스트" 맵이 glm53 의 attention.py 를 dsv4 indexer 에 대조해 거짓 실패). 41,165 checks OK
  • RUNBOOK EXP-9, MEASUREMENTS 원장, STEP_KERNEL_MAP 포인터, build/glm53 스냅샷 (33/22)

🤖 Generated with Claude Code


Note

Medium Risk
Changes indexer head-gate numerics and sparse top-k inputs (opt-in only), so incorrect routing or ranking shifts could affect attention quality despite strong offline checks.

Overview
Adds glm53_indexer_gate_splitk, an opt-in overlay that replaces the sparse indexer’s fp32 head-gate torch.mm(hidden.float(), _wp_fp32) with a split-K Triton kernel when VLLM_GLM53_INDEXER_GATE_SPLITK=1 (profile default 0 = stock).

Why: On decode shapes (M≤16), cuBLAS picks a two-block gemmSN path (~47–86 µs/layer × 11 layers). The new kernel does the same [M,4096]×[4096,16] multiply via per-(row, K-slice) programs and fp32 atomics (~10 µs offline). M>16 (prefill, larger verify batches) still uses torch.mm.

Wiring: attention.py overlay calls head_gate; glm53_prefill_fastpath.py uses the same helper for the fused-K-gate arm (lazy import with stock fallback). Manifest pins attention.py and adds glm53_indexer_gate.py.

Numerics: fp32 accumulation with different summation order — not bit-exact (max |diff| ~2.4e-6 offline, 0 top-1/top-4 ranking flips in probe trials). RUNBOOK EXP-9 quality bracket required; estimated ceiling ~0.65%/step (ride on EXP-7/8 boots, no solo boot).

Also: probes/indexer_gate_check.py, MEASUREMENTS/RUNBOOK/STEP_KERNEL_MAP updates, test_glm53_indexer_gate_splitk_contracts, and per-profile overlay symbol contract tests (fixes false failures when dsv4 and glm53 both own different mla/indexer.py overlays).

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

…te_splitk, opt-in)

Indexer.forward 의 torch.mm(hidden.float(), _wp_fp32) ([M,4096]x[4096,16] fp32,
층당 1회 x 11) 을 cuBLAS 가 2블록 gemmSN 커널로 답한다: 유휴 GB10 47 us, 트레이스
(CUPTI) 86 us. (행, K-슬라이스 512) 마다 프로그램 하나 + fp32 atomic 의 split-K
Triton 커널이 같은 곱을 10 us 에 낸다. M<=16(디코드) 만 라우팅, 나머지는 stock.

- overlay/modules/glm53_indexer_gate_splitk: attention.py 오버레이(플릿 preimage
  a0870c31..., fi618 과 동일) + 커널 파일. 노브 VLLM_GLM53_INDEXER_GATE_SPLITK,
  정확히 "1" 만 켬, 기본 0 = stock 과 같은 torch.mm 호출.
- glm53_prefill_fastpath.py 의 융합 인덱서(FUSED_K_GATE=1)도 같은 헬퍼를 탄다.
- 수치: fp32 누적 순서만 다름 — 300회/2,480행 max|diff| 2.4e-6, top-1 뒤집힘 0,
  top-4 집합 변화 0 (probes/indexer_gate_check.py). bit-exact 아님 -> 품질 브래킷.
- 천장 11 x 40 us = 0.44 ms/스텝, C=1 의 ~0.65% (<1%): 단독 부팅 금지, EXP-7/8
  부팅에 얹어 잰다. RUNBOOK EXP-9, MEASUREMENTS 원장.
- tests: test_overlay_symbol_contracts 를 프로필 단위로 (dsv4 mla_indexer 와 glm53
  glm53_tail_slot_persistent 가 같은 경로를 각자 소유 — 전역 "마지막 매니페스트"
  맵이 glm53 attention.py 를 dsv4 indexer 에 대조하고 있었다). 새 계약 테스트.
  41,165 checks OK. build/glm53 스냅샷 재구성 (33 overlays / 22 modules).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 2, 2026 11:16
@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-02T11:20:44.182830Z 83d9eae 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.

@choiceoh
choiceoh merged commit 2abc932 into feat/glm53-prep-fused-v2 Sep 2, 2026
4 checks passed

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

The split-K applicability predicate lacks CUDA/contiguity guards (risking incorrect behavior or crashes in non-CUDA/non-contiguous cases) and the kernel docstrings contain inconsistent measurement claims versus the PR’s documentation.

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

Pull request overview

Adds an opt-in optimization for GLM-5.3’s sparse indexer fp32 head-gate GEMM on small decode shapes (M≤16) by routing through a split-K Triton kernel, while keeping the stock torch.mm path as the default and for larger shapes. The PR also updates wiring so both the standard and fused-indexer arms share the same head-gate helper, and extends tests/docs/probes to validate the new overlay and its numerics caveat.

Changes:

  • Introduces glm53_indexer_gate_splitk overlay with a split-K Triton head-gate implementation and opt-in env knob (VLLM_GLM53_INDEXER_GATE_SPLITK=1).
  • Routes head-gate computation through a shared helper in both attention.py overlay and glm53_prefill_fastpath.py, with stock fallback when the module isn’t mounted.
  • Adds per-profile overlay symbol contract checking, new contracts test, probe script, and updates runbook/measurements/kernel map.
File summaries
File Description
tests/test_logic.py Makes overlay symbol contract checks profile-aware and adds glm53_indexer_gate_splitk contract test coverage.
STEP_KERNEL_MAP.md Documents the new EXP-9 module and split-K head-gate optimization reference.
RUNBOOK_KERNEL_CAMPAIGN2.md Adds EXP-9 runbook entry describing arming, numerics caveat, and measurement expectations.
profiles/glm53.env Mounts the new module and declares default-off knob VLLM_GLM53_INDEXER_GATE_SPLITK=0.
probes/indexer_gate_check.py Adds an offline numerics + timing probe (CUDA graph replay) for the split-K head gate.
overlay/modules/glm53_model_wiring/glm53_prefill_fastpath.py Lazily imports and uses the shared head-gate helper with a stock fallback for non-mounted environments.
overlay/modules/glm53_indexer_gate_splitk/requires Declares dependency on glm53_model_wiring.
overlay/modules/glm53_indexer_gate_splitk/README.md Documents purpose, arming method, numerics caveat, and offline timing results.
overlay/modules/glm53_indexer_gate_splitk/manifest.tsv Pins attention.py overlay and adds the new kernel helper module file.
overlay/modules/glm53_indexer_gate_splitk/glm5next_attention.py Replaces the fp32 head-gate torch.mm call with the shared helper import/call.
overlay/modules/glm53_indexer_gate_splitk/glm53_indexer_gate.py Implements split-K Triton kernel + helper routing and env-gated applicability.
MEASUREMENTS.md Records offline measurements and rationale for routing only M≤16 through split-K.
build/glm53/manifest.tsv Adds built artifacts for the pinned attention overlay and new kernel helper file.
build/glm53/glm5next_attention.py Snapshot of the overlayed attention module with helper-based head-gate call.
build/glm53/glm53_prefill_fastpath.py Snapshot of the model wiring helper import + callsite update.
build/glm53/glm53_indexer_gate.py Snapshot of the split-K head-gate helper module.
Review details
  • Files reviewed: 16/16 changed files
  • Comments generated: 3
  • 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 +72 to +74
def splitk_applicable(x: torch.Tensor, w: torch.Tensor) -> bool:
return (x.shape[0] <= MAX_M and w.dtype == torch.float32 and w.is_contiguous()
and w.shape[1] <= 16 and w.shape[0] % (_SPLIT * _BLOCK_K) == 0)
Comment on lines +12 to +15
product in 7 us. Both accumulate in fp32; only the summation order differs
(measured max |diff| 3e-5 on values of magnitude ~64, i.e. ~5e-7 relative,
0 top-1 rank flips over the offline trials) -- not bit-exact, so this stays
an opt-in behind a numerics bracket.
Comment on lines +12 to +15
product in 7 us. Both accumulate in fp32; only the summation order differs
(measured max |diff| 3e-5 on values of magnitude ~64, i.e. ~5e-7 relative,
0 top-1 rank flips over the offline trials) -- not bit-exact, so this stays
an opt-in behind a numerics bracket.

@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.

Approved. Cursor Bugbot completed successfully with no findings that need human review, and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

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