Simplified Overview (ELI5)
Written by Abrar Akhunji
Imagine you run an elite intelligence agency with 128 specialized forensic analysts.
Whenever a new 100-page report arrives, every single analyst creates their own detailed set of notes, charts, and summary folders.
- In standard AI models (Multi-Head Attention), every time a new word is typed, the AI stores 128 high-definition copies of key facts in GPU memory (the KV cache).
- When a document reaches 64,000 words, these notes take up over 50 Gigabytes of ultra-expensive GPU VRAM per user. A server with eight $35,000 GPUs runs out of memory after serving just a few dozen people simultaneously.
Engineers previously tried a blunt compromise called Grouped-Query Attention (GQA): forcing all 128 analysts to share just 8 generic note folders. It saved memory, but the analysts lost nuance and made more reasoning errors.
In DeepSeek-V2, DeepSeek-V3, and DeepSeek-R1, engineers introduced a mathematical masterpiece: Multi-Head Latent Attention (MLA).
Here is the magic:
- The Master Microfilm (Low-Rank Compression): Instead of storing 128 separate 128-dimensional note folders, MLA compresses all 128 perspectives into one ultra-dense 512-dimensional latent vector (like a high-density digital microfilm). Memory usage drops by 93%.
- The Lens Trick (Matrix Absorption): You might think the AI has to waste precious time blowing up the microfilm back into 128 giant folders every millisecond. But it doesn't! By flipping matrix multiplications around (the matrix absorption trick), the AI projects its magnifying lens (the single Query word) onto the microfilm directly, reading all 128 perspectives in a single nanosecond glance.
- Decoupled RoPE: It separates "what words mean" from "where words sit in the sentence," keeping the coordinates lightweight while compressing the meaning.
The result? You can serve 10x more concurrent users with 128k context windows on the exact same GPU cluster, with 100% of full Multi-Head Attention intelligence.
Here is the complete mathematical and kernel-level systems teardown of MLA and FlashMLA.
Senior Developer Systems Breakdown
Written by Abrar Akhunji
In modern large language model serving, the KV Cache Memory Bandwidth Wall is the primary bottleneck dictating batch capacity, serving cost, and generation latency. During autoregressive decoding ($B \ge 1, S=1$), matrix multiplications have an arithmetic intensity $\approx 1 \text{ FLOP / Byte}$. The GPU spends the overwhelming majority of its clock cycles reading historical Key and Value tensors from High Bandwidth Memory (HBM) across the bus into SRAM.
KV Cache Memory Footprint per Token (Precision = BF16 / FP16):
-----------------------------------------------------------------------------------------
Multi-Head Attention (MHA): 2 * n_layers * n_heads * d_head * 2 bytes
-> 2 * 61 * 128 * 128 * 2 = 4,001,792 Bytes / 1,000 tokens ~ 4.0 MB/seq
Grouped-Query Attention (GQA-8): 2 * n_layers * n_kv_heads * d_head * 2 bytes
-> 2 * 61 * 8 * 128 * 2 = 250,112 Bytes / 1,000 tokens ~ 0.25 MB/seq
(Downside: Significant reduction in KV capacity / retrieval precision)
Multi-Head Latent Attention (MLA): (d_c + d_R) * n_layers * 2 bytes
-> (512 + 64) * 61 * 2 = 70,272 Bytes / 1,000 tokens ~ 0.07 MB/seq
(93.3% VRAM reduction vs MHA with ZERO expressive capacity loss!)
While Grouped-Query Attention (GQA) reduces KV memory by enforcing key-value head sharing across query groups, it fundamentally constrains the model's associative memory capacity.
Multi-Head Latent Attention (MLA) solves this dilemma by projecting high-dimensional keys and values into a shared low-rank compressed latent space during storage, combined with Decoupled Rotary Positional Embeddings (RoPE) and Inference Matrix Absorption.
Below is the complete architectural, mathematical, and kernel breakdown of MLA and DeepSeek's SM90-native FlashMLA decoding engine.
The Mathematical Formulation of Multi-Head Latent Attention
Let $h_t \in \mathbb{R}^d$ denote the hidden representation for the token at generation step $t$, where $d$ is the model hidden dimension, $n_h$ is the number of attention heads, and $d_h$ is the per-head dimension.
Standard MHA vs Multi-Head Latent Attention (MLA) Architecture:
Standard Multi-Head Attention (MHA):
[ Hidden State h_t ] --+---> W^Q --> [ Q_t (n_h * d_h) ]
+---> W^K --> [ K_t (n_h * d_h) ] --> [ Stored in KV Cache: O(2 * n_h * d_h) ]
+---> W^V --> [ V_t (n_h * d_h) ] --> [ Stored in KV Cache: O(2 * n_h * d_h) ]
Multi-Head Latent Attention (MLA):
+---> W^DQ --> [ c_t^Q (d_c') ] --+--> W^UQ --> [ q_{t,i}^C (n_h * d_h) ]
[ Hidden State h_t ] --+ +--> W^QR --> [ q_{t,i}^R (n_h * d_R) ] (RoPE)
|
+---> W^DKV -> [ c_t^{KV} (d_c) ] -----------------> [ STORED IN KV CACHE: d_c ]
| (Compressed Latent KV)
|
+---> W^KR --> [ k_t^R (d_R) ] (Decoupled RoPE) ---> [ STORED IN KV CACHE: d_R ]
TOTAL CACHE: d_c + d_R
1. Low-Rank Key-Value Compression
Instead of generating full-rank keys and values directly, MLA down-projects $h_t$ into a compact latent vector $c_t^{KV} \in \mathbb{R}^{d_c}$ (where $d_c \ll n_h d_h$):
$c_t^{KV} = W^{DKV} h_t$
where $W^{DKV} \in \mathbb{R}^{d_c \times d}$ is the down-projection matrix.
The uncompressed content keys $k_{t,i}^C \in \mathbb{R}^{d_h}$ and values $v_{t,i}^C \in \mathbb{R}^{d_h}$ for the $i$-th head ($i \in {1, \dots, n_h}$) are generated via up-projection matrices $W^{UK} \in \mathbb{R}^{n_h d_h \times d_c}$ and $W^{UV} \in \mathbb{R}^{n_h d_h \times d_c}$:
$k_{t,i}^C = W_{(i)}^{UK} c_t^{KV}, \quad v_{t,i}^C = W_{(i)}^{UV} c_t^{KV}$
2. The Decoupled RoPE Mechanism
Standard Rotary Positional Embedding (RoPE) applies an orthogonal position-dependent rotation matrix $\mathbf{R}_t \in \mathbb{R}^{d_h \times d_h}$ to keys and queries:
$\tilde{k}_{t,i} = \mathbf{R}t k{t,i}$
Because $\mathbf{R}_t$ is position-dependent and matrix multiplication is non-commutative ($\mathbf{R}_t W^{UK} \neq W^{UK} \mathbf{R}_t$), incorporating RoPE directly into $c_t^{KV}$ prevents pre-computing or absorbing $W^{UK}$ at inference time.
MLA resolves this by decoupling content and position:
- $c_t^{KV} \in \mathbb{R}^{d_c}$ carries pure position-independent content.
- A dedicated lightweight key vector $k_t^R \in \mathbb{R}^{d_R}$ carries the RoPE positional information:
$k_t^R = \text{RoPE}(W^{KR} h_t)$
where $W^{KR} \in \mathbb{R}^{d_R \times d}$ and $d_R \ll d_h$ (typically $d_R = 64$).
The KV cache stores only the tuple $[c_t^{KV}, k_t^R]$ per token position.
The Matrix Absorption Trick: Operating in Latent Space
The naive execution of MLA at inference would require up-projecting $c_j^{KV} \to k_{j,i}^C$ and $c_j^{KV} \to v_{j,i}^C$ for all historical tokens $j \le t$ prior to computing attention, destroying memory bandwidth efficiency.
MLA's signature breakthrough is Inference Matrix Absorption:
1. Query Key Matrix Absorption
The attention score between the current query at step $t$ and historical key at step $j$ for head $i$ is:
$\text{Score}{t,j,i} = \frac{(q{t,i}^C)^T k_{j,i}^C + (q_{t,i}^R)^T k_j^R}{\sqrt{d_h + d_R}}$
Substituting $k_{j,i}^C = W_{(i)}^{UK} c_j^{KV}$:
$(q_{t,i}^C)^T k_{j,i}^C = (q_{t,i}^C)^T \left( W_{(i)}^{UK} c_j^{KV} \right)$
By associativity of linear transformations:
$(q_{t,i}^C)^T \left( W_{(i)}^{UK} c_j^{KV} \right) = \left( (W_{(i)}^{UK})^T q_{t,i}^C \right)^T c_j^{KV} = (\tilde{q}_{t,i}^C)^T c_j^{KV}$
The Optimization: Rather than decompressing $N$ historical keys in memory, we project the single current query $q_{t,i}^C$ with $(W_{(i)}^{UK})^T$ once at step $t$ into an absorbed query $\tilde{q}_{t,i}^C \in \mathbb{R}^{d_c}$. The dot product is then computed directly against the cached latent vectors $c_j^{KV}$ in SRAM!
Inference Matrix Absorption Flow:
Standard Latent Decoding (Memory-Heavy):
[ c_j^{KV} (HBM) ] --(Up-Project N tokens via W^UK)--> [ K_j (N * n_h * d_h) ] --> Dot [ Q_t ]
MLA Absorbed Decoding (Zero-Decompression in HBM):
[ Q_t (1 token) ] --(Absorb W^UK once)--> [ Q_t_absorbed (n_h * d_c) ] --+--> Direct Dot in SRAM!
+--> [ c_j^{KV} (d_c) ] (HBM)
2. Value Output Matrix Absorption
Similarly, context aggregation over historical values is:
$u_{t,i} = \sum_{j=1}^t A_{t,j,i} v_{j,i}^C = \sum_{j=1}^t A_{t,j,i} \left( W_{(i)}^{UV} c_j^{KV} \right) = W_{(i)}^{UV} \left( \sum_{j=1}^t A_{t,j,i} c_j^{KV} \right) = W_{(i)}^{UV} \tilde{u}_{t,i}$
Instead of materializing full values $v_{j,i}^C$, the attention kernel accumulates the weighted sum over cached latents $\tilde{u}_{t,i} \in \mathbb{R}^{d_c}$. The up-projection $W^{UV}$ is absorbed directly into the final linear output projection $W^O$:
$W_{\text{absorbed}}^O = W^O \cdot \text{diag}(W_{(1)}^{UV}, \dots, W_{(n_h)}^{UV})$
The GPU never stores, fetches, or decompresses keys or values in HBM during autoregressive decoding.
Architectural Pillars of Multi-Head Latent Attention
The 4 Pillars of Multi-Head Latent Attention & FlashMLA
- Dense Microfilm Latent Storage: Compresses 128 high-dimensional Key/Value heads into a single 512-dimensional latent vector c_t^{KV}, reducing per-token KV cache memory by 93.3%.
- Separation of Content & Geometry: Isolates position-dependent non-linear rotation to a tiny 64-dim decoupled key vector k_t^R, enabling linear projection absorption on content tensors.
- Associative Linear Transformation: Folds Key and Value up-projection weights directly into the current Query and Output layers, computing attention over compressed latents with zero HBM decompression.
- Hopper SM90 TMA & WGMMA Optimization: DeepSeek's custom CUDA decoding kernel leveraging Tensor Memory Accelerator and 128-thread Warp Group MMA to saturate memory bandwidth on NVIDIA H100/H800.
Empirical Systems Benchmark: MHA vs GQA-8 vs MLA
How does MLA compare against standard Multi-Head Attention (MHA) and Grouped-Query Attention (GQA-8) on an NVIDIA H100 SXM5 80GB serving a 70B/236B scale model across context lengths from 4k to 128k tokens?
The chart below measures KV Cache VRAM Footprint per Sequence (MB) across context lengths:
KV Cache Memory Footprint (MB / Sequence) Across Context Horizons
Benchmarking per-sequence VRAM consumption on 60-layer architectures. MLA achieves an order-of-magnitude reduction in memory footprint.
| context | Standard MHA (128 Heads) | GQA-8 (8 KV Groups) | MLA (DeepSeek Latent Cache) |
|---|---|---|---|
| 4,096 tokens | 16384 | 1024 | 288 |
| 16,384 tokens | 65536 | 4096 | 1152 |
| 65,536 tokens | 262144 | 16384 | 4608 |
| 131,072 tokens | 524288 | 32768 | 9216 |
Empirical Highlights:
- 128k Context Scalability: At 128k tokens, full MHA demands 524 GB of KV cache per stream (impossible on a single 8x H100 node without massive tensor/context parallelism). MLA requires only 9.2 GB, enabling multi-tenant high-throughput long-context serving.
- Serving Concurrency: On an 8x H100 cluster (640GB aggregate HBM3), MLA increases maximum concurrent 64k-token agent streams from 4 streams (GQA) to 48+ streams (MLA) with zero degradation in needle-in-a-haystack retrieval accuracy.
Production Implementation: PyTorch MLA with Matrix Absorption
Here is a clean, production-grade PyTorch implementation of Multi-Head Latent Attention featuring Decoupled RoPE, Low-Rank KV Compression, and runtime Matrix Absorption during decoding:
"""
multi_head_latent_attention.py
Production Reference Implementation of DeepSeek Multi-Head Latent Attention (MLA).
Includes Decoupled RoPE, Low-Rank KV Compression, and Matrix Absorption for Decoding.
"""
from __future__ import annotations
import math
import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Tuple, Optional
def apply_rope(x: torch.Tensor, freqs_cis: torch.Tensor) -> torch.Tensor:
"""
Applies 2D Rotary Positional Embeddings to input tensor.
Args:
x: [B, S, H, D] or [B, S, D]
freqs_cis: Complex exponential frequencies [B, S, D // 2]
"""
x_complex = torch.view_as_complex(x.float().reshape(*x.shape[:-1], -1, 2))
x_rotated = torch.view_as_real(x_complex * freqs_cis).flatten(-2)
return x_rotated.type_as(x)
class MultiHeadLatentAttention(nn.Module):
"""
Multi-Head Latent Attention (MLA) Layer.
Implements compressed latent KV caching and Query/Value matrix absorption.
"""
def __init__(
self,
dim: int = 4096,
num_heads: int = 64,
head_dim: int = 128,
kv_lora_rank: int = 512, # Compressed KV latent dimension (d_c)
q_lora_rank: int = 1536, # Compressed Query latent dimension (d_c')
rope_head_dim: int = 64 # Decoupled RoPE dimension (d_R)
) -> None:
super().__init__()
self.dim = dim
self.num_heads = num_heads
self.head_dim = head_dim
self.kv_lora_rank = kv_lora_rank
self.q_lora_rank = q_lora_rank
self.rope_head_dim = rope_head_dim
self.scale = 1.0 / math.sqrt(head_dim + rope_head_dim)
# 1. Query Projections (Low-Rank Down/Up + Decoupled RoPE)
self.w_dq = nn.Linear(dim, q_lora_rank, bias=False)
self.q_norm = nn.RMSNorm(q_lora_rank)
self.w_uq = nn.Linear(q_lora_rank, num_heads * head_dim, bias=False)
self.w_qr = nn.Linear(q_lora_rank, num_heads * rope_head_dim, bias=False)
# 2. Key-Value Projections (Low-Rank Down/Up + Decoupled RoPE)
self.w_dkv = nn.Linear(dim, kv_lora_rank, bias=False)
self.kv_norm = nn.RMSNorm(kv_lora_rank)
self.w_uk = nn.Linear(kv_lora_rank, num_heads * head_dim, bias=False)
self.w_uv = nn.Linear(kv_lora_rank, num_heads * head_dim, bias=False)
self.w_kr = nn.Linear(dim, rope_head_dim, bias=False)
# 3. Output Projection
self.w_out = nn.Linear(num_heads * head_dim, dim, bias=False)
def forward_prefill(
self,
x: torch.Tensor,
freqs_cis: torch.Tensor,
mask: Optional[torch.Tensor] = None
) -> Tuple[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:
"""
Prefill phase: Computes standard parallel multi-head attention.
Returns layer output and compressed KV cache tuple (c_kv, k_r).
"""
B, S, _ = x.shape
# Query pipeline
c_q = self.q_norm(self.w_dq(x))
q_c = self.w_uq(c_q).view(B, S, self.num_heads, self.head_dim)
q_r = self.w_qr(c_q).view(B, S, self.num_heads, self.rope_head_dim)
q_r = apply_rope(q_r, freqs_cis)
q = torch.cat([q_c, q_r], dim=-1)
# Key-Value compression
c_kv = self.kv_norm(self.w_dkv(x)) # [B, S, kv_lora_rank] - THIS IS STORED
k_c = self.w_uk(c_kv).view(B, S, self.num_heads, self.head_dim)
v_c = self.w_uv(c_kv).view(B, S, self.num_heads, self.head_dim)
k_r = self.w_kr(x).unsqueeze(2).expand(-1, -1, self.num_heads, -1)
k_r = apply_rope(k_r, freqs_cis) # THIS IS STORED
k = torch.cat([k_c, k_r], dim=-1)
# Attention computation
q = q.transpose(1, 2)
k = k.transpose(1, 2)
v = v_c.transpose(1, 2)
attn_weights = torch.matmul(q, k.transpose(-1, -2)) * self.scale
if mask is not None:
attn_weights = attn_weights + mask
attn_probs = F.softmax(attn_weights, dim=-1)
out = torch.matmul(attn_probs, v)
out = out.transpose(1, 2).contiguous().view(B, S, -1)
return self.w_out(out), (c_kv, k_r[:, :, 0, :])
def forward_decode_absorbed(
self,
x_t: torch.Tensor, # [B, 1, dim]
freqs_cis_t: torch.Tensor, # [B, 1, rope_dim // 2]
cached_c_kv: torch.Tensor, # [B, Context_Len, kv_lora_rank]
cached_k_r: torch.Tensor # [B, Context_Len, rope_dim]
) -> torch.Tensor:
"""
Decode phase using Matrix Absorption:
Avoids decompressing cached keys and values from HBM!
"""
B = x_t.shape[0]
# 1. Compute single query token representation
c_q = self.q_norm(self.w_dq(x_t))
q_c = self.w_uq(c_q).view(B, self.num_heads, self.head_dim)
q_r = self.w_qr(c_q).view(B, self.num_heads, self.rope_head_dim)
q_r = apply_rope(q_r.unsqueeze(1), freqs_cis_t).squeeze(1)
# 2. ABSORPTION STEP 1: Absorb W_UK into Query
w_uk_heads = self.w_uk.weight.view(
self.num_heads, self.head_dim, self.kv_lora_rank
)
q_absorbed = torch.einsum('bhd,hdk->bhk', q_c, w_uk_heads)
# 3. Compute attention scores directly in latent space!
score_content = torch.einsum('bhk,blk->bhl', q_absorbed, cached_c_kv)
score_rope = torch.einsum('bhd,bld->bhl', q_r, cached_k_r)
attn_weights = (score_content + score_rope) * self.scale
attn_probs = F.softmax(attn_weights, dim=-1)
# 4. ABSORPTION STEP 2: Aggregate over compressed latent values
u_tilde = torch.einsum('bhl,blk->bhk', attn_probs, cached_c_kv)
# 5. Project accumulated latents through W_UV and W_OUT
w_uv_heads = self.w_uv.weight.view(
self.num_heads, self.head_dim, self.kv_lora_rank
)
v_out = torch.einsum('bhk,hdk->bhd', u_tilde, w_uv_heads)
v_out = v_out.contiguous().view(B, 1, self.num_heads * self.head_dim)
return self.w_out(v_out)
FlashMLA & NVIDIA Hopper SM90 Kernel Architecture
To translate theoretical memory savings into maximum real-world throughput, DeepSeek designed FlashMLA, a specialized decoding kernel tuned for NVIDIA Hopper GPUs (H100/H800):
NVIDIA Hopper (SM90) FlashMLA Kernel Execution Hierarchy:
[ Global HBM3e Memory ] (Stores only c^{KV} [512] and k^R [64])
|
| (Async TMA Transfer via Tensor Memory Accelerator)
v
[ Shared Memory (SRAM) - 228 KB / SM ]
+-- Tile c^{KV}: [Tile_N x 512] (FP8 / BF16)
+-- Tile k^R: [Tile_N x 64]
|
| (Warp Group MMA - WGMMA.m64nKk16)
v
[ Tensor Core Registers (4 Warps = 128 Threads) ]
+-- Thread Accumulators: Register-Split GEMM-I (Q_absorbed * c^{KV})
+-- Softmax Online Normalization
+-- Register-Split GEMM-II (P * c^{KV})
|
v
[ Single Output Gemm Projection to Linear Out ]
Key Hopper Kernel Optimizations:
- Asynchronous TMA (Tensor Memory Accelerator): FlashMLA uses Hopper's hardware TMA engines to issue direct, asynchronous memory copy descriptors from global memory into Shared Memory (SRAM), completely bypassing register files and ALU instruction cycles.
- WGMMA (Warp Group Matrix Multiply-Accumulate): FlashMLA issues
wgmma.mma_asyncinstructions across 128-thread warp groups, executing GEMM operations directly from SRAM operands into accumulator registers. - Register-Pressure Minimization: By maintaining accumulator tiles split across warp groups and fusing online Softmax normalization with the latent Value accumulation loop, FlashMLA prevents register spilling and achieves >92% of theoretical HBM bandwidth utilization.
Structural Comparison: MHA vs MQA vs GQA vs MLA
| Architectural Dimension | Multi-Head Attention (MHA) | Multi-Query Attention (MQA) | Grouped-Query Attention (GQA-8) | Multi-Head Latent Attention (MLA) |
|---|---|---|---|---|
| KV Cache per Token | $2 \cdot n_h \cdot d_h$ | $2 \cdot 1 \cdot d_h$ | $2 \cdot n_{kv} \cdot d_h$ | $d_c + d_R$ (Compressed) |
| Example VRAM (60 Layers) | $4.0 \text{ MB} / 1\text{k tok}$ | $0.06 \text{ MB} / 1\text{k tok}$ | $0.25 \text{ MB} / 1\text{k tok}$ | $0.07 \text{ MB} / 1\text{k tok}$ |
| Expressive KV Capacity | Maximal ($n_h$ distinct heads) | Severe degradation | Moderate loss | Maximal ($n_h$ virtual heads) |
| Positional Encoding | Standard RoPE | Standard RoPE | Standard RoPE | Decoupled RoPE ($k_t^R$) |
| Decode HBM Decompression | N/A (Direct) | N/A (Direct) | N/A (Direct) | Zero (Matrix Absorption) |
| 128k Context Concurrency | Bottlenecked ($1\times$) | High ($30\times$) | Medium ($8\times$) | High ($30\times$ - $45\times$) |
Production Serving with vLLM and SGLang
Production serving engines have integrated native FlashMLA backends. To deploy DeepSeek-V2.5, DeepSeek-V3, or DeepSeek-R1 with FlashMLA acceleration:
Launching DeepSeek with FlashMLA in SGLang:
python3 -m sglang.launch_server \
--model-path deepseek-ai/DeepSeek-V3 \
--tp 8 \
--enable-flashmla \
--trust-remote-code \
--mem-fraction-static 0.90 \
--context-length 131072 \
--port 30000
Launching in vLLM:
vllm serve deepseek-ai/DeepSeek-R1 \
--tensor-parallel-size 8 \
--kv-cache-dtype auto \
--gpu-memory-utilization 0.95 \
--max-model-len 131072 \
--enforce-eager \
--enable-chunked-prefill
Key Takeaways for Senior AI Engineers
- Decouple Storage from Computation: High-dimensional KV heads are an artifact of legacy pre-training objectives. Compressing representations into low-rank latent spaces ($d_c=512$) decouples memory storage requirements from model width.
- Exploit Linear Associativity (Matrix Absorption): Never decompress cached tensors during autoregressive generation. Absorbing transformation matrices into the current Query and Output layers enables full attention computation directly inside the latent manifold.
- Decouple Geometric Embeddings: Non-linear operations like RoPE disrupt low-rank projection properties. Always isolate positional embeddings into separate low-dimensional key/query pathways.
- Kernel Specialization Dictates System Throughput: Algorithmic optimizations like MLA reach their full potential only when paired with hardware-native kernels (FlashMLA, WGMMA, TMA) that eliminate register pressure and maximize arithmetic intensity.
Sources & Further Reading:
- DeepSeek-V2 Technical Report: A Strong, Economical, and Efficient Mixture-of-Experts Language Model (DeepSeek-AI, 2024)
- DeepSeek-V3 Technical Report (DeepSeek-AI, 2024/2025)
- FlashMLA: Efficient MLA Decoding Kernel for NVIDIA Hopper GPUs
- vLLM Multi-Head Latent Attention Architecture Docs
- SGLang DeepSeek MLA Optimization Guide
