COE 592Lecture 4.2Part 07
EIE: the first accelerator for sparse, compressed networks
Why sparsity needs hardware support, Han's co-design paradigm, and how EIE exploits weight sparsity, activation sparsity and weight sharing by splitting a sparse matrix-vector product across processing elements.
- Concepts
- 3
- Slides
- 53-60
- Reading
- 18 min
Why this part matters
Parts 02 to 06 chose pruning ratios and recovered accuracy. They never asked the uncomfortable question: after you remove 90 percent of the weights, is the network actually faster? On a GPU the honest answer is often no, and sometimes it is slower. This part explains why, and shows what hardware must do for pruning to become speed and energy.
The vehicle is EIE, the Efficient Inference Engine from Han et al. at ISCA 2016, the first accelerator built to run directly on a pruned, quantized model. You will learn its three sources of savings with the exact numbers on the slide, why one of them is dynamic and the other two static, and how a sparse matrix-vector product is split across processing elements so that zero weights are never stored and zero activations are never multiplied. This is the bridge to the M:N tensor cores and point-cloud engines later in the lecture, to the exam question "explain EIE's three savings and its PE dataflow", and to any research project that deploys a pruned model on an embedded accelerator.
By the end you can
- Explain, with the EIE paper's Table IV numbers, why fine-grained sparsity gives little or even negative speedup on CPUs and GPUs.
- Name the three systems on slide 54 and the kind of sparsity each one exploits.
- State EIE's three sources of savings with their sparsity or bit width and their computation and memory factors, and explain the 5x versus 10x gap.
- Distinguish static from dynamic sparsity and say why ReLU makes activation sparsity dynamic.
- Draw the 8 x 4 example: assign rows to PEs round-robin, broadcast the nonzero activations, and count the multiplications that actually happen.
Take AlexNet's FC6 layer, a 9216 x 4096 matrix that Han's Pruning left 91 percent zeros. Feed it one input vector. The EIE paper timed exactly this layer on a desktop CPU and a Titan X GPU, once with the dense matrix and once with the sparse one stored in a compressed format and run through the vendor's sparse kernels (MKL and cuSPARSE). The results are the whole motivation for this part.
| Platform | Batch | Dense matrix | Sparse matrix | Sparse versus dense |
|---|---|---|---|---|
| Core i7-5930k CPU | 1 | 7516.2 μs | 3066.5 μs | 2.5x faster |
| GeForce Titan X GPU | 1 | 541.5 μs | 134.8 μs | 4.0x faster |
| GeForce Titan X GPU | 64 | 19.8 μs | 94.6 μs | 4.8x slower |
| EIE, 64 PEs | 1 | runs only the sparse form | 30.3 μs | 248x vs dense CPU |
Removing 91 percent of the multiplications bought only 2.5x on the CPU and 4x on the GPU, not the 11x the arithmetic promises. Worse, once the GPU batches 64 inputs so that the dense kernel can use its full width, the sparse kernel falls 4.8x behind. The paper's summary is blunt: "the irregular pattern caused by compression hinders the effective acceleration on CPUs and GPUs". A general-purpose core cannot skip a zero for free. It has to read an index, compute an address, gather a scattered activation and suffer the cache miss, and that bookkeeping costs more than the multiply it avoided. Custom accelerators before EIE did no better: sparse matrix-vector (SpMV) engines from scientific computing handle the static zeros in the weights but not the run-time zeros in the activations, and DNN accelerators of the day "must expand the network to dense form" before they can run it.
Why memory is the real enemy
| Operation (45 nm) | Energy | Relative to SRAM read |
|---|---|---|
| 32-bit SRAM read | 5 pJ | 1x |
| 32-bit DRAM read | 640 pJ | 128x |
| 32-bit float multiply | 3.7 pJ | about 0.7x |
The table is the second half of the argument, the one that decides whether a model can run on a phone at all: the 128x gap between an on-chip and an off-chip read dwarfs the multiply itself. A network with one billion connections evaluated at 20 Hz spends 20 x 10^9 x 640 pJ = 12.8 W on DRAM traffic alone, far past any mobile power budget. The lesson that Deep Compression drew from this is that the goal is not fewer FLOPs but a model small enough to live entirely in SRAM: AlexNet shrinks from 240 MB to 6.9 MB and VGG-16 from 552 MB to 11.3 MB, both with no loss of accuracy. Once the whole model fits on chip, every weight read is the cheap kind.
This is the point at which the five questions of the outline slide (what pruning is and how to formulate it, which granularity, which criterion, what ratio per layer, and how to fine-tune) hand over to a sixth that the outline never lists: on what hardware. All five are now answered, in lecture 04-1 and in parts 02 to 06 here, and the constraint ||W_P||_0 <= N has produced a model with few nonzeros. The rest of the lecture is about turning that small N into small time and small energy.
Han's paradigm: co-design the compression and the engine
Slide 56 draws the conventional flow as training on a server, then a big network shipped to a phone for slow, power-hungry inference. The proposed flow inserts a model compression stage between them and replaces the phone's generic processor with accelerated inference. The labels under each stage are five papers by the same group, and reading them as a set is the fastest way to see that compression and the engine were designed together. Neither is useful alone: a compressed model on a GPU gives the Table IV numbers above, and an engine for sparse models with nothing sparse to run is idle silicon. Together they deliver what the slide calls fast and power efficient: EIE with 64 PEs at 800 MHz draws about 600 mW and beats both baselines on the same nine FC and LSTM benchmarks by the margins below.
| EIE versus | Speedup | Energy efficiency |
|---|---|---|
| Core i7-5930k CPU | 189x | 24,000x |
| Titan X GPU | 13x | 3,400x |
The five paper labels on slide 56
- ICLR 2017, under Training
- DSD: dense-sparse-dense training, a regularizer that prunes and regrows during training to reach a better dense model
- NeurIPS 2015, under Model Compression
- Learning both Weights and Connections: train, prune, retrain, giving 9x fewer AlexNet and 13x fewer VGG-16 parameters without accuracy loss
- ICLR 2016 best paper, under Model Compression
- Deep Compression: pruning, trained quantization with a k-means codebook, then Huffman coding; AlexNet 240 MB to 6.9 MB (35x), VGG-16 552 MB to 11.3 MB (49x)
- ISCA 2016, under Accelerated Inference
- EIE: the ASIC that runs directly on the pruned, codebook-quantized weights
- FPGA 2017 best paper, under Accelerated Inference
- ESE: the same idea for sparse LSTMs on a Xilinx XCKU060 FPGA, 20x compression and 282 GOPS with load-balance-aware pruning
Three systems, three kinds of sparsity
Slide 54 lists the hardware this section covers, and each entry targets a different sparsity. EIE exploits Weight sparsity and Activation sparsity at the same time, which is what made it the first of its kind. The NVIDIA sparse tensor core accepts only structured M:N sparsity, trading flexibility for a dense-friendly pattern. TorchSparse and PointAcc exploit activation sparsity of a very different origin: point clouds are mostly empty space, so the zeros are in the input, not in the weights.
Roadmap for the rest of the lecture, from slide 54
- EIE (Han et al., ISCA 2016)
- Weight sparsity plus activation sparsity in fully connected layers, on a custom ASIC. This part and parts 08 and 09.
- NVIDIA Tensor Core (Ampere)
- M:N weight sparsity, specifically 2:4: two of every four consecutive weights must be zero, and the hardware skips the matching activations. Part 10.
- TorchSparse and PointAcc
- Activation sparsity of point clouds, where most voxels are empty, handled by sparse convolution on GPUs and on a custom accelerator. Parts 11 to 13.
Recall
Why does a 91 percent sparse FC6 layer run only 2.5x faster on a CPU, and slower than dense on a GPU at batch 64?
Recall
Name the three systems on slide 54 and the sparsity each exploits.
Look at one fully connected layer of AlexNet, FC7, a 4096 x 4096 matrix of 16.8 M weights that occupies 64 MB in 32-bit floating point. A dense engine stores all 16.8 M values and performs 16.8 M multiply-accumulate operations (MACs) for every input. After Deep Compression, the EIE paper reports that only 9% of the weights survive, about 35% of the input activations are nonzero, and 3% of the original FLOPs remain. EIE reaches that 3 percent by combining three savings that the slide states in round numbers.
| Source | Sparsity or bits | Computation saving | Memory saving | Rule of thumb |
|---|---|---|---|---|
| Sparse weight | 90% static sparsity | 10x less computation | 5x less memory footprint | 0 x A = 0 |
| Sparse activation | 70% dynamic sparsity | 3x less computation | none claimed on the slide | W x 0 = 0 |
| Weight sharing | 4-bit weights | none claimed on the slide | 8x less memory footprint | 2.09, 1.92 => 2 |
The first column is Weight sparsity. Pruning zeroed about 90 percent of the matrix, so a product 0 x A is known to be zero without looking at A. An engine that never stores those weights skips their multiplications for free, hence 10x less computation. The second column is Activation sparsity. About 70 percent of the input vector is zero because it came out of a ReLU, so W x 0 is also known without looking at W. Skipping those columns removes another factor of roughly 1 / 0.3 = 3.3, which the slide rounds to 3x, and the paper measures that skipping them saves about 65 percent of the computation cycles. The third column is Weight sharing: the surviving weights are not stored as32-bit floats but as 4-bit indices into a per-layer codebook of 2^4 = 16 shared values, which is where the crossed-out 2.09, 1.92 => 2 comes from. Both weights snap to the same centroid and are stored as the same index, and 32 / 4 is the 8x memory saving.
The formula packs all three savings into one line. The sum runs only over X_i ∩ Y, the columns that are nonzero in both the weight row and the activation vector, which is the 10x and the 3x. Each weight appears as S[I_ij], a codebook lookup, which is the 8x. The two computation factors multiply to 10 x 3 = 30x, which is why the paper can describe 102 GOPS (giga operations per second) of work on the compressed network as about 3 TOPS (tera operations per second) on the uncompressed one. The 8x from the codebook is a memory factor and does not reduce the operation count.
Why memory shrinks 5x and not 10x
The one number that trips students is the 5x. Ten percent of the weights survive, so why not 10x less memory? Because a nonzero that is stored without its neighbors must carry its position. EIE stores each surviving weight together with a 4-bit relative index (the number of zeros since the previous nonzero in the column), a scheme explained fully in part 08 under Compressed sparse column (CSC). The retrospective on the paper states it directly: "the weight and index are both 4bit giving a 50% storage overhead". Half of every stored entry is bookkeeping, so the 10x from sparsity is halved to 5x. Computation keeps its full 10x, since the index is read but never multiplied.
Worked example
From 3200 bits to 80 bits
Dense storage
100 weights in 32-bit floating point occupy 100 x 32 = 3200 bits.Prune to 10 percent, keep full precision
10 survivors, each with a 32-bit value plus a 32-bit position: 10 x 64 = 640 bits. That is 3200 / 640 = 5x, which is the slide's sparsity row: the index costs as much as the value.Add weight sharing
Weight sharing drops the value to a 4-bit codebook index (32 / 4 = 8x). EIE also keeps the position the same width as the value, a 4-bit relative index, so the index overhead stays at 2x and the 5x from step 2 holds: 10 x (4 + 4) = 80 bits. Relative to the 640-bit step this is 8x, the slide's weight-sharing row.40x overall
3200 / 80 = 40x, which is exactly 5 x 8. The decomposition assumes the index is as wide as the value, which is how EIE stores it: the slide assigns the index overhead to the sparsity factor and the bit-width gain to the sharing factor, and the two multiply.
Static versus dynamic
The italic words on the slide, static and dynamic, are the conceptual core of this part and the key to Static versus dynamic sparsity. The paper defines X_i as the set of columns where row i of W is nonzero and Y as the set of indices where a is nonzero, then says: "The set X_i is fixed for a given model. The set Y varies from input to input." Weight zeros are decided once, when pruning and Fine-tuning finish, so the storage format can be laid out offline with every zero already gone. Activation zeros are made fresh by ReLU for every input, since a different image produces a different set of negative pre-activations. No format can remove them in advance; the engine must find them at run time, which is the job of the Leading non-zero detection unit in part 08.
What the two words on the slide mean
- Static sparsity (weights)
- The set X_i of columns where row i has a nonzero is fixed once pruning and fine-tuning finish. It can be encoded offline into the storage format and never changes from input to input.
- Dynamic sparsity (activations)
- The set Y of indices where a_j is nonzero depends on this input: ReLU zeroed whatever came out negative. It must be detected at run time by scanning the vector.
The four factors behind the paper's 28,800x energy figure
- SRAM instead of DRAM
- 120x
- Weight sparsity
- 10x
- Weight sharing
- 8x
- Skipped activations
- 3x
- Product
- 120 x 10 x 8 x 3 = 28,800x
Quick check
Which of EIE's savings is dynamic, meaning it depends on the input at run time?
Quick check
Why does 90 percent weight sparsity cut EIE's memory only 5x while cutting computation 10x?
Recall
State EIE's three sources of savings with the numbers on slide 57.
Recall
Why is activation sparsity called dynamic while weight sparsity is static?
Slides 58 to 60 show the same small figure three times, and it is worth working it with real numbers before reading the rule. The input is a = (0, a1, 0, a3), the weight matrix is 8 x 4 with eleven nonzeros, and there are four processing elements. Give the symbols values: a = (0, 2, 0, 1), and in the matrix w00 = 1, w01 = 3, w03 = -2, w12 = 5, w21 = -1, w23 = 1, row 3 empty, w42 = 2, w43 = -3, w50 = 6, w63 = 2, w71 = -4. The colors on the slide say who owns what: row 0 is PE0, row 1 is PE1, row 2 is PE2, row 3 is PE3, and row 4 wraps around to PE0 again.
Worked example
Two broadcasts, seven multiplications
Scan a for its first nonzero
a0 = 0, so column 0 is skipped for every PE at once. The first nonzero is a1 = 2, and the controller broadcasts the pair (2, j = 1) to all four PEs.Each PE works column 1 of its own rows
PE0 holds w01 = 3: b0 += 3 x 2 = 6. PE2 holds w21 = -1: b2 += -2. PE3 holds w71 = -4: b7 += -8. PE1 has no nonzero in column 1 and does nothing.Scan on and broadcast a3
a2 = 0, so column 2 is skipped, and with it w12 and w42, which are never read. The next nonzero is a3 = 1, broadcast as (1, j = 3).Each PE works column 3
PE0: b0 += -2 x 1, giving 4; and b4 += -3 x 1 = -3. PE2: b2 += 1 x 1, giving -1; and b6 += 2 x 1 = 2. PE1 and PE3 have nothing in column 3.ReLU inside each PE
b = (4, 0, -1, 0, -3, 0, 2, -8) becomes (4, 0, 0, 0, 0, 0, 2, 0). The negative rows 2, 4 and 7 are the ones the slide draws as -b2, -b4, -b7 and zeroes after ReLU.7 multiplications instead of 32
The dense product needs 8 x 4 = 32 MACs. EIE performs 7, a 4.6x reduction, stores 11 weights instead of 32, and never touches columns 0 and 2.
| PE | Rows owned | Nonzero weights stored | MACs performed | Outputs before ReLU |
|---|---|---|---|---|
| PE0 | 0, 4 | 5 | 3 (w01, w03, w43) | b0 = 4, b4 = -3 |
| PE1 | 1, 5 | 2 | 0 (columns 0 and 2 skipped) | b1 = 0, b5 = 0 |
| PE2 | 2, 6 | 3 | 3 (w21, w23, w63) | b2 = -1, b6 = 2 |
| PE3 | 3, 7 | 1 | 1 (w71) | b3 = 0, b7 = -8 |
| Total | 8 rows | 11 of 32 | 7 of 32 dense MACs | ReLU keeps b0 = 4 and b6 = 2 |
The rule: interleave rows, broadcast activations
The paper states the partition in one sentence: with N PEs, "PE_k holds all rows W_i, output activationsb_i, and input activations a_i for which i (mod N) = k". Rows are dealt out round-robin like cards, so PE0 gets rows 0, 4, 8 and so on. Each PE keeps only the nonzeros of its rows, in its own CSC arrays and its own SRAM, so no PE ever sees the full matrix and no zero weight is stored anywhere. That is the rule of thumb 0 x A = 0 made physical. On the left of slide 58 the same idea appears as hardware: a grid of identical PEs wired to one central control unit that does the scanning and broadcasting (the slide draws 16; the EIE configuration evaluated in the paper uses 64).
The dataflow follows from the ownership. The paper describes it as "scanning vector a to find its next non-zero value a_j and broadcasting a_j along with its index j to all PEs. Each PE then multiplies a_j by the non-zero elements in its portion of column W_j, accumulating the partial sums in accumulators for each element of the output activation vector b." The broadcast is necessary because a_j lives in a column, and a column cuts across every PE's rows: any of the four might hold a nonzero in column j, and only the PE that owns row i is allowed to update b_i. The reward is that every output belongs to exactly one PE, so there is no reduction step between PEs at the end. The paper weighs this explicitly among three ways to partition the matrix and concludes that distributing rows gives "full locality for vector b. The drawback is that vector a needs to be broadcast". The broadcast is cheap: a is about 4 K long and about 30 percent dense, so around 1.2 K broadcasts per layer, each followed by many cycles of local work, and FIFOs decouple the controller from the PEs so the broadcast is not on the critical path.
Zero activations, the Activation sparsity of the previous concept, are handled by the scan itself. A zero is never broadcast, so its whole column is skipped for all N PEs in one decision, which is W x 0 = 0 made physical and what slide 60 highlights by boxing a0 = 0. In part 08 that scan is the Leading non-zero detection unit, and the word "logically" on slide 59 is a reminder that the tidy 8 x 4 grid is the logical view only. Physically PE0 holds a compressed slice with five entries and never sees the zeros that the figure draws.
- PE0rows 0, 4idle this broadcast5 stored0 MACs so far
- PE1rows 1, 5idle this broadcast2 stored0 MACs so far
- PE2rows 2, 6idle this broadcast3 stored0 MACs so far
- PE3rows 3, 7idle this broadcast1 stored0 MACs so far
Row i belongs to PE (i mod 4), so each output b_i is accumulated inside exactly one PE and no result ever crosses between PEs. The controller scans a for its next nonzero, broadcasts that value with its column index, and every PE multiplies it by the nonzero weights it holds in that column. A zero activation means the whole column is skipped for all four PEs at once, and a zero weight was never stored, so neither rule of thumb costs a cycle. The imbalance readout shows the price: whichever PE holds the most nonzeros in the broadcast column sets the pace.
Why interleave rather than block
The paper weighs three partitions (Section VII-A). Splitting by columns gives each a_j to one PE but needs a reduction across PEs and becomes unbalanced because a is 70 percent zero. 2D blocks need both a broadcast and a reduction. Splitting by rows keeps each b_i local and costs only one broadcast per column. Dealing rows out round-robin (rather than in contiguous blocks, a choice the paper does not justify explicitly) spreads each column's nonzeros across PEs. The small example already shows the residual problem: column 3 gives PE0 and PE2 two multiplications each while PE1 and PE3 get none, and over the whole product PE1 does nothing at all. The busiest PE sets the pace of every broadcast. This is the Load balance issue that the activation queue in part 08 softens by letting PEs run ahead, and that ESE later attacked at pruning time.
Quick check
In EIE, how are the rows of the weight matrix assigned to processing elements?
Quick check
The central control unit finds a nonzero activation a_j. What does EIE do with it?
Recall
In EIE with N PEs, which PE holds row i, and what happens when the controller finds a nonzero a_j?
Recall
Which layers did EIE accelerate, and which did it not?
Recap
If you remember nothing else
- Pruning alone leaves gains on paper: a 91 percent sparse AlexNet FC6 runs only 2.5x faster on a CPU and 4x on a Titan X at batch 1, and slower than dense at batch 64.
- Han's paradigm: train, compress (prune, quantize, Huffman), then run on an engine that computes directly on the compressed form (NeurIPS 2015, ICLR 2016, ISCA 2016, FPGA 2017).
- EIE was the first accelerator for sparse, compressed networks: 189x faster and 24,000x more energy efficient than a CPU, 13x and 3,400x versus a GPU, 102 GOPS on compressed work equal to 3 TOPS dense, 64 PEs at 800 MHz, 600 mW.
- Three savings: sparse weights (90 percent static) 10x compute and 5x memory; sparse activations (70 percent dynamic) 3x compute; weight sharing (4-bit) 8x memory. Rules of thumb 0 x A = 0 and W x 0 = 0.
- Static sparsity is fixed after training; dynamic sparsity is created by ReLU per input and must be detected at run time.
- Rows are interleaved, PE_k holds rows i with i mod N = k, so every output stays local; nonzero activations are broadcast with their index and zero activations skip whole columns.
- EIE targets matrix-vector products in FC and LSTM layers at batch size 1, not convolutions.
Sources
- EIE: Efficient Inference Engine on Compressed Deep Neural NetworkPaperISCA 2016, Han, Liu, Mao, Pu, Pedram, Horowitz, DallySavings factors, Table I energy, Table III densities, Table IV timings, Section III-C interleaving and broadcast, Section VII partitioning(opens in a new tab)
- Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman CodingPaperICLR 2016 best paper, Han, Mao, Dally35x and 49x, k-means codebook, fitting the model in SRAM(opens in a new tab)
- Learning both Weights and Connections for Efficient Neural NetworksPaperNeurIPS 2015, Han, Pool, Tran, Dally9x AlexNet and 13x VGG-16 parameter reduction(opens in a new tab)
- ESE: Efficient Speech Recognition Engine with Sparse LSTM on FPGAPaperFPGA 2017 best paper, Han et al.The FPGA'17 box on slide 56; load-balance-aware pruning(opens in a new tab)
- DSD: Dense-Sparse-Dense Training for Deep Neural NetworksPaperICLR 2017, Han et al.The ICLR'17 label under Training on slide 56(opens in a new tab)
- Retrospective: EIE, Efficient Inference Engine on Sparse and Compressed Neural NetworkPaperHan et al., 2023FC-only limitation, 50 percent index overhead, structured successors(opens in a new tab)
- MIT 6.5940 Fall 2024, Lecture 4: Pruning and Sparsity Part IIDocsSong Han, MIT HAN LabThe source deck these slides copy, including the 8 x 4 figure(opens in a new tab)
- Lecture 4 video: Pruning and Sparsity Part IIVideoMIT 6.5940, Song HanWalk-through of the EIE slides(opens in a new tab)
- Accelerating Inference with Sparsity Using the NVIDIA Ampere Architecture and NVIDIA TensorRTDocsNVIDIA Developer Blog2:4 definition for the roadmap row(opens in a new tab)
- TorchSparse: Efficient Point Cloud Inference EnginePaperMLSys 2022, Tang et al.Roadmap row(opens in a new tab)
- PointAcc: Efficient Point Cloud AcceleratorPaperMICRO 2021, Lin et al.Roadmap row(opens in a new tab)
- Song HanDocsMIT HAN LabStanford PhD advised by Bill Dally, for the affiliation note on slide 56(opens in a new tab)