This is a whole can of worms! Moving this discussi...
# ml-and-mlops-questions
b
This is a whole can of worms! Moving this discussion over to the #C06CR7K94KB channel to talk about it more
This is a great point, and overall agree. > But the problem is with complete vibe coded apps IMO, for throwaway code, i.e. code that’s not in the critical path of a project, e.g. html slidedecks, prototypes, and proof of concepts, I personally don’t read the code… it’s enough for me to just look at the output and probe it to see if the behavior is what I want. For code in the critical path, reading/reviewing is still important. As an open source maintainer, most of my time is spent reading other people’s code anyway… the sad part is that I’m writing less and less code myself and feel like I’m losing that skill. I know folks who do Leetcode exercises just to keep those skills alive. > At least back in the days when we used stackoverflow and copy pasted the code in it, we put in some effort to understand it as it was only a snippet and not end to end module. Good point… but I’m pretty sure there were SO memes out there back in the day of devs who just copy-pasta’d the code into their codebase without actually understanding it.
👍 1
a
Question (Related to Q4_0 quantization in llama.cpp) =====================================================
Copy code
How is the scale same. The scale and alpha/beta shouls change based on statergy (Min_Max,Percentile,MSE)
Answer (From Sammy’s frontier model) =============================================
Copy code
This is the subtle part. There are two different concepts of "strategy" that are easy to conflate.

Your code allows different strategies:

MinMax
Percentile
MSE
CrossEntropy

These strategies determine how you choose the quantization range (alpha, beta), and therefore the scale.

However, GGML Q4_0 does not use those strategies.

In your getAlphaBeta() you have:

if dtype == "I4" && quantExportFormat == types.GGUF {
    absMax := 0.0
    extreme := 0.0
    for _, w := range modelWeight {
        x := float64(w)
        ax := math.Abs(x)
        if ax > absMax {
            absMax = ax
            extreme = x
        }
    }
    return extreme, extreme
}

Notice what this does.

For GGUF Q4_0, you completely bypass:

* MinMax
* Percentile
* MSE

Every one of them.

You always return

alpha = extreme
beta  = extreme

So for your implementation, the scale is independent of the strategy.

⸻

Why does llama.cpp produce the same scale?

Because Q4_0 is defined as a symmetric, one-scale-per-32-values quantizer.

The block contains only

FP16 scale
16 packed bytes

There is no metadata to store:

* percentile
* clipping threshold
* optimized alpha
* optimized beta

So the scale is fundamentally constrained.

⸻

The optimization happens elsewhere

Suppose the block is

[-0.003
 0.008
 0.010
 ...
 0.041]

The scale becomes approximately

0.041 / -8

That stays fixed.

Now there are many possible integer vectors

[-2,-2,-1,...]
[-2,-1,-2,...]
[-1,-2,-2,...]
...

whose reconstructed values are all near the originals.

The optimizer searches among these integer assignments to reduce the total block error.

It doesn't necessarily change the scale.

⸻

If you changed the strategy…

Suppose you forced

Percentile 99%

Then you might choose

alpha = -0.032
beta  = 0.033

instead of

±0.041

Now the scale becomes

0.033 / -8

which is completely different.

But then you are no longer producing GGML Q4_0.

You are producing your own quantizer that happens to use the same storage layout.

⸻

In other words

There are two separate optimization problems:

1. Range selection

Choose

alpha
beta

Examples:

* MinMax
* Percentile
* MSE

This changes the scale.

⸻

2. Integer assignment

Given a fixed scale, choose

q0...q31

to minimize

Σ(original_i - q_i * scale)²

This changes the quantized values, but the scale can remain unchanged.

⸻

So when I said "the scale is the same," I meant:

For llama.cpp's Q4_0 implementation, the optimizer is not optimizing the range (alpha/beta); it is optimizing the integer assignments for a scale derived from the block's extreme value.

If your objective is to reproduce llama.cpp byte-for-byte, then your getAlphaBeta() for GGUF Q4_0 is already following the correct idea (choose the extreme value). The remaining difference lies in how the 32 quantized integers are chosen after the scale has been fixed.
WHAT???
Copy code
`For llama.cpp's Q4_0 implementation, the optimizer is not optimizing the range (alpha/beta); it is optimizing the integer assignments for a scale derived from the block's extreme value.
If let it run wild on my codebase, i will have to start taking pills. ======================== People wondering what the real answer is: ======================= Lamma.cpp Q4_0 packs the bits as below: [q0q16] [q1q17] [q2q18] …. where q0,q1,q2…q31 are quantized weights for block size=32. How did i find it , i went to llama.cpp repo and read the ggml/quantize.c file!!! There is no optimization or anything of that sort as suggested by the model. And people who have even used any form of optimization on quantization can tell by the speed with which the quantization happens. And moreover the MSE optimization that the
model
is suggesting is wrong, as the scale has to change (because alpha/beta will change) based on MSE error calculation. My point: READ THE CODE!!! IT WILL NEVER LIE
ack 1
b
Yeah… LLM reasoning traces/outputs can be pretty ridiculous 😂
f
haha, @acceptable-knife-37130 - i guess you dont like LLMS haha.
a
I know
rants
are funny when someone else does it. I enjoy it too, only when i am not affected or involved