Liu, Cai, Zhang, Wang, Hu, Yuan (CUHK / Microsoft Research) — CVPR 2023

EfficientViT: Cascaded Group Attention

A vision transformer built for speed, not FLOPs. The paper shows that attention is memory-bound, that multi-head attention wastes compute on redundant heads, and fixes both with a sandwich layout and cascaded group attention — feeding each head a different slice of the features and chaining them.

Prerequisites: Scaled dot-product attention + Multi-head attention + Matrix multiplication. We re-derive what we need.
10
Chapters
9
Simulations
2
Code Labs

Chapter 0: The Speed Trap

You have trained a beautiful Vision Transformer. On paper it is lean — only 1.5 GFLOPs, a third of what a ResNet-50 spends. You ship it to a phone expecting a third of the latency. Instead it runs slower than the ResNet. The FLOP counter lied to you.

This is the scenario EfficientViT was built to fix. The conventional way to make a vision model "efficient" is to drive down FLOPs (floating-point operations). DeiT, Swin, PVT, and the whole first wave of efficient transformers chased lower FLOPs. But a deployed model's wall-clock latency is not FLOPs — it is FLOPs plus the time spent moving tensors in and out of memory, reshaping them, and running element-wise operations that the FLOP counter ignores entirely.

Liu et al. measured where a transformer block actually spends its runtime on real hardware. The headline finding: in a standard ViT block, the multi-head self-attention (MHSA) is memory-bound — a large share of its runtime is not the matrix multiplies but the reshaping, the softmax, and the frequent reads/writes of the attention matrix. Meanwhile the heads themselves are highly redundant: many attention heads in the same layer compute nearly identical attention maps, so the model pays for h heads but gets the diversity of far fewer.

FLOPs Lie: What Actually Costs Time

A transformer block's runtime split into compute-bound matmuls (teal) versus memory-bound operations — reshape, softmax, normalization, element-wise (warm). A FLOP counter only sees the teal. Click "Profile" to reveal where the wall-clock time really goes.

Click to profile

EfficientViT attacks both problems at once with two ideas you will spend the next nine chapters understanding:

ProblemEfficientViT's fixChapter
Attention is memory-bound; reshape/softmax dominateSandwich layout — one attention layer wrapped in many cheap FFN layers2
Multi-head attention heads are redundant (compute the same map)Cascaded Group Attention — feed each head a different feature split4–5
Channels are allocated uniformly, wasting capacity on Q/KParameter reallocation — wide values, narrow Q/K, smaller FFN ratio6
The bet EfficientViT makes: Stop optimizing FLOPs. Optimize for the operations that are actually slow on hardware — memory access and reshaping. Reduce the number of memory-bound attention layers, and make the attention layers you keep diverse rather than redundant. The result (the EfficientViT-M family) runs faster than MobileNetV3 and MobileViT at the same accuracy on GPU and CPU — even though some of them spend more FLOPs than the models they beat. The FLOP-optimal model and the latency-optimal model are not the same model.

The landscape before EfficientViT

By 2022, "efficient ViT" research had converged on a small set of tricks: window attention (Swin) to make attention cost linear in tokens; spatial pooling of keys and values (PVT, MViT) to shrink the attention matrix; and hybrid conv-attention stems (MobileViT, LeViT) to cut early-layer cost. Every one of these reduces the theoretical cost of attention.

But Liu et al. pointed out that these models still place a full self-attention in every block, and still split that attention into many redundant heads. So even the "efficient" variants inherit the memory-bound tax on every layer and the head-redundancy waste in every attention. The opportunity was not a cleverer attention kernel — it was a cleverer budget: how many attention layers do you actually need, and how should each attention spend its channels?

Let us start by making "memory-bound" concrete, because the whole architecture follows from it.

Why can a Vision Transformer with fewer FLOPs than a ResNet still be slower on real hardware?

Chapter 1: Memory-Bound Attention

Every operation on a GPU is either compute-bound (limited by how fast the arithmetic units can multiply-add) or memory-bound (limited by how fast data moves between high-bandwidth memory and the compute units). The deciding quantity is arithmetic intensity — the ratio of arithmetic operations to bytes of memory traffic.

arithmetic intensity = (number of FLOPs) / (bytes read + bytes written)

If a kernel does a lot of math per byte it touches (high intensity), it is compute-bound and FLOPs predict its time. If it does little math per byte (low intensity), it is memory-bound and FLOPs are almost irrelevant — the time is set by memory bandwidth.

A big matrix multiply like Q·K⊤ is the high-intensity case: each output element reuses a whole row and column, so the bytes loaded are amortized over many multiply-adds. Matmuls are compute-bound and FLOPs do predict them. But the other operations in attention are the low-intensity case.

The hidden cost: everything that is not a matmul

Walk through one self-attention layer on a feature map of T tokens and C channels. Beyond the two matmuls (scores and the value mix), the layer also performs:

OperationFLOPsMemory trafficBound by
Q·K⊤ (scores)O(T²C)read Q,K; write [T,T]compute (big matmul)
softmax over the [T,T] matrixO(T²)read [T,T]; write [T,T]memory
reshape / transpose for heads~0read & write the whole tensormemory
A·V (value mix)O(T²C)read A,V; write [T,C]compute (big matmul)
add & LayerNormO(TC)read & write [T,C]memory

The softmax does only O(T²) arithmetic but reads and writes the entire O(T²) attention matrix — its arithmetic intensity is roughly 1, the textbook definition of memory-bound. Reshapes do essentially zero arithmetic but copy the whole tensor through memory. LayerNorm and the residual add are element-wise: one pass each way over the feature map for a handful of FLOPs per element.

Why this is the key insight. When the authors profiled a Swin-T block, they reported that the memory-bound operations (softmax, reshaping, element-wise) account for a large fraction of total runtime — comparable to, and in some configurations exceeding, the compute-bound matmuls. So the matmuls you optimized are not the bottleneck. The reshape-softmax-norm overhead is paid once per attention layer. The cheapest way to pay it less is to have fewer attention layers — exactly what the sandwich layout does in Chapter 2.

Worked example: the intensity gap

Take a modest stage: T = 196 tokens (a 14×14 grid), C = 192 channels, fp16 (2 bytes/element). Compare the score matmul against the softmax that follows it.

Score matmul Q·K⊤: output is T×T = 196×196. Each entry is a dot product over C = 192 channels, so 2×192 FLOPs (one multiply, one add per channel). Total ≈ 196×196×384 ≈ 14.7M FLOPs. Memory: read Q and K (2×196×192×2 bytes ≈ 0.15 MB), write the [196,196] matrix in fp16 (≈ 0.077 MB) ≈ 0.23 MB. Intensity ≈ 14.7M / 0.23M ≈ 64 FLOPs/byte — comfortably compute-bound.

Softmax over the same matrix: roughly 5 FLOPs per entry (max, subtract, exp, sum, divide) × 196×196 ≈ 0.19M FLOPs. Memory: read the [196,196] matrix and write it back ≈ 2×0.077 MB ≈ 0.15 MB. Intensity ≈ 0.19M / 0.15M ≈ 1.3 FLOPs/byte — squarely memory-bound.

The matmul does ~50× more arithmetic per byte than the softmax. On hardware that can do ~100 FLOPs per byte of bandwidth, the matmul saturates the compute units while the softmax stalls waiting for memory — and that stall is pure latency the FLOP counter never sees.

The Roofline: Compute-Bound vs Memory-Bound

The roofline model. The slanted line is the memory-bandwidth ceiling; the flat line is the peak-compute ceiling. Operations to the left (low intensity) are memory-bound — their speed is set by bandwidth, not FLOPs. Drag the slider to move an operation's arithmetic intensity and watch it cross the ridge point.

Arithmetic intensity 1.3
Misconception: "Fewer FLOPs always means faster." False on real hardware. A memory-bound operation's time is set by bytes moved, not FLOPs. You can cut a softmax's FLOPs in half and its runtime barely changes, because it was waiting on memory the whole time. Conversely, fusing a reshape away (eliminating a full read/write of the tensor) can save more wall-clock time than removing a million FLOPs of matmul. EfficientViT optimizes the right variable: the number of memory-bound passes.
Which property makes the softmax inside attention memory-bound rather than compute-bound?

Chapter 2: The Sandwich Layout

If attention is the expensive, memory-bound part of a block, the natural question is: how many attention layers do you actually need? A standard ViT block alternates one attention with one FFN, every layer, throughout the network. EfficientViT breaks that one-to-one rhythm.

The sandwich layout replaces the usual (attention, FFN) pair with a block that has a single self-attention layer sandwiched between N feed-forward layers on each side. Schematically, a sandwich block computes:

X → [FFN]×N → one Self-Attention → [FFN]×N → output

More precisely, each sub-layer is a residual update. Writing ΦF for an FFN sub-layer and ΦA for the self-attention sub-layer, a sandwich block applies:

Xi+1 = Xi + ΦA( (ΦF)N(Xi) ), then (ΦF)N again

The single attention layer does the expensive global token mixing once. The many FFN layers — which are pure pointwise matmuls, fully compute-bound and cheap per the roofline — do the channel mixing and the bulk of the representational work. Each FFN sub-layer is also wrapped with a depthwise convolution token interaction, so even between attention layers the model still gathers some local spatial context without paying for global attention.

Standard Block vs Sandwich Block

Left: a standard ViT block — attention and FFN alternate one-to-one. Right: an EfficientViT sandwich block — one attention layer (warm, memory-bound) wrapped in N FFN layers (teal, compute-bound) per side. Drag N to add FFN layers and watch the share of memory-bound attention shrink.

FFNs per side (N) 2

Why this is a strict win

It looks like you are removing attention layers — won't accuracy collapse? The paper's ablation says no, and here is the intuition. Attention's job is global, long-range token mixing. But once a layer has mixed tokens globally, the next layer's attention sees a feature map that already encodes those long-range relationships; a second consecutive attention is largely redundant. The FFNs, by contrast, are doing complementary work — nonlinear channel mixing — and they are cheap. So replacing redundant attention with extra FFN capacity keeps the accuracy while removing the memory-bound tax.

Reading the layout as a budget. A standard L-layer ViT pays the memory-bound attention overhead L times. A sandwich-layout EfficientViT with one attention per block and B blocks pays it only B times, with B much smaller than L, while spending the freed budget on FFNs that the hardware loves. The accuracy stays flat (the ablation shows a small gain, not a loss), and the latency drops. It is a Pareto improvement, not a tradeoff.

Worked example: counting memory-bound passes

Suppose a stage needs 6 layers of "work." A standard ViT spends them as 3 (attn, FFN) pairs — 3 attention layers, each paying the reshape+softmax+norm overhead. An EfficientViT sandwich block with N = 2 FFNs per side spends the same 6 layers as 2 FFN + 1 attn + 2 FFN + (1 more FFN to reach 6) — 1 attention layer. Same depth, same FFN count roughly, but one third of the memory-bound attention passes. If each attention contributes, say, 0.6 ms of memory-bound overhead, that is 1.2 ms saved per stage with no accuracy cost.

python
import torch.nn as nn

class SandwichBlock(nn.Module):
    """One memory-bound attention wrapped in 2N cheap FFN layers."""
    def __init__(self, dim, n_ffn=2):
        super().__init__()
        # N FFN layers before the attention ...
        self.pre  = nn.ModuleList([FFNwithDWConv(dim) for _ in range(n_ffn)])
        # ... exactly ONE self-attention (the only memory-bound part) ...
        self.attn = CascadedGroupAttention(dim)
        # ... and N FFN layers after.
        self.post = nn.ModuleList([FFNwithDWConv(dim) for _ in range(n_ffn)])

    def forward(self, x):
        for f in self.pre:  x = f(x)   # cheap, compute-bound
        x = self.attn(x)                  # expensive, memory-bound — ONCE
        for f in self.post: x = f(x)   # cheap, compute-bound
        return x
Misconception: "The sandwich layout just makes the network shallower to save time." No — the total depth is the same or greater; what changes is the mix. You are not deleting layers, you are converting expensive memory-bound attention layers into cheap compute-bound FFN layers. The model is just as deep; it is the composition of that depth that is re-budgeted toward operations the hardware runs fast.
What is the core idea of the sandwich layout, and why doesn't it hurt accuracy?

Chapter 3: Head Redundancy

The sandwich layout reduces how often we run attention. The next two chapters reduce how much each attention wastes. The waste has a name: head redundancy.

Recall standard multi-head attention. The C-channel input X is projected into h heads. Every head receives the same full input X and computes its own Q, K, V from it. The hope is that the heads specialize — one tracks objects, one tracks texture, one tracks position. The reality, Liu et al. measured, is that many heads in the same layer learn to compute nearly the same attention map. They are redundant: you pay for h heads of compute and memory, but the effective diversity is much lower.

Measuring redundancy

How do you quantify "two heads are similar"? Compare their attention matrices. Head a produces A(a) of shape [T,T]; head b produces A(b). Flatten each into a vector and take the cosine similarity:

sim(a,b) = <A(a), A(b)> / (∥A(a)∥ · ∥A(b)∥)

If sim(a,b) is close to 1, the two heads attend almost identically — the second head adds little. The paper visualizes the average pairwise head similarity across layers and finds it is high in vanilla MHSA: the heads cluster. The model is computing h attention maps but only a few of them are distinct.

Head Similarity Matrix

Pairwise cosine similarity between the attention maps of 6 heads. Bright = redundant (heads attend identically); dark = diverse. Drag from "Vanilla MHSA" (heads cluster, lots of bright off-diagonal) toward "Cascaded Group" (heads diversify, off-diagonal darkens).

Vanilla → Cascaded 0.00

Why redundancy happens

Two heads start from the same input X. Their only difference is their projection matrices WQ, WK. During training, nothing in the loss explicitly pushes the heads apart — gradient descent is perfectly happy to let several heads converge to a useful-but-similar pattern, because each one independently lowers the loss. There is no diversity pressure. So redundancy is the default, not the exception.

Worked example: redundancy costs you capacity. Suppose h = 8 heads but, by the similarity test, only 3 are distinct; the other 5 are near-copies. You are spending 8× the projection FLOPs and 8× the memory of an attention layer, but getting the representational power of 3 heads. That is a ~60% waste of the attention's compute on duplicated maps. EfficientViT's fix turns that waste into useful diversity for free.

The redundancy ↔ diversity tradeoff

The cure cannot simply be "use fewer heads" — that throws away the multi-head benefit of attending to several relationship types. Nor can it be a diversity loss term — that adds training complexity and hyperparameters. EfficientViT's insight is architectural: give each head a different input. If head a and head b never see the same features, they cannot collapse to the same attention map. Diversity becomes structural, guaranteed by construction rather than coaxed by a loss.

That single idea — feed each head a different slice of the feature channels — is group attention, and it is the subject of Chapter 4. Chaining the groups so each head also refines the next is the cascade of Chapter 5.

Misconception: "Redundant heads are harmless — they just average out." They are not harmless: they consume FLOPs, parameters, and memory bandwidth while contributing almost nothing the other copies don't already contribute. In a memory-bound layer, every redundant head is extra bytes moved for no representational gain. Redundancy is wasted budget, and budget is exactly what an efficient model cannot afford to waste.
What does "head redundancy" mean in standard multi-head self-attention, and what causes it?

Chapter 4: Group Attention

Standard multi-head attention feeds all C channels of the input to every head. Group attention does the opposite: it splits the C input channels into h disjoint groups, one per head, and feeds head j only its own group.

Let the input be X of shape [T, C]. Split the channel axis into h slices:

X = [ X1 | X2 | ... | Xh ],   each Xj of shape [T, C/h]

Head j computes its query, key, and value only from its own slice:

Qj = Xj WQj,   Kj = Xj WKj,   Vj = Xj WVj

where each projection W·j now has shape [C/h, d] instead of [C, d]. Then each head runs ordinary scaled dot-product attention on its own slice:

headj = Attention(Qj, Kj, Vj) = softmax(QjKj⊤ / √d) Vj

and the heads are concatenated and projected back to C channels by WO, exactly as in standard MHA.

Two wins at once

Win 1 — guaranteed diversity. Head 1 sees channels 1..C/h; head 2 sees channels C/h+1..2C/h. They process disjoint information, so they cannot collapse to the same attention map. The redundancy of Chapter 3 is eliminated by construction — no diversity loss required.

Win 2 — cheaper projections. In standard MHA, each head's WQ is [C, d] — it reads all C channels. In group attention it is [C/h, d] — it reads only C/h. With h heads, the total Q-projection cost drops from h·C·d to h·(C/h)·d = C·d, an h× reduction in the QKV projection compute and parameters.

Group Attention: Channel Splitting

The C input channels (top, one tile per channel) are split into h disjoint groups and routed to h heads. Each head's Q/K/V projection reads only its own slice. Drag the number of heads h and watch each head's slice (and projection width) shrink.

Heads (h) 4

Worked example: the projection saving, by the numbers

Let C = 192, h = 4 heads, head dimension d = 16. Standard MHA: each head's WQ is [192, 16] = 3,072 params; with 4 heads and 3 matrices (Q,K,V) that is 4×3×3,072 = 36,864 params for the QKV projections. Group attention: each head's WQ is [48, 16] = 768 params (because C/h = 192/4 = 48); 4×3×768 = 9,216 params. That is a 4× reduction — exactly h× — with more head diversity, not less. The freed budget is reinvested elsewhere (Chapter 6).

python
import torch

# Group attention: split C channels into h disjoint groups
X = torch.randn(T, C)          # [tokens, channels]
groups = X.chunk(h, dim=-1)   # h slices, each [T, C/h]

outs = []
for j, Xj in enumerate(groups):
    Qj = Xj @ WQ[j]            # [T, C/h] @ [C/h, d] -> [T, d]
    Kj = Xj @ WK[j]
    Vj = Xj @ WV[j]
    A  = (Qj @ Kj.T / d**0.5).softmax(-1)
    outs.append(A @ Vj)          # head j sees ONLY its slice
out = torch.cat(outs, -1) @ WO  # concat heads, project back to C
Misconception: "Group attention is just multi-head attention with fewer channels per head." Not quite. In standard MHA every head projects from the full C-channel input — the heads share the same source and only differ in their learned projections. In group attention each head projects from a disjoint slice of the input, so the heads' inputs differ, not just their weights. That input-level disjointness is what kills redundancy; reducing head width alone does not.
In group attention, what changes compared to standard multi-head attention, and what does it buy you?

Chapter 5: The Cascade

Group attention guarantees diversity, but it has a downside: by giving each head only C/h channels, each head's query is computed from a thinner, lower-capacity slice. A head that only ever sees 48 of 192 channels has a narrower view. EfficientViT recovers the lost capacity — and squeezes out even more diversity — with the cascade.

The idea, in one sentence: add the output of head j into the input of head j+1. Instead of all heads running independently on their own static slice, the heads run in sequence, and each later head sees its own raw slice plus the refined output of the head before it.

The cascade equation

Let Xj be head j's input slice (its group of C/h channels), as in Chapter 4. In group attention head j computes its query from Xj directly. In cascaded group attention, head j's input is augmented by adding the previous head's output:

X'j = Xj + headj−1,    for j = 2, ..., h    (X'1 = X1)
headj = Attention( X'jWQj, X'jWKj, X'jWVj )

Read it left to right. Head 1 runs on its own slice. Its output is added to head 2's slice before head 2 projects Q/K/V. Head 2's output is added to head 3's slice, and so on down the chain. The Concat-and-WO step at the end is unchanged — all the head outputs are still concatenated and projected back to C.

The Cascade: Heads Refine Each Other

Four heads in a cascade. Each head receives its own channel slice (warm) plus the output of the previous head (teal arrow) added in. Click "Step" to flow the cascade head by head and watch each head's effective input grow richer than its bare slice.

Head 0/4 — Ready

Why the cascade is clever — three effects at once

1. It recovers capacity without recovering cost. Each head still projects from C/h channels (so the projection stays h× cheaper), but because head j's input now contains head j−1's output, the effective receptive field over channels grows as you go down the chain. Later heads implicitly draw on the work of all earlier heads. The paper notes this increases the network's depth (the cascade is a chain of dependent computations) without increasing its width or its projection cost.

2. It increases attention diversity even further. Group attention made the heads' inputs disjoint. The cascade makes them progressively different: head 3 sees something head 1 and head 2 never saw (their combined refinement), so its attention map is even less likely to echo theirs. Diversity compounds along the chain.

3. It is a parameter-free interaction. The cascade adds no new parameters — it is just an addition of an already-computed tensor. You get richer, deeper, more diverse heads for the cost of a few element-wise adds, which are negligible even on the memory-bound side.

Worked example: tracing the cascade. Take h = 3, slices X1, X2, X3. Head 1 attends on X1 → o1. Head 2 attends on X2 + o1 → o2 — so o2 already reflects head 1's finding. Head 3 attends on X3 + o2 → o3 — and since o2 carried o1, head 3 transitively sees the whole chain. The final output is Concat(o1, o2, o3)WO. Each oj is computed from only C/h channels of projection, yet o3 has effectively integrated information from all three groups. Depth bought capacity that width would otherwise have to pay for.
python
import torch

def cascaded_group_attention(X, WQ, WK, WV, WO, h, d):
    """X: [T, C].  WQ/WK/WV: per-head [C/h, d].  WO: [h*d, C]."""
    groups = X.chunk(h, dim=-1)  # h slices of [T, C/h]
    prev = None
    outs = []
    for j in range(h):
        Xj = groups[j]
        if prev is not None:
            Xj = Xj + prev          # THE CASCADE: add previous head's output
        Qj = Xj @ WQ[j]; Kj = Xj @ WK[j]; Vj = Xj @ WV[j]
        A  = (Qj @ Kj.T / d**0.5).softmax(-1)
        oj = A @ Vj                  # [T, d]
        outs.append(oj)
        prev = oj                    # feed forward to the next head
    return torch.cat(outs, -1) @ WO   # [T, C]
Misconception: "The cascade is just a residual connection inside attention." It is related, but the direction matters: a residual adds a layer's input back to its own output. The cascade adds one head's output into the next head's input — it is a sequential dependency across heads, turning what was h parallel heads into a chain of h dependent computations. That chain is what adds depth and forces each head to differ from its predecessors.
What exactly does the "cascade" in Cascaded Group Attention do, and what does it cost?

Chapter 6: Parameter Reallocation

Group attention freed up an h× chunk of the QKV-projection budget. The cascade spent zero parameters. So EfficientViT has spare capacity — where should it go? The third design principle, parameter reallocation, answers this by moving parameters from where they are wasted to where they matter.

The authors used a structured pruning / sensitivity analysis (Taylor importance) to ask, layer by layer: which channels actually contribute to the output, and which are dead weight? The findings drive three reallocations:

ComponentReallocationWhy
Value (V) projectionWiden — give V more channels (often the full input width)The value carries the actual content that gets mixed; capacity here is high-impact
Query/Key (Q,K) projectionShrink — use a small head dimension d for Q and KQ,K only produce a similarity score; a small d is enough and saves compute
FFN expansion ratioReduce from 4 to ~2The standard 4× MLP ratio is redundant; 2× keeps accuracy at half the FFN params

The asymmetry between Q/K and V

This is the subtle, important insight. Q and K exist only to compute the attention scores Q·K⊤ — a [T,T] matrix of similarities. The score is a scalar per token-pair; you do not need a wide Q or K to produce a good similarity. So Q and K can live in a small dimension d with little accuracy loss. The value V, by contrast, is the information that actually gets aggregated and passed forward — its width directly bounds how much content each token can carry. So V should be wide.

Standard MHA ties them together: dq = dk = dv = C/h. EfficientViT unties them — narrow Q/K, wide V — putting parameters where they buy accuracy and starving the parts that don't.

Channel Budget: Before vs After Reallocation

The attention channel budget. Top bar: standard MHA spends equally on Q, K, V and a 4× FFN. Bottom bar: EfficientViT shrinks Q/K, widens V, and halves the FFN ratio. Drag to morph between them and watch parameters flow from Q/K and the FFN into V.

Standard → Reallocated 0.00

Worked example: where the parameters go

Take C = 192, h = 3 heads. Standard: dq = dk = dv = 64 per head; the Q, K, V projections each cost C×(h·d) = 192×192 = 36,864 params, and a 4× FFN costs 2×C×4C = 2×192×768 ≈ 295K params. Reallocated: set dq = dk = 16 (narrow), dv = 64 (wide); now Q and K each cost 192×48 = 9,216 params (4× less), V stays at 36,864, and a 2× FFN costs 2×192×384 ≈ 147K params (half). The total attention+FFN budget drops sharply, and the params that remain are concentrated in V — the high-impact component. Accuracy holds; latency falls.

The principle in one line. Profile to find which channels matter, then move parameters there. EfficientViT's profiling said: V matters, Q/K barely do, and the 4× FFN is half-wasted. Reallocating along those gradients is free accuracy — you spend the same or fewer parameters but place them where the model's sensitivity is highest. This is the same philosophy as the rest of the paper: don't optimize the proxy (FLOPs, uniform width); optimize the thing that actually moves the metric.
python
# EfficientViT unties Q/K width from V width
# Standard MHA: d_q = d_k = d_v = C // h   (tied, uniform)
# EfficientViT: narrow Q/K, wide V         (reallocated)
C, h = 192, 3
d_qk = 16          # small: Q,K only need to produce a similarity score
d_v  = 64          # large: V carries the content that gets aggregated

WQ = nn.Linear(C // h, d_qk, bias=False)   # [64, 16] per head
WK = nn.Linear(C // h, d_qk, bias=False)
WV = nn.Linear(C // h, d_v,  bias=False)   # [64, 64] per head — wider
# FFN expansion ratio 2 instead of the usual 4
ffn = nn.Sequential(nn.Linear(C, 2 * C), nn.GELU(), nn.Linear(2 * C, C))
Misconception: "Narrowing Q and K must hurt accuracy — they are half of attention." Attention's scores are scalars; Q and K only need enough dimensions to make those scalars discriminative, and the paper's sensitivity analysis shows a small d for Q/K suffices. It is the value V — the content that gets summed and propagated — whose width actually bounds representational capacity. Cutting Q/K and feeding the savings to V is a net accuracy gain at lower cost, not a sacrifice.
What is the key asymmetry behind EfficientViT's parameter reallocation in attention?

Chapter 7: Results & Ablations

EfficientViT assembles the three ideas — sandwich layout, cascaded group attention, parameter reallocation — into a family of models, EfficientViT-M0 through M5, built on a hierarchical (three-stage) backbone with overlapping-patch downsampling. The headline claim is a better speed–accuracy tradeoff than prior efficient models on both GPU and CPU.

The accuracy–throughput frontier

On ImageNet-1K, the EfficientViT-M family pushes the Pareto frontier of top-1 accuracy versus measured throughput. The largest model, EfficientViT-M5, reaches roughly 77–78% top-1 accuracy. Against strong efficient baselines — MobileNetV3, MobileViT, EfficientNet, and prior efficient ViTs — EfficientViT reports comparable or higher accuracy at substantially higher measured throughput on a V100 GPU and on an Intel CPU. Crucially, the comparison is on throughput, not FLOPs — the whole point of the paper is that throughput is what users feel.

Accuracy vs Throughput Frontier

Schematic accuracy–throughput plane. EfficientViT (warm curve) sits up-and-to-the-right of the baselines (teal) — more accurate at a given speed, or faster at a given accuracy. Drag to slide along the EfficientViT frontier from M0 (fast, lower-acc) to M5 (slower, higher-acc).

M0 → M5 M2

The ablation: which idea earns its keep

The paper ablates the three components by starting from a vanilla efficient-ViT baseline and adding each idea in turn. The qualitative picture (each component contributes, none is redundant):

ConfigurationEffect on accuracyEffect on speed
Vanilla baseline (full attention every block)referencereference
+ Sandwich layoutmaintains / slightly improves accuracyfaster — fewer memory-bound attention passes
+ Cascaded Group Attentionimproves accuracy — heads more diverse, deeperfaster — cheaper QKV projections
+ Parameter reallocationimproves accuracyfaster — params concentrated where they matter

The cascade is the part that matters most for accuracy: turning redundant parallel heads into a diverse, dependent chain measurably raises top-1, because the model now extracts more distinct relationships from the same attention budget. The sandwich layout is the part that matters most for speed: it directly removes the memory-bound passes the profiling in Chapter 1 identified as the bottleneck. Parameter reallocation tightens both.

Worked example: reading the tradeoff. Suppose the vanilla baseline gets 74.0% top-1 at 5,000 img/s. Adding the sandwich layout might hold ~74% but lift throughput to ~7,000 img/s (fewer attention passes). Adding cascaded group attention might push accuracy to ~75–76% while keeping throughput high (cheaper projections offset the cascade's chain). Reallocation nudges accuracy up again at no speed cost. Each step moves you up-and-right on the frontier — the ablation's whole purpose is to show that no single idea does it alone; the three compose.

Beyond classification

The paper also evaluates the EfficientViT backbone on downstream tasks — object detection and instance segmentation — where it transfers favorably, indicating the efficiency gains are not specific to classification but properties of the backbone. The same memory-aware design that speeds up ImageNet inference speeds up detection too.

Misconception: "EfficientViT wins because it has the fewest FLOPs." It does not — some EfficientViT models spend more FLOPs than the MobileNets they outpace. They win on measured throughput, because they have fewer memory-bound operations. This is the paper's entire thesis made concrete: optimize the hardware-relevant cost (memory traffic, reshape count), and you can beat a lower-FLOP model on the clock that actually matters.
In the ablation, which component contributes most to accuracy and which to speed?

Chapter 8: CGA Explorer

This is the payoff chapter. The interactive below assembles the whole mechanism — channel groups, per-head attention, and the cascade — into one controllable system. You drive every dial the paper exposes and watch how redundancy, diversity, and the cascade chain respond in real time.

Six tokens flow through cascaded group attention. Choose the number of heads h (how finely the C channels are split), toggle the cascade on or off, and pick which head to inspect. The top panel shows each head's channel slice and the cascade arrows feeding outputs forward; the middle panel shows the selected head's attention map; the bottom panel shows the pairwise head-similarity bar — your live readout of whether the heads are diverse (low bars) or redundant (high bars).

Cascaded Group Attention — Full Mechanism

Drive the full mechanism. Add heads to split the channels finer; toggle the cascade to chain the heads; select a head to inspect its attention map. Watch the bottom similarity bar: turning the cascade ON pushes the heads apart (lower bars = more diversity), turning it OFF lets them drift back together (redundancy).

Heads (h) 4
Diverse heads
Inspect head

Things to try, and what they reveal:

The whole paper in one widget. Group splitting gives you disjoint heads (diversity floor). The cascade chains them (diversity ceiling + depth + recovered capacity). The sandwich layout — not drawn here — means you only pay for this attention once per block, surrounded by cheap FFNs. Together they move you up-and-right on the accuracy–throughput frontier of Chapter 7: more diverse representation, fewer memory-bound passes.

Chapter 9: Limitations & Connections

EfficientViT is a precise, hardware-grounded contribution — and precisely because it is grounded in 2023-era hardware and a specific size regime, it has clear limits worth naming.

Limitations

How it connects to the rest of the field

EfficientViT sits at the intersection of three lineages — the Transformer itself, efficient/mobile vision, and the hardware-aware view of attention. Follow these to place it:

The foundation
Attention Is All You Need — scaled dot-product and multi-head attention, the exact mechanism EfficientViT re-budgets.
ViT for vision
Vision Transformer (ViT) — patches as tokens, the architecture EfficientViT makes deployable.
The hardware view
GPU Performance & the Roofline — arithmetic intensity, memory- vs compute-bound, the lens of Chapter 1.

Two more threads worth pulling: the memory-bound attention problem is attacked from the kernel side by FlashAttention (fuse the softmax/reshape passes so they never hit slow memory) — a complementary cure to EfficientViT's architectural one. And the head-redundancy observation echoes the head-pruning literature (Michel et al., "Are Sixteen Heads Really Better Than One?"), which removed redundant heads after training; EfficientViT instead prevents redundancy by construction.

Cheat sheet

ConceptOne-line summary
Memory-bound attentionSoftmax, reshape, norm have low arithmetic intensity (~1 FLOP/byte) — their time is set by memory bandwidth, not FLOPs. They dominate a ViT block's wall-clock.
Sandwich layoutOne self-attention per block, wrapped in N FFN (+ depthwise conv) layers per side. Fewer memory-bound passes; same depth; flat accuracy.
Head redundancyIn vanilla MHA, heads see the same input and learn near-identical attention maps — you pay for h heads, get the diversity of a few.
Group attentionSplit the C channels into h disjoint groups, one per head. Heads can't collapse (diversity by construction) and each QKV projection is h× cheaper.
The cascadeAdd head j−1's output into head j's input: X'j = Xj + headj−1. Adds depth + diversity + recovered capacity, zero new params.
Parameter reallocationNarrow Q/K (only need a score), wide V (carries content), FFN ratio 4→2. Put params where sensitivity is high.
Headline resultEfficientViT-M family beats MobileNetV3 / MobileViT on measured GPU+CPU throughput at equal accuracy (M5 ~77–78% top-1) — sometimes at more FLOPs.
The thesisOptimize hardware-relevant cost (memory traffic), not the FLOP proxy. The FLOP-optimal model and the latency-optimal model are different models.

You now understand EfficientViT end to end: why FLOPs lie, why attention is memory-bound, how the sandwich layout removes the bottleneck, why heads are redundant, and how cascaded group attention turns that waste into diverse, deep, parameter-free representation. The same questions — "where does the time actually go, and what is the budget really buying?" — are the right questions to ask of any architecture you design.