fix: map None quant method to q8_0 before lowercasing in GGUF export#6889
Open
anxkhn wants to merge 1 commit into
Open
fix: map None quant method to q8_0 before lowercasing in GGUF export#6889anxkhn wants to merge 1 commit into
anxkhn wants to merge 1 commit into
Conversation
In unsloth_save_pretrained_gguf and save_to_gguf_generic, the quant-method normalization loop ran `quant_method = quant_method.lower()` as its first statement, before the `elif quant_method is None: quant_method = "q8_0"` branch. Because `.lower()` executed first, a None element in the quantization_method list (e.g. quantization_method=[None] or ["q4_k_m", None]) raised `AttributeError: 'NoneType' object has no attribute 'lower'`, and the intended None -> q8_0 mapping was unreachable dead code. Handle None before lowercasing, matching the sibling loop in save_to_gguf, so a None element resolves to q8_0. Behavior is unchanged for string inputs. Add tests/saving/test_quant_method_none_normalization.py, a CPU-only test that extracts each loop via ast and checks that a None element maps to q8_0 instead of raising, alongside strings.
Contributor
There was a problem hiding this comment.
Code Review
This pull request fixes an AttributeError in unsloth/save.py that occurred when a None element was present in the quantization_method list. The fix ensures that None values are checked and mapped to 'q8_0' before calling .lower(). Additionally, a new CPU-only regression test has been added to verify this behavior using AST parsing and execution. There are no review comments to address.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Because
.lower()runs first, aNoneelement inside the list (for examplequantization_method=[None]or["q4_k_m", None]) raisesAttributeError: 'NoneType' object has no attribute 'lower', and theelif quant_method is None:branch is dead code that never runs. A barequantization_method=Noneis fine, it is guarded by the surroundingif quantization_method is not None:; the problem is specifically aNoneelement within the list.
The sibling loop in
save_to_ggufalready handles this correctly: it checksNoneviaelifand does not call.lower()up front. This change brings thetwo loops in line with it.
Fix
Handle
Nonebefore lowercasing and drop the now-redundantelif:A
Noneelement now resolves toq8_0. Behavior is unchanged for every stringinput.
Test
Adds
tests/saving/test_quant_method_none_normalization.py. Importingunsloth.savepulls inunsloth_zoo/Torch, so, following the existingtests/saving/test_is_gpt_oss_detection.pypattern, the test extracts eachloop's source with
astand execs it against sample inputs. It asserts that[None]maps to["q8_0"],["Q4_K_M", None]maps to["q4_k_m", "q8_0"],and that ordinary string inputs are unchanged. The test fails on the old
ordering (
AttributeError) and passes with this fix (6 passed).ruff checkon the touched files passes.