feat(megakernel,osar,drafter): 서빙 PDL 기본값, AR 대기 중 L2 프리페치, 드래프터 fc 겹치기, MoE go/no-go 프로브 (원장 27차) - #290
Conversation
…go 프로브 - tp_oneshot_ar: k_oneshot 이 HintArgs(최대 8 범위)를 받아 워프 1~7 이 prefetch.global.L2 로 걷는다 -- 스레드 0 의 폴링과 t_wait 는 그대로, n==0 은 옛 커널 그대로. oneshot_ar_hint / phase_counters 바인딩. shim 은 MK 발사의 note_consumer 를 "타깃 forward 의 몇 번째 콜렉티브 뒤" 로 파일해 두고 캡처가 발사에 굳힌다; forward 경계는 컴파일 영역 위의 Glm5NextForConditionalGeneration.forward. 노브 VLLM_GLM53_AR_PREFETCH (0 / 1 = 12 MB / N MB, 1..20). - 서빙 PDL: 드라이버는 env 를 읽는데 프로필에도 ab-glm53.sh 에도 없어서 지금까지 무장 부팅이 전부 PDL 없이 돌았다 -> glm53.env 기본 1, cand 팔에 명시. 그래프 캡처 안 체인 검사 probes/mk_pdl_graph_check.py. - probes: run_mk_probe.sh (b12x 파일까지 마운트하는 일반 러너), moe_decode_stream_probe.py (b12x static U 스윕 vs MK 레인 vs L2-warm), osar_build_check.py, oneshot_ar_disttest.py 힌트 팔. - RUNBOOK EXP-12/13/14. test_logic 44,471 checks. GPU 프로브는 srv2 가 비는 대로 돈다(다른 세션의 DRAFTW4 브래킷 뒤); 숫자는 원장에. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- shim: 힌트 표를 scope("target"/"drafter")별로 든다. 하나의 표를 나눠 쓰면 타깃의
더 풍부한 표가 드래프터의 열 개 콜렉티브 행을 덮거나, 드래프터의 ordinal 이 타깃의
행을 읽는다. begin_forward(scope) / prefetch_hint_table(scope).
- DFlash2Qwen3ForCausalLM.forward: 컴파일된 DFlashQwen3Model 위에서 "drafter" scope 의
경계를 연다 -- 드래프터의 층당 두 콜렉티브도 다음 GEMM 팩을 데운다.
- MEASUREMENTS 27차: 서빙 PDL 은 꺼져 있었다(발사당 −7.6%), MoE 커널은 레인과 같은
197~200 GB/s(90% 규칙으로 닫힘), L2-warm 은 W4 GEMM 에 7%(프리페치 상한 −0.4~0.6 ms 로
정정), AR 빌드 PASS, 드래프터 꼬리 인구조사, 전략 상한 대 프로브 정정표.
- RUNBOOK EXP-12/13/14 결과 줄.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
드래프터의 첫 GEMM fc 는 타깃 forward 가 끝나는 순간 입력(aux 은닉)이 다 있는데 stock 은 propose() 안, 샘플러 뒤에 계산한다. 그 사이는 DRAM 이 논다(AllGather 는 패브릭, 샘플러는 소형 커널). 생산자 = GPUModelRunner.execute_model 래퍼(forward 뒤 side stream 에서 cat + fc 를 영속 버퍼로, 이벤트 기록), 소비자 = DFlash2Qwen3ForCausalLM.combine_hidden_states(같은 토큰 수의 대기 결과만, 이벤트 대기 뒤; precompute_and_store_context_kv 와 드래프터 그래프보다 앞이라 MK 발사끼리 겹치지 않음). 수치 동일. 노브 VLLM_GLM53_DFLASH_EARLY_FC(기본 0), 생산자 실패는 부팅 동안 자동 해제. 상한 ~0.3 ms/스텝, EXP-10 위에서만 의미. RUNBOOK EXP-15(이것), EXP-16(드래프터 메가커널: 정정 상한 −0.8~1.0 ms, 착수 전 승인). test_logic 44,558 checks. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_751fe7cb-a3df-44dd-a4b0-92b126cc2492) |
There was a problem hiding this comment.
🟡 Changes recommended
새로 추가된 probes/run_mk_probe.sh가 set -euo pipefail 하에서 전달할 VLLM_* 환경변수가 없으면 조기 종료할 수 있어(의도된 “(none)” 케이스 불가) 수정이 필요합니다.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
운영자가 선택한 27차 캠페인 항목을 서빙 기본값/오버레이 배선/프로브·런북·측정 기록으로 반영해, GLM53 메가커널 경로의 PDL 기본 활성화, one-shot AR peer-wait 중 L2 프리페치 힌트 학습/적용, 드래프터 fc early side-stream 겹침을 추가합니다.
Changes:
VLLM_GLM53_MK_PDL=1을 프로필 기본값 및 A/B cand arm에 반영하고, CUDA graph 캡처 내 체인 리플레이 비트 동일성 프로브를 추가- one-shot AR 커널(
k_oneshot)에 HintArgs(by-value) 경로를 추가하고, shim/드라이버에서 hint table(스코프별) 학습·적용 배선 및 disttest/빌드체크 프로브 추가 - 드래프터
fc를 타깃 head+sampler 구간 아래 side stream으로 실행하는 early-fc 오버레이 및 계약 테스트 추가
File summaries
| File | Description |
|---|---|
| tests/test_logic.py | AR prefetch/early-fc/PDL 관련 계약(문자열·배선·프로토콜) 테스트 추가 및 실행 목록에 포함 |
| RUNBOOK_KERNEL_CAMPAIGN2.md | EXP-12~16 런북 항목 추가/정정 및 게이트/상한/판정 규칙 문서화 |
| profiles/glm53.env | PDL 기본값(1) 및 AR prefetch/early-fc 노브(기본 0) 선언, early-fc 모듈 마운트 추가 |
| probes/run_mk_probe.sh | 오프라인 프로브를 “합성 오버레이 + MoE 파일”까지 마운트해 실행하는 범용 러너 추가 |
| probes/osar_build_check.py | one-shot AR 확장 컴파일/바인딩(힌트/카운터) 존재 확인 프로브 추가 |
| probes/oneshot_ar_disttest.py | 힌트 유무에 따른 t_wait 측정(phase counters) 및 flush 포함 wall-time 비교 추가 |
| probes/moe_decode_stream_probe.py | 서빙 b12x MoE vs MK lane 스트리밍 속도 비교(go/no-go) 프로브 추가 |
| probes/mk_pdl_graph_check.py | CUDA graph 캡처 내 MK 체인(gemm→gemm→gemm, mhc→gemm) 리플레이 비트 동일/타이밍 프로브 추가 |
| overlay/modules/tp_oneshot_ar/README.md | AR wait 중 L2 prefetch 힌트 설계/학습/적용 프로토콜 문서화 |
| overlay/modules/tp_oneshot_ar/dsv4_oneshot_shim.py | forward 범위(begin/end) + ordinal 기반 hint table 학습 및 oneshot_ar_hint 경로 추가 |
| overlay/modules/tp_oneshot_ar/dsv4_oneshot_ar.cu | k_oneshot에 HintArgs(by value) + prefetch.global.L2 발행 및 바인딩(oneshot_ar_hint/phase_counters) 추가 |
| overlay/modules/glm53_model_wiring/glm5next_model.py | target forward 경계에서 osar begin/end 호출 및 early-fc 설치 훅 추가 |
| overlay/modules/glm53_megakernel/README.md | PDL 서빙 기본값 반영 및 체인 그래프 체크 프로브 언급 갱신 |
| overlay/modules/glm53_megakernel/glm53_megakernel.py | MK launch가 소비할 weights를 osar shim에 note_consumer로 노트하는 훅 추가 |
| overlay/modules/glm53_dflash2_fp8_head/qwen3_dflash2.py | drafter forward 경계(begin/end, scope=drafter) 및 early-fc 소비(combine_hidden_states) 추가 |
| overlay/modules/glm53_dflash_early_fc/requires | early-fc 오버레이의 의존 모듈 선언 추가 |
| overlay/modules/glm53_dflash_early_fc/README.md | early-fc 목적/프로토콜/노브 및 운영 방식 문서 추가 |
| overlay/modules/glm53_dflash_early_fc/manifest.tsv | early-fc 파일을 컨테이너 타깃 경로에 바인딩하는 매니페스트 추가 |
| overlay/modules/glm53_dflash_early_fc/glm53_dflash_early_fc.py | execute_model 래퍼(생산자) + drafter combine 소비자 프로토콜 구현 추가 |
| MEASUREMENTS.md | 27차 측정 결과(PDL 기본값 누락 발견, MoE go/no-go, L2-warm 이득 정정 등) 기록 추가 |
| launchers/ab-glm53.sh | cand arm에 MK_PDL=1을 명시해 구형 프로필에서 누락되는 것을 방지 |
| bench/bracket.py | env 스냅샷 대상에 AR_PREFETCH 및 DFLASH_EARLY_FC 추가 |
| build/glm53/qwen3_dflash2.py | overlay 변경사항을 빌드 산출물에 반영 |
| build/glm53/manifest.tsv | early-fc 파일 바인딩 항목 반영 |
| build/glm53/glm5next_model.py | overlay 변경사항(early-fc 설치 + osar 경계) 빌드 산출물 반영 |
| build/glm53/glm53_megakernel.py | overlay 변경사항(ar_note) 빌드 산출물 반영 |
| build/glm53/glm53_dflash_early_fc.py | early-fc 모듈 빌드 산출물 추가 |
| build/glm53/dsv4_oneshot_shim.py | shim 힌트 학습/적용 변경사항 빌드 산출물 반영 |
| build/glm53/dsv4_oneshot_ar.cu | 커널 HintArgs/바인딩 변경사항 빌드 산출물 반영 |
| build/dsv4/glm53_megakernel.py | overlay 변경사항(ar_note) dsv4 빌드 산출물 반영 |
| build/dsv4/dsv4_oneshot_shim.py | shim 힌트 학습/적용 변경사항 dsv4 빌드 산출물 반영 |
| build/dsv4/dsv4_oneshot_ar.cu | 커널 HintArgs/바인딩 변경사항 dsv4 빌드 산출물 반영 |
Review details
- Files reviewed: 32/32 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| envs=(-e "MK_PKG_PATH=${TARGET_PREFIX%/}") | ||
| _fwd="" | ||
| for v in $(compgen -v | grep -E '^VLLM_(GLM53|DSV4)_'); do | ||
| envs+=(-e "$v=${!v}") | ||
| _fwd="$_fwd $v=${!v}" | ||
| done |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7dc5edf712
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| out = _ORIG_EXECUTE_MODEL(self, *args, **kwargs) | ||
| if not _DISABLED: | ||
| try: | ||
| launch_early_fc(self) |
There was a problem hiding this comment.
Launch the FC before execute_model returns
With VLLM_GLM53_DFLASH_EARLY_FC=1, this wrapper waits until the entire original execute_model call has returned before launching the side-stream FC. In the checked runner, execute_model already enqueues compute_logits and the logits collective before constructing execute_model_state (overlay/modules/glm53_drop_audit/gpu_model_runner.py:4667-4699), and launch_early_fc then waits for the current stream's tail. Consequently the FC cannot overlap the target head or logits AllGather as intended; it can overlap only the subsequent sampler, substantially invalidating the optimization's expected timing. Hook the launch immediately after the target forward instead of after the whole runner method.
Useful? React with 👍 / 👎.
| if not _DISABLED: | ||
| try: | ||
| launch_early_fc(self) | ||
| except Exception: | ||
| _DISABLED = True |
There was a problem hiding this comment.
Clear stale pending output when the producer falls back
If a successful producer launch is not consumed because that step skips drafting, _deneb_early_fc_pending remains set. When a later producer returns False or raises—especially the advertised failure-to-stock path here—the old pending tuple is not cleared; a subsequent combine_hidden_states call with the same token count can therefore accept the previous step's output and draft from stale hidden states instead of running the stock projection. Clear any pending result before attempting each new launch and on the exception path.
Useful? React with 👍 / 👎.
| exec docker run --rm --gpus all --entrypoint /bin/bash \ | ||
| --mount "type=bind,src=$REPO,dst=/repo,readonly" \ | ||
| "${envs[@]}" "${mounts[@]}" \ | ||
| "$IMAGE" -lc "$cmd" |
There was a problem hiding this comment.
Refuse to run the probe while serving containers are live
Despite the script's explicit requirement that no GLM53 container or TP=4 boot be active on any host, this path unconditionally starts another container with --gpus all and performs no local or fleet-wide docker ps guard. If an operator overlooks the comment, the MoE probe alone allocates several gigabytes of weight sets and drives the GPU continuously, which can both invalidate the experiment and pressure or OOM the serving process. Add the same fleet serving-container preflight used by the launcher utilities before starting this container.
Useful? React with 👍 / 👎.
… docs for 28차 The bracket with the lane actually served (compile-cache fix, MK-MLA off on both arms): C=1 step/s 15.95 -> 16.235 (+1.8%), pos-1 acceptance 64.5% vs 61.6%, quality 9/9, Korean 0/16, prefill unchanged. Per the operator's rule a proven improvement becomes the default and the other side is removed: VLLM_DFLASH2_FP8_DENSE=1 in profiles/glm53.env, the `w8` (fp8 pair, no pack) scheme deleted from the pass, the probe and the tests. READMEs: the drafter arm's result and the compile-cache lesson; the MLA wiring's real-row shadow and fixed scratch. Ledger references renumbered to 28차 (27차 is taken by PR #290). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… (28차 defaults + MLA fix; ledger 28차 above 27차, runbook items 11-14, ab base pin kept) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_b4f293e6-0424-4dd8-9c83-8f9a2a61a0ab) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ce226e0df9
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| def _drafter_of(runner): | ||
| """The drafter ForCausalLM that owns `fc`, or None.""" | ||
| spec = getattr(runner, "speculator", None) | ||
| model = getattr(spec, "model", None) |
There was a problem hiding this comment.
Read the drafter from the runner's actual field
When VLLM_GLM53_DFLASH_EARLY_FC=1, this lookup always returns None in the checked V2 runner: GPUModelRunner constructs the DFlash proposer as self.drafter (overlay/modules/glm53_drop_audit/gpu_model_runner.py:650-705) and never defines self.speculator. Consequently _drafter_of() returns here and the early FC is never launched, so the optimization silently remains on the stock path.
Useful? React with 👍 / 👎.
| input_batch = getattr(st, "input_batch", None) | ||
| n = int(getattr(input_batch, "num_tokens", 0) or 0) | ||
| if n <= 0 or n > aux[0].shape[0]: |
There was a problem hiding this comment.
Derive the token count from an available runner state
Even after resolving the drafter, every producer attempt still returns False here because the checked runner's ExecuteModelState contains scheduler_output, logits, and hidden states but no input_batch (overlay/modules/glm53_drop_audit/gpu_model_runner.py:510-523). Thus input_batch is always None, n becomes zero, and the advertised side-stream FC can never execute; obtain the scheduled token count from a field that the runner actually exposes.
Useful? React with 👍 / 👎.
| check(_same(first[0], ref_g), "gemm->gemm->gemm: graph replay == eager bitwise") | ||
| check(all(_same(a, b) for a, b in zip(first[1], ref_m)), | ||
| "mhc->gemm: graph replay == eager bitwise (out, residual, mixes)") |
There was a problem hiding this comment.
Compare PDL results with a non-PDL reference
When this probe is run with VLLM_GLM53_MK_PDL=1, both ref_g/ref_m and the captured outputs are produced by the same PDL-enabled launch path, so a stable numerical error caused by an unsafe pre-wait read passes these checks. The recommended separate PDL=0 invocation prints no output hash or values that can be compared across processes, meaning the probe does not actually establish the claimed PDL-on versus PDL-off numerical equivalence before the profile enables PDL by default.
Useful? React with 👍 / 👎.
| wrapper = B12xMoEWrapper( | ||
| num_experts=E, top_k=TOPK, hidden_size=HID, intermediate_size=INTER, | ||
| use_cuda_graph=True, max_num_tokens=64, num_local_experts=E, | ||
| activation="swigluoai_uninterleave", swiglu_alpha=1.0, | ||
| swiglu_beta=0.0, swiglu_limit=10.0) |
There was a problem hiding this comment.
Construct the probe with the serving wrapper capacity
This does not construct the same static kernel specialization that serving uses: the profile launches with MAX_BATCHED=8192, which becomes the expert layer's moe_config.max_num_tokens, while this wrapper is capped at 64 tokens. The resulting static workspace has max_rows=512 here versus the serving path's 640-row static cutoff, and workspace.max_rows is passed into _get_static_kernel and its cache key (overlay/modules/b12x_zero_weight_micro/moe_dispatch.py:2048-2057). Because the layout and compiled specialization being timed differ, the probe cannot support its claimed served-kernel bandwidth comparison without matching the serving capacity.
Useful? React with 👍 / 👎.
| best = max(rates.values()) | ||
| print(f"b12x best {best:.0f} GB/s = {100 * best / lane:.0f} pct of the " | ||
| f"lane's {lane:.0f} GB/s; U=40 -> {rates[40]:.0f} GB/s " | ||
| f"({100 * rates[40] / lane:.0f} pct)") | ||
| return 0 |
There was a problem hiding this comment.
Enforce the documented MoE go/no-go threshold
The probe documents a go/no-go rule of b12x reaching at least 90% of the lane rate, but this path returns success unconditionally after merely printing the percentages. If a future run measures below the threshold, automation—or an operator relying on the exit status used by the other gate probes��will still treat it as a passing run, potentially closing the MoE axis on a negative result; return nonzero or record an explicit failing check when the selected serving rate is below the threshold.
Useful? React with 👍 / 👎.
| best = max(rates.values()) | ||
| print(f"b12x best {best:.0f} GB/s = {100 * best / lane:.0f} pct of the " | ||
| f"lane's {lane:.0f} GB/s; U=40 -> {rates[40]:.0f} GB/s " | ||
| f"({100 * rates[40] / lane:.0f} pct)") | ||
| return 0 |
There was a problem hiding this comment.
Enforce the documented MoE go/no-go threshold
The probe documents a go/no-go rule of b12x reaching at least 90% of the lane rate, but this path returns success unconditionally after merely printing the percentages. If a future run measures below the threshold, automation—or an operator relying on the exit status used by the other gate probes—will still treat it as a passing run, potentially closing the MoE axis on a negative result; return nonzero or record an explicit failing check when the selected serving rate is below the threshold.
Useful? React with 👍 / 👎.
지도(#300) 다음 칸: 문서가 말하는 구조·기본값·흡수량을 지금 상태와 맞췄다. 코드 변경 0. - README: 구성 표가 "overlay/ 단일 manifest + 16파일" 이었다 -- 루트 overlay/manifest.tsv 는 없어졌고 모듈(42) × 프로필(dsv4 18 / glm53 25 / qwen38 1)을 compose-overlays.sh 가 build/<profile>/manifest.tsv 로 렌더한다. 배포 레이아웃에 glm53 경로(~/overlays/glm53, 4노드 동일)와 A/B base 가 MEGAKERNEL=0 을 명시하는 이유, 재배포가 브래킷 대상이라는 규율 추가. tools/ 절 신설 -- census.py(소유권·인접성), trace_step_composition, trace_step_tail, trace_common 과 각 도구의 함정, 플릿 CPU 규율. - profiles/README: 모듈 × 프로필 표가 실제 프로필과 어긋나 있었다 -- 쓰이는 모듈 10개 누락, 삭제된 glm53_async_dflash 잔존. 기계적으로 일치시켰고 (누락 0 확인), glm53 상태(bring-up, blocked -> 커널 캠페인 · 매일 부팅)와 기본 노브 행을 넣었다. "이식 가능한 모듈 넷" 은 매니페스트 전 행이 absent 인 모듈 열 개로 정정하되, 형식(계약)과 내용(모델 무관)은 다른 명제라고 단서를 달았다. - MEASUREMENTS: 두 스택(dsv4 프로덕션 / glm53 캠페인)이 한 원장에 섞여 있다는 안내와 기준선 제목의 스택 명시. glm53 기준선 블록 신설 -- 28차 §8 부팅의 요약이다. 쓰다가 오귀속을 잡았다: 그 20:36 부팅에는 MK_PDL 이 없었다 (PR #290 은 20:57 머지) -> "현행 프로필 = 이 기준선 + PDL 한 칸, 그 칸의 종단 수치는 아직 없다" 로 적었고 다른 두 문서의 출처도 분리했다. - RUNBOOK EXP-6 · 메가커널 README: 세그먼트 흡수량이 예측치(MHC 179->45)로만 있었다. 실측 열 추가 -- MHC 179->89(+잔여 7), quant+GEMM 376->187, KDA 미무장, MLA 22->11. 천장 4.9 ms 는 낙관으로 판정: 커널 -304 발인데 시간이 준 자리는 MHC -0.5 와 양자화 -1.5 뿐이다. - KERNEL_CAMPAIGN: 1차 캠페인의 두 결론("overlay-ownable 타깃 없음", "디코드는 논외")이 뒤집힌 경위와, 여전히 유효한 부분(MoE 47% 는 대역폭 바닥)을 후속 블록으로. - RUNTIME_GUARD_AUDIT: manifest 경로 각주(감사 결론은 이미지에 대한 것이라 오버레이가 늘어도 무효화되지 않는다). #301 반영: census --after 인접성 모드를 README 도구 표에, MHC_PASSES 노브를 프로필 표에, TileLang mhc PDL 봉인과 우리 MK PDL 이 다른 축이라는 포인터를 지도에 넣었다. 병합된 census.py 로 지도의 수치(1,582 / 402 / 25.4%)를 재확인. 테스트: 44,627 checks OK. Co-authored-by: choiceoh <choiceoh@srv4.tail7fec17.ts.net> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…31차로 PR #304 는 #301(672430e)에서 갈라져 나왔고, 그 뒤 main 이 #300·#302·#303·#305· #306·#307·#308(#309)로 앞서 나가면서 충돌 상태(dirty)가 됐다. 코드 파일은 겹치지 않았고(KDA 원패스·kpool 은 #304 단독), 겹친 것은 문서·프로필·테스트 넷이다. **RUNBOOK 충돌 2건** (1) 새 EXP 절의 삽입 위치: main 이 EXP-16 뒤에 EXP-22(로컬 양자화)·EXP-21(v2 레인)을 넣었고 #304 는 같은 자리에 EXP-20(미세 융합 묶음 2)을 넣었다. 경쟁이 아니라 가산이므로 셋 다 두되 기존 배열(최신 먼저)을 따라 22 → 21 → 20 순으로 둔다. (2) "순서와 근거" 절: main 은 평평한 번호 목록을 지우고 자기가 새로 만든 상태 표로 보내는 안내문으로 바꿨고(`채택·기각·닫힘은 위 상태 표에 있다`), #304 는 그 목록에 18번(EXP-20)을 덧붙였다. **main 의 재구성을 취하되**, 사라질 뻔한 #304 의 항목을 main 의 "다음 부팅 창에서" 목록에 8번으로 옮겨 실험이 목록과 함께 증발하지 않게 했다. **원장 번호 충돌 (자동 병합이 못 보는 것)** #304 는 자기 측정을 `★29차` 로 적었는데, 그 사이 main 에 다른 29차(메가커널 로컬 양자화, #307)와 30차(비상주 v2 레인, #305)가 먼저 들어왔다. 텍스트로는 충돌하지 않아 병합 결과에 **서로 다른 29차 둘**이 남았다. 28차 항목이 세운 선례("원장 번호 27 은 PR #290 이 쓰고 있어 28 로 적는다")대로 다음 빈 번호인 **31차** 로 옮겼고, 왜 옮겼는지 절 머리에 한 줄 남겼다. 측정값 자체는 손대지 않았다. 같은 번호를 가리키던 참조 6곳을 함께 고쳤다: MEASUREMENTS 절 제목, RUNBOOK EXP-20 표의 기각 축, `glm53_kda_onepass/README.md`, `moe_gate_sm121/README.md`, `profiles/glm53.env`, `tests/test_logic.py`. main 이 자기 29차를 가리키는 참조 (`VLLM_GLM53_MK_LOCALQ` 주석)는 그대로 두었다. **자동 병합분 검증** - `profiles/glm53.env`: main 의 `VLLM_GLM53_MK_LOCALQ` 와 #304 의 세 노브 (`KDA_DUAL_GEMM`·`KDA_ONEPASS`·`KPOOL_UPDATE_DIRECT_POS`) 전부 기본 0 으로 잔존. `MODULES=` 목록은 main 의 항목 하나도 잃지 않고 `glm53_kda_onepass` 만 늘었다. - overlay ↔ build 사본 3쌍(`glm53_kda_onepass.py`, `glm5next_kda.py`, `sparse_attn_indexer_kpool.py`) 모두 동일. - `tests/test_logic.py`: 양쪽 테스트 공존, `micro-fusion bundle 2 contracts` 통과. 검증: `tests/test_logic.py` all OK (6106 checks; 이 호스트엔 torch 부재로 일부 SKIP). 충돌 마커 0, 변경된 .py 전부 파싱 OK, `run_micro_fusion_check.sh` bash -n OK. GPU 검증(프로브 VERDICT·트레이스 물리확인)은 하지 않았다 — 이 환경에 GPU 가 없다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JTghtTjyfT23vuhZwHzBSM
**1. 원장 번호 충돌 — #311 의 29차를 32차로** main 에 서로 다른 29차 두 개가 남아 있었다: `메가커널 29차`(로컬 양자화 커널, PR #307, 5d52c16 으로 먼저 안착)와 `29차`(레버 2~7 브래킷 체인, PR #311, 65b2362 로 나중). 두 계열은 한 수열이다 — 28차 항목이 "원장 번호 27 은 PR #290 이 쓰고 있어 28 로 적는다"고 적으며 메가커널 27차를 피해 간 것이 그 증거다. 그 선례대로 **나중에 들어온 #311 쪽을 다음 빈 번호 32차로** 옮겼다(30·31 사용 중). 절 제목과 본문의 `item 2/5/6` 참조를 포함해 50곳을 고쳤고, 어느 쪽을 가리키는지 한 줄씩 분류해 **메가커널 29차를 가리키는 13곳은 그대로 두었다**(RUNBOOK EXP-22 5곳, `glm53.env` 2곳, megakernel README·py 4곳, 절 제목, #304 재번호 주석). 왜 옮겼는지는 31차와 같은 형식으로 절 머리에 남겼다. 측정값은 손대지 않았다. **2. RUNBOOK 상태 표 — 빠진 세 줄과 낡은 한 줄** 표가 EXP-20·21·22 를 아예 담고 있지 않았다. 각 절과 원장에 적힌 값만으로 채웠다: - EXP-20(미세 융합 묶음 2) — 브래킷 대기, 노브 3개 기본 0, 오프라인 게이트 PASS, 런치 −249/1,548 · −0.25 ms/스텝(C=1, 31차) - EXP-21(MK-GEMM v2) — 프로브 먼저, `MK_GEMM2` 프로필 미선언, exact PASS 이후 노출 프로브·스탬프 대기(30차 §4~5) - EXP-22(로컬 양자화) — 프로브 먼저 · 단독 부팅 금지, 노출 47.4 → 31.8 µs/층 (투영 −0.66 ms/스텝, 메가커널 29차) 그리고 **EXP-7 행이 낡아 있었다**: #311 이 `PREP_FUSED` 를 기본값 1 로 올리고 16.39 → 17.59 step/s(+7.3%)를 실측했는데 표는 아직 "부팅 대기 · `PREP_FUSED=0`" 이었다. 프로필 실값으로 확인해 "채택 · 기본값" 으로 고쳤다. 이제 표는 EXP 1~22 를 빠짐없이, 중복 없이 담는다. 검증: `tests/test_logic.py` all OK (6167 checks), 변경된 .py 파싱 OK, `bash -n` OK, overlay ↔ build 사본 동기 유지. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JTghtTjyfT23vuhZwHzBSM
무엇
전략 문서("메가커널 대대적 개선 방안", 2026-09-04)의 후보 중 운영자가 고른 항목의 구현과 프로브 결과. 세 커밋.
mk_pdl_enabled()는 env 를 읽는데 프로필에도ab-glm53.sh에도 없어서 지금까지의 무장 부팅은 전부 PDL 없이 돌았다.profiles/glm53.env기본 1, cand 팔에 명시. 그래프 캡처 안 체인 검사probes/mk_pdl_graph_check.py.VLLM_GLM53_AR_PREFETCH, 기본 0) —k_oneshot이 힌트 8범위를 값으로 받아 워프 1~7 이prefetch.global.L2로 걷는다(스레드 0 폴링·t_wait 불변, n==0 은 옛 커널 그대로). shim 이 MK 발사의note_consumer를 "어느 모델 forward 의 몇 번째 콜렉티브 뒤" 로 학습해(모델별 표) 캡처가 굳힌다; 경계는 컴파일 영역 위의Glm5NextForConditionalGeneration.forward와DFlash2Qwen3ForCausalLM.forward.glm53_dflash_early_fc,VLLM_GLM53_DFLASH_EARLY_FC, 기본 0) — 생산자 =execute_model래퍼, 소비자 = 드래프터의combine_hidden_states. 수치 동일.run_mk_probe.sh(b12x 까지 마운트하는 일반 러너),moe_decode_stream_probe.py,osar_build_check.py, disttest 힌트 팔.프로브 결과 (srv2, 원장 27차)
전략 상한 대 프로브의 정정표는 27차 6번에. 남은 큰 항목(k 축소, W4 팔, EXP-7)은 실측 형태의 상한 위에 있다.
게이트
tests/test_logic.py44,558 checks 통과 (프리페치 계약·early-fc 계약·scope 별 표 프로토콜 포함).RUNBOOK EXP-12/13/14 결과, EXP-15 추가, EXP-16(드래프터 메가커널) 은 정정 상한 −0.8~1.0 ms 로 착수 전 승인 항목.
🤖 Generated with Claude Code
Note
Medium Risk
Touches one-shot AllReduce CUDA, CUDA-graph replay, and model-runner patching on the decode critical path; new knobs default off except MK PDL (perf-only with bitwise gates), but mis-wiring could affect distributed boots or timing.
Overview
Documents 27차 probe findings and wires three performance levers that were missing or only probed before: serving PDL is now on in
profiles/glm53.envand theab-glm53.shcand arm (prior armed boots ran MK without it), withprobes/mk_pdl_graph_check.pyvalidating captured MK chains.Adds EXP-13 AR L2 prefetch (
VLLM_GLM53_AR_PREFETCH, default off):k_oneshotaccepts learned weight hints during the peer-wait window; the one-shot shim learns ranges from megakernelnote_consumercalls per forward ordinal (separate target / drafter scopes), and target/drafter forwards bracket collectives viabegin_forward/end_forward.Introduces EXP-15 early drafter
fc(glm53_dflash_early_fc, default off): a producer onGPUModelRunner.execute_modelrunsfcon a side stream after the target forward; the drafter overlay’scombine_hidden_statesconsumes the buffer (same numerics).New offline tooling:
run_mk_probe.sh, MoE go/no-go (moe_decode_stream_probe.py),osar_build_check.py, extended disttest;bench/bracket.pysnapshots the new env keys; contract tests intests/test_logic.py. RUNBOOK/MEASUREMENTS record revised ceilings (MoE axis closed at ~103% of lane; AR prefetch ~0.4–0.6 ms/step vs earlier strategy estimates).Reviewed by Cursor Bugbot for commit ce226e0. Bugbot is set up for automated code reviews on this repo. Configure here.