Buckets:
| """tree-v2 extension module (chiku-inu) — star-tree machinery validated by | |
| tree-dev/sim_tree_identity.py (240-token greedy identity vs sequential oracle). | |
| Ships alongside sitecustomize.py, which imports this at the end. Registers: | |
| 1. runner patch — duplicated branch positions AFTER slot mapping + step flag | |
| 2. attention patch — star-tree decode attention (paged, graph-safe) replacing | |
| the unified op on tree verify steps | |
| 3. star_reject() — fused rejection walk on the pinned vLLM layout | |
| (target rows 0..KW-1; full-accept next = row K; last-position salvage | |
| next = the sampler bonus; salvage KV relocation via stashed caches) | |
| REQUIRE philosophy: every assumption is checked at boot/first-use and raises — | |
| no silent fallbacks (the tree-v1 lesson). | |
| """ | |
| from __future__ import annotations | |
| import importlib.abc | |
| import importlib.util | |
| import os | |
| import sys | |
| from typing import Any | |
| SPEC_TREE_SPEC = os.environ.get("SPEC_TREE_SPEC", "1") == "1" | |
| TREE_W = int(os.environ.get("SPEC_TREE_WIDTH", "2")) | |
| TREE_REQUIRE = os.environ.get("TREE_REQUIRE", "1") == "1" | |
| STAR_REJECT_FUSED = os.environ.get("STAR_REJECT_FUSED", "1") == "1" | |
| TREE_STATS_EVERY = int(os.environ.get("TREE_STATS_EVERY", "2048")) | |
| TREE_FAIL_ON_PLACEHOLDER_SPEC = ( | |
| os.environ.get("TREE_FAIL_ON_PLACEHOLDER_SPEC", "1") == "1" | |
| ) | |
| def _conf_K() -> int: | |
| import json | |
| try: | |
| cfg = json.loads(os.environ.get("SPECULATIVE_CONFIG", "{}")) | |
| n = int(cfg.get("num_speculative_tokens", 0)) | |
| except Exception: | |
| n = 0 | |
| if n <= 0 or n % TREE_W: | |
| return 0 | |
| return n // TREE_W | |
| TREE_K = _conf_K() # chain length; scheduler sees K*W drafts | |
| _STATE: dict[str, Any] = { | |
| "tree_step": False, # set by runner patch per step (host-side) | |
| "kv_caches": {}, # layer_name -> kv_cache tensor (stashed by attn patch) | |
| "layers": {}, # layer_name -> v4 per-layer fast-path cache | |
| "attn_calls": 0, # python op-body invocations (dispatch diagnostic) | |
| "windows": {}, # layer_name -> window int (0=full) | |
| "seq_lens": None, # current step's seq_lens tensor (runner patch) | |
| "steps": 0, "acc_tokens": 0, "salvages": 0, "full_accepts": 0, | |
| } | |
| def _log(msg: str) -> None: | |
| print(f"[tree-v2] {msg}", file=sys.stderr, flush=True) | |
| def _fail(msg: str) -> None: | |
| if TREE_REQUIRE: | |
| raise RuntimeError(f"[tree-v2] REQUIRE: {msg}") | |
| _log(f"WARN (require off): {msg}") | |
| # ---------------- star attention kernel (validated: star_attn_paged.py) ----- | |
| _KERNELS: dict[str, Any] = {} | |
| _P_CACHE: dict[Any, Any] = {} | |
| _PREWARMED_REJECT: set[tuple[int, int, str]] = set() | |
| def _get_star_attn_kernel() -> Any: | |
| if "attn" in _KERNELS: | |
| return _KERNELS["attn"] | |
| import triton | |
| import triton.language as tl | |
| def _k_star_gqa( | |
| q_ptr, kc_ptr, vc_ptr, o_ptr, P_ptr, seqlen_ptr, bt_ptr, scale, | |
| sq_r, sq_h, skc_b, skc_s, skc_h, so_r, so_h, | |
| G: tl.constexpr, D: tl.constexpr, BK: tl.constexpr, | |
| BS: tl.constexpr, WINDOW: tl.constexpr, R: tl.constexpr, BG: tl.constexpr, | |
| ): | |
| # GQA KV-head sharing: one program per (row, KV-head) scores all G sibling | |
| # query heads against each KV tile loaded once (bf16 tensor-core tl.dot). | |
| r = tl.program_id(0) | |
| kvh = tl.program_id(1) | |
| d = tl.arange(0, D) | |
| g = tl.arange(0, BG) | |
| real = g < G | |
| qh = kvh * G + g | |
| q_g = tl.load(q_ptr + r * sq_r + qh[:, None] * sq_h + d[None, :], | |
| mask=real[:, None], other=0.0) # [BG, D] bf16 | |
| ctx = tl.load(seqlen_ptr) - R # seq_lens includes this step's R tokens | |
| Pr = tl.load(P_ptr + r) | |
| end = ctx + Pr | |
| if WINDOW > 0: | |
| start = tl.maximum(end - (WINDOW - 1), 0) | |
| else: | |
| start = 0 | |
| start = (start // BK) * BK | |
| m_i = tl.full([BG], -float("inf"), tl.float32) | |
| l_i = tl.zeros([BG], tl.float32) | |
| acc = tl.zeros([BG, D], tl.float32) | |
| nblocks = tl.cdiv(end - start, BK) | |
| for b in range(nblocks): | |
| base = start + b * BK | |
| offs = base + tl.arange(0, BK) | |
| if WINDOW > 0: | |
| kmask = (offs < end) & (offs > (end - WINDOW)) | |
| else: | |
| kmask = offs < end | |
| phys = tl.load(bt_ptr + offs // BS, mask=kmask, other=0) | |
| tok = phys * skc_b + (offs % BS) * skc_s + kvh * skc_h | |
| Kt = tl.load(kc_ptr + tok[:, None] + d[None, :], mask=kmask[:, None], other=0.0) | |
| Vt = tl.load(vc_ptr + tok[:, None] + d[None, :], mask=kmask[:, None], other=0.0) | |
| s = tl.dot(q_g, tl.trans(Kt)) * scale # [BG, BK] f32 | |
| s = tl.where(kmask[None, :], s, -float("inf")) | |
| m_new = tl.maximum(m_i, tl.max(s, axis=1)) | |
| alpha = tl.exp(m_i - m_new) | |
| p = tl.exp(s - m_new[:, None]) | |
| acc = acc * alpha[:, None] + tl.dot(p.to(tl.bfloat16), Vt) | |
| l_i = l_i * alpha + tl.sum(p, axis=1) | |
| m_i = m_new | |
| soff = ctx + r | |
| sphys = tl.load(bt_ptr + soff // BS) | |
| sslot = soff - (soff // BS) * BS | |
| ks = tl.load(kc_ptr + sphys * skc_b + sslot * skc_s + kvh * skc_h + d).to(tl.float32) | |
| ss = tl.sum(q_g.to(tl.float32) * ks[None, :], axis=1) * scale | |
| m_new = tl.maximum(m_i, ss) | |
| alpha = tl.exp(m_i - m_new) | |
| ps = tl.exp(ss - m_new) | |
| vs = tl.load(vc_ptr + sphys * skc_b + sslot * skc_s + kvh * skc_h + d).to(tl.float32) | |
| acc = acc * alpha[:, None] + ps[:, None] * vs[None, :] | |
| l_i = l_i * alpha + ps | |
| tl.store(o_ptr + r * so_r + qh[:, None] * so_h + d[None, :], | |
| acc / l_i[:, None], mask=real[:, None]) | |
| _KERNELS["attn"] = _k_star_gqa | |
| return _k_star_gqa | |
| def _star_P_tensor(K: int, W: int, device: Any) -> Any: | |
| import torch | |
| key = (K, W, device) | |
| if key not in _P_CACHE: | |
| # device-side construction — a host-list tensor() is an H2D copy, | |
| # illegal during CUDA-graph capture (run3 lesson) | |
| R = 1 + K * W | |
| P = torch.zeros(R, dtype=torch.int32, device=device) | |
| ar = torch.arange(1, K + 1, dtype=torch.int32, device=device) | |
| P[1 : K + 1] = ar | |
| P[K + 1 :] = ar.repeat_interleave(W - 1) | |
| _P_CACHE[key] = P | |
| return _P_CACHE[key] | |
| # ---------------- fused rejection walk (pinned vLLM layout) ----------------- | |
| def _get_star_reject_kernel() -> Any: | |
| if "reject" in _KERNELS: | |
| return _KERNELS["reject"] | |
| import triton | |
| import triton.language as tl | |
| def _k_star_reject( | |
| ta_ptr, # int32[K*W] argmax of TARGET rows | |
| draft_ptr, # int32[K] main-path draft ids | |
| topk_ptr, # int32[K, W] | |
| bonus_ptr, # int32[1] sampler bonus (= b_K's continuation row) | |
| out_ptr, # int32[K+1] | |
| valid_ptr, # int32[1] | |
| salv_ptr, # int32[1]: salvaged physical tree node or 0 | |
| K: tl.constexpr, W: tl.constexpr, | |
| ): | |
| NT: tl.constexpr = K * W | |
| n_acc = 0 | |
| nxt = -1 | |
| salv_node = 0 | |
| done = False | |
| for i in tl.static_range(K): | |
| if not done: | |
| pred = tl.load(ta_ptr + i) | |
| main = tl.load(draft_ptr + i) | |
| if pred == main: | |
| tl.store(out_ptr + i, pred) | |
| n_acc += 1 | |
| else: | |
| offs = tl.arange(0, W) | |
| cand = tl.load(topk_ptr + i * W + offs, mask=offs > 0, other=-2) | |
| hitmask = cand == pred | |
| anyhit = tl.sum(hitmask.to(tl.int32), axis=0) > 0 | |
| if anyhit: | |
| j = tl.min(tl.where(hitmask, offs, W * 2), axis=0) | |
| node = K + 1 + i * (W - 1) + (j - 1) | |
| tl.store(out_ptr + i, pred) | |
| n_acc += 1 | |
| salv_node = node | |
| if node < NT: | |
| nxt = tl.load(ta_ptr + node) | |
| else: | |
| nxt = tl.load(bonus_ptr) # last-position salvage | |
| done = True | |
| if nxt == -1: | |
| if n_acc < K: | |
| nxt = tl.load(ta_ptr + n_acc) # plain rejection | |
| else: | |
| nxt = tl.load(ta_ptr + K) # full accept (row K) | |
| tl.store(out_ptr + n_acc, nxt) | |
| tl.store(valid_ptr, n_acc + 1) | |
| tl.store(salv_ptr, salv_node) | |
| _KERNELS["reject"] = _k_star_reject | |
| return _k_star_reject | |
| def star_reject(target_argmax, draft_main, topk, bonus_token, K, placeholder, device, | |
| out_width=None): | |
| """Run the fused walk. out_width: vLLM expects (1, max_spec_len+1) = K*W+1 | |
| PLACEHOLDER-filled columns; the walk writes at most K+1 of them.""" | |
| import torch | |
| out = torch.full((1, out_width or (K + 1)), placeholder, dtype=torch.int32, device=device) | |
| valid = torch.zeros(1, dtype=torch.int32, device=device) | |
| salv = torch.zeros(1, dtype=torch.int32, device=device) | |
| kern = _get_star_reject_kernel() | |
| kern[(1,)]( | |
| target_argmax.to(torch.int32), draft_main.to(torch.int32).contiguous(), | |
| topk.to(torch.int32).contiguous(), bonus_token.to(torch.int32).reshape(1), | |
| out.view(-1), valid, salv, K=K, W=TREE_W, | |
| ) | |
| return out, valid, salv | |
| def star_reject_from_drafts(target_argmax, draft_token_ids, bonus_token, K, placeholder, device): | |
| """draft_token_ids = the K*W scheduled drafts in [main(K); branches(K*(W-1), | |
| grouped by position)] order — reconstruct main/topk and run the fused walk. | |
| No reliance on side-channel topk state.""" | |
| main = draft_token_ids[:K] | |
| branches = draft_token_ids[K:].reshape(K, TREE_W - 1) | |
| import torch | |
| topk = torch.cat([main.reshape(K, 1), branches], dim=1) | |
| return star_reject(target_argmax, main, topk, bonus_token, K, placeholder, device, | |
| out_width=K * TREE_W + 1) | |
| def prewarm_star_reject(K: int, W: int, device: Any, placeholder: int = -1) -> None: | |
| """Force Triton to compile the star rejection kernel before real inference.""" | |
| import torch | |
| key = (K, W, str(device)) | |
| if key in _PREWARMED_REJECT or K <= 0 or W <= 1: | |
| return | |
| target = torch.arange(K * W, dtype=torch.int64, device=device) | |
| draft = torch.arange(K * W, dtype=torch.int64, device=device) | |
| bonus = torch.zeros(1, dtype=torch.int64, device=device) | |
| star_reject_from_drafts(target, draft, bonus, K, placeholder, device) | |
| if device.type == "cuda" and not torch.cuda.is_current_stream_capturing(): | |
| torch.cuda.synchronize() | |
| _PREWARMED_REJECT.add(key) | |
| _log(f"star rejection prewarmed (K={K}, W={W}, device={device})") | |
| def relocate_salvaged_kv(salv_node: int, K: int) -> None: | |
| """Copy each layer's salvaged-branch KV (slot ctx+K+i) into the accepted | |
| slot (ctx+i). Called host-side only on salvage steps (~30%).""" | |
| import torch | |
| seq_lens = _STATE["seq_lens"] | |
| if seq_lens is None: | |
| _fail("relocate: seq_lens not stashed") | |
| return | |
| R = 1 + K * TREE_W | |
| # seq_lens already includes this step's R tokens | |
| base = seq_lens[0:1].to(torch.long) - R | |
| # salv_node is the physical input row: K+1 + pos0*(W-1) + branch0. | |
| # The previous W=2-only relocation copied base+K+pos, which is wrong for | |
| # W>2 when branch 2/3 wins and corrupts the accepted chain's KV. | |
| pos = ((int(salv_node) - (K + 1)) // (TREE_W - 1)) + 1 | |
| src = base + int(salv_node) | |
| dst = base + pos | |
| for name, kv in _STATE["kv_caches"].items(): | |
| kc, vc = kv.unbind(1) # [num_blocks, bs, Hkv, D] each | |
| fk = kc.reshape(-1, *kc.shape[2:]) | |
| fv = vc.reshape(-1, *vc.shape[2:]) | |
| fk[dst] = fk[src] | |
| fv[dst] = fv[src] | |
| def record_step(valid_count: int, salv: int, K: int) -> None: | |
| s = _STATE | |
| s["steps"] += 1 | |
| s["acc_tokens"] += valid_count | |
| s["salvages"] += 1 if salv else 0 | |
| s["full_accepts"] += 1 if valid_count == K + 1 and not salv else 0 | |
| if s["steps"] % TREE_STATS_EVERY == 0: | |
| _log(f"stats steps={s['steps']} tok/step={s['acc_tokens']/s['steps']:.3f} " | |
| f"salvages={s['salvages']} full={s['full_accepts']} " | |
| f"attn_py_calls/step={s['attn_calls']/max(1,s['steps']):.1f} " | |
| f"(~37=EAGER dispatch, ~0=FULL-graph replay)") | |
| # ---------------- runner patch: positions + step flag ----------------------- | |
| def _apply_runner_tree_patch(module: Any) -> None: | |
| import torch | |
| runner_cls = module.GPUModelRunner | |
| orig_prepare = runner_cls._prepare_inputs | |
| def _prepare_inputs(self: Any, scheduler_output: Any, *a: Any, **kw: Any) -> Any: | |
| result = orig_prepare(self, scheduler_output, *a, **kw) | |
| spec = scheduler_output.scheduled_spec_decode_tokens | |
| tree = False | |
| if SPEC_TREE_SPEC and len(spec) == 1: | |
| (toks,) = spec.values() | |
| ksch = len(toks) | |
| if ( | |
| TREE_FAIL_ON_PLACEHOLDER_SPEC | |
| and ksch | |
| and any(int(tok) < 0 for tok in toks) | |
| ): | |
| _fail( | |
| "scheduler handed negative tree draft tokens before " | |
| f"GPU verify: len={ksch} head={list(toks)[:8]}" | |
| ) | |
| if ksch and ksch % TREE_W == 0: | |
| K = ksch // TREE_W | |
| R = 1 + ksch | |
| pos = getattr(self.positions, "gpu", self.positions) | |
| # duplicate branch positions onto their main siblings. | |
| # branch rows are grouped BY POSITION (topk[:,1:W].flatten()): | |
| # row 1+K+t belongs to position 1 + t // (W-1) | |
| import torch as _t | |
| t = _t.arange(K * (TREE_W - 1), device=pos.device) | |
| pos[1 + K : R] = pos[1 + (t // (TREE_W - 1))] | |
| _STATE["seq_lens"] = self.seq_lens[:1] | |
| tree = True | |
| _STATE["tree_step"] = tree | |
| return result | |
| runner_cls._prepare_inputs = _prepare_inputs | |
| orig_dummy = runner_cls._dummy_run | |
| def _dummy_run(self: Any, num_tokens: int, *a: Any, **kw: Any) -> Any: | |
| # With MAX_NUM_SEQS=1 + spec K*W, a (1+K*W)-token dummy run is uniquely | |
| # the tree shape. Do NOT gate on uniform_decode: call sites pass it | |
| # inconsistently (run5: star path missed warmup AND capture), and a | |
| # star-valued dummy attention never affects piecewise replay semantics. | |
| R = 1 + TREE_K * TREE_W | |
| is_tree_shape = SPEC_TREE_SPEC and TREE_K > 0 and num_tokens == R | |
| prev = _STATE["tree_step"] | |
| if is_tree_shape: | |
| _STATE["tree_step"] = True | |
| _STATE["seq_lens"] = self.seq_lens[:1] | |
| try: | |
| return orig_dummy(self, num_tokens, *a, **kw) | |
| finally: | |
| _STATE["tree_step"] = prev | |
| runner_cls._dummy_run = _dummy_run | |
| _log(f"runner positions+dummy patch installed (pid {os.getpid()})") | |
| # ---------------- star attention dispatch (called INSIDE the op body) ------- | |
| # Inserted into vllm's unified_attention_with_output impl by a serve.py disk | |
| # patch (the stack's proven mechanism for compiled-region changes). Op bodies | |
| # are opaque to Dynamo: this python runs at capture time / eagerly, never | |
| # traced — is_current_stream_capturing is legal here (run2 lesson). | |
| def maybe_star_attention(query, key, value, output, layer, kv_cache, md) -> bool: | |
| """Return True if the star-tree path handled this attention call.""" | |
| import torch | |
| if md is None or not SPEC_TREE_SPEC or TREE_K <= 0: | |
| return False | |
| # EXCLUDE the drafter's own attention (agent-smith's documented gotcha): | |
| # draft_model.* has a different KV-share/layout; applying the star kernel | |
| # there caused the W=4 run's illegal memory access. | |
| if "draft" in getattr(layer, "layer_name", ""): | |
| return False | |
| num = getattr(md, "num_actual_tokens", -1) | |
| R = 1 + TREE_K * TREE_W | |
| if num != R or getattr(md, "max_query_len", -1) != R: | |
| return False | |
| if not _STATE["tree_step"]: | |
| return False | |
| # v4 fast path: everything layer-constant cached on first call; the | |
| # per-call python is one dict hit + cache-write + one kernel launch. | |
| # Calls are COUNTED: attn_calls/steps ~37 => eager dispatch; ~0 => replay. | |
| _STATE["attn_calls"] = _STATE.get("attn_calls", 0) + 1 | |
| lc = _STATE["layers"].get(layer.layer_name) | |
| if lc is None: | |
| from vllm.v1.attention.backends.flash_attn import reshape_and_cache_flash | |
| impl = layer.impl | |
| if getattr(impl, "logits_soft_cap", None): | |
| _fail("logits_soft_cap unsupported in star kernel") | |
| key_cache, value_cache = kv_cache.unbind(1) | |
| sw = getattr(impl, "sliding_window", (-1, -1)) | |
| window = sw[0] + 1 if isinstance(sw, tuple) and sw[0] >= 0 else 0 | |
| H, Hkv, D = impl.num_heads, impl.num_kv_heads, impl.head_size | |
| dev = query.device | |
| lc = { | |
| "rcf": reshape_and_cache_flash, | |
| "kc": key_cache, "vc": value_cache, | |
| "dtype": layer.kv_cache_dtype, | |
| "ks": layer._k_scale, "vs": layer._v_scale, | |
| "H": H, "Hkv": Hkv, "D": D, "G": H // Hkv, | |
| "win": window, "scale": float(impl.scale), | |
| "BS": key_cache.shape[1], | |
| "P": _star_P_tensor(TREE_K, TREE_W, dev), | |
| "out32": torch.empty(num, H, D, dtype=torch.float32, device=dev), | |
| "kern": _get_star_attn_kernel(), | |
| "kcs": (key_cache.stride(0), key_cache.stride(1), key_cache.stride(2)), | |
| } | |
| _STATE["layers"][layer.layer_name] = lc | |
| _STATE["kv_caches"][layer.layer_name] = kv_cache | |
| prewarm_star_reject(TREE_K, TREE_W, dev, -1) | |
| import torch as _t | |
| _log(f"star attention layer-cache built ({layer.layer_name}, " | |
| f"capturing={_t.cuda.is_current_stream_capturing()}, num={num}) pid={os.getpid()}") | |
| lc["rcf"]( | |
| key, value, lc["kc"], lc["vc"], | |
| md.slot_mapping[:num], lc["dtype"], lc["ks"], lc["vs"], | |
| ) | |
| H, D = lc["H"], lc["D"] | |
| Hkv = lc["Hkv"] | |
| q = query[:num].reshape(num, H, D) | |
| out32 = lc["out32"] | |
| lc["kern"][(num, Hkv)]( # grid (rows, KV-heads) for GQA sharing | |
| q, lc["kc"], lc["vc"], out32, lc["P"], | |
| md.seq_lens[:1], md.block_table[0], | |
| lc["scale"], | |
| q.stride(0), q.stride(1), | |
| lc["kcs"][0], lc["kcs"][1], lc["kcs"][2], | |
| out32.stride(0), out32.stride(1), | |
| G=lc["G"], D=D, BK=32, | |
| BS=lc["BS"], WINDOW=lc["win"], R=num, BG=16, | |
| num_warps=4, num_stages=1, | |
| ) | |
| output[:num].copy_(out32.to(output.dtype).reshape(output[:num].shape)) | |
| return True | |
| # ---------------- registration ---------------------------------------------- | |
| class _Loader(importlib.abc.Loader): | |
| def __init__(self, inner: Any, apply_fn: Any) -> None: | |
| self._inner = inner | |
| self._apply = apply_fn | |
| def create_module(self, spec: Any) -> Any: | |
| return self._inner.create_module(spec) | |
| def exec_module(self, module: Any) -> None: | |
| self._inner.exec_module(module) | |
| self._apply(module) | |
| class _Finder(importlib.abc.MetaPathFinder): | |
| def __init__(self, target: str, apply_fn: Any) -> None: | |
| self._target = target | |
| self._apply = apply_fn | |
| self._busy = False | |
| def find_spec(self, fullname: str, path: Any = None, target: Any = None) -> Any: | |
| if fullname != self._target or self._busy: | |
| return None | |
| self._busy = True | |
| try: | |
| spec = importlib.util.find_spec(fullname) | |
| finally: | |
| self._busy = False | |
| if spec is None or spec.loader is None: | |
| return None | |
| spec.loader = _Loader(spec.loader, self._apply) | |
| return spec | |
| if SPEC_TREE_SPEC: | |
| sys.meta_path.insert(0, _Finder("vllm.v1.worker.gpu_model_runner", _apply_runner_tree_patch)) | |
| # star attention is inserted into the unified op IMPL by a serve.py disk | |
| # patch; no meta-path wrapper (Dynamo traces Attention.forward — run2). | |
| _log(f"tree-v2 ext armed: W={TREE_W}, fused_reject={STAR_REJECT_FUSED}, require={TREE_REQUIRE}") | |
Xet Storage Details
- Size:
- 20.2 kB
- Xet hash:
- 01efb80a4fb63c391f310f1a819259dae5b36a239d3389a44342b7a7b210538c
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.