huggingface/transformers · error · ValueError
Cannot reverse the transform with TP or quantization
Error message
Cannot reverse the transform with TP or quantization
What it means
Raised by WeightTransform.reverse_transform (core_model_loading.py:924). Reversing a transform builds the inverse operations so an HF model can be saved back in the original checkpoint layout, but quantization operations have no reverse_op yet (see the TODO in the source). If the transform carries a quantization_operation (e.g. the weights were dequantized from FP8/GPTQ on load), reversal is impossible and the method refuses.
Source
Thrown at src/transformers/core_model_loading.py:924
source_pattern_that_matched = self.source_patterns[int(matching_group_name[1:])]
# If we matched, we always replace with the first target pattern, in case we have several (one to many transform)
replacement = self.target_patterns[0]
# Allow capturing groups in patterns, i.e. to add a prefix to all keys (e.g. timm_wrapper, sam3)
if r"\1" in replacement:
# The index of the internal group we need to replace is the index of the matched named group as it comes
# inside that matched named group
replaced_group_idx = self.compiled_sources.groupindex[matching_group_name] + 1
replacement = replacement.replace(r"\1", match_object.group(replaced_group_idx))
renamed_key = key_to_match.replace(match_object.group(0), replacement, 1)
if prefix_dot is not None:
renamed_key = prefix_dot + renamed_key
return renamed_key, source_pattern_that_matched
def reverse_transform(self) -> WeightTransform:
"""Reverse the current `WeightTransform` instance, to be able to save with the opposite weight transformations."""
# TODO: check this and relax when quantizer have `reverse_op`
if self.quantization_operation is not None:
raise ValueError("Cannot reverse the transform with TP or quantization")
kwargs = {}
# Add the reverse ops if applicable (it needs to be provided at __init__)
if hasattr(self, "operations"):
# All reverse ops, in reverse order
kwargs["operations"] = [op.reverse_op for op in self.operations[::-1]]
reverse_transform = self.__class__(
source_patterns=self._original_target_patterns, target_patterns=self._original_source_patterns, **kwargs
)
reverse_transform.scope_prefix = self.scope_prefix
reverse_transform.base_model_prefix = self.base_model_prefix
return reverse_transform
def materialize_tensors(self) -> dict[str, list[torch.Tensor]]:
"""
Materialize all the tensors that were saved in `self.collected_tensors`. This function removes them from the
internal attribute to avoid keeping them in memory during the different `self.convert` operations, and returnView on GitHub (pinned to a597f97485)
Solutions
- Do not request the reverse/original save for quantized checkpoints; save in HF format instead (omit the convert-to-original option).
- Start from the non-quantized original checkpoint if you need a round trip back to the original layout.
- Track the upstream TODO: once quantizers implement reverse_op this restriction may be relaxed — check your transformers version.
Example fix
# before model.save_pretrained(out_dir, convert_to_original=True) # model was fp8-dequantized on load -> raises # after model.save_pretrained(out_dir) # save in HF format; original-layout export unsupported for quantized loads
Defensive patterns
Strategy: type-guard
Validate before calling
def can_reverse(transform) -> bool:
return transform.quantization_operation is None Type guard
def is_reversible(transform) -> bool:
return getattr(transform, 'quantization_operation', None) is None Try / catch
try:
reverse = transform.reverse_transform()
except ValueError:
# quantized load: save in HF layout instead
model.save_pretrained(out_dir) Prevention
- Check transform.quantization_operation is None before requesting original-layout export.
- Keep an unquantized copy of the source checkpoint when round trips are required.
- Gate convert-to-original saving behind a capability check in your export tooling.
When it happens
Trigger: Calling model.save_pretrained(..., convert_to_original=True) or transform.reverse_transform() on a model whose conversion pipeline included a quantizer (Fp8, bitsandbytes, etc.), i.e. quantization_operation is not None on the transform.
Common situations: Trying to round-trip a checkpoint that was loaded through a quantizer path: convert original checkpoint -> HF (with dequantization) -> attempt to save back to original format. The quantized -> original re-quantization step is not implemented, so this direction is blocked.
Related errors
- TP and DP cannot be used together
- You need to install optimum-quanto in order to use KV cache
- `nbits` for `quanto` backend has to be one of [`2`, `4`] but
- `axis_key` for `quanto` backend has to be one of [`0`, `-1`]
- `axis_value` for `quanto` backend has to be one of [`0`, `-1
AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14).
Data as JSON: /api/errors/f339e41aa3c4af0d.
Report an issue: GitHub.