COE 592Lecture 03Full guide
Neural network efficiency metrics
The whole lecture on one page, taught concept by concept. Work through the parts in order, mark each concept once you understand it, and open the slide chips when you want the original slides.
- Parts
- 4
- Concepts
- 18
- Slides
- 29
- Reading
- 108 min
Part 01: Latency, throughput and energy
The efficiency triangle of storage, latency and energy, what latency and throughput each measure, why one does not imply the other, the analytical latency model, and why data movement dominates energy.
5 concepts, slides 1-9
Why this part matters
Your research project will put a detector on an embedded board, and the board will judge it by three costs that have nothing to do with accuracy: does the model fit, does it answer before the next frame arrives, and does it drain the battery. Every metric in this lecture exists to predict one of those three costs before you ever flash the board.
This part gives you the map and the first three costs. It fixes the vocabulary (latency, throughput, energy), shows why a latency number is meaningless without the conditions it was measured under, works the batching example that exams love, derives a one-line latency model that separates what the network controls from what the hardware controls, and ends with the energy table that explains why every efficient design of the last decade is really a design for moving fewer bytes. Parts 02 to 04 then fill in the metrics that feed these costs.
By the end you can
- Place any efficiency metric in the memory or computation group and say which of storage, latency and energy it predicts.
- Define latency and throughput, and compute both for a batched design.
- Explain with numbers why higher throughput does not imply lower latency, and lower latency does not imply higher throughput.
- Write Latency ≈ max(T_computation, T_memory) with its sub-formulas, label each term NN or hardware specification, and decide compute-bound versus memory-bound.
- Quote the 45 nm energy table and argue why data movement, not arithmetic, sets the energy bill of an inference.
Suppose the detector you trained in the cloud is to run on a Jetson-class board mounted on a vehicle. Before the board can use it, three separate questions must be answered. Does the model fit in the flash and RAM you have? Does one inference finish before the next camera frame lands, roughly every 33 ms at 30 frames per second? And how much charge does each inference pull from the battery? Slide 4 draws these as the three outer goals of a triangle, Smaller, Faster and Greener, and the three costs that quantify them: Storage, Latency and Energy.
The part of the triangle that matters is the middle. All three costs are driven by only two resources, Computation and Memory. Storage is purely a memory question: how many bytes the weights occupy. Latency and energy depend on both, because an inference both performs arithmetic and moves data, and each of those takes time and burns charge. That is why the metric list on the side of the slide has exactly two groups. The efficiency metrics that are memory-related are the number of parameters, the model size and the total and peak number of activations. The computation-related ones are MACs, FLOPs with their rate FLOPS, and OPs with their rate OPS.
| Goal | Cost | Resource | Metrics that predict it |
|---|---|---|---|
| Smaller | Storage | Memory | #parameters, model size |
| Faster | Latency | Computation and memory | MACs, OPs, model size, peak #activations |
| Greener | Energy | Computation and memory | MACs, OPs, and above all the bytes moved |
This taxonomy is the spine of the whole lecture. Parts 02 and 03 fill the memory group (parameters, model size, activations), part 04 fills the computation group (MACs, FLOPs, OPs), and this part explains the three costs those metrics are meant to predict. Whenever a later metric appears, place it here first: which group is it in, and which cost does it feed?
Metrics you count versus costs you measure
One distinction keeps the rest of the part honest. Parameters and MACs are properties of the network alone. You can count them on paper from the layer shapes, and they do not change when you move the model to another chip. Latency, throughput and energy are properties of the network running on a specific processor with a specific runtime. They must be measured, or at least estimated from hardware numbers. The same split reappears in the latency model of concept 4 as NN specification versus hardware specification.
Quick check
In the efficiency triangle, which pair of resources drives all three of storage, latency and energy?
Recall
Name the two groups of efficiency metrics, list the members of each, and say which cost each group predicts.
Slide 5 shows the same Cityscapes street segmented twice. The two masks look almost identical, and by the usual accuracy metric they are: SegFormer-B5 reaches 82.4 mIoU and EfficientViT-L1 reaches 82.7 mIoU. The difference is time. SegFormer needs 638 ms per frame and EfficientViT needs 45.9 ms (the slide rounds to 46 ms). At 30 frames per second a new frame arrives every 33 ms, so one model falls nineteen frames behind for every frame it finishes, and the other almost keeps up.
That per-frame time is latency: the delay between starting one specific task and finishing it. Patterson and Hennessy call the same quantity response time or execution time, the time between the start and completion of a task. It is a property of one task, not of a stream of tasks, and the next concept shows why that restriction matters. The 13.9x gap (638 / 45.9) is exactly the headline of the EfficientViT paper, which reports up to 13.9x GPU latency reduction over SegFormer at the same or better accuracy (Cai et al., ICCV 2023).
| Model | mIoU | Parameters | MACs | Orin latency | A100 throughput |
|---|---|---|---|---|---|
| SegFormer-B5 | 82.4 | 85M | 1460G | 638 ms | 12 image/s |
| EfficientViT-L1 | 82.7 | 40M | 282G | 45.9 ms | 122 image/s |
| Ratio | +0.3 | 2.1x fewer | 5.2x fewer | 13.9x faster | 10x more |
Read the ratio row carefully, because it plants the seed for concept 4. The MAC count falls 5.2x, but latency falls 13.9x. If latency were simply proportional to arithmetic, the two ratios would match. They do not, because SegFormer's softmax attention moves large intermediate tensors through memory, and that data movement, not its MACs, is what makes it slow on an edge GPU. MACs alone do not predict latency; they are one input to it.
Four conditions every latency must state
The slide's footnote is not fine print. Latency is measured, so it depends on everything in the measurement. The paper's setup sentence names four things: the hardware, the runtime, the numeric precision and the batch size. Change any one of them and the number changes, sometimes by an order of magnitude. The same paper measures EfficientViT-B1 at 24.3 ms on Orin and 0.82 s on a Jetson Nano, and SegFormer-B1 at 146 ms on Orin and 5.6 s on Nano. Same model, same precision, same batch size, different board: 34x to 38x apart.
The measurement conditions behind slide 5
- Hardware
- NVIDIA Jetson AGX Orin: 2048-core Ampere GPU, 64 Tensor Cores at 43 dense FP16 TFLOPS (the CUDA cores alone give 10.6), 204.8 GB/s LPDDR5, 15 W to 60 W
- Runtime
- TensorRT, which NVIDIA describes as turning a trained model into a fast, GPU-specific program for inference; the speedup depends on the model, precision, batch size and GPU
- Precision
- fp16, half the bytes per weight and activation of fp32
- Batch size
- 1, one image per inference, which is what an on-device detector sees
Quick check
Which set of conditions must accompany a reported latency for it to be comparable?
Recall
Define latency in one sentence and name the four conditions that slide 5 states for its numbers.
Slide 6 replaces one street with two mosaics of video clips and asks a different question: not how long one clip takes, but how many clips get done per second. One system manages 6.1 videos per second, the other 77.4. Those two numbers come from Table 5 of the TSM paper (Lin, Gan and Han, ICCV 2019): I3D at 306 GFLOPs versus TSM8F at 33 GFLOPs, both on a single Tesla P100.
That rate is throughput: the amount of work completed per unit time, what Patterson and Hennessy also call bandwidth. The TSM paper is unusually helpful here because it states its protocol: latency was measured with batch size 1 and throughput with batch size 16. TSM8F's latency is 17.4 ms. If throughput were the reciprocal of latency you would expect 1000 / 17.4 = 57.5 videos per second, yet the paper reports 77.4. The extra comes from batching, and it is the whole point of slide 7.
Two designs, same processor, opposite answers
Slide 7 pits two designs against each other. Design 1 handles one image at a time and takes 50 ms per image. Design 2 takes four images together and finishes the whole group in 100 ms. Each image in Design 2 waits the full 100 ms, because nothing leaves the processor until the batch is done.
| Design | How images are handled | Per-image latency | Images per batch | Batch time | Throughput |
|---|---|---|---|---|---|
| Design 1 | One after another | 50 ms | 1 | 50 ms | 1 / 0.050 = 20 image/s |
| Design 2 | Four in parallel | 100 ms | 4 | 100 ms | 4 / 0.100 = 40 image/s |
Worked example
Answering slide 7's two questions
Does higher throughput mean lower latency?
No. Design 2 has twice the throughput (40 versus 20 image/s) and twice the latency (100 versus 50 ms). Batching raised both, because throughput counts images and latency counts the wait of one image, and that image waits for its whole batch.Does lower latency mean higher throughput?
No. Design 1 has half the latency and half the throughput. With no parallelism, a fast single lane still moves only one image per step, so a short step buys a short wait but not a high rate.When the two coincide
Throughput equals 1 / latency only when the batch size is 1 and nothing is pipelined or run in parallel. Any batching or parallelism breaks the identity, always in the direction of more throughput per unit of latency.
Batching multiplies throughput by b = 4 (4x the reciprocal of latency) while latency stays at 100 ms for every image. In one 1 s window this design completes 10 whole batches, 40 images. The TSM preset back-computes its batch time from the paper's 77.4 video/s at batch 16, so it illustrates the arithmetic rather than confirming it.
A second scenario for practice
A cloud server serves the same model at two batch sizes. At batch 1 a request takes 2 ms. At batch 32 the whole batch takes 8 ms, because the GPU can spread thirty-two images over its cores far more efficiently than one.
| Setting | Batch time | Images per batch | Latency per image | Throughput |
|---|---|---|---|---|
| Batch 1 | 2 ms | 1 | 2 ms | 500 image/s |
| Batch 32 | 8 ms | 32 | 8 ms | 4000 image/s |
| Change | 4x longer | 32x more | 4x worse | 8x better |
Batching paid 4x latency to buy 8x throughput. Whether that is a good trade depends on who is waiting. A brake camera needs one frame answered now: latency, at batch size 1, which is why slide 5 measured that way. A data center indexing videos overnight needs clips per hour: throughput, at whatever batch size fills the GPU. Your research project sits on the first side of that line.
Quick check
Design 2 processes 4 images in parallel in 100 ms. What are its latency and throughput?
Recall
A design processes 8 images together every 200 ms. What are its latency and throughput, and what would the naive reciprocal give?
Concept 2 left a puzzle: MACs fell 5.2x but latency fell 13.9x. To resolve it you need a model of where the milliseconds go. Watch one layer execute. The processor loads the input activations, loads the layer's weights, multiplies and accumulates, and stores the output activations. Two of those steps are arithmetic; the other two are data movement. Real hardware does not wait for one to finish before starting the other. While the multipliers chew on the current tile, the memory system is already fetching the next weights, so the two streams run side by side and the layer finishes when the slower stream finishes.
Computation time is the operation count divided by the rate at which the processor retires operations. Memory time is the bytes that must move divided by the memory bandwidth, once for the weights and once for the activations in and out. Now look at the colour coding on the slide, because it is the sentence the exam wants. Every numerator is a property of the network: operations, model size, activation sizes. Every denominator is a property of the processor: operations per second, bandwidth. That split is the NN specification versus hardware specification distinction, and it makes efficiency a co-design problem. You change numerators by redesigning the network, denominators by choosing hardware, and latency by whichever of the two you can actually afford to change.
| Term | Numerator: NN specification | Denominator: hardware specification |
|---|---|---|
| T_computation | Number of operations in the model (MACs, OPs: part 04) | Operations per second of the processor (OPS) |
| T_move(weights) | Model size (part 02) | Memory bandwidth |
| T_move(activations) | Input activation size + output activation size (peak #activations: part 03) | Memory bandwidth |
The same model appears in the industry literature under different names. NVIDIA's GPU performance guide states that memory time is bytes accessed divided by memory bandwidth, math time is operations divided by math bandwidth, and the longer of the two shows what limits performance: math-limited if math time is longer, memory-limited if memory time is longer. The roofline model of Williams, Waterman and Patterson (CACM 2009) writes the same idea as a rate, attainable performance = min(peak compute, bandwidth x operational intensity). The vocabulary to adopt is compute-bound when T_computation wins and memory-bound when T_memory wins. One caution before using datasheet numbers: dividing by a peak OPS figure gives a floor on T_computation, not an estimate of it, because real kernels rarely keep every multiplier busy. The measured time over that floor is the inverse of the utilisation the runtime achieved.
Worked example A: a toy model and two processors
Worked example
Toy numbers that show the regime flipping
Start on a 100 GOPS processor
The model has 1 GOP of work, so T_computation = 1e9 / 1e11 = 10 ms. Weights are 50 MB and activations in plus out are 20 MB, over 10 GB/s: T_weights = 5 ms, T_activations = 2 ms, T_memory = 7 ms. Latency ≈ max(10, 7) = 10 ms, compute-bound.Buy a 200 GOPS processor
T_computation halves to 5 ms, but T_memory is still 7 ms. Latency ≈ max(5, 7) = 7 ms, not 5 ms. The model became memory-bound and 2 ms of the new compute sits idle every inference.Quantize the weights to 8-bit instead
Model size drops to 12.5 MB (part 02 shows why), so T_weights = 1.25 ms and T_memory = 3.25 ms. On the fast processor latency is back to max(5, 3.25) = 5 ms: the hardware upgrade only paid off once the network side shrank too.Three configurations
Configuration T_computation T_memory Latency Regime 100 GOPS, 32-bit weights 10 ms 5 + 2 = 7 ms 10 ms Compute-bound 200 GOPS, 32-bit weights 5 ms 5 + 2 = 7 ms 7 ms Memory-bound 200 GOPS, 8-bit weights 5 ms 1.25 + 2 = 3.25 ms 5 ms Compute-bound
The two Orin presets use 43 TFLOPS dense fp16 on the Tensor Cores and 204.8 GB/s from NVIDIA's Jetson AGX Orin page, MACs and parameters from the EfficientViT paper, and a 1024 × 2048 input with 19 output classes at 2 bytes each. Dividing by a peak rate gives a floor: measured latencies were 45.9 ms and 638 ms, 3.5x and 9.4x above it, and the gap shows what a first-order model leaves out.
Worked example B: back to slide 5
Worked example
Predicting the Orin numbers from public specifications
EfficientViT-L1, computation
282 GMACs is 564 GFLOPs at two FLOPs per MAC (part 04). TensorRT runs fp16 convolutions and matrix multiplies on the Tensor Cores, which the Orin page rates at 43 dense FP16 TFLOPS (the CUDA cores alone would give 10.6), so T_computation ≈ 564 / 43 000 ≈ 13.1 ms.EfficientViT-L1, memory
Weights: 40M x 2 bytes = 80 MB, over 204.8 GB/s gives 0.39 ms. Activations: input 3 x 1024 x 2048 x 2 B = 12.6 MB, output 19 x 1024 x 2048 x 2 B = 79.7 MB, sum 92.3 MB, over the same bandwidth 0.45 ms. T_memory ≈ 0.84 ms.Compare with measurement
Prediction max(13.1, 0.84) ≈ 13.1 ms, strongly compute-bound. Measured: 45.9 ms, 3.5x above the floor, so the runtime achieved roughly 29% of the Tensor Core peak. That is a normal utilisation for a real network: kernel launches, layers too small to fill the GPU, and intermediate activations moving between layers all sit outside the formula.SegFormer-B5 by the same recipe
1460 GMACs = 2920 GFLOPs, so T_computation ≈ 2920 / 43 000 ≈ 68 ms. Weights 85M x 2 B = 170 MB give 0.83 ms; the activations are the same 0.45 ms. Prediction ≈ 68 ms. Measured: 638 ms, 9.4x above the floor, about 11% utilisation.Reading the two misses
Both models land above the floor, as every real model does, but SegFormer misses by almost three times as much. The crude model counts only input and output activations. SegFormer's softmax attention materializes large intermediate attention maps that the formula never sees, which is exactly the memory traffic the EfficientViT paper set out to remove. The model is a first-order floor; the size of the miss tells you which term you forgot.Floor versus measurement
Model T_computation T_memory Floor Measured Miss, utilisation EfficientViT-L1 564 / 43 000 = 13.1 ms 0.39 + 0.45 = 0.84 ms 13.1 ms 45.9 ms 3.5x, about 29% SegFormer-B5 2920 / 43 000 = 68 ms 0.83 + 0.45 = 1.3 ms 68 ms 638 ms 9.4x, about 11%
Quick check
A model is memory-bound on its current processor. Which change is guaranteed to reduce its latency under the max model?
Recall
Write the latency model with its sub-formulas and label every term NN or hardware.
Recall
Why max and not plus?
Recall
In the SegFormer versus EfficientViT comparison, MACs drop 5.2x but latency drops 13.9x. What does that tell you?
The third cost is energy, and slide 9 settles where it goes with one table. In a 45 nm process at 0.9 V, a 32-bit integer add costs 0.1 pJ and a 32-bit integer multiply 3.1 pJ. Reading one 32-bit word from DRAM costs 640 pJ. The multiply is the most expensive arithmetic on the list, and the memory access is two hundred times dearer than it.
Rough energy per operation, 45 nm, 0.9 V, 32-bit (slide 9, after Horowitz 2014 as tabulated by Han et al. 2015)
- int ADD
- 0.1 pJ
- float ADD
- 0.9 pJ
- Register file access
- 1 pJ
- int MULT
- 3.1 pJ
- float MULT
- 3.7 pJ
- SRAM cache access
- 5 pJ
- DRAM memory access
- 640 pJ
Three ratios from that table are worth memorizing. DRAM over integer multiply is 640 / 3.1 ≈ 206, which the slide rounds to 200x. DRAM over SRAM is 640 / 5 = 128, so keeping data on-chip is worth two orders of magnitude on its own. And float add over integer add is 0.9 / 0.1 = 9, a seed for quantization: the same arithmetic in integers is nine times cheaper per add. Han et al. summarize the whole table in one line, that memory access is three orders of magnitude more energy expensive than simple arithmetic (640 / 0.1 = 6400).
The chain the slide writes across the top follows directly: data movement means more memory references, and more memory references mean more energy. Horowitz's own framing in the ISSCC 2014 talk is that a DRAM access at 1 to 2 nJ is a couple of orders of magnitude above a cache access or a functional operation at around 10 pJ, and that even with better I/O circuits DRAM will stay expensive, around 0.6 nJ per 8 bytes, because requests and data still have to travel a long physical distance. The slide's 640 pJ per 32-bit word is about half of the 1.3 nJ per 64-bit access in his Figure 1.1.9, as the provenance note below explains.
The log axis of the slide's chart is not decoration either. On a linear axis the six small bars would be invisible next to DRAM; a 0.1 pJ bar next to a 640 pJ bar is a pixel next to a page. Only a logarithmic axis can show both, and it is the honest way to read any table whose entries span four decades.
Worked example: AlexNet's energy bill
Worked example
Arithmetic versus weight fetch for one AlexNet inference
Arithmetic in 32-bit integers
Weights read once from DRAM
AlexNet has 61M parameters (part 02). Reading each once as a 32-bit word: 61e6 x 640 pJ = 39.0 mJ. That is 16.8x the arithmetic, before a single activation has moved.Two alternatives
Keep the same weights in SRAM: 61e6 x 5 pJ = 0.31 mJ, cheaper than the arithmetic. Or keep DRAM but use float arithmetic: 724e6 x (3.7 + 0.9) = 3.33 mJ, still twelve times below the DRAM bill.Two orders of magnitude versus a factor of two
Changing where the weights live changes the total by two orders of magnitude; changing how the arithmetic is done changes it by less than a factor of two.The bill, line by line
Item Count Energy each Total Integer MACs (multiply + add) 724M 3.1 + 0.1 = 3.2 pJ 2.32 mJ Weights read once from DRAM 61M 640 pJ 39.0 mJ Same weights read from SRAM 61M 5 pJ 0.31 mJ Float MACs instead of integer 724M 3.7 + 0.9 = 4.6 pJ 3.33 mJ
Per-operation costs are the 45 nm, 0.9 V figures from slide 9 (Horowitz 2014, as tabulated by Han et al. 2015). The AlexNet presets use 724M MACs as one multiply plus one add each, and one fetch per weight for its 61M weights.
Every efficiency technique later in the course can be read as a way of cutting that memory line. Keep weights in on-chip SRAM, which is 128x cheaper per access than DRAM. Reuse each fetched value as many times as possible before it leaves the chip; Horowitz notes that efficient designs complete on the order of a thousand operations per DRAM fetch. And make the model small enough to fit on-chip in the first place, which is what model size in part 02, peak activations in part 03, and pruning and quantization later in the course are all about.
Quick check
In the 45 nm table, how does one 32-bit DRAM access compare with one 32-bit integer multiply?
Recall
Quote the DRAM to integer multiply energy ratio, the numbers behind it, and the process conditions.
Recall
For one AlexNet inference, how does the energy of fetching every weight once from DRAM compare with the energy of all its integer MACs?
Recap
If you remember nothing else
- Three goals (smaller, faster, greener) map to three costs (storage, latency, energy). All three are driven by two resources, computation and memory, so the metrics split into memory-related and computation-related.
- Latency is the delay for one task. SegFormer-B5 takes 638 ms and EfficientViT-L1 takes 45.9 ms on Jetson AGX Orin with TensorRT, fp16, batch size 1: a 13.9x gap at equal or better mIoU.
- A latency number without hardware, runtime, precision and batch size is not comparable to any other.
- Throughput is items per second. Batching raises it (Design 2: 40 image/s) while raising latency (100 ms). Throughput equals 1 / latency only with batch size 1 and no parallelism.
- Latency ≈ max(T_computation, T_memory) because data movement and computation overlap. Numerators are NN specification, denominators are hardware specification.
- A faster processor helps only when compute-bound. A memory-bound model needs smaller weights, smaller activations or more bandwidth.
- At 45 nm and 0.9 V: int ADD 0.1 pJ, int MULT 3.1 pJ, SRAM 5 pJ, DRAM 640 pJ. One DRAM access costs about 206 int multiplies, and a float ADD costs 9 int ADDs.
- Fetching AlexNet's 61M weights once from DRAM (39 mJ) costs about 17 times its 724M MACs of integer arithmetic (2.3 mJ).
Sources
- EfficientViT: Multi-Scale Linear Attention for High-Resolution Dense PredictionPaperICCV 2023, Cai, Li, Hu, Gan and HanTable 3: SegFormer-B5 638 ms and EfficientViT-L1 45.9 ms on Jetson AGX Orin, TensorRT, fp16, batch 1; the 13.9x claim; Nano latencies.(opens in a new tab)
- SegFormer: Simple and Efficient Design for Semantic Segmentation with TransformersPaperNeurIPS 2021, Xie et al.Table 1a: 82.4 (single-scale) / 84.0 (multi-scale) mIoU for B5 on Cityscapes validation.(opens in a new tab)
- TSM: Temporal Shift Module for Efficient Video UnderstandingPaperICCV 2019, Lin, Gan and HanTable 5: I3D 6.1 V/s versus TSM8F 77.4 V/s on a Tesla P100; latency at batch 1, throughput at batch 16.(opens in a new tab)
- Learning both Weights and Connections for Efficient Neural NetworksPaperNeurIPS 2015, Han, Pool, Tran and DallyFigure 1: the seven-row 45 nm energy table on slide 9; memory access three orders of magnitude above arithmetic.(opens in a new tab)
- Computing's energy problem (and what we can do about it)PaperIEEE ISSCC 2014, M. HorowitzFigure 1.1.9 arithmetic and 64-bit memory costs; DRAM at 1 to 2 nJ, about 0.6 nJ per 8 bytes even with better I/O.(opens in a new tab)
- MIT 6.5940 TinyML and Efficient Deep Learning Computing, Lecture 2: Basics of Deep LearningDocsMIT HAN Lab, Fall 2023Slides 52 to 57 are the originals of slides 4 to 9, including the overlapped load, compute and store pipeline that justifies the max.(opens in a new tab)
- Roofline: An Insightful Visual Performance Model for Multicore ArchitecturesPaperCommunications of the ACM 2009, Williams, Waterman and PattersonAttainable performance = min(peak compute, bandwidth x operational intensity), the rate form of the max model.(opens in a new tab)
- GPU Performance Background User's GuideDocsNVIDIAMath time versus memory time, and math-limited versus memory-limited, defined exactly as in slide 8.(opens in a new tab)
- Jetson AGX OrinDocsNVIDIA2048-core Ampere GPU, 64 Tensor Cores at 43 dense FP16 TFLOPS (10.6 FP16 TFLOPS on CUDA cores alone), 204.8 GB/s LPDDR5, 15 W to 60 W.(opens in a new tab)
- TensorRT Quick Start GuideDocsNVIDIAWhat TensorRT does, and that speedup depends on model, precision, batch size and GPU.(opens in a new tab)
- Computer Organization and Design, RISC-V Edition, 2nd editionBookElsevier 2020, Patterson and HennessyChapter 1: response time (execution time) versus throughput (bandwidth).(opens in a new tab)
Part 02: Parameters and model size
Counting weights for linear, convolution, grouped and depthwise layers, totaling AlexNet to 61M parameters, and converting parameter count into storage at different bit widths.
4 concepts, slides 10-17
Why this part matters
Every result you will meet later in this course, from pruning AlexNet "9x smaller" to Deep Compression's "35x" storage cut, is a ratio of two numbers computed the way this part teaches. Before you can judge pruning, quantization or an architecture search, you must be able to count what a network stores, and the same count decides whether a model fits into a microcontroller's flash.
Lecture 02 taught how linear, convolution, grouped and depthwise layers compute their outputs. This part does not repeat that. It asks one narrower question of each layer: how many numbers does it keep? Four short formulas answer it, AlexNet gives them a real workout, and one multiplication by the bit width turns the answer into megabytes. Along the way you will find a typo on the slide, a hidden value to compute yourself, and a simulator you can use to check every parameter and model-size number here and the MAC and FLOP numbers in part 04.
By the end you can
- Define #Parameters as the element count of all weight tensors and explain why n, h and w never enter it.
- Write and derive the four counting formulas (linear, convolution, grouped, depthwise) and justify the single division by g.
- Total AlexNet layer by layer, identify where 96 percent of the weights sit, and spot the slide's conv1 typo.
- Convert a parameter count to model size at any bit width in bits, KB and MB, stating the decimal convention.
- Predict how architecture choices (groups, depthwise filters, linear layer width) move model size before touching hardware.
Start with the smallest network worth drawing: five inputs x0 to x4 and three outputs y0 to y2, every input wired to every output. Count the arrows. Each input sends one arrow to each output, so there are 3 × 5 = 15 arrows, labelled from w00 up to w42. Each arrow carries exactly one learned number, its weight. That is the whole idea of the number of parameters: it is the synapse count, the number of weights, and for this layer it is 15.
Now look at the same layer the way a framework stores it. The inputs for a batch are a matrix X of shape n × c_i, the weights are a matrix W of shape c_o × c_i, and the outputs come out as Y = X · W^T of shape n × c_o. The fifteen arrows have become the fifteen elements of W. This is the second, equivalent definition the slides give: #Parameters is the number of elements in the network's weight tensors. For one linear layer that is the product of its two dimensions.
One thing in that matrix picture deserves a second look. The batch size n appears in X and in Y, but never in W. Feed the layer one image or a thousand and the weight matrix is the same c_o × c_i block. Parameter count is a property of the model, not of the data flowing through it. Hold on to this observation: it returns in the next concept for spatial size, and it is the reason parameters and MACs behave so differently in part 04.
The slides define the count for the "given" (slide 10) or "entire" (slide 11) neural network; both mean the same thing, the sum over every layer. They also say bias is ignored, and this lecture keeps that convention throughout. In PyTorch a linear layer stores a bias vector of length c_o and a convolution stores one bias per output channel, so the true count is larger by c_o per layer (PyTorch Conv2d documentation). Next to c_o · c_i that is a rounding error, which is why the lecture drops it.
Notation used on slides 11 to 14 and in the rest of this lecture
- n
- Batch size, the number of inputs processed together
- c_i, c_o
- Input and output channels (for a linear layer, input and output features)
- h_i, h_o
- Input and output height
- w_i, w_o
- Input and output width
- k_h, k_w
- Kernel height and width
- g
- Number of groups in a grouped convolution
Layer mechanics live in lecture 02
How a linear layer, a convolution, padding and stride, grouped and depthwise convolution and pooling produce their outputs, including the output-shape arithmetic behind numbers like 96 × 55 × 55, was covered in lecture 02: neurons and linear layers, convolution layers, padding, stride and grouped convolution and pooling.
Recall
A linear layer maps 512 inputs to 256 outputs. How many parameters does it have, ignoring bias, and does the batch size change that number?
Take AlexNet's third convolution: 384 filters, each looking at 256 input channels through a 3 × 3 window. One filter is a small brick of numbers, 256 deep and 3 × 3 across, so it holds 256 · 9 = 2,304 weights. There are 384 such bricks, so the layer holds 384 · 2,304 = 884,736 weights. That is the whole convolution formula for the #Parameters, read off the shape of the weight tensor.
Notice what is missing. The input is 256 × 13 × 13 and the output is 384 × 13 × 13, yet 13 appears nowhere in the count. A convolution slides the same brick to every output position, so the weights are shared across space. Goodfellow, Bengio and Courville make the point with an edge detector: a two-element kernel applied to a 320 × 280 image stores two parameters, where a dense matrix doing the same job would store billions (Goodfellow et al., section 9.2). The kernel size and the channel counts set the parameter count; the output height and width do not. Part 04 will show that MACs do multiply by h_o · w_o, because the brick is reapplied at every position, and that is the single most important difference between the two metrics.
Grouped convolution: derive it, do not memorize it
A grouped convolution with g groups cuts the c_i input channels into g slices of c_i/g and the c_o output channels into g slices of c_o/g, then runs g ordinary convolutions side by side, each reading only its own input slice and writing only its own output slice. So count one group with the formula you already have: (c_o/g) · (c_i/g) · k_h · k_w. There are g groups, so multiply by g. One factor of g cancels.
This matches what a framework actually stores. PyTorch gives Conv2d a weight of shape (out_channels, in_channels / groups, kH, kW) and requires that in_channels and out_channels are both divisible by groups (PyTorch documentation). The historical reason AlexNet has g = 2 in three of its layers is hardware, not elegance: the network was trained across two GTX 580 GPUs with 3 GB each, and "the kernels of the second, fourth, and fifth convolutional layers are connected only to those kernel maps in the previous layer which reside on the same GPU" (Krizhevsky et al., 2012, section 3.5). Grouping halved the weights each GPU had to hold.
Depthwise convolution: the limit g = c_i = c_o
Push the grouping to its extreme, one channel per group, and you get a depthwise convolution. Now g = c_i = c_o and every channel has its own private k_h × k_w filter. In the MobileNets paper this is stated directly: "the depthwise convolution applies a single filter to each input channel" (Howard et al., 2017, section 3.1). Plug g = c_i into the grouped formula and the c_i cancels.
Worked example
One 3 × 3 layer with 256 input and 256 output channels
Standard convolution
256 · 256 · 3 · 3 = 589,824 weights.Grouped with g = 2
589,824 / 2 = 294,912. Each of the two groups is a 128 → 128 convolution with 147,456 weights.Grouped with g = 8
589,824 / 8 = 73,728. Eight groups of 32 → 32.Depthwise, g = 256
256 · 9 = 2,304. Each channel keeps one 3 × 3 filter.Ratio to the standard layer
Layer Count #Parameters Ratio Standard, g = 1 256 · 256 · 9 589,824 1 Grouped, g = 2 256 · 256 · 9 / 2 294,912 1/2 Grouped, g = 8 256 · 256 · 9 / 8 73,728 1/8 Depthwise, g = 256 256 · 9 2,304 1/256
| Layer | #Parameters | Depends on h, w? | Depends on n? | Why |
|---|---|---|---|---|
| Linear | c_o · c_i | Only through c_i after a flatten | No | Every input feature is wired to every output feature; a flattened c_i carries h × w |
| Convolution | c_o · c_i · k_h · k_w | No | No | c_o filters, each c_i deep and k_h × k_w wide |
| Grouped convolution | c_o · c_i · k_h · k_w / g | No | No | g independent convolutions on c_i/g and c_o/g channels |
| Depthwise convolution | c_o · k_h · k_w | No | No | Grouped with g = c_i = c_o, one filter per channel |
The simulator collects all four formulas, adds the bit width from the final concept of this part and the MACs from part 04, and carries a preset for every parameterized AlexNet layer. Try conv3 now and confirm 884,736, then change h_o and watch which readouts move.
Change h_o or w_o and watch MACs move while the parameter count and model size stay still. Only c_i, c_o, k_h, k_w and g touch the weight count, and only the bit width turns that count into storage.
Quick check
A 3 × 3 convolution has c_i = 64 and c_o = 128. How many parameters does it have?
Quick check
Doubling the input resolution of a CNN does what to a convolution layer's parameter count and MAC count?
Recall
Write the grouped-convolution count two ways and say why the division is by g, not g squared.
AlexNet is the convolutional network whose variant won the ILSVRC-2012 challenge with a top-5 test error of 15.3%, and its authors state up front that it has "60 million parameters and 650,000 neurons" (Krizhevsky et al., 2012). It is also the best possible exercise for this part: five convolutions, three of them grouped, three max-pools and three linear layers, with input 3 × 224 × 224. Walk it top to bottom and apply the right #Parameters formula at each layer. The output shapes come from lecture 02; here we only count.
Worked example
Counting AlexNet, part one: the convolutions
conv1: 11 × 11, 96 channels, stride 4, pad 2
Output 96 × 55 × 55. Weights 96 · 3 · 11 · 11 = 34,848. The stride and padding set the 55, but they do not touch the count.maxpool 3 × 3, stride 2
Output 96 × 27 × 27. Pooling takes a maximum; it learns nothing and stores nothing: 0 parameters.conv2: 5 × 5, 256 channels, pad 2, groups 2
Output 256 × 27 × 27. Grouped, so 256 · 96 · 5 · 5 / 2 = 307,200.maxpool 3 × 3, stride 2
Output 256 × 13 × 13, 0 parameters.conv3: 3 × 3, 384 channels, pad 1
Output 384 × 13 × 13. 384 · 256 · 3 · 3 = 884,736.conv4: 3 × 3, 384 channels, pad 1, groups 2
Output 384 × 13 × 13. 384 · 384 · 3 · 3 / 2 = 663,552.conv5: 3 × 3, 256 channels, pad 1, groups 2
Output 256 × 13 × 13. The slide hides this one behind a question mark. Compute it before you reveal the answer below.
Recall
conv5: 3 × 3 kernels, 256 output channels, 384 input channels, groups 2. How many parameters?
Worked example
Counting AlexNet, part two: the linear layers and the total
maxpool 3 × 3, stride 2
Output 256 × 6 × 6, 0 parameters. This map is flattened into a vector of 256 · 6 · 6 = 9,216 values.fc6: linear, 4096 outputs
4096 · 9,216 = 37,748,736. One layer, and already more than half of the network.fc7: linear, 4096 outputs
4096 · 4096 = 16,777,216.fc8: linear, 1000 outputs
1000 · 4096 = 4,096,000, one output per ImageNet class.Total
2,332,704 in the convolutions plus 58,621,952 in the linear layers gives 60,954,656, about 61M, which is what the slide and the paper both round to.
| Layer | Output C × H × W | Count | #Parameters | Share |
|---|---|---|---|---|
| Image | 3 × 224 × 224 | 0 | ||
| conv1, 11 × 11, 96 ch, stride 4, pad 2 | 96 × 55 × 55 | 96 · 3 · 11 · 11 | 34,848 | 0.06% |
| maxpool 3 × 3, stride 2 | 96 × 27 × 27 | 0 | ||
| conv2, 5 × 5, 256 ch, pad 2, groups 2 | 256 × 27 × 27 | 256 · 96 · 5 · 5 / 2 | 307,200 | 0.50% |
| maxpool 3 × 3, stride 2 | 256 × 13 × 13 | 0 | ||
| conv3, 3 × 3, 384 ch, pad 1 | 384 × 13 × 13 | 384 · 256 · 3 · 3 | 884,736 | 1.45% |
| conv4, 3 × 3, 384 ch, pad 1, groups 2 | 384 × 13 × 13 | 384 · 384 · 3 · 3 / 2 | 663,552 | 1.09% |
| conv5, 3 × 3, 256 ch, pad 1, groups 2 | 256 × 13 × 13 | 256 · 384 · 3 · 3 / 2 | 442,368 | 0.73% |
| maxpool 3 × 3, stride 2 | 256 × 6 × 6 | 0 | ||
| fc6, linear 4096 | 4096 | 4096 · (256 · 6 · 6) | 37,748,736 | 61.93% |
| fc7, linear 4096 | 4096 | 4096 · 4096 | 16,777,216 | 27.52% |
| fc8, linear 1000 | 1000 | 1000 · 4096 | 4,096,000 | 6.72% |
| Five convolutions | 2,332,704 | 3.83% | ||
| Three linear layers | 58,621,952 | 96.17% | ||
| Total | 60,954,656 | 100% |
Where the weights actually are
The share column is the real lesson. The five convolutions together hold 2.3M weights, under 4 percent. The three linear layers hold 58.6M, about 96 percent, and fc6 alone holds 62 percent. Krizhevsky and colleagues knew this: a footnote in the paper says that "most of the net's parameters are in the first fully-connected layer" (Krizhevsky et al., 2012). Every input of fc6 is wired to every one of its 4,096 outputs, and it has 9,216 inputs, so the dense wiring the convolutions avoided comes back in one enormous matrix.
There is a subtle exception hiding in that 9,216. The previous concept said parameter counts do not depend on input resolution, and for every convolution that is true. But fc6 takes the flattened 256 × 6 × 6 map as its c_i, and the 6 × 6 came from 224 × 224 through the strides and pools. Feed AlexNet a larger image and fc6 would need a larger weight matrix. The first linear layer after a flatten is the one place where resolution leaks into the parameter count. Global average pooling, introduced in Network in Network, removes that leak: it averages each channel to one number, and "there is no parameter to optimize" in it (Lin, Chen and Yan, 2014), so the classifier input no longer grows with the image.
This table is the starting line for two results you will study later. Han and colleagues pruned AlexNet "from 61 million to 6.7 million" parameters with no loss of accuracy, a 9x reduction (Han et al., 2015), and Deep Compression then cut its storage "from 240MB to 6.9MB" (Han, Mao and Dally, 2016). Both papers attack exactly the layers this table flags: when 96 percent of the weights sit in three linear layers, that is where pruning pays.
Quick check
In AlexNet, which group of layers holds most of the 61M parameters?
Recall
Which AlexNet layers hold about 96 percent of the parameters, and why is fc6 so large?
A parameter count is a number of boxes. To know how much storage the boxes take, you need the size of each box. Store AlexNet's 61M weights as 32-bit floating point and each weight takes 4 bytes, so the whole network takes 61M × 4 B = 244 MB. Store the same weights as 8-bitintegers and the same network takes 61 MB. Nothing about the architecture changed; only the bit width did.
That is the definition of model size: the storage needed for the weights of the network, the #Parameters times the bits each one occupies. The slide lists MB, KB and bits as the common units, and the formula as written produces bits. To reach bytes divide by 8, and to reach megabytes divide by another 10^6. The slide is explicit that its megabyte is decimal, 244 × 10^6 bytes. For a single layer, kilobytes are the natural unit: AlexNet's conv3 holds 884,736 weights, which at 8 bits is 884,736 bytes, or 884.7 KB (divide bytes by 10^3), and at 32 bits 3,538.9 KB.
| Data type | Size in bits | Size (decimal MB) | Slide rounding |
|---|---|---|---|
| 32-bit float (fp32) | 1,950.5 Mbit | 243.8 MB | 244 MB |
| 16-bit (fp16 or bfloat16) | 975.3 Mbit | 121.9 MB | 122 MB |
| 8-bit integer (int8) | 487.6 Mbit | 61.0 MB | 61 MB |
| 4-bit integer (int4) | 243.8 Mbit | 30.5 MB | 30.5 MB |
| 1-bit (binary weights) | 61.0 Mbit | 7.6 MB | 7.6 MB |
The formula assumes one data type for the whole network. Mixed-precision models break that assumption, and then the size is a sum over layers, each layer's count times its own bit width. That is the form you need when, for example, the first and last layers stay at 8 bits while the middle is pushed to 4.
Why the multiplication matters for this course
The parameter count is fixed once the architecture is chosen, but the bit width is a knob. The lecture on quantization turns that knob, and this formula says exactly what it buys: every halving of the bit width halves the model size with no change to the architecture. Deep Compression combined pruning, quantization and Huffman coding to take AlexNet "from 240MB to 6.9MB" (Han, Mao and Dally, 2016); their 240 MB starting point is, up to rounding, the 244 MB computed in this concept. Part 03 shows a microcontroller SRAM budget of 256 kB (the MCU constraint, a budget for activations). The slides do not give a flash size, but a typical MCU of this class, such as the STM32F746 used by MCUNet (Lin et al., NeurIPS 2020), has about 1 MB of flash, where the weights would live; even 8-bitAlexNet at 61 MB is about 60 times too large for that flash, which is why edge deployment starts with counting.
Quick check
A 10M-parameter model stored entirely in 16-bit numbers occupies how much storage?
Recall
61M parameters at 8 bits: what is the model size in MB, and in bits?
Recap
If you remember nothing else
- #Parameters is the number of elements in the weight tensors of the whole network. Bias is ignored in this lecture.
- Linear c_o · c_i. Convolution c_o · c_i · k_h · k_w. Grouped divides that by g. Depthwise is c_o · k_h · k_w.
- Parameter count ignores batch size and spatial size. MACs (part 04) do not, because every filter is reapplied at every output position.
- AlexNet has 60,954,656 parameters, about 61M. conv1 is 34,848 (the slide prints 24,848) and the hidden conv5 is 442,368.
- The three linear layers hold about 96 percent (58.6M). fc6 alone is 37.7M because its input is the flattened 256 × 6 × 6 map.
- Pooling layers have zero parameters.
- Model size = #Parameters × bit width. 61M weights are 244 MB at 32-bit, 122 MB at 16-bit and 61 MB at 8-bit, in decimal MB.
Sources
- ImageNet Classification with Deep Convolutional Neural NetworksPaperNeurIPS 2012, Krizhevsky, Sutskever and Hinton60 million parameters, per-layer kernel shapes, same-GPU connectivity behind groups = 2, first fully connected layer holds most parameters.(opens in a new tab)
- torch.nn.Conv2dDocsPyTorch documentationWeight shape (out_channels, in_channels / groups, kH, kW), divisibility by groups, depthwise as groups = in_channels, bias shape.(opens in a new tab)
- MIT 6.5940 TinyML and Efficient Deep Learning Computing, Fall 2024DocsMIT HAN Lab, Song HanLecture 2, Basics of Deep Learning, is the source deck for slides 10 to 17 including the conv1 typo.(opens in a new tab)
- Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman CodingPaperICLR 2016, Han, Mao and DallyAlexNet storage reduced 35x, from 240 MB to 6.9 MB.(opens in a new tab)
- Learning both Weights and Connections for Efficient Neural NetworksPaperNeurIPS 2015, Han, Pool, Tran and DallyAlexNet pruned 9x, from 61 million to 6.7 million parameters.(opens in a new tab)
- MobileNets: Efficient Convolutional Neural Networks for Mobile Vision ApplicationsPaperarXiv 2017, Howard et al.Depthwise convolution applies a single filter per input channel; Table 2 gives parameter shares of 1 x 1, depthwise and linear layers.(opens in a new tab)
- Prefixes for binary multiplesDocsNIST1 MB = 10^6 bytes, 1 MiB = 2^20 bytes.(opens in a new tab)
- torchvision.models.alexnetDocsPyTorch documentation61,100,840 parameters; implementation follows the One weird trick variant, not the 2012 paper.(opens in a new tab)
- Deep Learning, chapter 9: Convolutional NetworksBookMIT Press, Goodfellow, Bengio and CourvilleSection 9.2, parameter sharing: a two-parameter edge kernel versus a dense matrix with billions of entries.(opens in a new tab)
- MCUNet: Tiny Deep Learning on IoT DevicesPaperNeurIPS 2020, Lin et al.Runs TinyNAS networks on the STM32F746, a microcontroller with 320 kB SRAM and 1 MB flash.(opens in a new tab)
- Network In NetworkPaperICLR 2014, Lin, Chen and YanGlobal average pooling replaces fully connected classifier layers and has no parameters to optimize.(opens in a new tab)
Part 03: Activations and peak memory
Why activations rather than parameters are the memory bottleneck in inference and training, how memory is spread across layers of MobileNetV2 and MCUNet, and how to compute total and peak activations for AlexNet.
4 concepts, slides 18-22
Why this part matters
When a vision model is pushed onto a UAV, a robot controller or an IoT board, the first question a compiler or a reviewer asks is not "how many parameters" but "what is the peak activation". Those boards carry 256 kB to 512 kB of SRAM and no DRAM, and it is the activations, not the weights, that have to live there.
Part 02 counted weights and turned them into a model size. This part counts the other tensor family, the activations, and shows why they decide fit. You get the two ratios to quote in an exam (parameters fell 4.6x while peak activation rose 1.8x; in training, 4.3x against 1.1x), the reason MobileNet-style models can still fail on a microcontroller, a rule for where in a network the memory sits, and a formula for peak memory that you can apply to any layer list.
By the end you can
- Explain why activations, not parameters, bound memory in both CNN inference and training, quoting 4.6x against 1.8x and 4.3x against 1.1x.
- Read a per-block or per-layer memory profile and say which layers set the SRAM peak, which set the flash budget, and why resolution and channel growth cause it.
- Compute total and peak #activations for a given layer list using peak ≈ max over layers of input + output, and convert to bytes for a chosen bit width.
- State the assumptions behind the peak approximation: layer-by-layer execution, no branches, no in-place operations, no scratch buffers.
- Place weights in flash and activations in SRAM, and connect activation size to the memory term of the latency model from part 01.
Take a real target: an STM32F746 microcontroller has a Cortex-M7 core, 1 MB of flash and 320 kB of SRAM. It has no DRAM and no operating system; MCUNet describes such boards as bare-metal devices (Lin et al., 2020). Now take two ImageNet classifiers that both reach about 70 percent top-1 accuracy with every value stored as an 8-bit integer. ResNet-18 needs 11.2 MB for its weights. MobileNetV2 at width 0.75 needs about 2.5 MB as MCUNet's Figure 8 labels the bar, a 4.6x reduction on the slide (strictly 11.2 / 2.5 ≈ 4.5; the paper rounds to 4.6x). If parameters were the memory story, the second model would be the obvious choice.
Then look at the other pair of bars. The largest amount of activation memory that ResNet-18 needs at any moment is 0.9 MB. For MobileNetV2-0.75 it is 1.7 MB. The efficient model is 1.8x worse on peak activations, and the MCUNet paper says so plainly: MobileNetV2 "reduces the model size by 4.6x compared to ResNet-18, but the peak activation size increases by 1.8x, making it even more difficult to fit the SRAM on microcontrollers" (Lin et al., 2020). Neither model fits 320 kB. The memory bottleneck moved without anyone shrinking it.
Two budgets, and the smaller one belongs to activations
The reason the two bars behave differently is that they are paid from different memories. Weights are read-only: they are written once when the firmware is flashed and only read during inference, so they live in flash, the larger and cheaper memory. Activations are produced by one layer and consumed by the next on every single inference, so they must sit in memory that can be written and read at speed, which on a microcontroller is the on-chip SRAM. MCUNet puts it in one sentence: "SRAM constrains the activation size (read&write); Flash constrains the model size (read-only)" (Lin et al., 2020). The model size from part 02 answers the flash question. The peak activation answers the SRAM question, and SRAM is the scarcer of the two by a factor of two to four on every board in MCUNet's list (the STM32F746 has about 3x more flash than SRAM).
This also explains why bit width alone does not rescue MobileNetV2. The slide already assumes 8-bit integers for both weights and activations. Even after that 4x shrink from 32-bit floats, the peak sits at 1.7 MB. MCUNet's Table 1 reports 1.7 MB for full-width int8 MobileNetV2 (6.8 MB in fp32), 5.3x over the 320 kB of an STM32F746, not counting im2col or other runtime buffers. Quantization scales both bars by the same factor; it does not change which bar is the problem.
| Model | Param memory (flash) | Peak activation (SRAM) | Fits STM32F746 (1 MB flash, 320 kB SRAM)? | Fits STM32H743 (2 MB flash, 512 kB SRAM)? |
|---|---|---|---|---|
| ResNet-18 | 11.2 MB | 0.9 MB | No (flash and SRAM) | No (flash and SRAM) |
| MobileNetV2-0.75 | 2.5 MB | 1.7 MB | No (flash and SRAM) | No (flash and SRAM) |
| MCUNet (paper, Figure 8) | 1.9 MB | 0.49 MB | No (flash and SRAM) | Yes |
The MCUNet row comes from Figure 8 of the same paper and is there to show what solving the right problem looks like: its designers shrank the peak activation below 0.5 MB rather than chasing a smaller parameter count, and only then did an ImageNet model fit a 512 kB board. The 4.6x model is not an efficient model for this class of device; it is an efficient model for a phone, where DRAM is plentiful and flash is not the constraint.
Why MobileNetV2 in particular: an imbalanced profile
The right-hand chart explains where MobileNetV2's peak comes from. Plot the memory that each of its eighteen blocks needs and the profile is wildly uneven: block 2 needs 1372 kB, blocks 0, 1, 3 and 4 sit between roughly 500 kB and 600 kB, and the remaining thirteen blocks mostly need 40 kB to 170 kB. Draw the 256 kB constraint of a typical microcontroller and exactly five blocks cross it. MCUNetV2, the follow-up paper that this chart comes from, states it directly: "The first 5 blocks have large peak memory, exceeding the memory constraints of MCUs, while the remaining 13 blocks easily fit 256kB memory constraints. The third block has 8x larger memory usage than the rest of the network" (Lin et al., 2021).
The two charts on the slide come from different papers with different memory accounting: the left bars are MCUNet's (2020) figures for MobileNetV2-0.75, while the right chart is MCUNetV2's analytic input-plus-output count for full-width MobileNetV2 in int8, so the numbers are not directly comparable. Its block 2 peak is 16×112×112 + 96×112×112 = 1,404,928 B, which is 1372 kB in 1024-byte kilobytes.
The cause is the shape of MobileNetV2's inverted residual block. Each block first expands the channel count about six times with a 1×1 convolution, applies a depthwise 3×3, and projects back down. The depthwise step is what makes the block cheap in weights and MACs, exactly as part 02 computed. But the expanded tensor exists at full spatial resolution, and in the early blocks that resolution is 112×112 or 56×56. Six times the channels at a large H×W gives a huge activation in a block that owns almost no parameters. MCUNet's per-block peak memory analysis (Figure 11) measures the same imbalance on a MobileNetV2 scaled to 0.3x width to fit 320 kB: even then one block has 2.2x the peak activation of the average block (Lin et al., 2020). A model can be light in weights and heavy in activations at the same time, and this architecture is the canonical example.
Quick check
At about 70 percent ImageNet top-1 with 8-bit values, what happens to peak activation memory going from ResNet-18 to MobileNetV2-0.75?
Recall
Why is MobileNetV2 not microcontroller friendly even though it has few parameters?
Recall
Where do weights and activations live on a microcontroller at run time, and which one sets the peak?
Inference keeps a few activations alive; training keeps all of them. Switch to 32-bit floats and a training step of ResNet-50. Its weights take 102 MB. Its activations, for one mini-batch, take 707 MB, about 7x more. Now swap in MobileNetV2 at width 1.4: the weights fall to about 24 MB, a 4.3x reduction, but the activations fall only to about 626 MB, a 1.1x reduction. The TinyTL paper that produced these numbers concludes: "It is the activation that bottlenecks the training memory, not the parameters" (Cai et al., 2020).
| Model | Parameters (MB) | Activations (MB) | Activations ÷ parameters |
|---|---|---|---|
| ResNet-50 | 102 | 707 | about 7x |
| MobileNetV2-1.4 | about 24 | about 626 | about 26x |
| Reduction | 4.3x | 1.1x |
The mechanism is backpropagation itself. Write one linear layer as a_(i+1) = a_i W + b, where a_i is the layer's input activation. To update the weight you need the gradient of the loss with respect to W, and that gradient is the outer product of the input activation with the gradient flowing back from the next layer.
The forward pass computes a_1, then a_2, and so on up to the loss. The backward pass returns in reverse order, and when it reaches layer i it must still have a_i. So every layer's input has to be held from the moment it is produced until the backward pass comes back to it. Goodfellow, Bengio and Courville make the same point for a multilayer perceptron: "we need to store the input to the nonlinearity of the hidden layer. This value is stored from the time it is computed until the backward pass has returned to the same point," and the cost per layer is O(m·n_h) for a mini-batch of m examples and n_h hidden units (Goodfellow et al., 2016, section 6.5.7). Depth multiplies that cost by the number of layers, and the batch size multiplies it again.
| Mode | Which activations are held | How many | Memory rule |
|---|---|---|---|
| Inference | Input and output of the layer running now | Two tensors | Largest input + output pair |
| Training | Every layer input a_i until its dL/dW_i is computed | All tensors, times the batch | Sum of all activations × batch size |
Worked example
AlexNet in fp32, inference against training
Inference peak
The last concept derives AlexNet's peak (440,928 values) and total (932,264 values); take them as given here. At 4 bytes each, the peak is 1.76 MB of activations alive at once.Training, batch of one
All 932,264 activations are held for the backward pass: 932,264 × 4 B = 3.73 MB, more than double the inference peak before counting gradients.Training, batch of sixteen
Activations scale with the batch: 16 × 3.73 MB ≈ 60 MB. The weights do not scale; AlexNet's 61M parameters stay at 244 MB whatever the batch, and their gradients add another 244 MB.Why the slide's bars look the way they do
AlexNet is unusual: its huge fully connected layers make weights dominate even in training. ResNet-50 and MobileNetV2 are mostly convolutions with large feature maps, so at the slide's batch of 8 their activations (707 MB and about 626 MB) dwarf their weights (102 MB and 24 MB).
The formula also points to the cure that TinyTL proposes and that this course returns to when it reaches on-device learning. The bias gradient in equation 2 needs no stored activation at all. If you freeze the weights and update only biases (plus a small added module), the a_i tensors never have to be kept, and the 707 MB term collapses. That is a memory argument, not an accuracy argument, and it is only visible once you have separated activations from parameters as this slide does. It matters doubly on a microcontroller, because TinyTL notes that DRAM access consumes two orders of magnitude more energy than on-chip SRAM access (Cai et al., 2020), echoing the Horowitz numbers from part 01.
Quick check
Why does training need far more activation memory than inference for the same network?
Recall
Quote the four ratios from slides 18 and 19 and say what each one compares.
Recall
Why does training need every activation while inference needs only two?
Plot, layer by layer, how much memory the activations and the weights of an efficient network take, and a clear shape appears. For MCUNet, a network designed for microcontrollers, the first six layers need 50 kB to 75 kB of activation memory and almost no weight memory, and activation stays the dominant term, mostly 20 kB to 55 kB, out to about layer 17. Around layers 18 to 30 both are small, under about 15 kB. From layer 32 onward the weight memory climbs to 35 kB to 75 kB while activations stay near 5 kB to 10 kB. The total traces a U: expensive at both ends, cheap in the middle, for two different reasons. The chart comes from MCUNet's on-device training work and shows the memory needed to update each layer, which is the stored input activation plus the weight and its gradient. The same geometry governs inference, as the AlexNet arithmetic below shows.
| Layers | Activation memory | Weight memory | Dominant |
|---|---|---|---|
| 0 to 5 | 50 to 75 kB | about 0 | Activation |
| 6 to 17 | 20 to 55 kB | about 0 | Activation |
| 18 to 30 | under 15 kB | under 15 kB | Neither |
| 32 to 42 | 5 to 10 kB | 35 to 75 kB | Weight |
The two counting rules from part 02 predict this. An activation tensor holds C × H × W values. A convolution weight tensor holds C_o × C_i × k_h × k_w values. Now follow a CNN from input to output. At every downsampling stage the spatial size halves in each direction, so H × W drops by 4x, while the channel count typically only doubles. The activation count C × H × W therefore falls by about 2x per stage. The weight count contains C_o × C_i, which grows by about 4x when channels double and does not care about H and W at all. MCUNetV2 states the consequence: "the memory bottleneck tends to appear at the early stage of the network" because resolution shrinks faster than channels grow (Lin et al., 2021).
The same U in numbers you already computed
You do not have to trust the chart. Take the AlexNet layers from part 02, put each layer's output activation count next to its weight count, and the profile reproduces itself from arithmetic.
| Layer | Output C×H×W | Activations | Weights | Which dominates |
|---|---|---|---|---|
| conv1 | 96×55×55 | 290,400 | 34,848 | Activations, 8x |
| conv2 | 256×27×27 | 186,624 | 307,200 | Weights, 1.6x |
| conv3 | 384×13×13 | 64,896 | 884,736 | Weights, 14x |
| conv4 | 384×13×13 | 64,896 | 663,552 | Weights, 10x |
| conv5 | 256×13×13 | 43,264 | 442,368 | Weights, 10x |
| fc6 | 4096 | 4,096 | 37,748,736 | Weights, 9,216x |
| fc7 | 4096 | 4,096 | 16,777,216 | Weights, 4,096x |
| fc8 | 1000 | 1,000 | 4,096,000 | Weights, 4,096x |
The first convolution has 8x more activations than weights: a 55×55 map with 96 channels is large, and an 11×11 filter over only 3 input channels is small. By conv3 the map is 13×13 and the weights are already 14x the activations. The fully connected layers are the extreme: fc6 emits 4,096 values and owns 37.7M weights. Nothing about AlexNet was designed to show this; it is the geometry of every CNN.
What each end of the U decides
- The early, activation-heavy stage sets the SRAM peak. That is why MobileNetV2's problem in the previous concept was in blocks 0 to 4, and why MCUNetV2 runs only that stage in patches.
- The late, weight-heavy stage sets the flash budget and most of the parameter count. Pruning and quantization pay off most there.
- The cheap middle is where on-device training is affordable: updating a middle layer needs neither a large stored activation nor a large weight gradient. This band is exactly what the training chart above measures, and the paper it comes from exploits exactly that band (Lin et al., 2022).
Quick check
In the MCUNet per-layer profile, which memory dominates the last layers, and why?
Recall
In one sentence each: why is activation memory high in early layers, and why is weight memory high in late layers?
Now make the peak a number you can compute. AlexNet takes a 3×224×224 image: 150,528 values. Its first convolution emits 96×55×55 = 290,400 values. While that convolution runs, both tensors must exist, because the layer is still reading the image as it writes the output: 150,528 + 290,400 = 440,928. When the first pooling layer runs, the image is no longer needed and can be freed, but the convolution output (290,400) and the pooling output (69,984) are both alive: 360,384. Memory rises and falls one layer at a time.
Two counts fall out of this picture. The total number of activations is the sum over the input and every layer output, which for AlexNet is 932,264. The peak number of activations is the largest number alive at any one moment. For a plain chain of layers executed one at a time, that is the largest input plus output pair. MCUNetV2 gives the rule and the reason: "the memory required for a layer is the sum of input and output activation (since weights can be partially fetched from Flash)", and the runtime "allocates the input and output activation buffer in SRAM, and releases the input buffer after the whole layer computation is finished" (Lin et al., 2021).
The approximation sign carries four assumptions, and an exam answer should name at least one of them. The network runs layer by layer, with no two layers in flight together. Weights are streamed from flash and are not counted in SRAM. There are no residual branches; if there are, MCUNetV2 says to add the memory of all branches alive at the same time, counting a shared input once. And there are no in-place tricks: MCUNet shows that a depthwise layer can overwrite its input channel by channel, needing N + 1 instead of 2N values (Lin et al., 2020). Real runtimes also need scratch buffers for im2col or accumulation, which push the true peak slightly above the formula.
Sweep through AlexNet yourself before reading the worked example. Watch which two bars are highlighted, how the running peak stops moving after the first layer, and how the bit width and the SRAM preset change whether the same 440,928 values fit.
| Layer executing | Input | Output | Live | At 8-bit |
|---|---|---|---|---|
| 150,528 | 290,400 | 440,928 | 440.9 kB | |
| 290,400 | 69,984 | 360,384 | 360.4 kB | |
| 69,984 | 186,624 | 256,608 | 256.6 kB | |
| 186,624 | 43,264 | 229,888 | 229.9 kB | |
| 43,264 | 64,896 | 108,160 | 108.2 kB | |
| 64,896 | 64,896 | 129,792 | 129.8 kB | |
| 64,896 | 43,264 | 108,160 | 108.2 kB | |
| 43,264 | 9,216 | 52,480 | 52.5 kB | |
| 9,216 | 4,096 | 13,312 | 13.3 kB | |
| 4,096 | 4,096 | 8,192 | 8.2 kB | |
| 4,096 | 1,000 | 5,096 | 5.1 kB |
Each bar is one tensor at 8-bit, linear scale; the dashed window holds the executing layer's input and output. Bytes are elements × bits ÷ 8 and kB is decimal (÷ 1000), as on slide 17. Selected preset: STM32F412, Cortex-M4. Weights are not counted here because on a microcontroller they stay in flash and are streamed in, so SRAM only has to hold the two live activation buffers.
Worked example
Total and peak activations of AlexNet
Write the C × H × W column
150,528; 290,400; 69,984; 186,624; 43,264; 64,896; 64,896; 43,264; 9,216; 4,096; 4,096; 1,000, from the image through fc8. Each entry is channels × height × width, or just the channel count for a linear layer.Sum for the total
932,264 values, matching the slide. This is the number that training would have to hold.Form the eleven adjacent sums
Input + output while each layer executes
- conv1 runs (image + conv1 out)
- 150,528 + 290,400 = 440,928
- pool1 runs (conv1 out + pool1 out)
- 290,400 + 69,984 = 360,384
- conv2 runs (pool1 out + conv2 out)
- 69,984 + 186,624 = 256,608
- pool2 runs (conv2 out + pool2 out)
- 186,624 + 43,264 = 229,888
- conv3 runs (pool2 out + conv3 out)
- 43,264 + 64,896 = 108,160
- conv4 runs (conv3 out + conv4 out)
- 64,896 + 64,896 = 129,792
- conv5 runs (conv4 out + conv5 out)
- 64,896 + 43,264 = 108,160
- pool3 runs (conv5 out + pool3 out)
- 43,264 + 9,216 = 52,480
- fc6 runs (pool3 out + fc6 out)
- 9,216 + 4,096 = 13,312
- fc7 runs (fc6 out + fc7 out)
- 4,096 + 4,096 = 8,192
- fc8 runs (fc7 out + fc8 out)
- 4,096 + 1,000 = 5,096
Pick the maximum
The first row wins: 440,928 while conv1 runs. The runner-up, conv1 output plus pool1 output, is 360,384, and by conv3 the pairs are a quarter of the peak.Convert to bytes for a bit width
AlexNet activation memory by bit width (kB decimal, KiB binary)
- Peak, 8-bit integers
- 440,928 B ≈ 441 kB (431 KiB)
- Peak, 32-bit floats
- 1,763,712 B ≈ 1.76 MB (1.68 MiB)
- Total, 8-bit integers
- 932,264 B ≈ 932 kB (910 KiB)
- Total, 32-bit floats
- 3,729,056 B ≈ 3.73 MB (3.56 MiB)
Peak = 440,928 values
441 kB at 8-bit and 1.76 MB at 32-bit. Even fully quantized, AlexNet's first layer alone exceeds a 256 kB or 320 kB microcontroller, and the peak is 47 percent of the total.
The same arithmetic explains why MobileNetV2 failed in the first concept. Its first convolution maps a 3×224×224 image to 32×112×112: 150,528 + 401,408 = 551,936 values, which MCUNetV2 quotes as "539kB even when quantized in int8" (using 1024-byte kilobytes). A 224 input through a standard stem can never run layer by layer on a 256 kB board, whatever happens to the weights afterwards.
Finally, connect the counts back to latency. Part 01 approximated memory time as the bytes of activations and weights moved divided by the memory bandwidth. The per-layer input plus output is the activation traffic of that layer, so the same column that gives the peak also feeds the latency model. Peak tells you whether the model fits; total tells you how many activation bytes cross the memory interface per inference.
Quick check
During layer-by-layer inference, which quantity approximates the peak activation memory of a CNN?
Recall
A toy CNN: input 3×32×32, a convolution to 16×32×32, a pool to 16×16×16, then a linear layer to 10 outputs. Total and peak #activations?
Recall
AlexNet's peak is 440,928 values. How many kB is that at 8-bit and at 32-bit, and does either fit a 320 kB STM32F746?
Recap
If you remember nothing else
- SRAM holds activations (read and write); flash holds weights (read only). SRAM is the smaller budget, so activations decide whether a model fits.
- ResNet-18 to MobileNetV2-0.75 at about 70 percent top-1, int8: parameter memory 4.6x smaller, peak activation 1.8x larger.
- MobileNetV2's memory is imbalanced: 1372 kB at block 2, the first five blocks above 256 kB, the remaining thirteen below it.
- Training keeps every layer input for dL/dW. ResNet-50 in fp32 at batch 8: 102 MB of weights against 707 MB of activations; MobileNetV2-1.4 cuts weights 4.3x but activations only 1.1x.
- Activation memory is high in early layers (large H×W) and weight memory is high in late layers (large C_o·C_i); the middle is cheap.
- Total #activations sums every tensor (AlexNet: 932,264). Peak ≈ the largest input + output pair (AlexNet: 150,528 + 290,400 = 440,928 at conv1).
- 440,928 values are 441 kB at 8-bit and 1.76 MB at 32-bit, above a 256 kB or 320 kB microcontroller either way.
- The peak formula assumes layer-by-layer execution and ignores residual branches, in-place tricks and runtime scratch buffers.
Sources
- MCUNet: Tiny Deep Learning on IoT DevicesPaperNeurIPS 2020, Lin, Chen, Lin, Cohn, Gan and Han4.6x and 1.8x, SRAM versus flash roles, MCU list with STM32F746 at 320 kB, 5.3x in Table 1, in-place depthwise convolution, 2.2x block imbalance on a 0.3x-width MobileNetV2 (Figure 11).(opens in a new tab)
- MCUNetV2: Memory-Efficient Patch-based Inference for Tiny Deep LearningPaperNeurIPS 2021, Lin, Chen, Cai, Gan and HanPeak = input + output rule, imbalanced MobileNetV2 profile with 1372 kB peak, 539 kB first-conv example, resolution versus channel growth. True source of the right chart on slide 18.(opens in a new tab)
- TinyTL: Reduce Activations, Not Trainable Parameters for Efficient On-Device LearningPaperNeurIPS 2020, Cai, Gan, Zhu and Han102 MB versus 707 MB, 4.3x versus 1.1x (the slide halves the paper's batch 16 values, so it shows batch 8), equation 2 for backpropagation memory, bias-only updates, DRAM access two orders of magnitude costlier than SRAM.(opens in a new tab)
- On-Device Training Under 256KB MemoryPaperNeurIPS 2022, Lin, Zhu, Wang, Cai, Gan and HanFigure 11(a): activation and weight memory of updating each layer of MCUNet. True source of slide 20.(opens in a new tab)
- ImageNet Classification with Deep Convolutional Neural NetworksPaperNeurIPS 2012, Krizhevsky, Sutskever and HintonAlexNet architecture: five convolutions, max pooling, three fully connected layers, about 60M parameters.(opens in a new tab)
- Deep Learning, chapter 6: Deep Feedforward NetworksBookMIT Press, Goodfellow, Bengio and Courville, 2016Section 6.5.7: hidden-layer inputs are stored until the backward pass returns, at cost O(m n_h) per layer.(opens in a new tab)
- MIT 6.5940 TinyML and Efficient Deep Learning Computing, Fall 2023DocsMIT HAN LabLecture 02 slides 70 to 75 are the origin of slides 18 to 22. The 14, 16, 16, 17 axis typo is already in Figure 1 of the MCUNetV2 paper and was carried into this deck and the slide.(opens in a new tab)
- Get started with LiteRT for MicrocontrollersDocsGoogle for DevelopersThe tensor arena preallocates RAM for input, output and intermediate arrays; the model ships as a byte array.(opens in a new tab)
- STM32F746NG product pageDocsSTMicroelectronicsCortex-M7 up to 216 MHz, 1 MB flash, 320 KB SRAM; the same figures appear in MCUNet's table 1.(opens in a new tab)
Part 04: MACs, FLOPs and operations
Counting computation as multiply-accumulate operations for matrix products and each layer type, AlexNet's 724M MACs, and converting to FLOPs, FLOPS, OPs and OPS.
5 concepts, slides 23-29
Why this part matters
Part 02 measured what a network stores and part 03 what it must hold in memory. This part measures what it must compute. That number is the numerator of computation time in the Latency model of slide 8, the figure every accelerator datasheet is quoted against, and the figure you will report for any model in the research project.
The counting unit is the multiply-accumulate, and everything else is bookkeeping on top of it: how many MACs a matrix product costs, how many each layer type costs, what AlexNet adds up to, and how the count becomes FLOPs, OPs and finally milliseconds on a specific chip. The surprise waiting at the centre of the part is that the layers holding almost all of AlexNet's weights do almost none of its arithmetic. Every exam question on efficiency metrics circles back to that inversion.
By the end you can
- Define a multiply-accumulate operation and count MACs for a matrix-vector product and a matrix-matrix product.
- Fill the MACs table for linear, convolution, grouped and depthwise layers, and explain why conv MACs equal parameters times h_o·w_o.
- Reproduce AlexNet's 724M MACs layer by layer and explain why convolutions dominate compute while linear layers dominate parameters.
- Convert MACs to FLOPs and OPs, and tell a count (FLOPs, OPs) apart from a rate (FLOPS, OPS).
- Estimate T_computation for a model on a device from the model's OPs and the device's OPS.
Start with one neuron that has four inputs. Its output before the activation function is w₁x₁ + w₂x₂ + w₃x₃ + w₄x₄. A processor evaluates that as four identical steps: multiply a weight by an input, add the product to a running total. Each step is one multiply-accumulate operation, and the whole of neural network inference is this step repeated a few hundred million times.
The definition is standard well beyond this course. The Wikipedia entry on the multiply-accumulate operation gives exactly a ← a + (b × c), and notes that IEEE 754-2008 defines a fused multiply-add that performs the whole step with a single rounding. Sze, Chen, Yang and Emer call the MAC "the fundamental component" of DNN processing in their survey of efficient DNN hardware. Counting MACs is therefore counting what the hardware executes, not an abstraction layered over it.
From one neuron to a matrix-vector product
A layer of m neurons that each read the same n inputs is a matrix-vector multiplication: an m × n weight matrix times an n-vector. Each of the m outputs needs n MACs, one per weight in its row, so the product costs m · n MACs. Notice that this is also the number of weights. In a matrix-vector product, every weight is touched exactly once.
Feed the layer a batch of inputs at once and the vector becomes a matrix. The slide renames the dimensions here: the input count becomes k and the letter n is reused for the batch, the number of columns of B. The result is a general matrix-matrix multiplication: A of size m × k times B of size k × n gives C of size m × n. Every one of the m · n cells of C is a dot product over the shared dimension k, so it costs k MACs, and the whole product costs m · n · k.
Dimensions used in the GEMM count
- m
- Rows of A and of C: the number of outputs (neurons)
- k
- Columns of A and rows of B: the shared dimension summed over, the number of inputs per neuron
- n
- Columns of B and of C: the number of input vectors, the batch
Why a whole network reduces to this
A Linear layer is literally a matrix-vector product at batch size one and a GEMM for a batch. Convolution looks different but is executed the same way: frameworks reorder the input patches into columns (the im2col trick described in the CS231n notes) so that a convolution becomes one large GEMM, and the MobileNets paper points out that this is why convolutions can ride on "highly optimized general matrix multiply (GEMM) functions". NVIDIA's performance guide states the cost of a GEMM as 2 · M · N · K floating point operations because "each FMA is 2 operations, a multiply and an add", which previews the FLOP conversion at the end of this part. Once you can count MACs for a matrix product, you can count them for every layer.
Recall
Write the MAC operation, and state how many MACs an m × n matrix times an n-vector costs.
Take the first layer of AlexNet. One filter spans all 3 input channels with an 11 × 11 window, so it holds 3 × 11 × 11 = 363 weights. Producing a single output pixel is one dot product of those 363 weights against a patch of the image: 363 MACs. But the filter does not produce one pixel. It slides to every one of the 55 × 55 = 3,025 output positions, and there are 96 filters. So the layer costs 363 × 3,025 × 96 = 105,415,200 MACs from only 34,848 weights.
That example contains the whole rule. In a convolution layer every weight is applied once per output position, so the MAC count is the parameter count from part 02 multiplied by the output height and width:
The other rows of the slide's table follow from the same idea. A Linear layer has h_o = w_o = 1, so its MACs equal its parameters, c_o · c_i. A Grouped convolution splits the channels into g groups, so each filter sees only c_i / g input channels and both parameters and MACs are divided by g. A Depthwise convolution is the extreme case g = c_i = c_o: each filter sees exactly one channel, so c_i disappears from the formula entirely and only c_o · k_h · k_w weights remain, each still applied h_o · w_o times.
| Layer | Parameters | MACs | MACs per parameter |
|---|---|---|---|
| Linear | c_o · c_i | c_o · c_i | 1 |
| Convolution | c_o · c_i · k_h · k_w | c_o · c_i · k_h · k_w · h_o · w_o | h_o · w_o |
| Grouped convolution | c_o · c_i · k_h · k_w / g | c_o · c_i · k_h · k_w · h_o · w_o / g | h_o · w_o |
| Depthwise convolution | c_o · k_h · k_w | c_o · k_h · k_w · h_o · w_o | h_o · w_o |
How a convolution slides, how padding and stride set the output size, and how groups partition channels were covered in lecture 02, part 02 and part 03. This part only counts, and it takes the kernel size and output shape of each layer as given.
Why this mirrors part 02
Goodfellow, Bengio and Courville explain parameter sharing in one sentence that is the whole story of this part: sharing "does not affect the runtime of forward propagation, it is still O(k × n), but it does further reduce the storage requirements of the model to k parameters". Convolution saves storage by reusing weights, and reusing weights is exactly what makes the arithmetic grow. That is why parts 02 and 04 are mirror images. The layers cheapest to store are the most expensive to run.
Worked example: the MobileNet block that makes depthwise worth it
The MobileNets paper replaces one standard 3 × 3 convolution with a depthwise 3 × 3 followed by a pointwise 1 × 1. Its equations 4 and 5 give the depthwise and separable costs, and dividing by the standard cost gives the ratio 1 / N + 1 / D_K², where N is the number of output channels and D_K the kernel size. The formulas in the table let you reproduce that with real numbers.
Worked example
Standard versus depthwise separable at 112 × 112, 32 to 64 channels
Standard 3 × 3 convolution
64 × 32 × 3 × 3 × 112 × 112 = 231,211,008 MACs.Depthwise 3 × 3
32 × 3 × 3 × 112 × 112 = 3,612,672 MACs. No c_i factor.Pointwise 1 × 1
64 × 32 × 1 × 1 × 112 × 112 = 25,690,112 MACs. A convolution with k = 1.Ratio
(3,612,672 + 25,690,112) / 231,211,008 = 0.1267, and 1 / 64 + 1 / 9 = 0.1267.Result
About 7.9× fewer MACs at 64 output channels, approaching the paper's "between 8 to 9 times less computation" as the channel count grows and the 1 / D_K² = 1 / 9 pointwise term is all that remains.
The calculator below lets you scrub every symbol in the table. Its FLOPs, OPs and hardware rows are explained in the last concept of this part; for now watch how parameters and MACs move apart as the output size grows.
illustrative mobile GPU-class figure
Drag h_o = w_o and watch MACs climb while parameters stay put: a convolution reuses every weight at every output position. Switch to linear and the two counts collapse into one. The hardware box only divides: the same layer takes 1000× longer at 1 GFLOPS than at 1 TFLOPS, and marketing peak TOPS are rarely sustained, so treat the time as a floor.
Quick check
A grouped convolution has c_i = 96, c_o = 256, a 5 × 5 kernel, a 27 × 27 output and g = 2. How many MACs does it perform?
Recall
A grouped convolution has 384 filters over 384 input channels, a 3 × 3 kernel, a 13 × 13 output and g = 2. How many MACs, how many parameters, and what is their ratio?
Slide 25 hands you the eight weighted layers of AlexNet with their output shapes and an empty MACs column. Slide 26 fills it in, except for one layer hidden behind a question mark. Work through the column yourself before you read the answers. Every entry is the formula from the previous concept with the layer's numbers substituted, and the pooling layers contribute nothing because they hold no weights.
Worked example
AlexNet, layer by layer (batch size 1, bias ignored)
conv1: 11 × 11, 3 to 96 channels, output 55 × 55
96 × 3 × 11 × 11 × 55 × 55 = 105,415,200conv2: 5 × 5, 96 to 256 channels, groups 2, output 27 × 27
256 × 96 × 5 × 5 × 27 × 27 / 2 = 223,948,800. Without the groups it would be 447,897,600; g = 2 halves it.conv3: 3 × 3, 256 to 384 channels, output 13 × 13
384 × 256 × 3 × 3 × 13 × 13 = 149,520,384conv4: 3 × 3, 384 to 384 channels, groups 2, output 13 × 13
384 × 384 × 3 × 3 × 13 × 13 / 2 = 112,140,288conv5: 3 × 3, 384 to 256 channels, groups 2, output 13 × 13
This is the entry the slide hides. Compute it before revealing.Recall
conv5 MACs?
256 × 384 × 3 × 3 × 13 × 13 / 2 = 74,760,192fc6: 256 × 6 × 6 = 9,216 inputs to 4,096 outputs
4,096 × 9,216 = 37,748,736. The flattened pooling output is the input vector.fc7: 4,096 to 4,096
4,096 × 4,096 = 16,777,216fc8: 4,096 to 1,000 classes
1,000 × 4,096 = 4,096,000Total
724,406,816 MACs, the slide's "724M in total". Sze et al. list the same figure, 724M MACs and 61M weights, in their survey table.
Put the parameters next to the MACs
The total is not the interesting number. The interesting number appears when you place the parameter counts from part 02 beside the MACs and add a column for their ratio, which by the previous concept is just h_o · w_o.
| Layer | Shape | Parameters | MACs | MACs per parameter |
|---|---|---|---|---|
| conv1 | 96 × 3 × 11 × 11, out 55 × 55 | 34,848 | 105,415,200 | 3,025 |
| conv2 | 256 × 96 × 5 × 5 / 2, out 27 × 27 | 307,200 | 223,948,800 | 729 |
| conv3 | 384 × 256 × 3 × 3, out 13 × 13 | 884,736 | 149,520,384 | 169 |
| conv4 | 384 × 384 × 3 × 3 / 2, out 13 × 13 | 663,552 | 112,140,288 | 169 |
| conv5 | 256 × 384 × 3 × 3 / 2, out 13 × 13 | 442,368 | 74,760,192 | 169 |
| fc6 | 4096 × (256 × 6 × 6) | 37,748,736 | 37,748,736 | 1 |
| fc7 | 4096 × 4096 | 16,777,216 | 16,777,216 | 1 |
| fc8 | 1000 × 4096 | 4,096,000 | 4,096,000 | 1 |
| conv1 to conv5 | five convolutions | 2,332,704 (3.8%) | 665,784,864 (91.9%) | |
| fc6 to fc8 | three linear layers | 58,621,952 (96.2%) | 58,621,952 (8.1%) | |
| Total | eight weighted layers | 60,954,656 | 724,406,816 |
The five convolutions hold 2,332,704 parameters, under 4% of the network, yet perform 665,784,864 MACs, 92% of the compute. The three linear layers hold 58,621,952 parameters, 96% of the network, yet perform only 58,621,952 MACs, 8% of the compute. The last column explains it: each conv1 weight is used 3,025 times, each conv3 to conv5 weight 169 times, each linear weight once. Large spatial maps early in the network make convolution compute heavy. Large c_i · c_o products late in the network make the linear layers parameter heavy.
Flip the toggle and watch which single layer is largest. Under parameters it is fc6, about 62% of the network on its own. Under MACs it is conv2, about 31%, while conv1, invisible on the parameter bar at 0.06%, grows to 15% because its 34,848 weights each fire 3,025 times. Each layer's exact count is listed below the bar.
- conv134,848 (0.1%)
- conv2307,200 (0.5%)
- conv3884,736 (1.5%)
- conv4663,552 (1.1%)
- conv5442,368 (0.7%)
- fc637,748,736 (61.9%)
- fc716,777,216 (27.5%)
- fc84,096,000 (6.7%)
What this means for making a model faster
The inversion sets the strategy for the rest of the course. Pruning or quantizing the linear layers shrinks Model size dramatically, because that is where the weights are, but it barely changes the MAC count and therefore barely changes computation time. To make inference faster you must attack the convolutions: fewer channels, grouped or depthwise filters as in MobileNet, or a lower input resolution so that h_o · w_o shrinks in every layer at once. The pruning lecture that follows will keep returning to this table, and when you profile a model for the research project, report both columns, not one.
Quick check
Pruning removes 90 percent of the weights in AlexNet's fc6 and fc7. Roughly how much does the network's total MAC count fall?
Recall
Which AlexNet layer family holds most of the parameters, which performs most of the MACs, and why?
A MAC hides two arithmetic operations: a multiply and an add. When each is counted as one floating point operation, one MAC is two FLOPs, and AlexNet's 724,406,816 MACs become 1,448,813,632 FLOPs. The slide rounds that to 1.4G; the exact figure is 1.449G, and showing the factor of two matters more than the rounding.
The count on its own says nothing about time. To get time you need to know how fast a processor can drain it, and that is a different quantity with an almost identical name. FLOPS, with a capital S, is floating point operations per second: a throughput that belongs to the hardware. FLOPs, with a lowercase s, is a plural count that belongs to the model. TOP500 ranks supercomputers by exactly this rate, reporting Linpack results as Rmax and Rpeak in Flop/s, and NVIDIA's GPU performance background guide writes the time a math-limited kernel takes as its number of operations divided by the processor's math bandwidth, which is FLOPs over FLOPS.
This is the computation time term of the latency model on slide 8, where the numerator is a network specification and the denominator a hardware specification. Run AlexNet's count through a few devices and the scale of the answer changes by orders of magnitude while the model does not change at all.
| Processor | Count ÷ rate | T_computation |
|---|---|---|
| 1 GFLOPS | 1.449 × 10^9 / 10^9 | 1,449 ms |
| 100 GFLOPS | 1.449 × 10^9 / 10^11 | 14.5 ms |
| 1 TFLOPS | 1.449 × 10^9 / 10^12 | 1.45 ms |
| 67 TOPS (Orin Nano, INT8 sparse peak) | 1.449 × 10^9 / 6.7 × 10^13 | 0.022 ms |
OPs: the same count for any data type
The F in FLOP assumes floating point arithmetic. A quantized network, the kind you deploy on a microcontroller or an INT8 accelerator, stores weights and activations at an Bit width of 8 bits and multiplies integers. Those are not floating point operations, but they are still operations, and there are still two per MAC. The lecture therefore generalizes: an operation (OP) is one multiply or add of any data type, AlexNet is 724M × 2 = 1.4G OPs, and OPS is operations per second. The layer compute calculator in the second concept of this part uses OPS in its hardware box for exactly this reason: the formula for time does not care whether the operands were floats.
| Term | Kind | Meaning | Belongs to |
|---|---|---|---|
| MAC | Count | One multiply accumulated into a sum | A model, per inference |
| FLOP | Count | One floating point multiply or add; a MAC is two | A model, per inference |
| OP | Count | One operation of any data type; a MAC is two | A model, per inference |
| FLOPS | Rate | Floating point operations per second | A processor |
| OPS | Rate | Operations per second, any data type | A processor |
Quick check
A model needs 3.6G FLOPs and a chip sustains 400 GFLOPS. What is T_computation?
Quick check
Why does the lecture generalize from FLOPs to OPs?
Quick check
A datasheet advertises a board at 67 TOPS. What kind of quantity is that?
Recall
State the rule that turns a MAC count into a FLOP count and a FLOP count into a time, then apply it: AlexNet on a 1 TFLOPS processor.
Recall
Why use OPs rather than FLOPs for an INT8 model, and how many OPs per MAC?
Slide 29 lists the ten works the lecture draws on. Six were used directly in this lecture's counting and examples; the other four appear here as context for the architectures and normalization layers of lecture 02 and the pruning lectures ahead.
Used in this lecture
- Dumoulin and Visin, Convolution arithmetic (GitHub repository and arXiv 1603.07285): the output-shape arithmetic behind every h_o × w_o in this part.
- Stanford CS231n, lecture 5, Image Classification with CNNs: parameter sharing, the output-size formula and im2col.
- Krizhevsky, Sutskever and Hinton, ImageNet Classification with Deep Convolutional Neural Networks, NeurIPS 2012: the AlexNet layers counted on slides 25 and 26.
- Sandler et al., MobileNetV2: Inverted Residuals and Linear Bottlenecks, CVPR 2018: the depthwise design that cuts both parameters and MACs, and the "MAdd" convention.
- Deng, Li, Han, Shi and Xie, Model Compression and Hardware Acceleration for Neural Networks: A Comprehensive Survey, Proceedings of the IEEE 108(4), 2020: the wider map of compression techniques that these metrics evaluate.
- Song Han, MIT 6.5940 TinyML and Efficient Deep Learning Computing, lecture 2: the direct source of slides 23 to 28.
Context for other lectures
- Ioffe and Szegedy, Batch Normalization, ICML 2015.
- Wu and He, Group Normalization, ECCV 2018.
- Simonyan and Zisserman, Very Deep Convolutional Networks for Large-Scale Image Recognition, ICLR 2015.
- He, Zhang, Ren and Sun, Deep Residual Learning for Image Recognition, CVPR 2016.
Recap
If you remember nothing else
- A MAC is a <- a + b·c. A matrix-vector product costs m·n MACs and a matrix-matrix product m·n·k MACs.
- Linear: c_o·c_i. Convolution: c_o·c_i·k_h·k_w·h_o·w_o. Grouped: divide by g. Depthwise: c_o·k_h·k_w·h_o·w_o, with no c_i.
- Convolution MACs equal parameters times h_o·w_o. Linear MACs equal parameters.
- AlexNet performs 724,406,816 MACs. Its convolutions hold 3.8 percent of the parameters but perform 92 percent of the MACs; the linear layers are the reverse.
- One MAC is two FLOPs, so AlexNet is about 1.45G FLOPs, which the slide rounds to 1.4G.
- FLOPs and OPs are counts that belong to a model. FLOPS and OPS are rates that belong to a processor. T_computation = OPs / OPS.
- OPs generalizes FLOPs to quantized integer networks; the count per MAC stays two.
- Conventions differ: many papers and tools report MACs under the label FLOPs. Check before comparing numbers.
Sources
- MIT 6.5940 Fall 2023, Lecture 2: Basics of Deep LearningVideoMIT HAN Lab, Song HanSlides 77 to 85 are the source of slides 23 to 28: MAC, MV, GEMM, per-layer MACs, AlexNet 724M, FLOP, FLOPS, OP, OPS.(opens in a new tab)
- ImageNet Classification with Deep Convolutional Neural NetworksPaperNeurIPS 2012, Krizhevsky, Sutskever and HintonAlexNet: five convolution and three linear layers, about 60M parameters.(opens in a new tab)
- Efficient Processing of Deep Neural Networks: A Tutorial and SurveyPaperProceedings of the IEEE, Sze, Chen, Yang and EmerMAC as the fundamental component; AlexNet at 61M weights and 724M MACs, with FC layers at 58.6M of each.(opens in a new tab)
- MobileNets: Efficient Convolutional Neural Networks for Mobile Vision ApplicationsPaperarXiv, Howard et al.Equations 4 and 5 give the depthwise and separable costs; the unnumbered ratio that follows is 1/N + 1/D_K^2, 8 to 9 times less computation; Mult-Adds; GEMM via im2col.(opens in a new tab)
- MobileNetV2: Inverted Residuals and Linear BottlenecksPaperCVPR 2018, Sandler et al.Operations reported as multiply-adds (MAdd).(opens in a new tab)
- Deep Learning, chapter 9: Convolutional NetworksBookMIT Press, Goodfellow, Bengio and CourvilleSection 9.2: parameter sharing keeps forward runtime O(k x n) while cutting storage to k parameters.(opens in a new tab)
- Matrix Multiplication Background User's GuideDocsNVIDIA Deep Learning Performance documentationGEMM costs 2 * M * N * K FLOPs (the page itself writes FLOPS) because each FMA is two operations, a multiply and an add.(opens in a new tab)
- GPU Performance Background User's GuideDocsNVIDIA Deep Learning Performance documentationMath time equals the number of operations divided by the processor's math bandwidth: T_computation = FLOPs / FLOPS when math limited.(opens in a new tab)
- torch.nn.Conv2dDocsPyTorch documentationOutput-size formula, groups semantics, groups = in_channels as depthwise convolution.(opens in a new tab)
- CS231n Convolutional Neural Networks for Visual Recognition: course notesDocsStanford UniversityParameter sharing, output-size arithmetic, AlexNet conv1 at 55 x 55 x 96, im2col.(opens in a new tab)
- TOP500 List, November 2024DocsTOP500Rmax and Rpeak columns reported in PFlop/s.(opens in a new tab)
- fvcore FlopCountAnalysisDocsDetectron2 documentation, MetaCounts one fused multiply-add as one flop: the opposite convention to this course.(opens in a new tab)
- Multiply-accumulate operationArticleWikipediaDefinition a <- a + (b x c) and the IEEE 754-2008 fused multiply-add. Used only for the definition.(opens in a new tab)
- Jetson modulesDocsNVIDIA DeveloperJetson Orin Nano up to 67 TOPS and AGX Orin up to 275 TOPS.(opens in a new tab)
- Jetson Orin specificationsDocsNVIDIAThe TOPS figures are sparse INT8; dense INT8 ratings are about half, for example 170 sparse against 85 dense.(opens in a new tab)
- Model Compression and Hardware Acceleration for Neural Networks: A Comprehensive SurveyPaperProceedings of the IEEE 108(4), Deng, Li, Han, Shi and XieReference 9 on slide 29.(opens in a new tab)
- A guide to convolution arithmetic for deep learningDocsDumoulin and Visin, GitHub and arXiv 1603.07285Reference 1 on slide 29: output-shape arithmetic.(opens in a new tab)