WhichLLM Model Normalization: Complete List of Suffixes Stripped from Model IDs
WhichLLM strips 13 regex-defined suffixes—including quantisation markers, precision flags, and variant tags—via the _normalize_name helper in src/whichllm/models/grouper.py to group related models under a single family identifier.
When working with the WhichLLM repository, model normalization is the critical first step that collapses variant-specific names into logical families. The private helper _normalize_name iterates over a hard-coded list of regular-expression suffixes, removing any that match the end of a model ID. This process ensures that quantised, instruction-tuned, or dated releases do not fragment the same base model across multiple groups.
The _normalize_name Helper in src/whichllm/models/grouper.py
The core of WhichLLM model normalization lives in src/whichllm/models/grouper.py. Inside this file, _normalize_name performs a regex-based stripping pass over incoming model identifiers.
Each suffix pattern is anchored to the end of the string with $, so only trailing components are removed. The function runs the substitution loop up to three times, catching suffixes that stack on top of one another.
How the Suffix-Stripping Loop Works
The loop inside _normalize_name applies the following logic:
- Compile the suffix regex list defined in the same module.
- For each model ID, scan the list and delete the first matching suffix found at the end.
- Repeat up to three iterations to dismantle stacked variants such as
model-gguf-fp16. - Return the cleaned identifier for downstream grouping.
After suffix removal, additional normalization steps collapse embedded version fragments and standardise size tokens. For example, mistral-small-3.2-24b may be simplified to mistral-small-24b depending on the full ruleset in place.
Full List of Removed Suffixes
The _normalize_name helper recognizes and removes these suffix patterns:
-gguf$— GGUF format indicator (e.g.,llama-2-7b-gguf)-gptq$— GPTQ quantisation (e.g.,mixtral-8x7b-gptq)-awq$— AWQ quantisation (e.g.,phi-1.5-awq)-instruct$— Instruction-tuned variant (e.g.,mistral-7b-instruct)-chat$— Chat-oriented variant (e.g.,gemma-2b-chat)-it$— Instruction shorthand (e.g.,deepseek-coder-it)-hf$— HuggingFace-compatible fork (e.g.,stablelm-7b-hf)-fp8$— 8-bit floating-point (e.g.,gemma-2b-fp8)-fp16$— 16-bit floating-point (e.g.,gemma-2b-fp16)-bf16$— BFloat16 precision (e.g.,gemma-2b-bf16)-nvfp4$— NVIDIA 4-bit FP format (e.g.,gemma-2b-nvfp4)-\d+bit$— Generic "X-bit" quantisation (e.g.,opt-125m-4bit)-\d{4}$— Four-digit date or version tag (e.g.,qwen3-4b-2507)
Why WhichLLM Strips Model ID Suffixes
The purpose of WhichLLM model normalization is to treat different quantised or fine-tuned releases as members of the same logical family. Without this cleaning step, a benchmark dataset would treat llama-2-7b-gguf and llama-2-7b-fp16 as unrelated entries.
By stripping these suffixes in src/whichllm/models/grouper.py, the higher-level group_models function can aggregate ModelInfo objects under a shared family_id. This behavior is essential for accurate grouping, benchmarking, and CLI display output.
Code Examples: Normalizing and Grouping Models
You can call _normalize_name directly to preview the cleaning step:
from whichllm.models.grouper import _normalize_name
# Raw model IDs from common repositories
raw_ids = [
"llama-2-7b-gguf",
"mixtral-8x7b-gptq",
"gemma-2b-fp16",
"qwen3-4b-2507",
"deepseek-coder-instruct"
]
norm_names = [_normalize_name(mid) for mid in raw_ids]
print(norm_names)
# ['llama-2-7b', 'mixtral-8x7b', 'gemma-2b', 'qwen3-4b', 'deepseek-coder']
For production use, the public group_models API consumes ModelInfo objects and returns ModelFamily instances:
from whichllm.models.grouper import group_models
from whichllm.models.types import ModelInfo
models = [
ModelInfo(id="llama-2-7b-gguf", base_model=None),
ModelInfo(id="llama-2-7b-fp16", base_model=None),
ModelInfo(id="llama-2-7b", base_model=None)
]
families = group_models(models)
print(families[0].family_id) # → "llama-2-7b"
How Stacked Suffixes Are Handled
Some model IDs carry multiple variant markers simultaneously, such as model-name-gguf-fp16. The _normalize_name loop is intentionally capped at three passes to handle these stacked suffixes without over-processing.
Because the regex list is evaluated sequentially during each pass, the function removes the outermost suffix first, then continues inward. This design prevents fragmented families even when upstream repositories append multiple format or precision indicators.
Related Files in the Normalization Pipeline
Several modules cooperate to deliver the final grouped output:
src/whichllm/models/grouper.py— Defines_normalize_nameand the suffix list, and exposesgroup_models.src/whichllm/models/types.py— DeclaresModelInfoandModelFamilydata structures consumed by the grouper.src/whichllm/cli.py— Entry point that invokesgroup_modelsto present cleaned families to the user.
Summary
- WhichLLM removes 13 regex-defined suffixes during model normalization, covering quantisation, precision, variants, dates, and generic bit-width markers.
- The logic resides in
_normalize_nameinsidesrc/whichllm/models/grouper.py. - A three-pass loop dismantles stacked suffixes like
model-gguf-fp16. - Cleaned IDs feed directly into
group_models, which aggregatesModelInforecords into unifiedModelFamilyobjects. - Supporting types live in
src/whichllm/models/types.py, while the CLI orchestration happens insrc/whichllm/cli.py.
Frequently Asked Questions
What is the exact list of suffixes WhichLLM removes?
WhichLLM removes suffixes matching -gguf$, -gptq$, -awq$, -instruct$, -chat$, -it$, -hf$, -fp8$, -fp16$, -bf16$, -nvfp4$, -\d+bit$, and -\d{4}$. These patterns cover GGUF and GPTQ quantisation, chat or instruct variants, common precision flags, generic bit-width labels, and four-digit date or version tags.
How does WhichLLM handle multiple suffixes on one model ID?
The _normalize_name helper runs its suffix-stripping loop up to three times. This multi-pass design removes stacked suffixes sequentially, so an identifier like model-gguf-fp16 is fully cleaned to model before grouping occurs.
Where is the model normalization logic implemented?
The normalization logic is implemented in src/whichllm/models/grouper.py. This file contains both the private _normalize_name function and the public group_models API that relies on it.
Can I use WhichLLM's normalization function directly in my own code?
Yes. You can import _normalize_name from whichllm.models.grouper and apply it to raw model identifier strings. For full family aggregation, import group_models and pass it a list of ModelInfo objects as defined in src/whichllm/models/types.py.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →