<svg viewBox="0 0 760 470" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,Segoe UI,Roboto,sans-serif">
<rect x="0" y="0" width="760" height="470" fill="#0d1117"/>
<text x="380" y="28" fill="#e6edf3" font-size="21" font-weight="700" text-anchor="middle">TPU — Google's Tensor Processing Unit</text>
<text x="380" y="48" fill="#8b98a5" font-size="12" text-anchor="middle">custom ASIC for matrix multiply: systolic array architecture, designed for TensorFlow/JAX workloads</text>
<!-- === LEFT: Systolic array (core of TPU) === -->
<rect x="30" y="65" width="295" height="230" rx="6" fill="#080d14" stroke="#233043" stroke-width="1.2"/>
<text x="177" y="83" fill="#e6edf3" font-size="11" text-anchor="middle" font-weight="600">Systolic Array (MXU — Matrix Multiply Unit)</text>
<!-- 8x8 grid of processing elements -->
<g fill="#1e3a5f" stroke="#3b82f6" stroke-width="0.5">
<!-- Row 1 -->
<rect x="70" y="95" width="16" height="16" rx="1"/><rect x="90" y="95" width="16" height="16" rx="1"/><rect x="110" y="95" width="16" height="16" rx="1"/><rect x="130" y="95" width="16" height="16" rx="1"/><rect x="150" y="95" width="16" height="16" rx="1"/><rect x="170" y="95" width="16" height="16" rx="1"/><rect x="190" y="95" width="16" height="16" rx="1"/><rect x="210" y="95" width="16" height="16" rx="1"/>
<!-- Row 2 -->
<rect x="70" y="115" width="16" height="16" rx="1"/><rect x="90" y="115" width="16" height="16" rx="1"/><rect x="110" y="115" width="16" height="16" rx="1"/><rect x="130" y="115" width="16" height="16" rx="1"/><rect x="150" y="115" width="16" height="16" rx="1"/><rect x="170" y="115" width="16" height="16" rx="1"/><rect x="190" y="115" width="16" height="16" rx="1"/><rect x="210" y="115" width="16" height="16" rx="1"/>
<!-- Row 3 -->
<rect x="70" y="135" width="16" height="16" rx="1"/><rect x="90" y="135" width="16" height="16" rx="1"/><rect x="110" y="135" width="16" height="16" rx="1"/><rect x="130" y="135" width="16" height="16" rx="1"/><rect x="150" y="135" width="16" height="16" rx="1"/><rect x="170" y="135" width="16" height="16" rx="1"/><rect x="190" y="135" width="16" height="16" rx="1"/><rect x="210" y="135" width="16" height="16" rx="1"/>
<!-- Row 4 -->
<rect x="70" y="155" width="16" height="16" rx="1"/><rect x="90" y="155" width="16" height="16" rx="1"/><rect x="110" y="155" width="16" height="16" rx="1"/><rect x="130" y="155" width="16" height="16" rx="1"/><rect x="150" y="155" width="16" height="16" rx="1"/><rect x="170" y="155" width="16" height="16" rx="1"/><rect x="190" y="155" width="16" height="16" rx="1"/><rect x="210" y="155" width="16" height="16" rx="1"/>
<!-- Row 5-8 (simplified) -->
<rect x="70" y="175" width="16" height="16" rx="1"/><rect x="90" y="175" width="16" height="16" rx="1"/><rect x="110" y="175" width="16" height="16" rx="1"/><rect x="130" y="175" width="16" height="16" rx="1"/><rect x="150" y="175" width="16" height="16" rx="1"/><rect x="170" y="175" width="16" height="16" rx="1"/><rect x="190" y="175" width="16" height="16" rx="1"/><rect x="210" y="175" width="16" height="16" rx="1"/>
<rect x="70" y="195" width="16" height="16" rx="1"/><rect x="90" y="195" width="16" height="16" rx="1"/><rect x="110" y="195" width="16" height="16" rx="1"/><rect x="130" y="195" width="16" height="16" rx="1"/><rect x="150" y="195" width="16" height="16" rx="1"/><rect x="170" y="195" width="16" height="16" rx="1"/><rect x="190" y="195" width="16" height="16" rx="1"/><rect x="210" y="195" width="16" height="16" rx="1"/>
</g>
<!-- Data flow arrows -->
<!-- Weight stationary: weights loaded, activations flow -->
<g stroke="#34d399" stroke-width="0.8" opacity="0.6">
<line x1="78" y1="90" x2="78" y2="215"/><line x1="98" y1="90" x2="98" y2="215"/>
<line x1="118" y1="90" x2="118" y2="215"/><line x1="138" y1="90" x2="138" y2="215"/>
<line x1="158" y1="90" x2="158" y2="215"/><line x1="178" y1="90" x2="178" y2="215"/>
<line x1="198" y1="90" x2="198" y2="215"/><line x1="218" y1="90" x2="218" y2="215"/>
</g>
<text x="147" y="88" fill="#6ee7b7" font-size="7.5" text-anchor="middle">activations flow ↓</text>
<g stroke="#fbbf24" stroke-width="0.8" opacity="0.6">
<line x1="65" y1="103" x2="230" y2="103"/><line x1="65" y1="123" x2="230" y2="123"/>
<line x1="65" y1="143" x2="230" y2="143"/><line x1="65" y1="163" x2="230" y2="163"/>
<line x1="65" y1="183" x2="230" y2="183"/><line x1="65" y1="203" x2="230" y2="203"/>
</g>
<text x="52" y="153" fill="#fbbf24" font-size="7" text-anchor="middle" transform="rotate(-90,52,153)">weights →</text>
<!-- Size annotation -->
<text x="177" y="228" fill="#93c5fd" font-size="8.5" text-anchor="middle">128×128 (TPUv4) or 256×256 (TPUv5e)</text>
<text x="177" y="242" fill="#8b98a5" font-size="8" text-anchor="middle">each PE: one FMA (BF16 multiply-accumulate)</text>
<text x="177" y="256" fill="#6b7684" font-size="8" text-anchor="middle">data flows through PEs: no memory roundtrip</text>
<text x="177" y="270" fill="#6b7684" font-size="7.5" text-anchor="middle">= maximum compute density, minimum data movement</text>
<text x="177" y="286" fill="#34d399" font-size="8" text-anchor="middle">128² = 16,384 MACs/cycle per MXU</text>
<!-- === RIGHT TOP: TPU generations === -->
<rect x="340" y="65" width="390" height="130" rx="6" fill="#0b1220" stroke="#233043" stroke-width="1"/>
<text x="535" y="83" fill="#e6edf3" font-size="10" text-anchor="middle" font-weight="600">TPU Generations</text>
<text x="360" y="103" fill="#6b7684" font-size="9">TPUv2 (2017): 45 TFLOPS BF16, 16 GB HBM</text>
<text x="360" y="119" fill="#8b98a5" font-size="9">TPUv3 (2018): 123 TFLOPS, 32 GB, liquid-cooled</text>
<text x="360" y="135" fill="#60a5fa" font-size="9">TPUv4 (2021): 275 TFLOPS, 32 GB HBM2e</text>
<text x="360" y="151" fill="#34d399" font-size="9" font-weight="600">TPUv5e (2023): best perf/$ for inference</text>
<text x="360" y="167" fill="#fbbf24" font-size="9" font-weight="600">TPUv5p (2024): 459 TFLOPS, 95 GB HBM2e</text>
<text x="360" y="185" fill="#c4b5fd" font-size="9">Trillium (TPUv6, 2025): 4.7x v5e perf</text>
<!-- === RIGHT BOTTOM: TPU vs GPU === -->
<rect x="340" y="203" width="390" height="95" rx="6" fill="#0b1220" stroke="#233043" stroke-width="1"/>
<text x="535" y="221" fill="#e6edf3" font-size="10" text-anchor="middle" font-weight="600">TPU vs GPU (architectural differences)</text>
<text x="360" y="241" fill="#4285f4" font-size="9">TPU: fixed-function systolic (BF16/INT8)</text>
<text x="360" y="255" fill="#8b98a5" font-size="8.5"> higher utilization on matmul, less flexible</text>
<text x="360" y="273" fill="#76b900" font-size="9">GPU: programmable CUDA cores + Tensor Cores</text>
<text x="360" y="287" fill="#8b98a5" font-size="8.5"> more general, bigger ecosystem, more formats</text>
<!-- === BOTTOM: TPU Pod + who uses it === -->
<rect x="30" y="305" width="700" height="110" rx="5" fill="#0b1220" stroke="#233043" stroke-width="1"/>
<text x="380" y="323" fill="#e6edf3" font-size="10" text-anchor="middle" font-weight="600">TPU Pods — Scaling to Thousands</text>
<!-- Pod visualization -->
<g fill="#1e3a5f" stroke="#4285f4" stroke-width="0.4">
<rect x="50" y="335" width="12" height="12" rx="1"/><rect x="64" y="335" width="12" height="12" rx="1"/><rect x="78" y="335" width="12" height="12" rx="1"/><rect x="92" y="335" width="12" height="12" rx="1"/>
<rect x="50" y="349" width="12" height="12" rx="1"/><rect x="64" y="349" width="12" height="12" rx="1"/><rect x="78" y="349" width="12" height="12" rx="1"/><rect x="92" y="349" width="12" height="12" rx="1"/>
<rect x="50" y="363" width="12" height="12" rx="1"/><rect x="64" y="363" width="12" height="12" rx="1"/><rect x="78" y="363" width="12" height="12" rx="1"/><rect x="92" y="363" width="12" height="12" rx="1"/>
<rect x="50" y="377" width="12" height="12" rx="1"/><rect x="64" y="377" width="12" height="12" rx="1"/><rect x="78" y="377" width="12" height="12" rx="1"/><rect x="92" y="377" width="12" height="12" rx="1"/>
</g>
<text x="74" y="400" fill="#4285f4" font-size="8" text-anchor="middle">pod slice</text>
<text x="140" y="345" fill="#8b98a5" font-size="9">TPUv4 Pod: 4096 chips, 1.1 ExaFLOPS</text>
<text x="140" y="361" fill="#8b98a5" font-size="9">TPUv5p Pod: 8960 chips</text>
<text x="140" y="377" fill="#8b98a5" font-size="9">Inter-chip: ICI (custom optical fabric)</text>
<text x="140" y="393" fill="#6b7684" font-size="8.5">3D torus topology, no InfiniBand needed</text>
<!-- Who uses it -->
<text x="480" y="345" fill="#e6edf3" font-size="9" font-weight="600">Trained on TPUs:</text>
<text x="480" y="361" fill="#8b98a5" font-size="9">Gemini (Google), PaLM, T5, BERT</text>
<text x="480" y="377" fill="#8b98a5" font-size="9">Midjourney, Anthropic (early Claude)</text>
<text x="480" y="393" fill="#6b7684" font-size="8.5">Available: Google Cloud (on-demand/reserved)</text>
<!-- Economics -->
<text x="380" y="430" fill="#e6edf3" font-size="9.5" text-anchor="middle" font-weight="600">TPU pricing: $1.37/chip-hr (v5e) — competitive with H100 ($2-3/hr) for training LLMs in JAX</text>
<text x="380" y="446" fill="#8b98a5" font-size="9" text-anchor="middle">Limitation: JAX/TensorFlow only (no CUDA, no PyTorch native) — ecosystem lock-in to Google Cloud</text>
<text x="380" y="464" fill="#6b7684" font-size="11" text-anchor="middle">TPU proves custom silicon beats general GPUs at the workloads you design for — if you control the software stack.</text>
</svg>
```nsor Processing Unit (TPU) is Google's custom machine-learning accelerator, designed around high-throughput matrix multiplication for training and inference in the Google software and cloud ecosystem.\n\n```svg\n<svg viewBox="0 0 760 500" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,Segoe UI,Roboto,sans-serif">\n <rect x="0" y="0" width="760" height="500" fill="#0d1117"/>\n <text x="380" y="32" fill="#e6edf3" font-size="21" font-weight="700" text-anchor="middle">The TPU Systolic Array — Matrix Multiply as Dataflow</text>\n <text x="380" y="54" fill="#8b98a5" font-size="12.5" text-anchor="middle">one value read from memory feeds many multiply-accumulates — that reuse is the whole point</text>\n\n <!-- weights label (top) -->\n <text x="385" y="108" fill="#6ee7b7" font-size="12" text-anchor="middle">weights stay resident in each cell (stationary)</text>\n\n <rect x="250" y="126" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="273" y="154" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="304" y="126" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="327" y="154" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="358" y="126" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="381" y="154" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="412" y="126" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="435" y="154" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="466" y="126" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="489" y="154" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="250" y="180" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="273" y="208" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="304" y="180" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="327" y="208" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="358" y="180" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="381" y="208" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="412" y="180" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="435" y="208" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="466" y="180" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="489" y="208" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="250" y="234" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="273" y="262" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="304" y="234" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="327" y="262" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="358" y="234" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="381" y="262" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="412" y="234" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="435" y="262" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="466" y="234" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="489" y="262" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="250" y="288" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="273" y="316" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="304" y="288" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="327" y="316" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="358" y="288" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="381" y="316" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="412" y="288" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="435" y="316" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="466" y="288" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="489" y="316" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="250" y="342" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="273" y="370" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="304" y="342" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="327" y="370" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="358" y="342" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="381" y="370" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="412" y="342" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="435" y="370" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <rect x="466" y="342" width="46" height="46" rx="4" fill="#0f1c17" stroke="#34d399" stroke-width="1"/>\n <text x="489" y="370" fill="#6ee7b7" font-size="13" text-anchor="middle" font-family="ui-monospace,monospace">×+</text>\n <path d="M186 149 L246 149 M238 144 L246 149 L238 154" stroke="#fbbf24" stroke-width="1.4" fill="none"/>\n <path d="M186 203 L246 203 M238 198 L246 203 L238 208" stroke="#fbbf24" stroke-width="1.4" fill="none"/>\n <path d="M186 257 L246 257 M238 252 L246 257 L238 262" stroke="#fbbf24" stroke-width="1.4" fill="none"/>\n <path d="M186 311 L246 311 M238 306 L246 311 L238 316" stroke="#fbbf24" stroke-width="1.4" fill="none"/>\n <path d="M186 365 L246 365 M238 360 L246 365 L238 370" stroke="#fbbf24" stroke-width="1.4" fill="none"/>\n <path d="M273 390 L273 418 M268 410 L273 418 L278 410" stroke="#60a5fa" stroke-width="1.4" fill="none"/>\n <path d="M327 390 L327 418 M322 410 L327 418 L332 410" stroke="#60a5fa" stroke-width="1.4" fill="none"/>\n <path d="M381 390 L381 418 M376 410 L381 418 L386 410" stroke="#60a5fa" stroke-width="1.4" fill="none"/>\n <path d="M435 390 L435 418 M430 410 L435 418 L440 410" stroke="#60a5fa" stroke-width="1.4" fill="none"/>\n <path d="M489 390 L489 418 M484 410 L489 418 L494 410" stroke="#60a5fa" stroke-width="1.4" fill="none"/>\n\n <!-- activations label -->\n <text x="150" y="261" fill="#fcd34d" font-size="12" text-anchor="middle" transform="rotate(-90 150 261)">activations stream in</text>\n <!-- psum label -->\n <text x="385" y="440" fill="#93c5fd" font-size="12" text-anchor="middle">partial sums accumulate downward → outputs</text>\n\n <!-- right facts -->\n <text x="548" y="150" fill="#cbd5e1" font-size="12" font-weight="700">MXU</text>\n <text x="548" y="170" fill="#8b98a5" font-size="13">128×128 (or 256×256)</text>\n <text x="548" y="192" fill="#8b98a5" font-size="13">real array, not 5×5</text>\n <text x="548" y="224" fill="#c4b5fd" font-size="13" font-weight="700">bfloat16</text>\n <text x="548" y="244" fill="#8b98a5" font-size="13">wide range, low bits</text>\n <text x="548" y="284" fill="#6ee7b7" font-size="13">one memory read</text>\n <text x="548" y="302" fill="#8b98a5" font-size="13">→ many MACs</text>\n\n <text x="380" y="484" fill="#6b7684" font-size="13" text-anchor="middle">No register file re-fetch per multiply: operands march through the array, so energy goes to arithmetic, not data movement.</text>\n</svg>\n```\n\n**The core is a systolic matrix unit.** Activations and weights stream through a two-dimensional multiply-accumulate array, maximizing data reuse and reducing energy spent moving operands. Vector units and on-chip memory handle the operations surrounding matrix multiplication.\n\n**Why the systolic array is so efficient.** In a conventional processor every multiply re-fetches its operands from registers or memory. In a systolic array a weight is loaded once into a cell and stays put, reused across a whole stream of activations, while partial sums accumulate as they march down the array. One memory read therefore feeds many multiply-accumulates, and that operand reuse is where the energy-per-operation advantage comes from.\n\n**TPUs are systems, not isolated chips.** High-bandwidth memory, fast chip-to-chip interconnects, and pod-scale topology allow large models to span many devices. XLA compiles TensorFlow, JAX, and supported PyTorch workloads into programs matched to that hardware.\n\n**The generations trace a clear arc.** TPU v1 in 2016 was inference-only, with an 8-bit matrix unit on a PCIe card. v2 and v3 added training, HBM, and the bfloat16 numeric format, and organized chips into pods. v4 introduced optically reconfigurable interconnects that rewire the pod topology to the workload, and the later v5e and v5p chase performance per dollar and per watt at very large scale. Throughout, the real differentiator is the pod: thousands of chips wired into a single machine.\n\n**The trade is specialization for efficiency.** TPUs can be highly efficient on well-shaped tensor workloads, while GPUs generally offer a broader programming ecosystem and more flexibility for irregular kernels.\n\n| Generation | Focus | Notable |\n|---|---|---|\n| TPU v1 (2016) | inference only | 8-bit MXU on a PCIe card |\n| TPU v2 / v3 | training and inference | HBM, bfloat16, pod scale |\n| TPU v4 | large-scale training | optical circuit switch interconnect |\n| TPU v5e / v5p | scale and cost | performance per dollar, huge pods |\n\nRead a TPU through an *operand-reuse* lens rather than a *peak-FLOPS* lens: the systolic array wins by getting many multiply-accumulates out of each value it reads from memory, so its efficiency comes from dataflow — how long a weight stays resident and how far a partial sum travels before it is written back — not from clock speed. Every design choice around it, from bfloat16 to pod-scale optical interconnects, is about keeping that array fed without paying to move data.\n
tputpu tensor processing unitgoogle tputensor processing unithardware
Explore 500+ Semiconductor & AI Topics
From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.