Same Ruler, Smarter Placement: GPTQ
Suppose a layer adds two contributions, each worth 0.6. Its output is 1.2. If our storage format only permits integer weights, rounding both contributions independently gives 1 + 1 = 2. Each rounding decision was locally reasonable, but together they moved the output a long way.
Now round the first weight to 1 and leave it fixed. Before rounding the second, reduce it to 0.2: the two contributions again sum to 1.2. Finally round that adjusted weight to 0. The stored weights are now 1 and 0, giving an output of 1. We still have an error, but a much smaller one.
GPTQ uses this idea: after rounding a weight, adjust the weights that remain free to preserve the layer’s outputs as well as possible. The complication is choosing adjustments that work across many inputs, where the weights do not all contribute equally.
In the AWQ article, we explored changing channel scales before quantization. Here we keep the quantization grid fixed and investigate compensation. We will start with two weights, build up to a reproducible 4×4 example, and then explain the Hessian and Cholesky machinery that makes the process practical.
1. Preserve the Output, Not Each Weight
Our opening example is a single linear output:
\[y = w_0x_0 + w_1x_1 = 0.6x_0 + 0.6x_1.\]For the input $x_0=x_1=1$, the output is 1.2. With a grid spacing of 1, the complete sequence is:
| State | First weight | Second weight | Output | Output error |
|---|---|---|---|---|
| Original | 0.6 | 0.6 | 1.2 | 0 |
| Independent rounding | 1 | 1 | 2.0 | +0.8 |
| First rounded, second compensated | 1 | 0.2 | 1.2 | 0 |
| Both rounded after compensation | 1 | 0 | 1.0 | −0.2 |
The intermediate value 0.2 is allowed because the second weight has not been stored on the integer grid yet. It is a working value. Once we round it, it becomes fixed too.
Figure 1. Moving a weight farther can preserve the output better. We take one input, x₀ = x₁ = 1, and a grid spacing of 1. Rounding both weights at once lands on [1, 1] and overshoots the target 1.2 by 0.8. Freezing the first weight and compensating the second restores 1.2 exactly at the intermediate step; final rounding still leaves a residual error of −0.2.
Notice the apparent contradiction. The second stored weight, 0, is farther from its original value 0.6 than the independently rounded value 1 is. Yet the final output is better: squared output error falls from 0.64 to 0.04.
There is no contradiction once we distinguish the objectives. We are trying to preserve a computation, not produce the closest possible copy of every individual weight.
This example explains the mechanism, not a complete calibration procedure. It uses one input, one output, and no damping. For a different input, say $x_0=1, x_1=-1$, the original output is 0, independent rounding also gives 0, and our compensated result gives 1. A repair that helps one input can harm another.
That is the next problem we must solve.
2. Calibration Tells Us Which Adjustments Can Help
A linear layer does not see just one input. During calibration, we run representative inputs through the model and collect the activation vectors arriving at the layer. For a language model, these are internal token representations, not the token IDs themselves.
Stack those vectors as columns of $X$. Let $W$ hold the original weights, with one row per output channel and one column per input channel. Then:
\[Y = WX, \qquad \hat Y = \hat W X.\]Each column of $Y$ is the layer’s output for one calibration vector. We choose quantized weights by trying to keep these outputs close:
\[L(\hat W) = \|WX-\hat W X\|_F^2.\]The squared Frobenius norm means “square every output difference and add them.” For four output channels and eight calibration vectors, it adds 32 squared differences. We can compare the outputs directly; calibration does not need a correct next-token label for this local objective.
When can one weight cover for another?
Suppose two input channels repeatedly take similar values. Increasing one weight and decreasing the other can leave their combined contribution nearly unchanged. If the channels behave differently across inputs, that cancellation becomes less reliable.
For example, consider two activation matrices:
\[X_{\text{similar}} = \begin{bmatrix}1&1\\1&0.9\end{bmatrix}, \qquad X_{\text{separate}} = \begin{bmatrix}1&0\\0&1\end{bmatrix}.\]In the first, the two channels have similar activation patterns across the two samples. In the second, each sample activates only one channel. A change to the second weight cannot repair the first sample in that second case, because its input is zero there.
Figure 2. Calibration determines whether compensation can help. The upper plots show the two channels across the two samples of each activation matrix above; the lower plots show the actual squared reconstruction error over the two weight changes. The dashed vertical line fixes the first weight change at +0.4. With similar channels, moving the second weight by about −0.420 cuts the error from 0.32 to under 0.001; with separately activated channels, its best change is zero and the error stays 0.16.
The matrix that summarizes these relationships is the input Gram matrix, $XX^T$. Its diagonal adds squared activations for each channel; its off-diagonal entries add products between pairs of channels.
This is an uncentred quantity. We do not subtract channel means, and it is not generally a covariance matrix. Two channels can have a large product sum because they stay positive together, even when their fluctuations around their means are uncorrelated. That is relevant because the layer multiplies the actual activations, including their means.
We now have a reason to want a curvature calculation: it tells us which combinations of weight changes preserve these observed outputs.
3. The Hessian Is a Map of Output Damage
Start with one row of weights. Write its change as a column vector $\delta$. The output-error vector is $X^T\delta$, so its squared error is:
\[L_{\text{row}}(\delta) = \|X^T\delta\|_2^2 = \delta^TXX^T\delta = \frac12\delta^TH\delta, \qquad H=2XX^T.\]This is an exact quadratic. Its curvature is the Hessian $H$. We are not approximating the model’s end-to-end training loss with this expression; we are measuring a particular layer’s reconstruction error on particular inputs.
The gradient is zero at the original weights, where reconstruction error is zero. It therefore cannot tell us which forced rounding change is least damaging. The curvature describes how error grows as we move away from that point.
The contours in Figure 2 are a picture of this quadratic. On a tilted ellipse, a vertical slice can reach lower error by moving sideways along the other coordinate. On a circle, once the horizontal displacement is fixed, any extra vertical displacement increases error.
Two useful consequences follow directly from the formula:
- One Hessian serves all output rows. Each row has different weights, but sees the same input matrix $X$.
- Its dimensions count input channels. If $W$ is $d_{out}\times d_{in}$, then $H$ is $d_{in}\times d_{in}$. We do not construct a Hessian indexed by every parameter in the model.
Large diagonal entries mean large damage when a channel’s weight changes alone. They do not tell the whole story once other weights can move. Joint directions can be inexpensive even when both individual directions are expensive. That is why activation magnitude alone cannot specify the compensation.
The Slope and Curvature primer develops the derivative machinery in more detail. The short derivation above is enough to understand the algorithm; the algebra for the constrained update is in the appendix.
4. Round, Freeze, Compensate
We maintain two versions of the weights: the stored, quantized values and a floating-point working copy. At each step:
- Round the current working column onto the chosen grid.
- Freeze those quantized values.
- Adjust only the columns that have not yet been quantized.
An output row is independent of the other output rows in our reconstruction objective. Processing a whole column simply performs the same kind of step for all rows together.
Which inverse does the update use?
Let $F$ be the input columns still free before the current column $q$ is rounded. Define:
\[A=H+\lambda I, \qquad G_F=(A_{FF})^{-1}.\]The damping parameter $\lambda$ is explained below. With zero damping and an invertible remaining Hessian, this is the raw reconstruction problem. With positive damping, the full quadratic also penalizes weight displacement from the original weights:
\[L_{\text{damped}}(\delta) =\|X^T\delta\|_2^2+\frac{\lambda}{2}\|\delta\|_2^2.\]For one row, let the current working weight be $v_q$, its rounded value be $Q(v_q)$, and the rounding residual be:
\[e_q=v_q-Q(v_q).\]The change to each remaining weight is:
\[v_j \leftarrow v_j-e_q\frac{[G_F]_{qj}}{[G_F]_{qq}}, \qquad j\in F,\ j\ne q.\]Read this as rounding residual × an input-dependent compensation ratio. The sign matters. For example, a positive residual and a negative ratio increase the remaining weight.
The matrix is the inverse of the remaining Hessian block. Taking a slice of the original inverse is generally different. Previously frozen columns are no longer available to help, so the next step must reflect their removal. GPTQ’s Cholesky formulation encodes this sequence without repeatedly rebuilding each inverse.
Also distinguish curvature from its inverse. The diagonal $[G_F]_{qq}$ is an inverse effective curvature; its reciprocal measures the minimum quadratic cost of forcing a displacement in this coordinate while the others remain adjustable. Calling both quantities “stiffness” obscures the relationship.
Why add damping?
Calibration may leave some directions poorly determined. Perhaps two channels almost duplicate each other, or a channel rarely activates. Optimizing against that narrow evidence can encourage large weight movements that rely on fragile cancellation.
Adding $\lambda I$ penalizes those movements and improves conditioning. The reference default sets $\lambda$ to 1% of the mean Hessian diagonal. With a positive-semidefinite $H$ and positive $\lambda$, every eigenvalue of $A$ is at least $\lambda$. In floating-point arithmetic we still need to check that factorization succeeds. An all-zero calibration matrix needs explicit handling; its mean diagonal cannot supply positive damping.
Damping changes the objective, not just the implementation. It discourages large adjustments overall, but does not promise that every individual weight update shrinks monotonically as the parameter increases.
The reference GPTQ implementation handles dead channels, adds damping, and uses an upper-triangular Cholesky factor for the sweep. Our example below keeps all channels active and uses factorization-based solves.
5. A Complete Example on the Same 4×4 Weights
We retain the weights from the AWQ article:
\[W=\begin{bmatrix} 0.10&2.50&-0.30&0.05\\ -0.20&3.20&0.15&-0.08\\ 0.40&-2.80&0.25&0.12\\ -0.15&2.10&-0.40&0.06 \end{bmatrix}.\]To isolate compensation, both methods use one fixed grid with spacing 0.5, symmetric integer codes from −7 to 7, and ties rounded to the even integer. Thus the representable weights run from −3.5 to 3.5. These 15 levels fit in four bits, leaving one code unused. This is a deliberately simple teaching quantizer, not a claim about every GPTQ checkpoint format.
We do not recompute the scale after compensation or change granularity between methods. To make the rounding rule explicit, let $z(v)$ be the integer code stored for a working weight $v$. We calculate it in three steps:
- Divide $v$ by the grid spacing, 0.5, to express the weight in grid steps.
- Round that number to the nearest integer, using round-to-even for an exact tie.
- Restrict the result to the available code range from −7 to 7.
In symbols:
\[z(v)=\max\!\left(-7,\min\!\left(7,\operatorname{round}_{\text{even}}(v/0.5)\right)\right).\]The stored code is an integer. Multiplying it by the spacing gives the represented weight used in our matrices:
\[Q(v)=0.5\,z(v).\]For example, $v=3.20$ becomes $3.20/0.5=6.4$, which rounds to code 6 and represents the weight $Q(3.20)=3.0$. Similarly, $v=0.15$ becomes 0.3 grid steps, rounds to code 0, and represents 0. Values outside the grid saturate at an endpoint: $v=4.0$ produces code 7 and represents 3.5. Round-to-even matters only at an exact midpoint; for example, 0.25 becomes code 0, while 0.75 becomes code 2.
Explicit calibration inputs
Here are all eight synthetic calibration vectors, arranged as columns:
\[X=\begin{bmatrix} 0.60&0.60&0.60&0.60&0.40&0.40&0.40&0.40\\ 4.80&4.80&3.20&3.20&4.80&4.80&3.20&3.20\\ 0.36&0.24&0.36&0.24&0.36&0.24&0.36&0.24\\ 0.24&0.16&0.16&0.24&0.16&0.24&0.24&0.16 \end{bmatrix}.\]Their per-channel mean absolute magnitudes are exactly $[0.5,4.0,0.3,0.2]^T$, preserving the earlier article’s magnitudes. Unlike a magnitude vector alone, this matrix also specifies which values occur together. Because all entries are positive, its mean vector equals that magnitude vector.
Direct multiplication gives:
\[H=2XX^T=\begin{bmatrix} 4.16&32&2.4&1.6\\ 32&266.24&19.2&12.8\\ 2.4&19.2&1.4976&0.96\\ 1.6&12.8&0.96&0.6656 \end{bmatrix}.\]The damping value is $\lambda=0.681408$. Every number below comes from these inputs, with full precision retained internally. Displayed intermediate values are rounded only for reading.
Follow output row 1
Using zero-based indexing, row 1 starts as $[-0.20,3.20,0.15,-0.08]$. First, −0.20 rounds to 0, giving a residual of −0.20. The compensation ratios into columns 1, 2, and 3 are approximately −0.107351, −0.118986, and −0.082914. The working row becomes:
\[[0,\ 3.178530,\ 0.126203,\ -0.096583].\]Next, 3.178530 rounds to 3.0. The residual is +0.178530. The remaining problem now supplies different ratios: approximately −6.741632 into column 2 and −4.697844 into column 3. For column 2:
\[v_2 \leftarrow 0.126203-(0.178530)(-6.741632)\approx1.329786.\]This is the step to notice. A weight originally equal to 0.15 moves above 1 because it helps replace output lost when the much louder channel’s weight rounds down. The objective permits that tradeoff; it does not require weights to remain individually close to their starting values.
Figure 3. Each frozen column leaves fewer ways to compensate. We follow output row 1 of the 4×4 example through the actual sweep on the fixed grid (step 0.5, codes −7 to 7, ties to even). Frozen columns stay fixed, and the remaining floats are re-optimized given the whole frozen prefix. In the highlighted step, column 1’s residual +0.178530 raises column 2 from 0.126203 to 1.329786 before it is rounded; the compensation ratios change as fewer columns remain available.
The whole row trace fits in a table:
| Column rounded | Working value before rounding | Stored value | Row after compensation |
|---|---|---|---|
| 0 | −0.200000 | 0.0 | [0, 3.178530, 0.126203, −0.096583] |
| 1 | 3.178530 | 3.0 | [0, 3, 1.329786, 0.742123] |
| 2 | 1.329786 | 1.5 | [0, 3, 1.5, 0.620812] |
| 3 | 0.620812 | 0.5 | [0, 3, 1.5, 0.5] |
At the final column, there is nowhere left to compensate. Its residual contributes to the final error. Earlier compensation reduces damage; it does not make that residual disappear.
The two final matrices
Independent round-to-nearest gives:
\[\hat W_{\text{RTN}}=\begin{bmatrix} 0&2.5&-0.5&0\\ 0&3&0&0\\ 0.5&-3&0&0\\ 0&2&-0.5&0 \end{bmatrix}.\]The sequential GPTQ sweep gives:
\[\hat W_{\text{GPTQ}}=\begin{bmatrix} 0&2.5&0&0\\ 0&3&1.5&0.5\\ 0.5&-3&1.5&1\\ 0&2&0&0.5 \end{bmatrix}.\]Both are entirely on the same grid. Their squared weight errors are 0.3344 for RTN and 5.1144 for GPTQ. Judged as a copy of the original matrix, GPTQ looks substantially worse. Now evaluate the computation those weights perform.
6. Measure the Outputs, Then Test the Limit
For a familiar input, take the calibration mean $\bar x=[0.5,4.0,0.3,0.2]^T$. The original output is the same as in the AWQ example:
\[W\bar x=[9.970,\ 12.729,\ -10.901,\ 8.217]^T.\]The two quantized outputs are:
\[\hat W_{\text{RTN}}\bar x=[9.850,\ 12.000,\ -11.750,\ 7.850]^T,\] \[\hat W_{\text{GPTQ}}\bar x=[10.000,\ 12.550,\ -11.100,\ 8.100]^T.\]Squared output error falls from 1.401331 to 0.086231 for this input. That is useful, but a mean input can conceal errors that vary across samples. Our principal evaluation therefore uses all eight calibration vectors:
| Measurement | RTN | GPTQ |
|---|---|---|
| Total calibration squared output error | 11.682280 | 1.278664 |
| Mean squared output error per calibration vector | 1.460285 | 0.159833 |
| Squared output error at the mean input | 1.401331 | 0.086231 |
| Squared weight error | 0.334400 | 5.114400 |
The mean in the second row divides by eight input vectors, not by 32 output elements. This makes it comparable in units to the squared error on a single input: each value sums error over four output channels.
The reported output errors exclude the damping penalty. Damping guides the weight adjustments, while these measurements ask how closely the resulting layer reproduces its original outputs.
What if the input relationship changes?
Construct a separate stress input:
\[x_{\text{stress}}=[0.5,4.0,-0.3,-0.2]^T.\]The magnitudes are familiar, but the last two channels have reversed signs. Compensation that relied on their positive contributions now works differently. Squared output error is 0.954531 for RTN and 3.484431 for GPTQ.
Figure 4. Compensation depends on the input relationships holding. Compensation helps on these calibration inputs and hurts on a deliberately changed pattern. Both comparisons use the same weights, bit width, scale, and rounding rule, and each value sums squared error over the four output channels. The stress input is a diagnostic construction, not a measured deployment distribution.
This does not establish a general failure rate or a ranking between algorithms. It exposes the dependency we built into the method: the input relationships used to choose compensation need to be informative about the inputs encountered later.
A practical evaluation should include representative held-out inputs and end-to-end quality checks. Good layer reconstruction on calibration samples is evidence about that objective, not a guarantee of unchanged perplexity, reasoning ability, or downstream task performance.
We also should not compare this table numerically with the old AWQ table as an algorithm contest. We retained its starting weights and magnitudes, but chose an explicit calibration set and a different, fixed grid to isolate this mechanism.
7. Reproduce the Numbers Without a Large Model
The complete NumPy example contains the inputs, quantizer, factorization, sweep, and measurements. It runs on a CPU and prints the matrices, row trace, and error totals:
1
python gptq_example.py
NumPy must be installed in the selected Python environment. No model download or GPU is required.
The core loop is short. Here $U$ is upper triangular and satisfies $A^{-1}=U^TU$:
1
2
3
4
5
6
7
working = weights.copy()
result = np.zeros_like(weights)
for q in range(weights.shape[1]):
before = working[:, q].copy()
result[:, q] = quantize(before)
error = (before - result[:, q]) / upper[q, q]
working[:, q:] -= error[:, None] * upper[q, q:]
Each iteration rounds the working column, normalizes its residual, and applies one outer-product update. Including the current column in that update sets its working value to the stored value; later iterations touch only later columns.
The script uses Cholesky factorization and linear solves to construct the needed inverse information. It does not use a generic matrix-inverse call. For this small demonstration it materializes that information so the factor identity can be checked directly.
Verification goes beyond checking the printed answer. After each step, the script independently solves the constrained quadratic with the frozen prefix fixed, and checks that the remaining working weights match its solution. It also verifies that when the input Gram matrix is diagonal, compensation vanishes and the result equals RTN.
Useful experiments are to change the calibration inputs, adjust damping, or alter the fixed grid spacing for both methods. Observe the final output error and the weight movements together. A smaller calibration error accompanied by much larger weight displacement is a reason to inspect held-out behavior, not automatically a reason to prefer the configuration.
This is an educational implementation of the sequential core. It omits checkpoint packing, group-scale selection, activation ordering, and block batching so the arithmetic remains inspectable.
8. How the Same Idea Scales to Large Layers
GPTQ builds on Optimal Brain Quantization, but makes the compensating updates practical at large widths. Its main engineering moves are a shared column order across rows, batched updates to later columns, and a Cholesky formulation of the changing inverse information. The GPTQ paper develops this progression and evaluates it on language models.
Cholesky stores the update schedule
The inverse of the remaining Hessian changes after each column is frozen. Rather than repeatedly forming it, we can obtain the needed compensation ratios from rows of the upper-triangular factor $U$:
\[\frac{[G_F]_{qj}}{[G_F]_{qq}}=\frac{U_{qj}}{U_{qq}}.\]The appendix derives this relationship. In the code, dividing the residual by $U_{qq}$ and multiplying by $U_{qj}$ produces exactly this ratio. $U$ is a triangular factor, not the inverse Hessian itself.
Batching changes when distant updates happen
Within a block, each column must receive earlier compensation before it is rounded. Columns beyond that block can wait: none of their rounding decisions has happened yet. We accumulate the block’s residuals, then apply its effect to the distant columns with a matrix multiplication.
The benefit is better use of memory bandwidth and GPU matrix operations. The dependencies inside the block still exist. Processing block size and quantization group size are separate controls: the former schedules updates; the latter determines which weights share quantization parameters.
Ordering is a choice, not a free accuracy guarantee
Our example uses columns 0, 1, 2, 3. Activation ordering instead prioritizes larger Hessian diagonals. That gives sensitive channels more remaining weights to use for compensation, but quality and implementation tradeoffs depend on the model and configuration.
It does not universally require permuting input activations at inference. The reference code restores quantized columns to their original order; group metadata and the serving format determine any remaining layout requirements. Avoid treating an offline processing order as an unavoidable runtime operation.
The costs are also worth separating. Building $H$ costs $O(nd_{in}^2)$ for $n$ calibration vectors. Factorization costs $O(d_{in}^3)$, and the all-row sweep costs $O(d_{out}d_{in}^2)$. Thus the full accounting includes calibration:
\[O\!\left(nd_{in}^2+d_{in}^3+d_{out}d_{in}^2\right).\]The square Hessian is still a substantial offline memory cost. Shared computation makes it manageable in cases where a separate optimization schedule for every weight would be impractical; it does not make that cost disappear.
9. What GPTQ Does and Does Not Promise
There are three distinct decisions in a deployment: how to choose quantized weights, how to store them, and which kernel executes the layer. Compensation belongs to the first decision. It runs during quantization, not anew for every generated token.
For weight-only four-bit deployment with higher-precision activations, serving kernels consume packed weights and quantization parameters. A suitable kernel can dequantize tiles as needed rather than materialize the entire full-precision matrix. Actual latency depends on the format, hardware, shapes, and kernel support; the optimization method’s name alone does not determine it.
The comparison with AWQ is consequently narrower than “which is always better?”:
| Question | AWQ | GPTQ |
|---|---|---|
| Main quality mechanism | Activation-informed channel scaling before quantization | Sequential rounding with compensation into remaining weights |
| Information guiding that mechanism | Activation statistics and evaluation of candidate scales | Input Gram matrix and the remaining quadratic problem |
| Role of calibration | Find useful scaling choices | Estimate useful compensation relationships |
| What to measure in deployment | Quality, memory, and latency under the chosen format and kernel | The same measurements under comparable conditions |
The AWQ paper describes evaluating scaling choices; it should not be reduced to “only collect activation averages.” Neither method has a universal accuracy advantage. Compare them with matched constraints and representative evaluation rather than mixing scale granularity, calibration, and kernels into one headline result.
For GPTQ itself, the continuous compensation subproblem is exact for the stated quadratic and fixed rounding decision, assuming the needed positive-definite system and exact arithmetic. With damping, that statement applies to the regularized objective. It does not mean the final discrete matrix is globally optimal.
The algorithm commits to rounding decisions in an order, uses finite calibration data, and optimizes a local proxy. Once a column is frozen, it cannot be revisited by later compensation. Layerwise processing also does not jointly optimize all layers, although calibration inputs for later blocks can reflect earlier quantization errors.
The useful lesson is concrete: preserving each weight independently can be the wrong objective. GPTQ uses relationships between input channels to choose a better collection of rounded weights for the observed computation. Our example makes both sides visible: larger weight changes, smaller calibration output error, and a failure when the assumed input relationship changes.
The next article turns to LoRA, QLoRA, and LoftQ, where low-rank adaptation and quantization meet. The distinction developed here remains useful: compressing a trained computation and adapting that computation are related operations with different objectives.
Appendix: The Update and the Cholesky Identity
This appendix supplies the algebra behind the sweep. It is optional for following the worked example.
A. Derive the compensating step
At the current step, assume the remaining working weights minimize the damped quadratic subject to the already frozen prefix. Let $d$ be an additional change restricted to the free coordinates $F$. The first-order term on those coordinates is zero, leaving incremental cost:
\[\frac12d^TA_{FF}d.\]Quantization forces $d_q=c=Q(v_q)-v_q$. With $b_q$ the basis vector selecting coordinate $q$, use a Lagrange multiplier $\nu$:
\[\mathcal{J}(d,\nu)=\frac12d^TA_{FF}d+\nu(b_q^Td-c).\]Stationarity gives $A_{FF}d+\nu b_q=0$. Writing $G_F=(A_{FF})^{-1}$, substitute $d=-\nu G_Fb_q$ into the constraint:
\[-\nu[G_F]_{qq}=c, \qquad d_j=c\frac{[G_F]_{jq}}{[G_F]_{qq}}.\]Since $c=-e_q$ and $G_F$ is symmetric, this is the update in §4. The minimum incremental quadratic cost is:
\[\frac{c^2}{2[G_F]_{qq}}.\]This also explains why the reciprocal inverse diagonal is the effective curvature. Repeating the constrained minimization preserves the premise for the next step: the remaining float weights are optimal given the newly frozen prefix. The rounding choice itself is still a greedy commitment, not a search over all possible final matrices.
B. Why a triangular factor replaces repeated elimination
For a two-coordinate remaining problem, write:
\[G_F=\begin{bmatrix}a&b\\b&c\end{bmatrix}, \qquad U=\begin{bmatrix}\sqrt a&b/\sqrt a\\0&\sqrt{c-b^2/a}\end{bmatrix}, \qquad G_F=U^TU.\]The ratio used for the first compensation is:
\[\frac{U_{01}}{U_{00}}=\frac{b}{a}.\]After fixing the first coordinate, the remaining inverse is $c-b^2/a$, which is precisely $U_{11}^2$. It is not simply the old inverse entry $c$.
In higher dimensions, removing coordinate $q$ from the free set gives, with $R$ denoting the other free coordinates:
\[G_R=(G_F)_{RR} -\frac{(G_F)_{Rq}(G_F)_{qR}}{(G_F)_{qq}}.\]Successive Cholesky rows encode these eliminations. Thus one factor supplies the changing ratios required by the whole fixed-order sweep. This is why reusing successive rows of the original inverse would produce a different algorithm.
C. Notation at a glance
| Symbol | Meaning |
|---|---|
| $W$, $\hat W$ | Original and quantized weights; shape $d_{out}\times d_{in}$ |
| $X$ | Calibration inputs; shape $d_{in}\times n$ |
| $H=2XX^T$ | Hessian of one row’s reconstruction loss |
| $A=H+\lambda I$ | Hessian after damping |
| $F$, $R$ | Free coordinates before and after freezing the current one |
| $G_F=(A_{FF})^{-1}$ | Inverse for the current free problem |
| $U$ | Upper-triangular factor satisfying $A^{-1}=U^TU$ |
| $v_q$, $Q(v_q)$ | Current float value and its grid value |
| $e_q=v_q-Q(v_q)$ | Rounding residual |
| $\Delta$ | Fixed grid spacing; 0.5 in the 4×4 example |