Unverified Commit 447ce222 authored by Injae Ryou's avatar Injae Ryou Committed by GitHub
Browse files

[GGUF] Support non-standard quant types with prefix (e.g. UD-IQ1_S) (#39471)


Signed-off-by: default avatarInjae Ryou <injaeryou@gmail.com>
Co-authored-by: default avatarIsotr0py <mozf@mail2.sysu.edu.cn>
parent 65e4e46f
......@@ -81,6 +81,25 @@ class TestIsRemoteGGUF:
assert not is_remote_gguf("repo/model:INVALID_M")
assert not is_remote_gguf("repo/model:Q9_K_M")
def test_is_remote_gguf_nonstandard_quant_type(self):
"""Test is_remote_gguf with non-standard quant types containing
a known GGML type."""
# Non-standard quant types with known GGML type after prefix
assert is_remote_gguf("unsloth/Qwen3.5-35B-A3B-GGUF:UD-Q4_K_XL")
assert is_remote_gguf("user/Model:UD-Q4_K_M")
assert is_remote_gguf("user/SomeModel:Custom-Q8_0")
# Exact GGML type after prefix (no suffix stripping needed)
assert is_remote_gguf("user/Model-GGUF:UD-IQ4_NL")
assert is_remote_gguf("user/Model-GGUF:UD-Q8_0")
# Completely unknown quant types should still fail
assert not is_remote_gguf("repo/model:TOTALLY-RANDOM")
assert not is_remote_gguf("user/Model:UD-INVALID")
# No dash separator → not recognized as prefixed
assert not is_remote_gguf("repo/model:UDIQ4NL")
def test_is_remote_gguf_without_colon(self):
"""Test is_remote_gguf without colon."""
assert not is_remote_gguf("repo/model")
......@@ -143,6 +162,14 @@ class TestSplitRemoteGGUF:
assert repo_id == "repo/model"
assert quant_type == "Q3_K_S"
def test_split_remote_gguf_nonstandard_quant_type(self):
"""Test split_remote_gguf with non-standard quant types in GGUF repos."""
repo_id, quant_type = split_remote_gguf(
"unsloth/Qwen3.5-35B-A3B-GGUF:UD-Q4_K_XL"
)
assert repo_id == "unsloth/Qwen3.5-35B-A3B-GGUF"
assert quant_type == "UD-Q4_K_XL"
def test_split_remote_gguf_with_path_object(self):
"""Test split_remote_gguf with Path object."""
repo_id, quant_type = split_remote_gguf(Path("unsloth/Qwen3-0.6B-GGUF:IQ1_S"))
......
......@@ -40,15 +40,48 @@ def check_gguf_file(model: str | PathLike) -> bool:
@cache
def is_remote_gguf(model: str | Path) -> bool:
"""Check if the model is a remote GGUF model."""
"""Check if the model is a remote GGUF model.
Recognizes two forms:
1. Standard: ``repo_id:quant_type`` where *quant_type* is a known
GGML quantization type (e.g. ``Q4_K_M``).
2. Non-standard: ``repo_id:quant_type`` where *quant_type* contains
a known GGML type with extra prefixes (e.g. ``UD-Q4_K_XL``).
A warning is logged and actual file existence is validated later
during download.
"""
pattern = r"^[a-zA-Z0-9][a-zA-Z0-9._-]*/[a-zA-Z0-9][a-zA-Z0-9._-]*:[A-Za-z0-9_+-]+$"
model = str(model)
if re.fullmatch(pattern, model):
_, quant_type = model.rsplit(":", 1)
return is_valid_gguf_quant_type(quant_type)
if is_valid_gguf_quant_type(quant_type):
return True
if is_nonstandard_gguf_quant_type(quant_type):
logger.warning(
"Non-standard GGUF quant type '%s' detected.",
quant_type,
)
return True
return False
def is_nonstandard_gguf_quant_type(quant_type: str) -> bool:
"""Check if a non-standard quant type contains a known GGML type.
Splits the quant type by the last ``-`` and checks whether the
trailing part is a standard GGML type. For example::
UD-Q4_K_XL → rsplit → ["UD", "Q4_K_XL"] → Q4_K_XL valid ✓
UD-IQ4_NL → rsplit → ["UD", "IQ4_NL"] → IQ4_NL valid ✓
Custom-UD-Q4_K → rsplit → ["Custom-UD", "Q4_K"] → Q4_K valid ✓
RANDOM → no "-" → False
"""
if "-" not in quant_type:
return False
_, remainder = quant_type.rsplit("-", 1)
return is_valid_gguf_quant_type(remainder)
# Common suffixes used in GGUF file naming conventions
# e.g., Q4_K_M, Q3_K_S, Q5_K_L, Q2_K_XL
_GGUF_QUANT_SUFFIXES = ("_M", "_S", "_L", "_XL", "_XS", "_XXS")
......@@ -84,7 +117,9 @@ def split_remote_gguf(model: str | Path) -> tuple[str, str]:
f"Wrong GGUF model or invalid GGUF quant type: {model}.\n"
"- It should be in repo_id:quant_type format.\n"
f"- Valid base quant types: {GGMLQuantizationType._member_names_}\n"
f"- Extended suffixes also supported: {_GGUF_QUANT_SUFFIXES}",
f"- Extended suffixes also supported: {_GGUF_QUANT_SUFFIXES}\n"
"- Non-standard GGUF quant types also supported: "
"dash-separated prefixes (e.g. UD-Q4_K_XL, Custom-Q8_0)",
)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment