Granite Switch — Build AI models like you build software
96
stars
67
commits
Python
primary language
Sep 10, 2026
updated
| Browse adapter functions | Pre-composed Models on HF | Tutorials |
Software is built from libraries — you pick the ones you need, compose them, and ship. Granite Switch brings this to AI models: choose adapter functions for RAG, safety, factuality, and more, compose them into a single model, and deploy with one command. Swap or upgrade any component independently, just like updating a dependency.
An adapter function is a LoRA adapter trained to a specific input/output contract — a score, a decision, a rewritten query — with the output schema enforced at the token level by Mellea. This is what makes them composable as software: each function has a known signature, not just a general-purpose text output.
Small models with the right adapter functions consistently outperform much larger generalist models on targeted tasks. Activated LoRA (aLoRA) makes this practical at scale: all adapter functions share one KV cache, activating on demand — so one deployment serves many capabilities with no memory or latency overhead.
Live race telemetry: aLoRA (74% KV cache hit rate, 5/16 finished) vs LoRA (29% KV hit rate, 1/16 finished) — same model, same hardware, different adapter technology.
Reproduce it yourself on Colab →
pip install "granite-switch[vllm]"
Other install options depending on your use case:
pip install "granite-switch[compose]" # Compose modular models
pip install "granite-switch[hf]" # HuggingFace inference
pip install "granite-switch[vllm20]" # vLLM 0.20+ (requires CUDA 13+)
pip install "granite-switch[dev]" # Everything
Requires Python 3.10+ and PyTorch 2.0+.
vLLM version note: This project currently defaults to vLLM 0.19.1 due to vLLM 0.20's dependency on CUDA 13.0+ (via PyTorch 2.11), which is incompatible with many existing environments running CUDA 12.x drivers. Use
.[vllm20]if your environment supports CUDA 13+.
Compose a base Granite model with adapter libraries into a single deployable checkpoint:
python -m granite_switch.composer.compose_granite_switch \
--base-model ibm-granite/granite-4.1-3b \
--adapters ibm-granite/granitelib-core-r1.0 ibm-granite/granitelib-rag-r1.0 ibm-granite/granitelib-guardian-r1.0 \
--output ./my-model
Use the adapter function composer to browse available adapter functions, compare benchmarks, and generate a ready-to-run compose command.
This downloads the base model, embeds compatible LoRA adapters (with a preference towards activated LoRA), adds control tokens and a chat template, and produces a model directory that works with both HuggingFace and vLLM.
Or skip composition and use a pre-composed model:
Tip: pre-download the model for faster startup. The first run will download several GB from Hugging Face, which can be slow. To download in advance using the fast transfer backend:
pip install "huggingface_hub[hf_transfer]" huggingface-cli login # one-time, if not already logged in HF_HUB_ENABLE_HF_TRANSFER=1 hf download ibm-granite/granite-switch-4.1-3b-previewSubsequent runs will use the local cache automatically.
vLLM + Mellea (recommended):
pip install mellea
python -m vllm.entrypoints.openai.api_server --model ibm-granite/granite-switch-4.1-3b-preview --port 8000
from mellea.backends.openai import OpenAIBackend
from mellea.stdlib.components.chat import Message
from mellea.stdlib.components.intrinsic.guardian import guardian_check
from mellea.stdlib.context import ChatContext
backend = OpenAIBackend(
model_id="ibm-granite/granite-switch-4.1-3b-preview",
base_url="http://localhost:8000/v1",
api_key="unused",
)
backend.register_embedded_adapter_model("ibm-granite/granite-switch-4.1-3b-preview")
ctx = ChatContext().add(Message("user", "Group X people are all lazy."))
score = guardian_check(ctx, backend, "social_bias", scoring_schema="user_prompt")
print(f"social_bias score: {score:.3f}")
# => social_bias score: 0.964
With standard LoRA, each adapter is trained against its own KV distribution — so switching adapter functions across complex flow control means discarding and recomputing the KV cache at every step. aLoRA adapter functions are instead trained against a common normalized KV cache, so they can all coexist in a single checkpoint and activate on demand without cross-contamination:
<guardian>, <query_rewrite>). Placing the token in the input sequence is what triggers activation — the adapter function's LoRA weights apply from that position forward.Like functions in a software library, adapter functions can be developed and benchmarked independently or jointly. They compose into one deployable model that contains all capabilities, in analogy to statically linked object code.
New here? Start with a 5-minute notebook and work your way up:
| Notebook | What you'll build | Time | |
|---|---|---|---|
| Hello Mellea | Call adapters through a clean Python API | 5 min | |
| RAG Flow | Query rewrite + answerability + citations in one model | 30 min | |
| Compose Your Own | Build a custom checkpoint from adapter function libraries | 15 min |
All notebooks run on Colab. See tutorials/README.md for the full list and guided learning paths.
Granite Switch is part of a coordinated stack:
Granite Switch was started by IBM Research and is developed in the open. We welcome bug reports, feature requests, and pull requests — see CONTRIBUTING.md for guidelines or open an issue.
Apache-2.0 — see LICENSE.
Python
76.4%
HTML
14.6%
Jupyter Notebook
8.4%
Granite Switch — Build AI models like you build software
96
stars
67
commits
Python
primary language
Sep 10, 2026
updated
| Browse adapter functions | Pre-composed Models on HF | Tutorials |
Software is built from libraries — you pick the ones you need, compose them, and ship. Granite Switch brings this to AI models: choose adapter functions for RAG, safety, factuality, and more, compose them into a single model, and deploy with one command. Swap or upgrade any component independently, just like updating a dependency.
An adapter function is a LoRA adapter trained to a specific input/output contract — a score, a decision, a rewritten query — with the output schema enforced at the token level by Mellea. This is what makes them composable as software: each function has a known signature, not just a general-purpose text output.
Small models with the right adapter functions consistently outperform much larger generalist models on targeted tasks. Activated LoRA (aLoRA) makes this practical at scale: all adapter functions share one KV cache, activating on demand — so one deployment serves many capabilities with no memory or latency overhead.
Live race telemetry: aLoRA (74% KV cache hit rate, 5/16 finished) vs LoRA (29% KV hit rate, 1/16 finished) — same model, same hardware, different adapter technology.
Reproduce it yourself on Colab →
pip install "granite-switch[vllm]"
Other install options depending on your use case:
pip install "granite-switch[compose]" # Compose modular models
pip install "granite-switch[hf]" # HuggingFace inference
pip install "granite-switch[vllm20]" # vLLM 0.20+ (requires CUDA 13+)
pip install "granite-switch[dev]" # Everything
Requires Python 3.10+ and PyTorch 2.0+.
vLLM version note: This project currently defaults to vLLM 0.19.1 due to vLLM 0.20's dependency on CUDA 13.0+ (via PyTorch 2.11), which is incompatible with many existing environments running CUDA 12.x drivers. Use
.[vllm20]if your environment supports CUDA 13+.
Compose a base Granite model with adapter libraries into a single deployable checkpoint:
python -m granite_switch.composer.compose_granite_switch \
--base-model ibm-granite/granite-4.1-3b \
--adapters ibm-granite/granitelib-core-r1.0 ibm-granite/granitelib-rag-r1.0 ibm-granite/granitelib-guardian-r1.0 \
--output ./my-model
Use the adapter function composer to browse available adapter functions, compare benchmarks, and generate a ready-to-run compose command.
This downloads the base model, embeds compatible LoRA adapters (with a preference towards activated LoRA), adds control tokens and a chat template, and produces a model directory that works with both HuggingFace and vLLM.
Or skip composition and use a pre-composed model:
Tip: pre-download the model for faster startup. The first run will download several GB from Hugging Face, which can be slow. To download in advance using the fast transfer backend:
pip install "huggingface_hub[hf_transfer]" huggingface-cli login # one-time, if not already logged in HF_HUB_ENABLE_HF_TRANSFER=1 hf download ibm-granite/granite-switch-4.1-3b-previewSubsequent runs will use the local cache automatically.
vLLM + Mellea (recommended):
pip install mellea
python -m vllm.entrypoints.openai.api_server --model ibm-granite/granite-switch-4.1-3b-preview --port 8000
from mellea.backends.openai import OpenAIBackend
from mellea.stdlib.components.chat import Message
from mellea.stdlib.components.intrinsic.guardian import guardian_check
from mellea.stdlib.context import ChatContext
backend = OpenAIBackend(
model_id="ibm-granite/granite-switch-4.1-3b-preview",
base_url="http://localhost:8000/v1",
api_key="unused",
)
backend.register_embedded_adapter_model("ibm-granite/granite-switch-4.1-3b-preview")
ctx = ChatContext().add(Message("user", "Group X people are all lazy."))
score = guardian_check(ctx, backend, "social_bias", scoring_schema="user_prompt")
print(f"social_bias score: {score:.3f}")
# => social_bias score: 0.964
With standard LoRA, each adapter is trained against its own KV distribution — so switching adapter functions across complex flow control means discarding and recomputing the KV cache at every step. aLoRA adapter functions are instead trained against a common normalized KV cache, so they can all coexist in a single checkpoint and activate on demand without cross-contamination:
<guardian>, <query_rewrite>). Placing the token in the input sequence is what triggers activation — the adapter function's LoRA weights apply from that position forward.Like functions in a software library, adapter functions can be developed and benchmarked independently or jointly. They compose into one deployable model that contains all capabilities, in analogy to statically linked object code.
New here? Start with a 5-minute notebook and work your way up:
| Notebook | What you'll build | Time | |
|---|---|---|---|
| Hello Mellea | Call adapters through a clean Python API | 5 min | |
| RAG Flow | Query rewrite + answerability + citations in one model | 30 min | |
| Compose Your Own | Build a custom checkpoint from adapter function libraries | 15 min |
All notebooks run on Colab. See tutorials/README.md for the full list and guided learning paths.
Granite Switch is part of a coordinated stack:
Granite Switch was started by IBM Research and is developed in the open. We welcome bug reports, feature requests, and pull requests — see CONTRIBUTING.md for guidelines or open an issue.
Apache-2.0 — see LICENSE.
Python
76.4%
HTML
14.6%
Jupyter Notebook
8.4%