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:

  1. Compile the suffix regex list defined in the same module.
  2. For each model ID, scan the list and delete the first matching suffix found at the end.
  3. Repeat up to three iterations to dismantle stacked variants such as model-gguf-fp16.
  4. 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.

Several modules cooperate to deliver the final grouped output:

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_name inside src/whichllm/models/grouper.py.
  • A three-pass loop dismantles stacked suffixes like model-gguf-fp16.
  • Cleaned IDs feed directly into group_models, which aggregates ModelInfo records into unified ModelFamily objects.
  • Supporting types live in src/whichllm/models/types.py, while the CLI orchestration happens in src/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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →