<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog | Jiangneng's Homepage</title><link>https://www.jiangnengli.com/post/</link><atom:link href="https://www.jiangnengli.com/post/index.xml" rel="self" type="application/rss+xml"/><description>Blog</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-us</language><image><url>https://www.jiangnengli.com/media/icon_hu_37c904991c0d686.png</url><title>Blog</title><link>https://www.jiangnengli.com/post/</link></image><item><title>Paper Notes: Dynamic Memory Compression</title><link>https://www.jiangnengli.com/post/llm-infra-kv-cache-reduction/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.jiangnengli.com/post/llm-infra-kv-cache-reduction/</guid><description>&lt;p&gt;&lt;strong&gt;Paper:&lt;/strong&gt;
&lt;/p&gt;
&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;
&lt;p&gt;Dynamic Memory Compression (DMC) optimizes LLM inference by allowing the model to autonomously decide when to merge redundant token representations in the KV cache based on learned contextual importance. To achieve this, the algorithm requires &amp;ldquo;retrofitting&amp;rdquo;—fine-tuning the pre-trained LLM on a fraction of its original data to teach the attention mechanism this dynamic pooling behavior. Consequently, while it drastically reduces memory footprint, it fundamentally alters the original model weights, making it incompatible with &amp;ldquo;training-free,&amp;rdquo; plug-and-play inference engines.&lt;/p&gt;
&lt;h2 id="key-takeaway"&gt;Key Takeaway&lt;/h2&gt;
&lt;p&gt;The core limitation of DMC is its dependency on &lt;strong&gt;2% of the original pre-training data&lt;/strong&gt; to train the merging mechanism. This is a non-trivial cost — unless every model provider commits to this retrofitting step, adoption remains impractical at scale. The training overhead makes it fundamentally different from training-free approaches like quantization or eviction-based methods.&lt;/p&gt;
&lt;p&gt;This concern has been echoed in practice. A similar merging request appeared in the vLLM project (
), where it was pointed out that the required training data makes it too expensive for general-purpose deployment.&lt;/p&gt;</description></item><item><title>Paper Notes: Speculative Decoding</title><link>https://www.jiangnengli.com/post/llm-infra-speculative-decoding/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.jiangnengli.com/post/llm-infra-speculative-decoding/</guid><description>&lt;p&gt;&lt;strong&gt;Papers:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Industry Adoption:&lt;/strong&gt; vLLM employs EAGLE as one of its most important speculative decoding features. See
.&lt;/p&gt;
&lt;h2 id="why-speculative-decoding-breaks-pagedattention-and-how-vllm-fixes-it"&gt;Why Speculative Decoding Breaks PagedAttention (and How vLLM Fixes It)&lt;/h2&gt;
&lt;h3 id="1-allocation-frequency-steady-pruning-vs-burst-and-kill"&gt;1. Allocation Frequency: Steady Pruning vs. Burst-and-Kill&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Beam Search&lt;/strong&gt; allocates and frees KV cache blocks at the pace of actual generation. With beam width = 3, each forward pass produces 3 new tokens. When a branch is pruned, the system triggers a single deallocation — the churn rate is synchronized with real generation speed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Speculative Decoding (Tree Attention)&lt;/strong&gt; operates in explosive bursts. The draft model generates an entire speculation tree (e.g., 15 candidate tokens) in a single, ultra-fast forward pass (a few milliseconds). The verifier then instantly rejects most of them — say 12 out of 15.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The critical gap:&lt;/strong&gt; Beam search prunes gradually. Speculative decoding forces the page table to insert 15 pointers, then execute 12 &lt;code&gt;Free&lt;/code&gt; operations just ~10ms later — every single step. This high-frequency &amp;ldquo;instant garbage collection&amp;rdquo; creates severe &lt;strong&gt;lock contention&lt;/strong&gt; on the CPU-side scheduler, and the management overhead can eat into the speedup gained from speculation.&lt;/p&gt;
&lt;h3 id="2-copy-on-write-fragmentation-at-micro-scale"&gt;2. Copy-on-Write Fragmentation at Micro Scale&lt;/h3&gt;
&lt;p&gt;CoW is elegant for beam search branching, but becomes a nightmare at speculative decoding&amp;rsquo;s micro-granularity.&lt;/p&gt;
&lt;p&gt;Consider a block of size 16 tokens with 3 empty slots remaining. Beam search fills one token at a time. But when the draft model forks into 3 parallel paths (A, B, C) each producing 3 tokens, CoW forces the system to immediately copy 3 independent physical blocks:&lt;/p&gt;
$$3 \times 16 = 48 \text{ token slots allocated, but only } 3 \times 3 = 9 \text{ draft tokens stored}$$&lt;p&gt;This is extreme &lt;strong&gt;internal fragmentation&lt;/strong&gt;. After verification kills paths B and C, those under-filled blocks must be freed immediately — adding to the allocation churn.&lt;/p&gt;
&lt;h3 id="3-the-engineering-solution-volatile-draft-buffer"&gt;3. The Engineering Solution: Volatile Draft Buffer&lt;/h3&gt;
&lt;p&gt;Because naive PagedAttention integration causes page table thrashing and internal fragmentation, production systems like vLLM and TensorRT-LLM &lt;strong&gt;do not&lt;/strong&gt; let draft tokens enter the global PagedAttention memory pool.&lt;/p&gt;
&lt;p&gt;Instead, they employ an isolation mechanism:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Volatile Draft Buffer:&lt;/strong&gt; Each sequence gets a small, contiguous temporary buffer (a simple array, not managed by the block allocator). Draft tokens are written directly here — no block allocation, no CoW, no fragmentation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In-place Overwrite:&lt;/strong&gt; The speculation tree is written into this buffer each step. Rejected tokens are simply overwritten by the next round of drafts — no &lt;code&gt;Free&lt;/code&gt; syscall needed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Commit on Verification:&lt;/strong&gt; Only after the verifier confirms tokens as correct are they &amp;ldquo;promoted&amp;rdquo; into the global PagedAttention KV cache as committed tokens, in a single batch write.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the real-world engineering answer: use a short-lived, lock-free ring buffer to absorb the high-frequency allocation/deallocation storm, and only touch the global page table for verified, permanent tokens.&lt;/p&gt;
&lt;h2 id="why-vllm-adopts-eagle-but-not-dmc"&gt;Why vLLM Adopts EAGLE but Not DMC&lt;/h2&gt;
&lt;p&gt;The key difference from approaches like
is &lt;strong&gt;decoupling&lt;/strong&gt;. EAGLE does not modify the base model weights at all — it trains a lightweight external draft head as a plug-in. If you don&amp;rsquo;t want speculative decoding, you simply remove the EAGLE head and the original model remains a standard, unmodified checkpoint.&lt;/p&gt;
&lt;p&gt;In contrast, DMC requires retrofitting the base model itself with 2% of pre-training data, permanently altering its weights. This makes it impractical unless every model provider commits to the training cost.&lt;/p&gt;
&lt;p&gt;With EAGLE, the training cost is absorbed by the open-source community: labs with compute (e.g., Tsinghua, Berkeley, LMSYS) pre-train EAGLE heads for popular models (Llama-3, Qwen, Mistral, etc.) and publish them on HuggingFace. End users simply download the plug-in weights and enjoy ~3x decoding speedup — no training required.&lt;/p&gt;</description></item><item><title>Paper Notes: FlashAttention</title><link>https://www.jiangnengli.com/post/llm-infra-flashattention1/</link><pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.jiangnengli.com/post/llm-infra-flashattention1/</guid><description>&lt;p&gt;&lt;strong&gt;Paper:&lt;/strong&gt;
&lt;/p&gt;
&lt;h2 id="1-tiling-and-safe-online-softmax-the-forward-pass-math"&gt;1. Tiling and Safe Online Softmax (The Forward Pass Math)&lt;/h2&gt;
&lt;p&gt;The fundamental bottleneck of standard attention is the $\Theta(N^2)$ memory requirement to materialize the attention score matrix in High Bandwidth Memory (HBM). FlashAttention solves this via &lt;strong&gt;tiling&lt;/strong&gt; (computing block by block in SRAM) combined with the &lt;strong&gt;Safe Online Softmax&lt;/strong&gt; mathematical trick.&lt;/p&gt;
&lt;h3 id="the-overflow-problem--safe-softmax"&gt;The Overflow Problem &amp;amp; Safe Softmax&lt;/h3&gt;
&lt;p&gt;Standard softmax operations $e^{x_i} / \sum e^{x_j}$ will trigger numerical overflow (e.g., NaN in FP16) if $x_i$ is large. To prevent this, a local maximum $m(x) = \max_i x_i$ is subtracted from all elements:&lt;/p&gt;
$$\text{softmax}(x_i) = \frac{e^{x_i - m(x)}}{\sum_j e^{x_j - m(x)}}$$&lt;h3 id="the-time-travel-reweighting-trick-online-softmax"&gt;The &amp;ldquo;Time-Travel&amp;rdquo; Reweighting Trick (Online Softmax)&lt;/h3&gt;
&lt;p&gt;Because blocks are processed sequentially and earlier blocks are discarded from SRAM, we cannot retroactively subtract a newly discovered global maximum from old blocks. Instead, FlashAttention leverages the exponential property $e^{a-b} = e^a \cdot e^{-b}$ to dynamically &amp;ldquo;decay&amp;rdquo; historical running states.&lt;/p&gt;
&lt;p&gt;For each new block $j$, the GPU computes the local scores $S_j = Q K_j^T$, the local max $m_{local}$, and the local exponentiated values $\tilde{P}_{local} = \exp(S_j - m_{local})$. The running variables are updated entirely in SRAM:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update Global Max:&lt;/strong&gt;
&lt;/p&gt;
$$m_{new} = \max(m_{old}, m_{local})$$&lt;p&gt;&lt;strong&gt;Update Running Denominator ($l$) via Exponential Decay:&lt;/strong&gt;
&lt;/p&gt;
$$l_{new} = l_{old} \cdot \exp(m_{old} - m_{new}) + \text{rowsum}(\tilde{P}_{local})$$&lt;p&gt;&lt;strong&gt;Update Running Numerator/Output ($O$) via Weighted Sum:&lt;/strong&gt;
&lt;/p&gt;
$$O_{new} = O_{old} \cdot \exp(m_{old} - m_{new}) + \tilde{P}_{local} V_{local}$$&lt;p&gt;By applying the decay factor $\exp(m_{old} - m_{new})$ to the history, the algorithm mathematically aligns all previous calculations to the new maximum without ever reloading old $K$ and $V$ matrices.&lt;/p&gt;
&lt;h2 id="2-loop-order-optimization-flashattention-1-vs-flashattention-2"&gt;2. Loop Order Optimization: FlashAttention-1 vs. FlashAttention-2&lt;/h2&gt;
&lt;p&gt;The physical execution speed of GPU kernels is heavily bound by HBM write operations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FlashAttention-1 (KV Outer Loop, Q Inner Loop):&lt;/strong&gt; FA1 iterates over $K, V$ blocks in the outer loop. For every inner loop step over $Q$, the intermediate, partially accumulated output block $O_i$ must be read from HBM, &amp;ldquo;un-normalized&amp;rdquo; by multiplying the old denominator, updated with the new block&amp;rsquo;s weighted sum, re-normalized, and written back to HBM. This causes a massive $O_i$ read/write overhead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FlashAttention-2 (Q Outer Loop, KV Inner Loop):&lt;/strong&gt; FA2 pins a $Q_i$ block in the outer loop and iterates through all $K_j, V_j$ blocks in the inner loop. The running variables $O_{run}$, $m_{run}$, and $l_{run}$ stay exclusively inside the SRAM registers. The intermediate $O_i$ is continuously accumulated using the decay formula and is written to HBM exactly once after the entire inner KV loop finishes. This simple loop swap eliminates the repetitive HBM writes, drastically dropping the constant factor in the $O(N^2 d^2 M^{-1})$ complexity.&lt;/p&gt;
&lt;h2 id="3-the-backward-pass-and-gradient-recomputation"&gt;3. The Backward Pass and Gradient Recomputation&lt;/h2&gt;
&lt;p&gt;During model training, the backward pass requires the full $N \times N$ attention probability matrix $P$ to calculate gradients using the Chain Rule. Writing this massive matrix to HBM during the forward pass would negate all memory optimizations.&lt;/p&gt;
&lt;h3 id="checkpointing-global-statistics"&gt;Checkpointing Global Statistics&lt;/h3&gt;
&lt;p&gt;Instead of storing the $N \times N$ matrix, the forward pass only saves the final global scalars to HBM: the global maximum ($m^{global}$) and the global denominator ($l^{global}$).&lt;/p&gt;
&lt;h3 id="on-the-fly-recomputation-and-matrix-calculus"&gt;On-the-Fly Recomputation and Matrix Calculus&lt;/h3&gt;
&lt;p&gt;During the backward pass, the GPU loads $Q_i$, $K_j$, $V_j$, and the upstream gradient $dO_i$ into SRAM. Because the true global maximum is already known, there is no need for dynamic reweighting. The exact local probability block $P_{ij}$ is reconstructed instantly:&lt;/p&gt;
$$P_{ij} = \frac{\exp(Q_i K_j^T - m^{global})}{l^{global}}$$&lt;p&gt;With $P_{ij}$ reconstructed locally, the gradients are computed using the multivariable chain rule, and the results are accumulated (+=):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gradient of V:&lt;/strong&gt;
&lt;/p&gt;
$$dV_j \mathrel{+}= P_{ij}^T \cdot dO_i$$&lt;p&gt;&lt;strong&gt;Gradient of Pre-Softmax Scores ($S$):&lt;/strong&gt;
&lt;/p&gt;
$$dS_{ij} = P_{ij} \circ (dO_i \cdot V_j^T - D_i)$$&lt;p&gt;(where $\circ$ is element-wise multiplication, and $D_i = \text{rowsum}(dO_i \circ O_i)$)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gradients of Q and K:&lt;/strong&gt;
&lt;/p&gt;
$$dQ_i \mathrel{+}= dS_{ij} \cdot K_j$$&lt;p&gt;
&lt;/p&gt;
$$dK_j \mathrel{+}= dS_{ij}^T \cdot Q_i$$&lt;p&gt;The strict accumulation logic (+=) represents the physical manifestation of the mathematical summation over all blocks. Once the local gradients are added to the accumulators in HBM, the massive $P_{ij}$ and $dS_{ij}$ blocks are immediately destroyed from SRAM, ensuring the memory footprint remains constant $\Theta(1)$ regardless of sequence length.&lt;/p&gt;</description></item><item><title>Paper Notes: vLLM PagedAttention</title><link>https://www.jiangnengli.com/post/llm-infra-pagedattention/</link><pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate><guid>https://www.jiangnengli.com/post/llm-infra-pagedattention/</guid><description>&lt;p&gt;&lt;strong&gt;Paper:&lt;/strong&gt;
&lt;/p&gt;
&lt;h2 id="executive-summary"&gt;Executive Summary&lt;/h2&gt;
&lt;p&gt;PagedAttention revolutionizes Large Language Model (LLM) inference by applying operating system virtual memory concepts to KV cache management. Instead of allocating contiguous GPU memory for a sequence&amp;rsquo;s maximum potential length (which causes massive external and internal fragmentation), PagedAttention divides the KV cache into fixed-size &lt;strong&gt;Physical Blocks&lt;/strong&gt; (e.g., storing 16 tokens each) and maps them dynamically via a &lt;strong&gt;Block Table&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="core-mechanisms--critical-insights"&gt;Core Mechanisms &amp;amp; Critical Insights&lt;/h2&gt;
&lt;h3 id="1-memory-management--copy-on-write-cow"&gt;1. Memory Management &amp;amp; Copy-on-Write (CoW)&lt;/h3&gt;
&lt;p&gt;To enable highly efficient memory sharing (e.g., multiple generated sequences sharing the same system prompt), PagedAttention implements a strict &lt;strong&gt;Reference Counting&lt;/strong&gt; (&lt;code&gt;ref_count&lt;/code&gt;) mechanism at the physical block level.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Shared Pointers&lt;/strong&gt;: Multiple logical blocks from different sequences can map to the exact same physical block. When this happens, the physical block&amp;rsquo;s &lt;code&gt;ref_count&lt;/code&gt; is incremented.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copy-on-Write (CoW) Execution&lt;/strong&gt;: When a sequence generates a new token and attempts to append it to the current physical block, the system first checks the &lt;code&gt;ref_count&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Trigger Condition&lt;/strong&gt;: If &lt;code&gt;ref_count &amp;gt; 1&lt;/code&gt; (meaning the block is shared), the sequence is not allowed to write directly. Instead, a CoW is triggered: the system allocates a brand-new physical block, copies the existing historical tokens into it, decrements the original block&amp;rsquo;s &lt;code&gt;ref_count&lt;/code&gt;, updates its own Block Table, and finally writes the new token into the newly copied block.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-hardware-bottleneck-dichotomy-prefill-vs-decoding"&gt;2. Hardware Bottleneck Dichotomy: Prefill vs. Decoding&lt;/h3&gt;
&lt;p&gt;The system must distinctly separate these two phases because they stress completely different physical hardware units on the GPU:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prefill Phase (Strictly Compute-Bound)&lt;/strong&gt;: To process the initial prompt (e.g., 1,000 tokens), the model must compute the Q, K, and V for all tokens. Because of the multi-layer Transformer architecture, every token must perform an Attention calculation with all preceding tokens to generate its distinct output ($O$) before passing through the FFN to the next layer. This results in a massive $O(N^2)$ Dense Matrix-Matrix Multiplication (GEMM). The GPU&amp;rsquo;s memory bandwidth is sufficient, but the Tensor Cores (ALUs) hit their maximum capacity. (This is where FlashAttention steps in to optimize).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Decoding Phase (Strictly Memory-Bound)&lt;/strong&gt;: During autoregressive generation, the model predicts only one token at a time. The arithmetic operation is a tiny Matrix-Vector Multiplication (GEMV). However, to compute this single step, the GPU must fetch the entire historical KV cache from the global HBM into the SRAM. The ALUs sit idle waiting for data to arrive. Thus, decoding speed is strictly bottlenecked by GPU memory bandwidth.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-fine-grained-branching-in-beam-search"&gt;3. Fine-Grained Branching in Beam Search&lt;/h3&gt;
&lt;p&gt;While architectural diagrams often simplify Beam Search (or parallel decoding) by showing sequences branching perfectly at the boundary of a block, the engineering reality is much more granular.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Token-Level Divergence&lt;/strong&gt;: Sequences branch at the exact token level, which almost always happens right in the middle of a physical block.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CoW Resilience&lt;/strong&gt;: The Copy-on-Write mechanism seamlessly handles this. If a beam diverges at the 5th token of a 16-token block, the CoW mechanism will copy those 5 tokens into a new physical block, and the new sequence will continue appending its unique 6th token into the new block, leaving the original shared block perfectly intact for the other beams.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-impact"&gt;System Impact&lt;/h2&gt;
&lt;p&gt;By combining dynamic block allocation, precise reference counting, and Copy-on-Write, PagedAttention achieves near-zero memory waste (less than 4% internal fragmentation in the final block). This fundamentally shifts the LLM inference paradigm, allowing batch sizes to scale significantly higher and dramatically improving overall system throughput.&lt;/p&gt;</description></item></channel></rss>