Home · ASPLOS 2025 · Machine Learning Systems

PICACHU: Plug-In CGRA Handling Upcoming Nonlinear Operations in LLMs

Jiajun Qin, Tianhua Xia, Cheng Tan, Jeff Zhang and Sai Qian Zhang

Conference
ASPLOS 2025
Published
2025
Pages
845-861
Citations
16

For a decade, accelerating a neural network meant accelerating matrix multiplication, because that was almost the entire cost — but in large language models the OTHER operations, the ones that reshape and normalise numbers rather than multiply matrices, have grown to take up to 46.3 percent of inference time, since they need exponentials and logarithms that hardware computes badly; building fixed circuits for today's handful of them fails because models keep inventing new ones, and approximating them in cheap integer arithmetic the way earlier models allowed destroys a large language model outright, taking perplexity from 6.75 to 70,000; this paper (NYU, ASU and Northeastern) instead plugs a small grid of reconfigurable tiles into the existing matrix engine, reusing its output memory, and computes each function by splitting the input into a part the number format already gives away for free and a remainder small enough for a four-term polynomial.

The argument in one glance

  1. Problem

    The part everyone treated as negligible now takes nearly half the time

    Accelerator design has assumed for a decade that matrix multiplication is where neural network time goes, which was correct for image models. Large language models broke that assumption. Profiling GPT2-XL, OPT-6.7B, BigBird and two LLaMA2 models on an A100 shows that the NONLINEAR operations — softmax, layer normalisation, activation functions, positional encodings — account for up to 46.3 percent of inference latency at a sequence length of 1024. The reason is that these operations need exponentials and logarithms, which matrix engines cannot do at all and general-purpose hardware does slowly.

  2. What people did

    Build dedicated circuits, or approximate in cheap integer arithmetic

    Two families of answers exist and both are sensible. The hardware answer is to add fixed units for the operations that matter — accelerators ship with dedicated softmax, activation and normalisation circuits, and these are fast and efficient for exactly what they implement. The software answer is to replace each function with a cheap polynomial evaluated in integer arithmetic, which worked well for earlier networks: methods built for BERT-scale models are established and widely cited.

  3. Why it fell short

    Fixed circuits go stale, and cheap approximations destroy the model

    The set of nonlinear operations keeps changing. An accelerator with dedicated units for ReLU, GeLU, softmax and layer normalisation matches this paper on GPT2-XL — and then LLaMA2-13B arrives using SwiGLU and RMSNorm, operations its circuits do not implement, and it must fall back to an on-chip general-purpose core. Meanwhile the integer approximations turn out to be catastrophic at this scale rather than merely lossy: applied to LLaMA-7B, one established method takes perplexity from 6.75 to roughly 70,000 — the model is not degraded, it is destroyed. Language models are far more sensitive to the precision of these operations than the networks those methods were validated on.

  4. This paper's idea

    A small reconfigurable grid, plugged into the matrix engine it already sits beside

    This paper (NYU, Arizona State and Northeastern — Qin, Xia, Tan, Zhang, Zhang) observes that although the operations keep changing, they are all built from a handful of mathematical primitives, all share loop-based structure, and all do many computations per byte fetched. That profile fits a COARSE-GRAINED RECONFIGURABLE ARRAY: a small grid of tiles, each reconfigured every cycle by a compiler, sitting between a fixed circuit and a field-programmable chip in efficiency. Sixteen such tiles are plugged into an existing matrix engine by reusing its output memory as their input. Each function is computed by splitting the input into a part the floating-point format already encodes for free and a remainder small enough for a short polynomial. Accuracy loss is under 0.1 percent even in 16-bit integers, for 14.9 percent of the area.

Why this problem is worth solving

The shift here is easy to miss because it inverts a long-settled assumption.

A transformer layer is mostly matrix multiplication, but not entirely. Between the multiplications sit operations that reshape numbers rather than combine them: SOFTMAX turns a row of scores into probabilities that sum to one, NORMALISATION rescales a vector to a standard mean and spread, ACTIVATION FUNCTIONS such as GeLU and SwiGLU introduce curvature so the network can represent more than a linear map, and POSITIONAL ENCODINGS such as RoPE inject word-order information using sines and cosines. In image models these cost almost nothing, and a decade of accelerator design treated them as negligible. In language models they do not. Measured on an A100 across five models, they take up to 46.3 percent of inference time, and the share grows with sequence length. The cause is what they require — exponentials, logarithms, divisions, trigonometric functions — none of which a matrix engine can perform and all of which are slow elsewhere
.

The architecture the paper reaches for is less familiar than a chip or an FPGA.

A COARSE-GRAINED RECONFIGURABLE ARRAY is a grid of small tiles connected by an on-chip network. Each tile holds functional units for basic arithmetic, a register file, and a configuration memory. Every cycle, each tile reads its configuration and performs whatever operation it says, with the same configuration signals also steering data between tiles. A compiler takes a loop, expresses it as a DATA FLOW GRAPH where each node is one operation, and assigns those nodes to tiles across time and space. The metric that matters is the INITIATION INTERVAL — how many cycles pass between the start of one loop iteration and the next — because for a loop running many iterations that number essentially IS the runtime. Reconfiguring at this granularity, whole operations rather than individual logic gates, places such arrays between fixed-function circuits and field-programmable chips: much more flexible than the former, far more efficient than the latter
.

What people did before, and where it broke

  • Dedicated circuits for the operations that matter. Accelerators ship with purpose-built softmax and normalisation units, and transformer accelerators add more. For the operations they implement these are excellent, and one such design matches this paper on GPT2-XL and OPT-13B.
  • But the operation set keeps moving. LLaMA2-13B uses SwiGLU and RMSNorm. Faced with operations its circuits do not implement, that accelerator offloads them to an on-chip general-purpose core and its latency rises sharply. Fixed units encode the state of model design at tape-out.
  • Replace each function with a cheap polynomial in integer arithmetic. This is well-established for earlier networks, with methods designed for BERT-scale models widely used, and it avoids hardware changes entirely.
  • But language models will not tolerate it. Applied to LLaMA-7B with the linear layers left untouched, one established method takes perplexity from 6.75 to about 70,000. Another, better-behaved method still moves it from 6.75 to 9.67, roughly 43 percent worse. These are not tuning failures; the models are simply far more sensitive than those the methods were validated on.
  • Approximate the functions with small neural networks. This generalises to new functions, which is the right instinct, but it requires training a network per function and has not been shown reliable inside a language model.
  • Build a general processor for the non-matrix work. One prior design targets exactly this. But it approximates using the same integer methods above and its accuracy was never evaluated, which for operations this sensitive leaves the central question unanswered.
  • The gap. Every approach optimised one corner: fixed circuits chose efficiency and lost flexibility, polynomial methods chose cheapness and lost accuracy, and the general processor chose coverage without establishing that its results were usable. Nothing had to satisfy all three at once, and nobody had checked whether an architecture already existed that could.

How a reconfigurable grid absorbs an unknown operation set

Match the operations in the compiler, reuse the neighbour's memory, and compute each function by splitting it

  1. Run matrix multiplication on a systolic array

    The dominant work goes to a grid of multiply-accumulate cells, which is what accelerators are built around. This handles the linear part well and is not the problem. It cannot compute an exponential, so everything else must go somewhere.

  2. Find the nonlinear operations in the compiler, not in the model new

    Lower the model from PyTorch through an intermediate representation, where each nonlinear operation appears as a handful of instructions — a GeLU becomes five. Pattern-match those groups and replace them with a call to the accelerator. A new operation needs no change to the representation itself, only that the front end lowers it.

  3. Compute each function by splitting the input in two new

    Rewrite an exponential as a power of two, split that exponent into a whole number and a fraction, obtain the whole-number part by writing it directly into the exponent field of a float, and evaluate only the fraction with a short polynomial. Logarithms, sines and cosines use the same shape. The user picks how many terms.

  4. Fuse the patterns those polynomials produce new

    The resulting data flow graphs repeat a few shapes constantly, some in every kernel examined. Give each recurring pair or triple its own functional unit that executes it in one cycle, and spread those across three different tile types so the mapping is not concentrated on a few tiles.

  5. Build precision out of shared narrow lanes new

    Give each tile four 16-bit integer lanes. Chain two with carries for 32-bit addition, all four with shifts for 32-bit multiplication, or run them independently for four times the throughput at 16 bits. Precision becomes a per-kernel choice rather than a fixed property of the silicon.

  6. Plug into the matrix engine by taking its output memory new

    Rather than giving the array its own memory, multiplex the systolic array output memory to serve as the shared buffer. That memory already holds exactly what the nonlinear operation consumes, so element-wise work can start the moment the matrix engine produces anything, with streaming and double-buffering hiding transfers.

Implemented in synthesisable Verilog and synthesised in a 45nm library, with a 16-tile array beside a 32-by-32 systolic array and a 40KB shared buffer at 1GHz, evaluated on GPT2-XL, OPT-6.7B, OPT-13B, LLaMA2-7B and LLaMA2-13B.

The idea

Ask what the operations have in common instead of what they are. The trap in this problem is that the list of nonlinear operations is genuinely open-ended — GeLU, GeGLU, SwiGLU, LayerNorm, RMSNorm, RoPE, and whatever appears next — so any design enumerating them is dated before it ships. The paper sidesteps this by characterising the CLASS rather than the members. All of them are built from a small set of mathematical primitives; all of them are loop-shaped, splitting cleanly into element-wise loops and reduction-then-element-wise loops; and all of them do many operations per byte fetched. That third property is the surprising one, because the standard roofline analysis, applied at the level of whole tensors, files these operations as memory-bound. Counting individual computations against individual memory accesses instead gives intensities from 5.3 up to 14.5 — each value is read once, worked on heavily, and written back. The conclusion about what hardware to use follows from the class, not the list. Discovering that an established model gives a misleading answer because it is applied at the wrong granularity is the same look-closer-at-the-measurement lesson covered elsewhere on this site where a metric everyone trusted stopped describing the situation it was invented for.

Let the number format do half the arithmetic. The algorithm underneath is the most elegant part and is worth stating plainly. To compute an exponential without an exponential unit, rewrite it as a power of two and split that exponent into a whole number and a fraction. The whole-number part costs nothing at all, because a floating-point number already stores a power of two in its exponent field — raising two to an integer is writing that integer into a field. The fractional part is confined to a range less than one wide, and over such a range a four-term polynomial is extremely accurate, which is exactly what the array’s adders and multipliers can evaluate. Logarithms split the same way into exponent and mantissa; sines and cosines range-reduce into a narrow interval first. One small hardware module performs the split, costing 1.7 percent of a tile’s area. The principle is general: divide the input so that one part is free in the representation you already have and the rest is small enough for a cheap approximation to be exact enough. Re-encoding a problem so that an expensive operation is replaced rather than optimised is the same change-the-representation move covered elsewhere on this site where the fix is not a faster circuit for the hard operation but an arrangement in which the hard operation is no longer needed.

Plug in rather than build alongside. The integration detail is easy to skip and does a lot of work. A conventional reconfigurable array wants its own memory; a systolic array already has input, weight and output memories of its own. Instead of adding a third, this design multiplexes the systolic array’s OUTPUT memory to serve as the array’s shared buffer — which is not merely thrifty but correct, because the matrix engine’s output is precisely what the nonlinear operation consumes. Element-wise operations can therefore begin the instant the matrix engine produces anything, overlapping the two engines with no tensor-size constraint at all, and even softmax’s first pass can overlap while the matrix engine still works. The nonlinear share of LLaMA2-7B runtime falls from 42.4 percent to 22.8 percent. Noticing that the resource a new component needs already exists next door in exactly the right form, rather than provisioning it again, is the same reuse-what-is-already-there instinct covered elsewhere on this site where the structure that appeared to be an obstacle turns out to be the thing the design should build on.

Computing an exponential with only add and multiply

The paper's method for exp, which is the primitive underneath softmax

Only addition, multiplication and one small extraction unit are used. No exponential circuit exists anywhere in the design.

Step 1 of 5

Change the base to the one the hardware understands

The natural exponential is awkward, but a power of two is not, because binary floating-point numbers are built out of powers of two. So the first step multiplies the input by the logarithm of e in base two, converting the problem of raising e to some power into raising two to a different power.

this multiplication is a single ordinary floating-point multiply by a constant, so it costs one operation
nothing has been approximated yet, only rewritten, so no accuracy has been given up at this point

Why it works

  • The operations change but their primitives do not → building the primitives rather than the operations covers what has not been invented yet → which is why SwiGLU and RMSNorm need no new hardware while a fixed-circuit design must fall back to a general-purpose core.
  • Splitting an input leaves one part encoded free in the floating-point exponent and the other confined below one → a four-term polynomial is accurate over that narrow range → so perplexity moves by at most 0.05 where an established integer method moves it by about 70,000.
  • The polynomials generate the same small graph shapes over and over, some in every kernel → giving each shape a functional unit that runs it in one cycle shortens the loop’s critical path → yielding 2.95 times the speed of a plain array of the same size, and up to 6.4.
  • Narrow lanes can be chained for width or run independently for throughput → precision becomes a per-kernel decision → letting 16-bit integers give four-way vectorisation and 2.77 times more speed where the accuracy budget allows.
  • The systolic array’s output memory already holds what the nonlinear operation reads → reusing it as the shared buffer removes both a memory and a copy → so element-wise work starts as soon as the matrix engine emits anything, cutting the nonlinear share of runtime from 42.4 percent to 22.8.

What it costs (trade-offs and scope)

  • A bigger array mostly does not help. Doubling from 16 tiles to 32 yields under 1.4 times rather than 2, which the authors attribute to the compiler’s mapping ability and place outside this work’s scope. Their suggested workaround is to run two independent halves rather than one larger array.
  • Vectorisation falls short of its theoretical gain. Four-way 16-bit vectorisation delivers 2.77 times on average rather than 4, because some instructions in the loop cannot be vectorised at all.
  • It is an addition, not a replacement. The design accelerates the nonlinear operations beside a matrix engine that still does the linear work. End-to-end gains are therefore bounded by how much of the runtime was nonlinear — 6.74 times on that part, but 3.36 times overall.
  • Some functions still need a lookup table. Operations that cannot be built from basic arithmetic, notably the Gaussian cumulative distribution inside GeLU, are stored as precomputed values. That works and is cheap, but it is a small fixed-function concession inside an argument about flexibility.
  • Evaluation is by synthesis and simulation. Results come from a 45nm synthesis with modelled memory and an analytical performance tool, not silicon, and the GPU comparison requires scaling the design to match A100 throughput before comparing.

The evaluation

Accuracy was measured by replacing only the nonlinear operations, leaving all linear layers in 16-bit floating point, on GPT2-XL, OPT-6.7B, OPT-13B, LLaMA2-7B and LLaMA2-13B — reporting perplexity on WikiText2 and accuracy on five reasoning benchmarks. Hardware was written in synthesisable Verilog and synthesised in a 45nm library, with memory modelled separately and end-to-end behaviour estimated analytically. The comparison set covers a fixed-circuit accelerator, a general-purpose non-matrix processor, a laptop-class CPU and an A100 GPU, with the design scaled to match the GPU’s throughput before comparing.

Handling the non-matrix operations in a language model

PropertyDedicated circuits per operationCheap integer polynomialsReconfigurable tile grid
Operations not anticipated at design time
Effect on model quality
Precision choice
Memory required
Measured end-to-end result
Against a plain array of the same size, the specialised tiles give 2.95 times the speed on average and up to 6.4, with 3.35 times the energy efficiency and 2.11 times the area efficiency. End to end the design beats a fixed-circuit accelerator by 1.86 times, a general non-matrix processor by 1.55 times, a CPU by 1.90 times and an A100 by 2.80 times on OPT and 3.36 on LLaMA. Within LLaMA the matrix work speeds up 2.43 times and the nonlinear work 6.74 times, dropping the nonlinear share of runtime from 42.4 percent to 22.8. The tile grid occupies 14.9 percent of combined area and 34.2 percent of power.Underlined values explain themselves when clicked.

Check yourself

Check your understanding

  1. 1. Integer approximations of nonlinear functions work acceptably in BERT-scale networks but take LLaMA-7B perplexity from 6.75 to roughly 70,000. Predict what that number means and why the gap is so extreme.

  2. 2. The design contains no exponential circuit, yet computes exponentials constantly for softmax. Predict how, using only multiplication, addition and one small extraction unit.

  3. 3. A fixed-circuit accelerator matches this design on GPT2-XL and OPT-13B, then loses badly on LLaMA2-13B. Predict what changed.

  4. 4. Doubling the array from 16 tiles to 32 yields under 1.4 times more speed rather than 2. Predict why the extra hardware goes largely unused.

Sources

Related papers on Machine Learning Systems

See all 212 →