Skip to content

Force NVFP4 W4A8 path for NVFP4_W4A16 layers on Blackwell, where NVFP4 normally uses the native W4A4 path. - #24364

Draft
ynankani wants to merge 8 commits into
ggml-org:masterfrom
ynankani:ynankani/Force_W4A16_NVFP4_to_W4A8
Draft

Force NVFP4 W4A8 path for NVFP4_W4A16 layers on Blackwell, where NVFP4 normally uses the native W4A4 path. #24364
ynankani wants to merge 8 commits into
ggml-org:masterfrom
ynankani:ynankani/Force_W4A16_NVFP4_to_W4A8

Conversation

@ynankani

@ynankani ynankani commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR adds support to force W4A8 path for W4A16_NVFP4 HF model layers on Blackwell, where NVFP4 normally uses the native W4A4 path.
This PR includes the below:

  1. Adds a GGUF metadata for storing NVFP4_W4A16 layers, output weight.
  2. Loads the NVFP4_W4A16 layer metadata in model hparams .
  3. Use the metadata to set the new GGML_HINT_NO_QUANT_SRC1 hint for NVFP4_W4A16 layers
  4. On Blackwell GPU, dispatch the hinted layers through W4A8 path instead of native W4A4 path
  5. Allow the new hint for the MoE layer mul_mat_id as well
  6. Test case for mul_mat for dense and mul_mat_id MoE models

Additional information

Observed a quality improvement for W4A8 compared to W4A4 and are able to meet stricter quality threshold of the test_mul_mat cases used by ggml.
Also it is mentioned that "W4A4 sometimes difficult to achieve for small LLMs" in this paper URL
Tested on : nvidia/Qwen3.6-35B-A3B-NVFP4

Force W4A8 for W4A16_NVFP4 layers:

Model Size Params Backend ngl Test t/s
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 pp512 4492.20 +/- 25.66
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 pp1024 4689.26 +/- 47.87
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 pp2048 4822.40 +/- 75.42
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 tg128 148.25 +/- 1.42
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 tg256 164.13 +/- 6.55

Master Baseline:

Model Size Params Backend ngl Test t/s
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 pp512 5486.02 +/- 253.52
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 pp1024 5445.48 +/- 211.56
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 pp2048 5865.13 +/- 171.27
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 tg128 155.60 +/- 6.73
qwen35moe 35B.A3B NVFP4 21.09 GiB 35.51 B CUDA 99 tg256 165.52 +/- 6.55

Perplexity Improvement:

Config Command PPL
Force W4A8 for W4A16_NVFP4 layers llama-perplexity -c 2048 -b 2048 -ngl 99 6.0264 +/- 0.03777
Master baseline llama-perplexity -c 2048 -b 2048 -ngl 99 6.1234 +/- 0.03851

Requirements

@ynankani
ynankani requested review from a team, CISC and ggerganov as code owners June 9, 2026 14:32
@github-actions github-actions Bot added testing Everything test related Nvidia GPU Issues specific to Nvidia GPUs python python script changes ggml changes relating to the ggml tensor library for machine learning labels Jun 9, 2026
Comment thread ggml/src/ggml-cuda/mmq.cu Outdated
mul_mat_q_case<GGML_TYPE_NVFP4, true>(ctx, args, stream);
break;
}
#endif // GGML_CUDA_HAS_BLACKWELL_TARGET

@sanmai sanmai Jun 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we opt out from this? A drop from 5486.02 to 4492.20 is very severe.

If you want a higher precision, there's a variety of Q4 quants that are just as small and even more precise (see #23572 for detailed comparisons).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to opt out from this, if you want to run W4A4 take a checkpoint with W4A4.
The intention of this PR is if a checkpoint has W4A16 layers it should have activations in higher precision.
This PR doesn't cause regression on pure W4A4_NVFP4 checkpoints.

You can confirm there is no regression by testing llama-bench with this PR on below checkpoints:

  1. Pure W4A4_NVFP4: https://huggingface.co/RedHatAI/Qwen3.6-35B-A3B-NVFP4
  2. W4A16_NVFP4: https://huggingface.co/nvidia/Qwen3.6-35B-A3B-NVFP4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There may be a case that there aren't other checkpoints or somebody likes one's calibration over another. I think many prefer increased speed and that is why they pick NVFP4. Usually Q4_K~ will always be better precision than NVFP4 if that is what they are going for and then it may end up faster than skipping the native FP4. We're blending checkpoints with Q_K quants and NVFP4 combined that can compensate for ppl loss. I think some selection control by the user would be a good balance to let them decide.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ModelOpt, Redhat came up with W4A16_NVFP4 after through investigations on performance and accuracy. Checkout this weight-only-quantization-schemes.

We should honor the intention behind creating a recipe/checkpoint which was specifically designed for W4A16_NVFP4.
If someone intends to use W4A4 on Blackwell they should use a W4A4 checkpoint.

Few PR on vLLM for reference, that were added by ModelOpt to support W4A16_NVFP4 :

  1. Mixed precision W4A16_NVFP4 : PR
  2. W4A16 linear support : PR

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some selection control by the user would be a good balance to let them decide.

I mean we can in principle add such a knob in the CUDA backend to give the ability to override model builder intents encoded in the GGUF, but the default should be what is encoded in the GGUF

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the knob for user controlled W4A4_NVFP4 fast path on Blackwell, even if the checkpoint specifies W4A16_NVFP4 layers

@am17an am17an left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't look into the PR in detail, but does using 8-bit activation disable the fp4 tensor core?

@ORippler

Copy link
Copy Markdown
Collaborator

I didn't look into the PR in detail, but does using 8-bit activation disable the fp4 tensor core?

Yes. Basically you can think of this as a step towards the support of weight-only-quantization-schemes in llama.cpp.

@ynankani
ynankani force-pushed the ynankani/Force_W4A16_NVFP4_to_W4A8 branch from b72a8c9 to 18f1df3 Compare June 17, 2026 12:26
@github-actions github-actions Bot added documentation Improvements or additions to documentation CUDA Related to the CUDA backend labels Jun 17, 2026
@ggerganov ggerganov self-assigned this Jun 25, 2026
@ORippler ORippler self-assigned this Jul 8, 2026

@ORippler ORippler left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ggerganov @CISC thoughts on this approach and the required granularity for W4A4 vs. W4A16?

Comment thread docs/build.md Outdated
Comment on lines +134 to +136
if (CMAKE_CUDA_ARCHITECTURES MATCHES "(^|;)12[0-9]a(-real|-virtual)?($|;)")
add_compile_definitions(GGML_CUDA_HAS_BLACKWELL_TARGET)
endif()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI this compile definition will be visible for all archs in CMAKE_CUDA_ARCHITECTURES (per arch specialization requires constructing nvcc commands by hand)

Comment thread conversion/base.py Outdated
Comment on lines +830 to +839
if self._is_nvfp4:
for tensor_name, entry in quant_layers.items():
if not isinstance(entry, dict) or entry.get("quant_algo") != "W4A16_NVFP4":
continue
if "lm_head" in tensor_name or "output" in tensor_name:
self._nvfp4_w4a16_output = True
continue
bid_m = re.search(r'\.layers\.(\d+)\.', tensor_name)
if bid_m:
self._nvfp4_w4a16_blocks.add(int(bid_m.group(1)))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://huggingface.co/nvidia/Qwen3.6-35B-A3B-NVFP4/blob/main/config.json#L455-L470

huggingface/modelopt seems to offer storing this information on a per-weight level, as opposed to per-transformer-block we parse here. Later on, we set the marker also on a per-weight/op level. I feel this is inconsistent and we should adapt the conversion script to support the finer level of granularity also

@ggerganov ggerganov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I read correctly, this introduces a path to do w4a8 where we normally do w4a4. And the reason is that w4a8 has higher accuracy?

Is there a case where we would want to use w4a4? If no, we can probably simplify a lot of the logic.

Yet, if there is specific tensor hardware for that, it's probably useful.

Comment thread src/llama-hparams.h Outdated
Comment on lines +164 to +167
// NVFP4 W4A16: per-layer + LM head flag, true where NVFP4 weights skip activation quantization.
std::array<bool, LLAMA_MAX_LAYERS> nvfp4_w4a16_layer_arr = {};
bool nvfp4_w4a16_output = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not feel like it belongs to hparams. It's too low-level, backend-specific information.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make this as a per-tensor attribute in llama-model at load time? This will also help acknowledge @ORippler's comment as well to have more flexibility for per-tensor information.

https://huggingface.co/nvidia/Qwen3.6-35B-A3B-NVFP4/blob/main/config.json#L455-L470
huggingface/modelopt seems to offer storing this information on a per-weight level, as opposed to per-transformer-block we parse here. Later on, we set the marker also on a per-weight/op level. I feel this is inconsistent and we should adapt the conversion script to support the finer level of granularity also

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should formulate this information to be per tensor. Also, it should abstract away the NVFP4 and make it more generic. For example, "allow 4-bit activations (bool)" seems generic enough.

We can represent this information with a map: tensor name -> bool. The values are false by default. The map is optional. To represent the map in GGUF, you'll need 2 arrays - the first one with the tensor names and the second one with the same size and the bool values.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"allow 4-bit activations (bool)"

I intuitively think about this PR/feature as "enabling Weight-only-Quantization schemes", so naming should signal this intent if you agree -> "weight-only quantization (bool)" / "allow activation quantization (bool)".

W4A16 is effectively weight-only, as LLMs are trained in BF16 precision typically

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some backends, we already quantize the activations by default (to 8-bits). So I'm not sure if it is not going to be a bit misleading to call it "weight-only quantization (bool)" / "allow activation quantization (bool)".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the change so allow-activation-quant is stored per-tensor. Since it is currently NVFP4-specific, activation quantization is enabled by default for all layers. For layers that use W4A16_NVFP4 as the quantization method, the activation-quant array stores the tensor name paired with false. Please review.

@ORippler

ORippler commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

If I read correctly, this introduces a path to do w4a8 where we normally do w4a4. And the reason is that w4a8 has higher accuracy?

Yes on both. The motivation is that doing W4A16 (or weight-only-quantization in general) may allow one to quantize more layers than when one quantizes both activations and weights. This reduces memory-footprint of the model, and furthermore increases decode throughput - decode is effectively weight-streaming in local inference with small BS setting)

@ggerganov

Copy link
Copy Markdown
Member

Correct me if I am wrong, but I think in the CUDA backend we already do w4a8 for existing types like Q4 - we do it by default. If that's the case, adding support for w4a8+nvfp4 would make sense only if it is better quality-wise than the existing w4a8+q4 methods.

@ORippler

ORippler commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

If that's the case, adding support for w4a8+nvfp4 would make sense only if it is better quality-wise than the existing w4a8+q4 methods.

I think that's going to be difficult to prove generally, though I can add the single model we have validated so far:

model source size params effective BPW NVFP4 mode
qwen35moe 35B.A3B Q4_K - Medium unsloth/Qwen3.6-35B-A3B-GGUF 20.60 GiB 34.66 B 5.105 n/a
qwen35moe 35B.A3B NVFP4 nvidia/Qwen3.6-35B-A3B-NVFP4 19.51 GiB 34.66 B 4.835 W4A16

@ggerganov

Copy link
Copy Markdown
Member

For my understanding, the nvidia/Qwen3.6-35B-A3B-NVFP4 readme says that the model was quantized with the Model Optimizer. Does the quantization process involve some form of quantization aware training?

My understanding is that if a model is trained natively in NVFP4 format, the best thing to do is keep the format intact during inference. I.e. it's not beneficial to use Q4 quantizations in such case on hardware that supports NVFP4. But I would assume that if the model was trained in NVFP4 in the first place, then the recommended way to run would be w4a4 (otherwise it would mean that 4-bit tensor cores weren't utilized during the training?).

If the model was not trained in NVFP4, and instead was quantized to NVFP4, then we have to justify and demonstrate in which cases it is worth it compared to the Q4 formats. One simple justification is that w4a4 is going to be utilized for faster speed. But with w4a8 we are throwing this away, so it's no longer obvious what is the benefit of NVFP4+w4a8.

It might be worth taking a look at the KLD between these quantizations and a reference BF16 model. For example, let's take a look at KLD and speed for: Q4_K_S, Q4_K_M, NVFP4+wa4a, NVFP4+w4a8.

@ORippler

Copy link
Copy Markdown
Collaborator

For my understanding, the nvidia/Qwen3.6-35B-A3B-NVFP4 readme says that the model was quantized with the Model Optimizer. Does the quantization process involve some form of quantization aware training?

No, training was involved, the checkpoint is yielded by PTQ only. QAT/QAD would be disclosed in the model card like this https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-NVFP4#training-methodology (this is a W4A4 checkpoint).

If the model was not trained in NVFP4, and instead was quantized to NVFP4, then we have to justify and demonstrate in which cases it is worth it compared to the Q4 formats [...]. it's no longer obvious what is the benefit of NVFP4+w4a8.

As outlined above, the proposed benefit of weight-only quantization is to allow the quantization of weights more aggressive at iso-quality. We will try to collect & present some numbers.

In general, the idea would be to go for NVFP4 with W4A16, the W4A8 path is just a transient step.

@ynankani
ynankani force-pushed the ynankani/Force_W4A16_NVFP4_to_W4A8 branch from 18f1df3 to 2c7052a Compare July 14, 2026 12:04
@ggerganov

Copy link
Copy Markdown
Member

In general, the idea would be to go for NVFP4 with W4A16, the W4A8 path is just a transient step.

For my understanding, is the expectation that W4A16 would be faster compared to W4A8 if implemented efficiently?

Comment thread docs/build.md
Comment on lines +278 to +280
#### GGML_CUDA_FORCE_W4A4

NVFP4 models that carry W4A16 layers request higher-precision activations, so on Blackwell those layers run through the W4A8 path instead of the native W4A4 path. Set `GGML_CUDA_DISABLE_FORCE_W4A8=1` to ignore that request and keep the native W4A4 path for faster prompt processing at the cost of accuracy.
NVFP4 models that carry W4A16 layers request higher-precision activations (W4A8), so on Blackwell those layers run through the W4A8 path instead of the native W4A4 path. Set `GGML_CUDA_FORCE_W4A4=1` to override that request and keep the native W4A4 path for faster prompt processing at the cost of accuracy.

@ggerganov ggerganov Jul 15, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point we can remove this compile-time option and toggle this functionality at runtime through a libllama argument. It will simply skip setting the quantization hints for the matrix multiplications (i.e. override the activation policy). The idea is to avoid "communicating" directly with backend.

Comment thread ggml/include/ggml.h Outdated
@@ -443,7 +443,7 @@ extern "C" {
enum ggml_op_hint {
GGML_HINT_NONE = 0,
GGML_HINT_SRC0_IS_HADAMARD = 1,
GGML_HINT_NO_QUANT_SRC1 = 2, // W4A16_NVFP4: keep activations higher precision.
GGML_HINT_NO_QUANT_SRC1 = 2, // keep src1 at higher precision (skip 4-bit activation quant).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we agree on the "allow 4-bit activations", then we should consistently name where relevant. For example here: GGML_HINT_SRC1_ALLOW_4BIT.

Comment thread gguf-py/gguf/constants.py Outdated
Comment on lines +28 to +30
# Per-tensor activation precision policy (tensor name -> allow 4-bit activations).
ALLOW_4BIT_ACT_TENSOR = "general.allow_4bit_act.tensor"
ALLOW_4BIT_ACT_VALUE = "general.allow_4bit_act.value"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can become more generic and future-proof to allow setting additional per-tensor options in the future. To do that, the array with the tensor names should be called something like "general.tensor_extra.name". And the "allow 4-bit activations" values should be stored in the bool array named "general.tensor_extra.allow_4bit_act".

Comment thread src/llama-graph.cpp Outdated
Comment on lines +1395 to +1398
if (no_quant_src1_for_weight(act_policy, w)) {
ggml_mul_mat_set_hint(res, GGML_HINT_NO_QUANT_SRC1);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be:

Suggested change
if (no_quant_src1_for_weight(act_policy, w)) {
ggml_mul_mat_set_hint(res, GGML_HINT_NO_QUANT_SRC1);
}
if (llama_act_policy_allow_4bit(act_policy, w)) {
ggml_mul_mat_set_hint(res, GGML_HINT_SRC1_ALLOW_4BIT);
}

Comment thread src/llama-graph.h Outdated
@@ -18,6 +18,7 @@ struct ggml_tensor;

struct llama_cparams;
struct llama_layer;
struct llama_weight_act_policy;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
struct llama_weight_act_policy;
struct llama_act_policy;

@JohannesGaessler

JohannesGaessler commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

My opinion is that we should solve this differently at a ggml level. As of right now we have this for "precision":

    // precision
    enum ggml_prec {
        GGML_PREC_DEFAULT =  0, // stored as ggml_tensor.op_params, 0 by default
        GGML_PREC_F32     = 10,
    };

I am interpreting "default" to mean that we don't really care about the precision and that the backends should just optimize for speed/memory use. So on Blackwell that would mean W4A4. But we can add something like GGML_PREC_A8 or GGML_PREC_A16 to indicate that we want the backend to use at least that number of bits for the activations. I think this would be preferable over making the distinction an "op hint" because my interpretation of what that should be is a hint to the backend regarding what optimizations could be done without any negative side effects by exploiting that the data has some special structure. And it's also not clear to me what a backend is supposed to do for the combination of GGML_PREC_F32 and GGML_HINT_SRC1_ALLOW_4BIT.

To be clear: I think that the way we currently define "precision" in ggml is poorly defined and needs more maintainer attention. My opinion is that GGML_PREC_F32 should require strict FP32 arithmetic, not just the numerical range of FP32. For that we should add a new value.

@ynankani

Copy link
Copy Markdown
Contributor Author

My opinion is that we should solve this differently at a ggml level. As of right now we have this for "precision":

    // precision
    enum ggml_prec {
        GGML_PREC_DEFAULT =  0, // stored as ggml_tensor.op_params, 0 by default
        GGML_PREC_F32     = 10,
    };

I am interpreting "default" to mean that we don't really care about the precision and that the backends should just optimize for speed/memory use. So on Blackwell that would mean W4A4. But we can add something like GGML_PREC_A8 or GGML_PREC_A16 to indicate that we want the backend to use at least that number of bits for the activations. I think this would be preferable over making the distinction an "op hint" because my interpretation of what that should be is a hint to the backend regarding what optimizations could be done without any negative side effects by exploiting that the data has some special structure. And it's also not clear to me what a backend is supposed to do for the combination of GGML_PREC_F32 and GGML_HINT_SRC1_ALLOW_4BIT.

To be clear: I think that the way we currently define "precision" in ggml is poorly defined and needs more maintainer attention. My opinion is that GGML_PREC_F32 should require strict FP32 arithmetic, not just the numerical range of FP32. For that we should add a new value.

This makes sense to me. It would reduce the ambiguity created by having multiple precision-related signals and hints.

@jeffbolznv

Copy link
Copy Markdown
Contributor

I agree it would be nice to have more clear instructions to the backend about what precision to use, but who makes that choice and how? And I think we need to be more clear about weight/activation precision vs accumulator precision/range.

@ynankani
ynankani force-pushed the ynankani/Force_W4A16_NVFP4_to_W4A8 branch from 0a1701e to a470fa6 Compare July 16, 2026 15:36
@ynankani

Copy link
Copy Markdown
Contributor Author

I agree it would be nice to have more clear instructions to the backend about what precision to use, but who makes that choice and how? And I think we need to be more clear about weight/activation precision vs accumulator precision/range.

In the current design for the gguf carries the information for activation precision per-tensor and backend honors it.
Maybe we can separate out the enum for accum and weight/activation or add a suffix for differentiating? @JohannesGaessler any guidance on this?

@ORippler

Copy link
Copy Markdown
Collaborator

For my understanding, is the expectation that W4A16 would be faster compared to W4A8 if implemented efficiently?

There is no straightforward answer to this, as WXAY with X/Y specifying bits does not tell whether its FP or INT. Generally, W4A16 is the way to go for weight-only-quantization as (I) it's the way that the checkpoint are validated during PTQ in weight-only-quantization settings, and (II) will be accelerated equally across HW stacks. I stress again to think about this PR as "adding support for weight-only-quantization schemes" rather than "add this one niche-case for ModelOpt + NVFP4"

And I think we need to be more clear about weight/activation precision vs accumulator precision/range.

+1 on this, as I think precision in its current form is only used to signal accumulator precision/range.

I agree it would be nice to have more clear instructions to the backend about what precision to use, but who makes that choice and how?

  • who = ggml maintainers for design, and ggml-graph-builders (i.e. llama.cpp via gguf in this specific instance) for consumption
  • how: currently, we solely define op-compliance via a backend passing test-backend-ops. Naturally, one could think of extending this and say F32 prec must keep tighter numerical bounds than F16. That's actually how it's implemented in this PR (W4A4 does not meet generic requirement, so it's relaxed unless the hint is given it should not). Extending this change will of course cause friction, and I'm not 100% convinced relying on numerical accuracy alone is sufficient

@ynankani
ynankani marked this pull request as draft July 23, 2026 15:04
@ynankani
ynankani force-pushed the ynankani/Force_W4A16_NVFP4_to_W4A8 branch from a470fa6 to 5de3322 Compare August 5, 2026 05:01
@ynankani
ynankani marked this pull request as ready for review August 5, 2026 13:38
@ggerganov

Copy link
Copy Markdown
Member

Trying to move this forward - prepared a ggml-level proposal concerning ggml_prec and making it well-defined: #26675. PTAL - we need to agree on that before proceeding here.

@ynankani
ynankani marked this pull request as draft August 11, 2026 12:37
@ynankani
ynankani force-pushed the ynankani/Force_W4A16_NVFP4_to_W4A8 branch from 822a5b7 to d47e561 Compare August 27, 2026 11:18
@github-actions github-actions Bot added model Model specific mtmd Related to multimodal functionality (video/image/audio) labels Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conversion CUDA Related to the CUDA backend documentation Improvements or additions to documentation ggml changes relating to the ggml tensor library for machine learning model Model specific mtmd Related to multimodal functionality (video/image/audio) Nvidia GPU Issues specific to Nvidia GPUs python python script changes testing Everything test related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants