For most small(ish) LLMs, you can use quantization to reduce VRAM requirements while training. Typically, you just quantize the entire model to a 4 or 8 bit format, train a LoRA adapter on that wuantized model, then apply it to the original BF16 model. This method is called qLoRA and Unsloth supports it directly, using bitsandbytes (BnB) quantization. Another popular method of quantization is torchao.
However, with the IBM Granite 4 Small and Tiny models (Mamba2-hybrid, MoE) qLoRA is not available, at least in 4 bits. Stock BnB fails to compress these models to any significant degree, because it does not natively support the 3D tensors that are used in the MoE MLP layers that comprise the bulk of the models. torchao 4-bit methods can be adapted to compress the tensors and infer, but don't support the backward pass for training.
The result is that one normally needs a GPU with VRAM to fit the entire unquantized BF16 model (so 64 Gb just for the weights of Granite 4 small, before any overhead for actual training). Or maybe a Hopper/Blackwell chip allows FP8 qLoRA - but for Granite 4 Small, that is still 32 Gb, leaving zero space for training on a 5090.
We propose a method of using bitsandbytes with some custom scaffolding and a custom model saving format to quantize the MLP layers in the experts to 4 bits, enabling memory-efficient training. This is not qLoRA - the quantized layers cannot be trained, the layers you train are not quantized. However, training only the attention and Mamba layers is a very common fine-tuning approach with Granite. StoneBnB enables this method with significantly less VRAM; the model is pre-quantized on a large-VRAM GPU, then can be trained and tested on a much smaller one, with the final merge of the adapter into the original model on the large GPU again.
The main drawback we observe so far is a significant speed penalty. However this frammerosk was NOT properly tested yet. Try at your own risk.
(image credit: Nick Evans)
This repository contains complete proof-of-concept code for this approach. We hope it can help fine-tune Grenite models and inform improvement of training frameworks.
Key Innovation: Patches BitsAndBytes to handle 3D MoE expert tensors, enabling 4-bit quantization of frozen layers while training LoRA adapters on unquantized attention and Mamba layers.
This package solves a critical problem: Granite MoE models use 3D weight tensors for their expert layers, which BitsAndBytes didn't originally support for quantization.
What we do:
This is NOT qLoRA (which trains on quantized layers). Instead, we:
Benefits:
# 1. Quantize your Granite model (requires high-VRAM machine: A100 40GB+)
python quantize_and_save_granite.py \
ibm-granite/granite-4.0-h-small \
./granite-small-quantized
# Alternatively, you can use versions on HuggingFace:
# Tiny: https://huggingface.co/ramendik/granite-4.0-h-tiny-stonebnb
# Small: https://huggingface.co/ramendik/granite-4.0-h-small-stonebnb
# 2. Fine-tune with LoRA (works on 32GB GPU for Granite 4-h small, 8 Gb for Granite 4-h Tiny)
python train_lora.py \
--model-name ./granite-small-quantized \
--dataset train_data.jsonl \
--output-dir ./output \
--batch-size 2 \
--gradient-accumulation-steps 8 \
--epochs 3 \
--rank 128 \
--alpha 256
# you can also use --model-name ramendik/granite-4.0-h-small-stonebnb
# Also supports Granite 4-h Tiny
# 3. Test the trained model by inferring, applying the adapter in ./output/final
python
>>> from load_quantized_model import load_quantized_model
>>> from peft import PeftModel
>>> base_model, tokenizer = load_quantized_model("./granite-small-quantized")
# or: base_model, tokenizer = load_quantized_model("ramendik/granite-4.0-h-small-stonebnb")
# Note: load_quantized_model() automatically patches MoE layers for memory-efficient training
>>> model = PeftModel.from_pretrained(base_model, "./output/final")
# 4. Merge adapter into original model (requires high-VRAM machine again)
# 4. Use the merged model (now works anywhere)
python
>>> from transformers import AutoModelForCausalLM, AutoTokenizer
>>> model = AutoModelForCausalLM.from_pretrained("./granite-small-custom")
>>> tokenizer = AutoTokenizer.from_pretrained("./granite-small-custom")
pip install torch transformers bitsandbytes peft datasets accelerate
# HIGHLY RECOMMENDED for long sequences (>4K tokens):
pip install flash-attn --no-build-isolation
# Or download pre-built wheels from:
# - Official: https://github.com/Dao-AILab/flash-attention/releases
# - Community (convenient): https://github.com/mjun0812/flash-attention-prebuild-wheels
Flash Attention 2 is critical if training with sequences longer than ~4K tokens. It reduces attention memory from O(nΒ²) to O(n), preventing OOM errors on long sequences.
# Clone or download the stonebnb directory
git clone https://github.com/mramendi/stonebnb
stonebnb stonebnb
β οΈ Quantization requires enough VRAM to load the full BF16 model:
On a high-VRAM machine:
python quantize_and_save_granite.py \
ibm-granite/granite-8b-code-base \
./granite-8b-quantized
What this does:
Output: A directory with:
pytorch_model.bin - Quantized weights + quant_stateconfig.json - Model configurationquantization_metadata.json - Info about quantized layersOptions:
--quantize-shared-mlp - also quantize the shared MLP layers to save a bit more VRAM. (The MoE router is never quantized)The quantized model can now be copied to machines with less VRAM for training. Alretharivetly you can use a ready quantized model from HuggingFace:
On a 8GB+ GPU for Tiny, 32GB+ GPU for Small:
python train_lora.py \
--model-name ./granite-8b-quantized \
--dataset train_data.jsonl \
--eval-dataset eval_data.jsonl \
--output-dir ./output \
--batch-size 2 \
--gradient-accumulation-steps 8 \
--epochs 3 \
--learning-rate 2e-4 \
--rank 128 \
--alpha 256
NOTE: This is a standard sample training script. Please modify and improve it as necessary for your case, including the addition of an evaluation dataset.
While teh quantized model is stored in the custom StoneBnB format, the resulting adapter is in the standard format.
Dataset Format (JSONL):
{"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"},
{"role": "assistant", "content": "The capital of France is Paris."}
]}
Each line in the JSONL dataset is one conversation. The script:
Training Parameters:
--batch-size: Per-device batch size (start with 2)--gradient-accumulation-steps: Accumulate gradients (effective batch = batch_size Γ this)--rank: LoRA rank (64-256, higher = more capacity but more memory)--alpha: LoRA alpha (typically 2Γrank)--epochs: Number of training epochsMemory Usage (Granite 8B with rank=128):
from load_quantized_model import load_quantized_model
from peft import PeftModel
# Load quantized base model
base_model, tokenizer = load_quantized_model("./granite-8b-quantized", device="cuda")
# Load LoRA adapter on top
model = PeftModel.from_pretrained(base_model, "./output/final")
# Use for inference
messages = [
{"role": "user", "content": "Hello!"}
]
inputs = tokenizer.apply_chat_template(messages, return_tensors="pt").to("cuda")
outputs = model.generate(inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0]))
python merge_adapter.py \
--base-model ibm-granite/granite-4.0-h-small \
--adapter ./output/final \
--output ./granite-small-custom
You can use the resulting standard Safetensors checkpoint like any other model of the same architecture.
Granite MoE models have a unique architecture:
(num_experts, hidden_size, intermediate_size)Standard BitsAndBytes only supports 2D matrices. When you try to quantize 3D tensors:
quant_state.shapereshape() back to original shapeWe patch three BitsAndBytes components:
quantize_4bit (functional.py):
quant_state.shapeParams4bit.cuda() (nn/modules.py):
quant_state.shape to know the target shapeInt4Tensor indexing (custom patch):
__getitem__ support for tensor indexingweight[expert_idx] to work on quantized expertsFile: moe_linear_4bit.py - Contains all patches
The key challenge: How do you train LoRA adapters when they sit on top of frozen quantized layers?
The mechanism:
When you have frozen layers followed by trainable layers, PyTorch's autograd needs to know that even though the frozen layer's weights don't have requires_grad=True, the inputs to those layers still need gradients computed (so they can flow back to the trainable layers before them).
Our solution:
# CRITICAL: Enable input gradient computation
model.enable_input_require_grads()
This tells PyTorch: "Even though these layer weights are frozen (requires_grad=False), still compute gradients with respect to the layer's inputs."
How it works in the computation graph:
Input activations
β (requires_grad=True)
Frozen quantized MoE experts
β (weight.requires_grad=False, but input grads ARE computed)
Attention/Mamba layers
β (requires_grad=True)
LoRA adapters
β (requires_grad=True, these ARE updated)
Output & Loss
Backward pass:
grad flows back through LoRA adapters β (updated)
grad flows back through attention/mamba β (updated via LoRA)
grad flows back through frozen experts β (input grads computed, weights not updated)
grad flows to earlier layers if needed β
Why this is necessary:
Without enable_input_require_grads():
requires_grad=False)With enable_input_require_grads():
Technical details:
The frozen quantized layers act like deterministic functions during training:
dequantize_4bit(weight) @ input (weight is frozen, input has grad)grad_input = grad_output @ weight.T (weight frozen, grad flows to input)This is why we can train through quantized layers safely - they're just frozen operations that pass gradients through.
The model has three types of layers:
MoE Experts (quantized, frozen):
Params4bit (uint8 data + quant_state)shared_mlp; you can quantize them if you wantAttention + Mamba (unquantized, LoRA-adapted):
Other layers (unquantized, frozen):
Gradient flow (forward pass):
input β [frozen quantized experts] β [attention + mamba + LoRA] β output
(no training here) (training happens here)
Why this works:
Key requirements:
model.enable_input_require_grads() - Allows gradients to flow back through frozen layersgradient_checkpointing=True - Saves memory by recomputing activationsQuantized models are saved in the StoneBnB format - a custom serialization format that preserves BitsAndBytes quantization state with 3D tensor support.
What it includes:
Why custom format?
save_pretrained() loses quant_state β model dequantizes on loadlm_head.weight sometimes missing β broken generationFile structure:
granite-8b-stonebnb/
βββ pytorch_model.bin # Weights + quant_state
βββ quantization_metadata.json # Layer info
βββ config.json # Standard HF config
βββ tokenizer files # Standard HF tokenizer
π Full specification: See STONEBNB_FORMAT.md for technical details.
train_lora.py - Main training script (vanilla, well-documented)quantize_and_save_granite.py - Quantize and save Granite modelssave_quantized_model.py - Save quantized model with metadataload_quantized_model.py - Load quantized model for training/inferencemoe_linear_4bit.py - BitsAndBytes patches for 3D MoE tensorsREADME.md - Main documentation (this file)APPROACH.md - Technical deep-dive on the approachSTONEBNB_FORMAT.md - Serialization format specificationcheck_lm_head_in_model.py - Verify lm_head is saved correctlyverify_saved_model_complete.py - List all layers in saved modelfix_missing_lm_head.py - Repair models missing lm_head (if needed)test_quantized_model_repl.py - Interactive testingtest_forward_vs_generate.py - Verify forward/generate worktest_bnb_moe_indexing.py - Test MoE expert indexingThe model was dequantized during loading. Causes:
device_map="auto" instead of device_map={"": "cuda"}Solution: Use load_quantized_model() which handles this correctly.
The lm_head.weight is missing or all zeros.
Solution: Re-quantize with the latest save_quantized_model.py which explicitly saves lm_head.
Solutions:
pip install flash-attn --no-build-isolation
# Or use pre-built wheels: https://github.com/mjun0812/flash-attention-prebuild-wheels
Flash Attention 2 reduces attention memory from O(nΒ²) to O(n). Without it, sequences >4K tokens will likely OOM.--batch-size (try 1)--max-seq-length (try 2048 or 4096)--rank (try 64)Check:
model.enable_input_require_grads() called?By default, only MoE expert layers:
block_sparse_moe.input_linear (3D: experts β hidden)block_sparse_moe.output_linear (3D: experts β hidden)Not quantized (kept in BF16):
You can optionally quantize more layers with --quantize-shared-mlp flag.
We only quantize MoE experts because:
Quantizing the layers we train (attention/mamba) would be qLoRA, which we don't do because:
This is a community contribution to make Granite models more accessible. If you find bugs or have improvements, please share them!
MIT (same as BitsandBytes)
If you use this in your work:
@software{stonebnb_2026,
title = {StoneBnB: BitsAndBytes Quantization for Granite MoE Models},
author = {Misha Ramendik},
year = {2026},
url = {https://github.com/mramendi/stonebnb}
}
NOTE: Claude Code was extensively used in the development of this solution.
Questions? Open an issue or check the Troubleshooting section.
25 commits
Python
100.0%
For most small(ish) LLMs, you can use quantization to reduce VRAM requirements while training. Typically, you just quantize the entire model to a 4 or 8 bit format, train a LoRA adapter on that wuantized model, then apply it to the original BF16 model. This method is called qLoRA and Unsloth supports it directly, using bitsandbytes (BnB) quantization. Another popular method of quantization is torchao.
However, with the IBM Granite 4 Small and Tiny models (Mamba2-hybrid, MoE) qLoRA is not available, at least in 4 bits. Stock BnB fails to compress these models to any significant degree, because it does not natively support the 3D tensors that are used in the MoE MLP layers that comprise the bulk of the models. torchao 4-bit methods can be adapted to compress the tensors and infer, but don't support the backward pass for training.
The result is that one normally needs a GPU with VRAM to fit the entire unquantized BF16 model (so 64 Gb just for the weights of Granite 4 small, before any overhead for actual training). Or maybe a Hopper/Blackwell chip allows FP8 qLoRA - but for Granite 4 Small, that is still 32 Gb, leaving zero space for training on a 5090.
We propose a method of using bitsandbytes with some custom scaffolding and a custom model saving format to quantize the MLP layers in the experts to 4 bits, enabling memory-efficient training. This is not qLoRA - the quantized layers cannot be trained, the layers you train are not quantized. However, training only the attention and Mamba layers is a very common fine-tuning approach with Granite. StoneBnB enables this method with significantly less VRAM; the model is pre-quantized on a large-VRAM GPU, then can be trained and tested on a much smaller one, with the final merge of the adapter into the original model on the large GPU again.
The main drawback we observe so far is a significant speed penalty. However this frammerosk was NOT properly tested yet. Try at your own risk.
(image credit: Nick Evans)
This repository contains complete proof-of-concept code for this approach. We hope it can help fine-tune Grenite models and inform improvement of training frameworks.
Key Innovation: Patches BitsAndBytes to handle 3D MoE expert tensors, enabling 4-bit quantization of frozen layers while training LoRA adapters on unquantized attention and Mamba layers.
This package solves a critical problem: Granite MoE models use 3D weight tensors for their expert layers, which BitsAndBytes didn't originally support for quantization.
What we do:
This is NOT qLoRA (which trains on quantized layers). Instead, we:
Benefits:
# 1. Quantize your Granite model (requires high-VRAM machine: A100 40GB+)
python quantize_and_save_granite.py \
ibm-granite/granite-4.0-h-small \
./granite-small-quantized
# Alternatively, you can use versions on HuggingFace:
# Tiny: https://huggingface.co/ramendik/granite-4.0-h-tiny-stonebnb
# Small: https://huggingface.co/ramendik/granite-4.0-h-small-stonebnb
# 2. Fine-tune with LoRA (works on 32GB GPU for Granite 4-h small, 8 Gb for Granite 4-h Tiny)
python train_lora.py \
--model-name ./granite-small-quantized \
--dataset train_data.jsonl \
--output-dir ./output \
--batch-size 2 \
--gradient-accumulation-steps 8 \
--epochs 3 \
--rank 128 \
--alpha 256
# you can also use --model-name ramendik/granite-4.0-h-small-stonebnb
# Also supports Granite 4-h Tiny
# 3. Test the trained model by inferring, applying the adapter in ./output/final
python
>>> from load_quantized_model import load_quantized_model
>>> from peft import PeftModel
>>> base_model, tokenizer = load_quantized_model("./granite-small-quantized")
# or: base_model, tokenizer = load_quantized_model("ramendik/granite-4.0-h-small-stonebnb")
# Note: load_quantized_model() automatically patches MoE layers for memory-efficient training
>>> model = PeftModel.from_pretrained(base_model, "./output/final")
# 4. Merge adapter into original model (requires high-VRAM machine again)
# 4. Use the merged model (now works anywhere)
python
>>> from transformers import AutoModelForCausalLM, AutoTokenizer
>>> model = AutoModelForCausalLM.from_pretrained("./granite-small-custom")
>>> tokenizer = AutoTokenizer.from_pretrained("./granite-small-custom")
pip install torch transformers bitsandbytes peft datasets accelerate
# HIGHLY RECOMMENDED for long sequences (>4K tokens):
pip install flash-attn --no-build-isolation
# Or download pre-built wheels from:
# - Official: https://github.com/Dao-AILab/flash-attention/releases
# - Community (convenient): https://github.com/mjun0812/flash-attention-prebuild-wheels
Flash Attention 2 is critical if training with sequences longer than ~4K tokens. It reduces attention memory from O(nΒ²) to O(n), preventing OOM errors on long sequences.
# Clone or download the stonebnb directory
git clone https://github.com/mramendi/stonebnb
stonebnb stonebnb
β οΈ Quantization requires enough VRAM to load the full BF16 model:
On a high-VRAM machine:
python quantize_and_save_granite.py \
ibm-granite/granite-8b-code-base \
./granite-8b-quantized
What this does:
Output: A directory with:
pytorch_model.bin - Quantized weights + quant_stateconfig.json - Model configurationquantization_metadata.json - Info about quantized layersOptions:
--quantize-shared-mlp - also quantize the shared MLP layers to save a bit more VRAM. (The MoE router is never quantized)The quantized model can now be copied to machines with less VRAM for training. Alretharivetly you can use a ready quantized model from HuggingFace:
On a 8GB+ GPU for Tiny, 32GB+ GPU for Small:
python train_lora.py \
--model-name ./granite-8b-quantized \
--dataset train_data.jsonl \
--eval-dataset eval_data.jsonl \
--output-dir ./output \
--batch-size 2 \
--gradient-accumulation-steps 8 \
--epochs 3 \
--learning-rate 2e-4 \
--rank 128 \
--alpha 256
NOTE: This is a standard sample training script. Please modify and improve it as necessary for your case, including the addition of an evaluation dataset.
While teh quantized model is stored in the custom StoneBnB format, the resulting adapter is in the standard format.
Dataset Format (JSONL):
{"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"},
{"role": "assistant", "content": "The capital of France is Paris."}
]}
Each line in the JSONL dataset is one conversation. The script:
Training Parameters:
--batch-size: Per-device batch size (start with 2)--gradient-accumulation-steps: Accumulate gradients (effective batch = batch_size Γ this)--rank: LoRA rank (64-256, higher = more capacity but more memory)--alpha: LoRA alpha (typically 2Γrank)--epochs: Number of training epochsMemory Usage (Granite 8B with rank=128):
from load_quantized_model import load_quantized_model
from peft import PeftModel
# Load quantized base model
base_model, tokenizer = load_quantized_model("./granite-8b-quantized", device="cuda")
# Load LoRA adapter on top
model = PeftModel.from_pretrained(base_model, "./output/final")
# Use for inference
messages = [
{"role": "user", "content": "Hello!"}
]
inputs = tokenizer.apply_chat_template(messages, return_tensors="pt").to("cuda")
outputs = model.generate(inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0]))
python merge_adapter.py \
--base-model ibm-granite/granite-4.0-h-small \
--adapter ./output/final \
--output ./granite-small-custom
You can use the resulting standard Safetensors checkpoint like any other model of the same architecture.
Granite MoE models have a unique architecture:
(num_experts, hidden_size, intermediate_size)Standard BitsAndBytes only supports 2D matrices. When you try to quantize 3D tensors:
quant_state.shapereshape() back to original shapeWe patch three BitsAndBytes components:
quantize_4bit (functional.py):
quant_state.shapeParams4bit.cuda() (nn/modules.py):
quant_state.shape to know the target shapeInt4Tensor indexing (custom patch):
__getitem__ support for tensor indexingweight[expert_idx] to work on quantized expertsFile: moe_linear_4bit.py - Contains all patches
The key challenge: How do you train LoRA adapters when they sit on top of frozen quantized layers?
The mechanism:
When you have frozen layers followed by trainable layers, PyTorch's autograd needs to know that even though the frozen layer's weights don't have requires_grad=True, the inputs to those layers still need gradients computed (so they can flow back to the trainable layers before them).
Our solution:
# CRITICAL: Enable input gradient computation
model.enable_input_require_grads()
This tells PyTorch: "Even though these layer weights are frozen (requires_grad=False), still compute gradients with respect to the layer's inputs."
How it works in the computation graph:
Input activations
β (requires_grad=True)
Frozen quantized MoE experts
β (weight.requires_grad=False, but input grads ARE computed)
Attention/Mamba layers
β (requires_grad=True)
LoRA adapters
β (requires_grad=True, these ARE updated)
Output & Loss
Backward pass:
grad flows back through LoRA adapters β (updated)
grad flows back through attention/mamba β (updated via LoRA)
grad flows back through frozen experts β (input grads computed, weights not updated)
grad flows to earlier layers if needed β
Why this is necessary:
Without enable_input_require_grads():
requires_grad=False)With enable_input_require_grads():
Technical details:
The frozen quantized layers act like deterministic functions during training:
dequantize_4bit(weight) @ input (weight is frozen, input has grad)grad_input = grad_output @ weight.T (weight frozen, grad flows to input)This is why we can train through quantized layers safely - they're just frozen operations that pass gradients through.
The model has three types of layers:
MoE Experts (quantized, frozen):
Params4bit (uint8 data + quant_state)shared_mlp; you can quantize them if you wantAttention + Mamba (unquantized, LoRA-adapted):
Other layers (unquantized, frozen):
Gradient flow (forward pass):
input β [frozen quantized experts] β [attention + mamba + LoRA] β output
(no training here) (training happens here)
Why this works:
Key requirements:
model.enable_input_require_grads() - Allows gradients to flow back through frozen layersgradient_checkpointing=True - Saves memory by recomputing activationsQuantized models are saved in the StoneBnB format - a custom serialization format that preserves BitsAndBytes quantization state with 3D tensor support.
What it includes:
Why custom format?
save_pretrained() loses quant_state β model dequantizes on loadlm_head.weight sometimes missing β broken generationFile structure:
granite-8b-stonebnb/
βββ pytorch_model.bin # Weights + quant_state
βββ quantization_metadata.json # Layer info
βββ config.json # Standard HF config
βββ tokenizer files # Standard HF tokenizer
π Full specification: See STONEBNB_FORMAT.md for technical details.
train_lora.py - Main training script (vanilla, well-documented)quantize_and_save_granite.py - Quantize and save Granite modelssave_quantized_model.py - Save quantized model with metadataload_quantized_model.py - Load quantized model for training/inferencemoe_linear_4bit.py - BitsAndBytes patches for 3D MoE tensorsREADME.md - Main documentation (this file)APPROACH.md - Technical deep-dive on the approachSTONEBNB_FORMAT.md - Serialization format specificationcheck_lm_head_in_model.py - Verify lm_head is saved correctlyverify_saved_model_complete.py - List all layers in saved modelfix_missing_lm_head.py - Repair models missing lm_head (if needed)test_quantized_model_repl.py - Interactive testingtest_forward_vs_generate.py - Verify forward/generate worktest_bnb_moe_indexing.py - Test MoE expert indexingThe model was dequantized during loading. Causes:
device_map="auto" instead of device_map={"": "cuda"}Solution: Use load_quantized_model() which handles this correctly.
The lm_head.weight is missing or all zeros.
Solution: Re-quantize with the latest save_quantized_model.py which explicitly saves lm_head.
Solutions:
pip install flash-attn --no-build-isolation
# Or use pre-built wheels: https://github.com/mjun0812/flash-attention-prebuild-wheels
Flash Attention 2 reduces attention memory from O(nΒ²) to O(n). Without it, sequences >4K tokens will likely OOM.--batch-size (try 1)--max-seq-length (try 2048 or 4096)--rank (try 64)Check:
model.enable_input_require_grads() called?By default, only MoE expert layers:
block_sparse_moe.input_linear (3D: experts β hidden)block_sparse_moe.output_linear (3D: experts β hidden)Not quantized (kept in BF16):
You can optionally quantize more layers with --quantize-shared-mlp flag.
We only quantize MoE experts because:
Quantizing the layers we train (attention/mamba) would be qLoRA, which we don't do because:
This is a community contribution to make Granite models more accessible. If you find bugs or have improvements, please share them!
MIT (same as BitsandBytes)
If you use this in your work:
@software{stonebnb_2026,
title = {StoneBnB: BitsAndBytes Quantization for Granite MoE Models},
author = {Misha Ramendik},
year = {2026},
url = {https://github.com/mramendi/stonebnb}
}
NOTE: Claude Code was extensively used in the development of this solution.
Questions? Open an issue or check the Troubleshooting section.
25 commits
Python
100.0%