[GH-ISSUE #8004] QwQ 32B Preview: Q4_K_M better than Q8_0 at coding #5121

Closed
opened 2026-04-12 16:13:02 -05:00 by GiteaMirror · 22 comments
Owner

Originally created by @leikareipa on GitHub (Dec 9, 2024).
Original GitHub issue: https://github.com/ollama/ollama/issues/8004

What is the issue?

It seems the Q4 version of QwQ Preview may consistently produce better coding responses than the Q8 version, even though I'd expect the opposite.

Both versions were downloaded via Ollama and tested varyingly with Ollama 0.5.1 and I think 0.4.7, can't remember at what point I updated. Context length is 8k-32k depending on the task, but I believe always more than the total number of input + output tokens. Otherwise default settings.

In my private 5-test coding/software development benchmark including JavaScript, C++ and assembly, Q4_K_M scores 70% and Q8_0 scores 50%. For reference, Bartowski's GGUFs score 60% for Q5_K_M, 40% for Q3_K_M and 10% for Q2_K. But each test is run only once per model, so there's room for noise in the results.

In other tests, Q4 still appears to produce better responses. For the prompt Write a program using QBasic that draws a natural-looking lightning bolt. Q4 gives code that works, albeit only partly looks like a lightning bolt, while Q8's code has various syntax errors. For a prompt asking the model to read ~10k tokens of a JavaScript 3D software renderer's reference manual and then write a fisheye pixel shader, Q4's code does it while Q8's code produces a broken effect.

These aren't average-over-x-runs results since even one run takes a while to finish on CPU, but on the whole it appears Q4 may well produce better solutions than Q8. I don't have any meaningful results for the FP16 version at this point, takes long to run.

The Q4_K_M I'm using has the ID hash 1211a3265dc8, and the Q8_0 9c62a2e770b7. This isn't the same Q4_K_M that's on Ollama right now, the model was updated on there about a day after I got it. But if the new version performs worse then that's a problem as well.

OS

Linux

GPU

Nvidia

CPU

AMD

Ollama version

0.5.1

Originally created by @leikareipa on GitHub (Dec 9, 2024). Original GitHub issue: https://github.com/ollama/ollama/issues/8004 ### What is the issue? It seems the Q4 version of QwQ Preview may consistently produce better coding responses than the Q8 version, even though I'd expect the opposite. Both versions were downloaded via Ollama and tested varyingly with Ollama 0.5.1 and I think 0.4.7, can't remember at what point I updated. Context length is 8k-32k depending on the task, but I believe always more than the total number of input + output tokens. Otherwise default settings. In my private 5-test coding/software development benchmark including JavaScript, C++ and assembly, Q4_K_M scores 70% and Q8_0 scores 50%. For reference, Bartowski's GGUFs score 60% for Q5_K_M, 40% for Q3_K_M and 10% for Q2_K. But each test is run only once per model, so there's room for noise in the results. In other tests, Q4 still appears to produce better responses. For the prompt `Write a program using QBasic that draws a natural-looking lightning bolt.` Q4 gives code that works, albeit only partly looks like a lightning bolt, while Q8's code has various syntax errors. For a prompt asking the model to read ~10k tokens of a JavaScript 3D software renderer's reference manual and then write a fisheye pixel shader, Q4's code does it while Q8's code produces a broken effect. These aren't average-over-x-runs results since even one run takes a while to finish on CPU, but on the whole it appears Q4 may well produce better solutions than Q8. I don't have any meaningful results for the FP16 version at this point, takes long to run. The Q4_K_M I'm using has the ID hash 1211a3265dc8, and the Q8_0 9c62a2e770b7. This isn't the same Q4_K_M that's on Ollama right now, the model was updated on there about a day after I got it. But if the new version performs worse then that's a problem as well. ### OS Linux ### GPU Nvidia ### CPU AMD ### Ollama version 0.5.1
GiteaMirror added the bug label 2026-04-12 16:13:02 -05:00
Author
Owner

@frenzybiscuit commented on GitHub (Dec 10, 2024):

how much free vram do you have when running the q8 version?

I am assuming you are using the same context size for both of them?

<!-- gh-comment-id:2530087133 --> @frenzybiscuit commented on GitHub (Dec 10, 2024): how much free vram do you have when running the q8 version? I am assuming you are using the same context size for both of them?
Author
Owner

@leikareipa commented on GitHub (Dec 10, 2024):

This is with 12 GB of VRAM total so all versions max it out, the bigger the model the more of it is CPU side. Should be the same context size.

<!-- gh-comment-id:2530491141 --> @leikareipa commented on GitHub (Dec 10, 2024): This is with 12 GB of VRAM total so all versions max it out, the bigger the model the more of it is CPU side. Should be the same context size.
Author
Owner

@frenzybiscuit commented on GitHub (Dec 10, 2024):

Are you using flash attention or quant k,v cache?

<!-- gh-comment-id:2531558583 --> @frenzybiscuit commented on GitHub (Dec 10, 2024): Are you using flash attention or quant k,v cache?
Author
Owner

@leikareipa commented on GitHub (Dec 10, 2024):

No flash attention and no KV cache quantization, all settings but context length should be default.

I ran my five-test bench on Ollama's FP16 version and it got 50%, same as the Q8. Less than the Q5_K_M at 60% and the Q4_K_M at 70%, though this is now using Ollama 0.5.1 rather than the older one. Looks less likely to be within margin of error now, but like I say it takes overnight per prompt on CPU so repeat tests can be done by someone with faster hardware.

<!-- gh-comment-id:2532400657 --> @leikareipa commented on GitHub (Dec 10, 2024): No flash attention and no KV cache quantization, all settings but context length should be default. I ran my five-test bench on Ollama's FP16 version and it got 50%, same as the Q8. Less than the Q5_K_M at 60% and the Q4_K_M at 70%, though this is now using Ollama 0.5.1 rather than the older one. Looks less likely to be within margin of error now, but like I say it takes overnight per prompt on CPU so repeat tests can be done by someone with faster hardware.
Author
Owner

@frenzybiscuit commented on GitHub (Dec 10, 2024):

I ran into a similar problem where the Q6 32b coder model for Qwen 2.5 was failing at a basic task but the Q8 14b version got it right.

I had to restart the model several times in Ollama before it finally started to work correctly.

What I noticed is that sometimes the VRAM was near full on restart and sometimes it was not. I have multiple GPU's and Ollama is preferring the one with the most VRAM and not splitting them correctly.

The one time it worked the VRAM was split correctly.

So my assumption is you may be using too much VRAM on the GPU. Try reducing the GPU layers and see if that makes a difference.

Edit: And yeah I know you're splitting the setup onto the CPU as well. Just try reducing the GPU layers (humor me) and see if it fixes it.

<!-- gh-comment-id:2532805035 --> @frenzybiscuit commented on GitHub (Dec 10, 2024): I ran into a similar problem where the Q6 32b coder model for Qwen 2.5 was failing at a basic task but the Q8 14b version got it right. I had to restart the model several times in Ollama before it finally started to work correctly. What I noticed is that sometimes the VRAM was near full on restart and sometimes it was not. I have multiple GPU's and Ollama is preferring the one with the most VRAM and not splitting them correctly. The one time it worked the VRAM was split correctly. So my assumption is you may be using too much VRAM on the GPU. Try reducing the GPU layers and see if that makes a difference. Edit: And yeah I know you're splitting the setup onto the CPU as well. Just try reducing the GPU layers (humor me) and see if it fixes it.
Author
Owner

@leikareipa commented on GitHub (Dec 11, 2024):

Thanks for the idea, I'll see if someone beats me to testing it since it would be even slower. I assume you could just disable GPU compute altogether with CUDA_VISIBLE_DEVICES=-1?

With GPU + CPU I did some repeat tests on the simple prompt Write a QBasic program that uses a function to print "Hello world" one character at a time. The number of working solutions out of all attempts by QwQ (default temperature etc.):

Q2 Q4 Q8
0/4 5/12 4/12

So Q4 was more reliable than Q8, short of being conclusive. The prompt may be too simple or obscure etc. anyway, but not enough compute to experiment and run a hundred iterations of something. My general superficial impression is the Q8 feels like a smaller model vs. the Q4, or that it's tripping over its laces trying to be fancier than a 32 b model can.

<!-- gh-comment-id:2536902052 --> @leikareipa commented on GitHub (Dec 11, 2024): Thanks for the idea, I'll see if someone beats me to testing it since it would be even slower. I assume you could just disable GPU compute altogether with `CUDA_VISIBLE_DEVICES=-1`? With GPU + CPU I did some repeat tests on the simple prompt `Write a QBasic program that uses a function to print "Hello world" one character at a time.` The number of working solutions out of all attempts by QwQ (default temperature etc.): | Q2 | Q4 | Q8 | | --- | ---- | ---- | | 0/4 | 5/12 | 4/12 | So Q4 was more reliable than Q8, short of being conclusive. The prompt may be too simple or obscure etc. anyway, but not enough compute to experiment and run a hundred iterations of something. My general superficial impression is the Q8 feels like a smaller model vs. the Q4, or that it's tripping over its laces trying to be fancier than a 32 b model can.
Author
Owner

@leikareipa commented on GitHub (Dec 14, 2024):

Did another test with Q4 vs Q8, and now also vs Q8 without GPU. The prompt (backticks escaped for formatting reasons here but not in the original):

\`\`\`js
// Pixel shader: Applies a vignette effect to the pixel buffer.
function ps_vignette(renderContext)
{
    const {width, height, data:pixels} = renderContext.pixelBuffer;
    const centerX = (width / 2);
    const centerY = (height / 2);
    const radius = Math.max(centerX, centerY);
    const intensity = 1.0;

    for (let y = 0; y < height; y++)
    {
        for (let x = 0; x < width; x++)
        {
            const dx = x - centerX;
            const dy = y - centerY;
            const distanceSquared = (dx * dx) + (dy * dy);
            const vignette = Math.max(0, 1 - (distanceSquared / (radius * radius)));

            const i = (x + y * width) * 4;
            pixels[i + 0] *= (1 - intensity + (vignette * intensity));
            pixels[i + 1] *= (1 - intensity + (vignette * intensity));
            pixels[i + 2] *= (1 - intensity + (vignette * intensity));
        }
    }
}
\`\`\`

Above is a sample pixel shader for a JavaScript 3D software renderer. Write a pixel shader that applies a fisheye effect.

Eight runs of it both for Q4 and Q8 and four for Q8 without GPU, 8k context length in all runs.

Q4 was again better than Q8, and Q8 on CPU made no clear difference. I've scored them based on how well they did on average:

Q4 Q8 Q8 no GPU
31% 9% 13%

The model in general does this task better when given the renderer's entire reference manual as context, but in any case, out of all runs, Q4 managed one good solution and three meh ones, while Q8 was able to generate one meh solution and one sub-meh - in terms of how good of a fisheye effect the code produced.

<!-- gh-comment-id:2542938631 --> @leikareipa commented on GitHub (Dec 14, 2024): Did another test with Q4 vs Q8, and now also vs Q8 without GPU. The prompt (backticks escaped for formatting reasons here but not in the original): ``` \`\`\`js // Pixel shader: Applies a vignette effect to the pixel buffer. function ps_vignette(renderContext) { const {width, height, data:pixels} = renderContext.pixelBuffer; const centerX = (width / 2); const centerY = (height / 2); const radius = Math.max(centerX, centerY); const intensity = 1.0; for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { const dx = x - centerX; const dy = y - centerY; const distanceSquared = (dx * dx) + (dy * dy); const vignette = Math.max(0, 1 - (distanceSquared / (radius * radius))); const i = (x + y * width) * 4; pixels[i + 0] *= (1 - intensity + (vignette * intensity)); pixels[i + 1] *= (1 - intensity + (vignette * intensity)); pixels[i + 2] *= (1 - intensity + (vignette * intensity)); } } } \`\`\` Above is a sample pixel shader for a JavaScript 3D software renderer. Write a pixel shader that applies a fisheye effect. ``` Eight runs of it both for Q4 and Q8 and four for Q8 without GPU, 8k context length in all runs. Q4 was again better than Q8, and Q8 on CPU made no clear difference. I've scored them based on how well they did on average: | Q4 | Q8 | Q8 no GPU | | --- | -- | --------- | | 31% | 9% | 13% | The model in general does this task better when given the renderer's entire reference manual as context, but in any case, out of all runs, Q4 managed one good solution and three meh ones, while Q8 was able to generate one meh solution and one sub-meh - in terms of how good of a fisheye effect the code produced.
Author
Owner

@frenzybiscuit commented on GitHub (Dec 14, 2024):

Are your models from the same provider or are they from different providers?

It's not uncommon for lower quant models to perform better then the actual unquant fp16 model. IIRC this has been documented in the past.

<!-- gh-comment-id:2543197531 --> @frenzybiscuit commented on GitHub (Dec 14, 2024): Are your models from the same provider or are they from different providers? It's not uncommon for lower quant models to perform better then the actual unquant fp16 model. IIRC this has been documented in the past.
Author
Owner

@leikareipa commented on GitHub (Dec 14, 2024):

Q4, Q8 and FP16 pulled via Ollama, but the weights on Ollama were updated about a day after release, the Q4 I have is pre-update.

I think somebody found Qwen 2.5 doing slightly better in Q4 than Q8 in some areas, but I believe that was like single digit % better. Here the figure is 30-300% depending on the task, doesn't seem right. Of course since you're modifying the weights you might get a lucky roll, but I'm not aware of any model that's on another level in Q4 compared to Q8 or FP16.

<!-- gh-comment-id:2543235975 --> @leikareipa commented on GitHub (Dec 14, 2024): Q4, Q8 and FP16 pulled via Ollama, but the weights on Ollama were updated about a day after release, the Q4 I have is pre-update. I think somebody found Qwen 2.5 doing slightly better in Q4 than Q8 in some areas, but I believe that was like single digit % better. Here the figure is 30-300% depending on the task, doesn't seem right. Of course since you're modifying the weights you might get a lucky roll, but I'm not aware of any model that's on another level in Q4 compared to Q8 or FP16.
Author
Owner

@frenzybiscuit commented on GitHub (Dec 14, 2024):

yeah if you're going to do comparisions do so with weights from the same update.

And yes, it's been documented before that Q4 can perform better then FP16. I was just reading about this a few hours ago. It's rare, but it does happen.

<!-- gh-comment-id:2543257353 --> @frenzybiscuit commented on GitHub (Dec 14, 2024): yeah if you're going to do comparisions do so with weights from the same update. And yes, it's been documented before that Q4 can perform better then FP16. I was just reading about this a few hours ago. It's rare, but it does happen.
Author
Owner

@leikareipa commented on GitHub (Dec 14, 2024):

If the post-update weights perform worse than the pre-update weights then wouldn't you say it's a problem all the same. But would be interesting to see what results others are getting.

<!-- gh-comment-id:2543307637 --> @leikareipa commented on GitHub (Dec 14, 2024): If the post-update weights perform worse than the pre-update weights then wouldn't you say it's a problem all the same. But would be interesting to see what results others are getting.
Author
Owner

@frenzybiscuit commented on GitHub (Dec 14, 2024):

If the post-update weights perform worse than the pre-update weights then wouldn't you say it's a problem all the same. But would be interesting to see what results others are getting.

A problem the developer would have to address, yes.

Not a problem with ollama specifically...

<!-- gh-comment-id:2543311170 --> @frenzybiscuit commented on GitHub (Dec 14, 2024): > If the post-update weights perform worse than the pre-update weights then wouldn't you say it's a problem all the same. But would be interesting to see what results others are getting. A problem the developer would have to address, yes. Not a problem with ollama specifically...
Author
Owner

@leikareipa commented on GitHub (Dec 14, 2024):

Not sure it's useful to get meta about who's to blame, this is 100% usage within Ollama and the issue seemingly hasn't been reported outside of Ollama so for now this seems reasonable.

Although who's the source of these particular quants? I was under the impression Alibaba only provided the FP16.

<!-- gh-comment-id:2543325630 --> @leikareipa commented on GitHub (Dec 14, 2024): Not sure it's useful to get meta about who's to blame, this is 100% usage within Ollama and the issue seemingly hasn't been reported outside of Ollama so for now this seems reasonable. Although who's the source of these particular quants? I was under the impression Alibaba only provided the FP16.
Author
Owner

@leikareipa commented on GitHub (Dec 14, 2024):

Adding results from Hugging Face Playground (should be the full BF16) for the fisheye prompt:

Q4 Q8 Q8 no GPU HF Playground
31% 9% 13% 31%

So something looks off with the Q8 (and FP16) on Ollama. On HF I set the temperature as 0.8 and top-p as 0.9, which should match the Ollama defaults. 8k context.

<!-- gh-comment-id:2543375934 --> @leikareipa commented on GitHub (Dec 14, 2024): Adding results from Hugging Face Playground (should be the full BF16) for the fisheye prompt: | Q4 | Q8 | Q8 no GPU | HF Playground | | --- | -- | --------- | ------------- | | 31% | 9% | 13% | 31% | So something looks off with the Q8 (and FP16) on Ollama. On HF I set the temperature as 0.8 and top-p as 0.9, which should match the Ollama defaults. 8k context.
Author
Owner

@frenzybiscuit commented on GitHub (Dec 15, 2024):

I'm going to sound like a broken record but this isn't the first time I've observed a Q4 model perform better then the Q8.

Basically quants are labotomized models and you can never be sure what part of the brain you're chopping off.

But if its performing better then FP16 something is up, I suppose.

You're -sure- these are the same version? Just because something is uploaded at the same time doesn't mean it's the same version. Maybe the uploader mixed up the Q4 model with an older version.

<!-- gh-comment-id:2543387015 --> @frenzybiscuit commented on GitHub (Dec 15, 2024): I'm going to sound like a broken record but this isn't the first time I've observed a Q4 model perform better then the Q8. Basically quants are labotomized models and you can never be sure what part of the brain you're chopping off. But if its performing better then FP16 something is up, I suppose. You're -sure- these are the same version? Just because something is uploaded at the same time doesn't mean it's the same version. Maybe the uploader mixed up the Q4 model with an older version.
Author
Owner

@leikareipa commented on GitHub (Dec 15, 2024):

The issue isn't whether there's some difference but that it appears to be categorical and fairly large, to the point of looking like a problem. It may also extend beyond coding but that's just what I happen to be testing with. I remember on YouTube Digital Spaceport tested the Q8 in Ollama and wasn't too impressed.

<!-- gh-comment-id:2543420974 --> @leikareipa commented on GitHub (Dec 15, 2024): The issue isn't whether there's some difference but that it appears to be categorical and fairly large, to the point of looking like a problem. It may also extend beyond coding but that's just what I happen to be testing with. I remember on YouTube Digital Spaceport tested the Q8 in Ollama and wasn't too impressed.
Author
Owner

@frenzybiscuit commented on GitHub (Dec 15, 2024):

Can u answer the question.

Are you certain the Q4 is from the same model/version/revision as the Q8?

thx

<!-- gh-comment-id:2543421455 --> @frenzybiscuit commented on GitHub (Dec 15, 2024): Can u answer the question. Are you certain the Q4 is from the same model/version/revision as the Q8? thx
Author
Owner

@leikareipa commented on GitHub (Dec 15, 2024):

I'm certain it's QwQ and there's only one revision of it on their Hugging Face. They did update their chat template the next day though, which my Q4 could have the older version of. But assuming Hugging Face's Playground has the updated template, which my Q8/FP16 also would have, then that's seemingly not the issue. But I encourage you to run tests with the Q4 using the old template vs the new one and see if you get a difference. It's hard to parse by eye but the old template was missing the 'you're harmless' directive in some circumstances that the new template added.

<!-- gh-comment-id:2543439989 --> @leikareipa commented on GitHub (Dec 15, 2024): I'm certain it's QwQ and there's only one revision of it on their Hugging Face. They did update their chat template the next day though, which my Q4 could have the older version of. But assuming Hugging Face's Playground has the updated template, which my Q8/FP16 also would have, then that's seemingly not the issue. But I encourage you to run tests with the Q4 using the old template vs the new one and see if you get a difference. It's hard to parse by eye but the old template was missing the 'you're harmless' directive in some circumstances that the new template added.
Author
Owner

@leikareipa commented on GitHub (Dec 17, 2024):

Writeup/condensement of the results, and some extra data: https://leikareipa.github.io/blog/comparing-quants-of-qwq-preview-in-ollama/

<!-- gh-comment-id:2547524161 --> @leikareipa commented on GitHub (Dec 17, 2024): Writeup/condensement of the results, and some extra data: https://leikareipa.github.io/blog/comparing-quants-of-qwq-preview-in-ollama/
Author
Owner

@jmorganca commented on GitHub (Dec 29, 2024):

Thanks for the issue @leikareipa! Different quants will behave differently. However, in this case fp16 should outperform others as this is closest to the data type the model was trained in. In this case it could be context size so definitely check that as well (i.e. the num_ctx parameter).

<!-- gh-comment-id:2564827456 --> @jmorganca commented on GitHub (Dec 29, 2024): Thanks for the issue @leikareipa! Different quants will behave differently. However, in this case fp16 should outperform others as this is closest to the data type the model was trained in. In this case it could be context size so definitely check that as well (i.e. the `num_ctx` parameter).
Author
Owner

@leikareipa commented on GitHub (Dec 29, 2024):

Odd that this was closed without testing, since as you say the behavior looks unusual.

<!-- gh-comment-id:2564834167 --> @leikareipa commented on GitHub (Dec 29, 2024): Odd that this was closed without testing, since as you say the behavior looks unusual.
Author
Owner

@akierum commented on GitHub (Apr 25, 2025):

Is this resolved yet?

<!-- gh-comment-id:2831113414 --> @akierum commented on GitHub (Apr 25, 2025): Is this resolved yet?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/ollama#5121