Instructions to use mohammad-mozaffari/llama_2_7b-PATCH-35Sparse with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use mohammad-mozaffari/llama_2_7b-PATCH-35Sparse with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="mohammad-mozaffari/llama_2_7b-PATCH-35Sparse")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("mohammad-mozaffari/llama_2_7b-PATCH-35Sparse", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use mohammad-mozaffari/llama_2_7b-PATCH-35Sparse with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "mohammad-mozaffari/llama_2_7b-PATCH-35Sparse" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "mohammad-mozaffari/llama_2_7b-PATCH-35Sparse", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/mohammad-mozaffari/llama_2_7b-PATCH-35Sparse
- SGLang
How to use mohammad-mozaffari/llama_2_7b-PATCH-35Sparse with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "mohammad-mozaffari/llama_2_7b-PATCH-35Sparse" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "mohammad-mozaffari/llama_2_7b-PATCH-35Sparse", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "mohammad-mozaffari/llama_2_7b-PATCH-35Sparse" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "mohammad-mozaffari/llama_2_7b-PATCH-35Sparse", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use mohammad-mozaffari/llama_2_7b-PATCH-35Sparse with Docker Model Runner:
docker model run hf.co/mohammad-mozaffari/llama_2_7b-PATCH-35Sparse
Release llama_2_7b-PATCH-35Sparse (mask only)
Browse files- .gitattributes +1 -0
- NOTICE +10 -0
- PATCH-Logo.png +3 -0
- PATCH-Pipeline.svg +0 -0
- README.md +132 -0
- load_patch_mask.py +93 -0
- mask.npz +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
PATCH-Logo.png filter=lfs diff=lfs merge=lfs -text
|
NOTICE
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
This repository distributes ONLY a binary pruning mask (which weight
|
| 2 |
+
positions are kept vs. zeroed). It contains no weights from the base model.
|
| 3 |
+
|
| 4 |
+
The mask is a derivative of the base model listed in the model card and is
|
| 5 |
+
provided under that base model's license. You must independently obtain the base
|
| 6 |
+
model and comply with its license and acceptable-use policy.
|
| 7 |
+
|
| 8 |
+
Mask-generation code: MIT (https://github.com/Paramathic/patch).
|
| 9 |
+
MaskLLM baselines are our own re-implementation; the MaskLLM method is due to
|
| 10 |
+
Fang et al. (NVIDIA), NeurIPS 2024.
|
PATCH-Logo.png
ADDED
|
Git LFS Details
|
PATCH-Pipeline.svg
ADDED
|
|
README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
base_model:
|
| 3 |
+
- meta-llama/Llama-2-7b-hf
|
| 4 |
+
library_name: transformers
|
| 5 |
+
license: llama2
|
| 6 |
+
tags:
|
| 7 |
+
- pruning
|
| 8 |
+
- sparsity
|
| 9 |
+
- 2:4-sparsity
|
| 10 |
+
- patch
|
| 11 |
+
- maskllm
|
| 12 |
+
- mask
|
| 13 |
+
pipeline_tag: text-generation
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
<div align="center">
|
| 17 |
+
<img src="./PATCH-Logo.png" alt="PATCH" width="360">
|
| 18 |
+
</div>
|
| 19 |
+
|
| 20 |
+
# llama_2_7b-PATCH-35Sparse
|
| 21 |
+
|
| 22 |
+
> **This checkpoint** (LLaMA-2 7B, PATCH-Tile, 35% sparsity): **50.08%** average zero-shot accuracy, **6.18** WikiText2 perplexity.
|
| 23 |
+
|
| 24 |
+
[](https://arxiv.org/abs/2509.23410) [](https://github.com/Paramathic/patch)
|
| 25 |
+
|
| 26 |
+
This repository hosts a **mask only** release for the paper
|
| 27 |
+
**[PATCH: Learnable Tile-level Hybrid Sparsity for LLMs](https://arxiv.org/abs/2509.23410)**.
|
| 28 |
+
PATCH (Pruning with a Learnable Tile-level Configuration for Hybrid Sparsity) learns a structured mask on **frozen** pretrained weights, assigning each tile as dense (0% sparsity) or 2:4 sparse (50% sparsity) to hit a flexible global sparsity target while staying hardware-friendly.
|
| 29 |
+
|
| 30 |
+
Because PATCH/MaskLLM keep the base weights **frozen**, we distribute *only the
|
| 31 |
+
binary keep/prune mask* (bit-packed in `mask.npz`) - **no weight values**. You
|
| 32 |
+
recover the sparse model by downloading the original base model and applying the
|
| 33 |
+
mask.
|
| 34 |
+
|
| 35 |
+
- Base model: [`meta-llama/Llama-2-7b-hf`](https://huggingface.co/meta-llama/Llama-2-7b-hf)
|
| 36 |
+
- Method: **PATCH-Tile** | Target sparsity: **35%** | Pattern: **Dense / 2:4 tiles**
|
| 37 |
+
- Measured mask sparsity: **35.08%** over 224 Linear layers (6,476,005,376 weights).
|
| 38 |
+
|
| 39 |
+
<div align="center">
|
| 40 |
+
<img src="./PATCH-Pipeline.svg" alt="PATCH pipeline" width="760">
|
| 41 |
+
</div>
|
| 42 |
+
|
| 43 |
+
## Results (LLaMA-2 7B)
|
| 44 |
+
|
| 45 |
+
| Sparsity | Method | Pattern | Avg Acc (% ↑) | WikiText2 PPL (↓) |
|
| 46 |
+
|---|---|---|---|---|
|
| 47 |
+
| 0% | Dense | - | 54.61 | 5.12 |
|
| 48 |
+
| 50% | Magnitude | 2:4 | 43.44 | 54.39 |
|
| 49 |
+
| 50% | Wanda | 2:4 | 44.30 | 11.15 |
|
| 50 |
+
| 50% | SparseGPT | 2:4 | 45.09 | 10.12 |
|
| 51 |
+
| 50% | Thanos | 2:4 | 44.80 | 11.19 |
|
| 52 |
+
| 50% | ProxSparse | 2:4 | 45.92 | 9.18 |
|
| 53 |
+
| 50% | MaskLLM | 2:4 | 48.62 | 6.78 |
|
| 54 |
+
| 45% | PATCH-Tile | Dense/2:4 | 48.99 | 6.55 |
|
| 55 |
+
| 35% | **PATCH-Tile** ⭐ | Dense/2:4 | **50.08** | **6.18** |
|
| 56 |
+
| 25% | PATCH-Tile | Dense/2:4 | 51.58 | 5.86 |
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
Per-task zero-shot accuracy (%) for this checkpoint:
|
| 60 |
+
|
| 61 |
+
| MMLU | PIQA | ARC-E | ARC-C | WinoG. | OBQA | RACE | HellaS. | **Average** |
|
| 62 |
+
|---|---|---|---|---|---|---|---|---|
|
| 63 |
+
| 29.93 | 76.71 | 70.88 | 36.95 | 65.67 | 28.20 | 39.33 | 52.96 | **50.08** |
|
| 64 |
+
|
| 65 |
+
All numbers are from the PATCH paper ([arXiv:2509.23410](https://arxiv.org/abs/2509.23410)); accuracy
|
| 66 |
+
is the average over MMLU, PIQA, ARC-Easy, ARC-Challenge, Winogrande, OpenBookQA,
|
| 67 |
+
RACE and HellaSwag, evaluated with the LM-Evaluation-Harness. PPL is WikiText2.
|
| 68 |
+
|
| 69 |
+
## Training hyper-parameters
|
| 70 |
+
|
| 71 |
+
| Hyper-parameter | Value |
|
| 72 |
+
|---|---|
|
| 73 |
+
| Fine-tuning dataset | SlimPajama (2B tokens) |
|
| 74 |
+
| Training steps | 2000 |
|
| 75 |
+
| Global batch size | 256 |
|
| 76 |
+
| Sequence length | 4096 |
|
| 77 |
+
| Mask tile size | 128 x 128 (hardware tiles: 128x128 / 128x64 / 64x128 / 64x64) |
|
| 78 |
+
| Logits init. | N(0, 0.014) |
|
| 79 |
+
| Tile-logit prior | SparseGPT (strength 3) |
|
| 80 |
+
| Regularization scope | Global (single target density) |
|
| 81 |
+
| Evaluation | LM-Eval-Harness (8 zero-shot tasks) + WikiText2 PPL @ seqlen 4096 |
|
| 82 |
+
| Hardware | 1 node x 4 GPUs, data parallel (HuggingFace Trainer) |
|
| 83 |
+
| Optimizer | Adam |
|
| 84 |
+
| Learning rate | 1e-4 |
|
| 85 |
+
| Gumbel scaling (kappa) | 100 -> 500 |
|
| 86 |
+
| Gumbel temp (tau) | 2 -> 0.05 |
|
| 87 |
+
| Sparsity reg. (lambda1) | 3 |
|
| 88 |
+
| Weight reg. (lambda2) | 0.1 |
|
| 89 |
+
|
| 90 |
+
## How to use
|
| 91 |
+
|
| 92 |
+
```python
|
| 93 |
+
from huggingface_hub import hf_hub_download
|
| 94 |
+
from transformers import AutoModelForCausalLM
|
| 95 |
+
import torch
|
| 96 |
+
from load_patch_mask import apply_patch_mask # shipped in this repo
|
| 97 |
+
|
| 98 |
+
npz = hf_hub_download(repo_id="mohammad-mozaffari/llama_2_7b-PATCH-35Sparse", filename="mask.npz")
|
| 99 |
+
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf", torch_dtype=torch.bfloat16)
|
| 100 |
+
apply_patch_mask(model, npz) # zeroes the pruned weights in place
|
| 101 |
+
```
|
| 102 |
+
|
| 103 |
+
Or from the command line:
|
| 104 |
+
|
| 105 |
+
```bash
|
| 106 |
+
python load_patch_mask.py --base_model meta-llama/Llama-2-7b-hf --mask_repo mohammad-mozaffari/llama_2_7b-PATCH-35Sparse
|
| 107 |
+
```
|
| 108 |
+
|
| 109 |
+
Speedup on real hardware requires a 2:4-aware / hybrid sparse kernel; see the
|
| 110 |
+
[GitHub repository](https://github.com/Paramathic/patch) and [STOICC](https://github.com/Paramathic/stoicc).
|
| 111 |
+
|
| 112 |
+
## License
|
| 113 |
+
|
| 114 |
+
The released mask is a derivative of the base model and is distributed under the
|
| 115 |
+
base model's license (**`llama2`**). You must comply with that license and
|
| 116 |
+
obtain access to the base model separately.
|
| 117 |
+
|
| 118 |
+
> Use governed by the Llama 2 Community License.
|
| 119 |
+
|
| 120 |
+
The mask-generation code is released under the MIT license (see the
|
| 121 |
+
[PATCH repository](https://github.com/Paramathic/patch)).
|
| 122 |
+
|
| 123 |
+
## Citation
|
| 124 |
+
|
| 125 |
+
```bibtex
|
| 126 |
+
@article{hourri2025patch,
|
| 127 |
+
title = {PATCH: Learnable Tile-level Hybrid Sparsity for LLMs},
|
| 128 |
+
author = {Hourri, Younes and Mozaffari, Mohammad and Mehri Dehnavi, Maryam},
|
| 129 |
+
year = 2025,
|
| 130 |
+
journal = {arXiv preprint arXiv:2509.23410}
|
| 131 |
+
}
|
| 132 |
+
```
|
load_patch_mask.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Apply a released PATCH / MaskLLM sparsity mask to a base model.
|
| 3 |
+
|
| 4 |
+
The released repositories contain ONLY the binary keep/prune mask
|
| 5 |
+
(bit-packed in `mask.npz`) - no weight values. To materialize the sparse
|
| 6 |
+
model you download the original base model and zero out the pruned weights:
|
| 7 |
+
|
| 8 |
+
python load_patch_mask.py \
|
| 9 |
+
--base_model meta-llama/Llama-2-7b-hf \
|
| 10 |
+
--mask_repo mohammad-mozaffari/llama_2_7b-PATCH-45Sparse
|
| 11 |
+
|
| 12 |
+
or use `apply_patch_mask(...)` from your own code.
|
| 13 |
+
"""
|
| 14 |
+
|
| 15 |
+
import argparse
|
| 16 |
+
import json
|
| 17 |
+
|
| 18 |
+
import numpy as np
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def load_mask_npz(npz_path):
|
| 22 |
+
"""
|
| 23 |
+
Load `mask.npz` and return {weight_name: bool_ndarray} plus metadata.
|
| 24 |
+
|
| 25 |
+
The archive stores, per masked weight:
|
| 26 |
+
* "<name>" : bit-packed uint8 array (np.packbits of the flat mask)
|
| 27 |
+
* "<name>.__shape__": original 2-D shape
|
| 28 |
+
and a single JSON blob under "__meta__".
|
| 29 |
+
"""
|
| 30 |
+
data = np.load(npz_path, allow_pickle=False)
|
| 31 |
+
meta = json.loads(str(data["__meta__"])) if "__meta__" in data else {}
|
| 32 |
+
masks = {}
|
| 33 |
+
for key in data.files:
|
| 34 |
+
if key == "__meta__" or key.endswith(".__shape__"):
|
| 35 |
+
continue
|
| 36 |
+
shape = tuple(int(x) for x in data[f"{key}.__shape__"])
|
| 37 |
+
n = int(np.prod(shape))
|
| 38 |
+
flat = np.unpackbits(data[key], count=n).astype(bool)
|
| 39 |
+
masks[key] = flat.reshape(shape)
|
| 40 |
+
return masks, meta
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def apply_patch_mask(model, npz_path):
|
| 44 |
+
"""Zero out pruned weights of `model` in place using the mask archive."""
|
| 45 |
+
import torch
|
| 46 |
+
|
| 47 |
+
masks, meta = load_mask_npz(npz_path)
|
| 48 |
+
sd = dict(model.named_parameters())
|
| 49 |
+
applied = 0
|
| 50 |
+
for name, mask in masks.items():
|
| 51 |
+
if name not in sd:
|
| 52 |
+
raise KeyError(
|
| 53 |
+
f"Mask key '{name}' not found in model parameters. "
|
| 54 |
+
f"Is '{meta.get('base_model', '?')}' the correct base model?"
|
| 55 |
+
)
|
| 56 |
+
w = sd[name]
|
| 57 |
+
m = torch.from_numpy(mask).to(device=w.device)
|
| 58 |
+
if tuple(m.shape) != tuple(w.shape):
|
| 59 |
+
raise ValueError(f"Shape mismatch for {name}: mask {tuple(m.shape)} vs weight {tuple(w.shape)}")
|
| 60 |
+
with torch.no_grad():
|
| 61 |
+
w.mul_(m.to(w.dtype))
|
| 62 |
+
applied += 1
|
| 63 |
+
print(f"Applied mask to {applied} weight tensors "
|
| 64 |
+
f"(target sparsity {meta.get('sparsity', '?')}, pattern {meta.get('pattern', '?')}).")
|
| 65 |
+
return model
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def _main():
|
| 69 |
+
from huggingface_hub import hf_hub_download
|
| 70 |
+
from transformers import AutoModelForCausalLM
|
| 71 |
+
|
| 72 |
+
p = argparse.ArgumentParser()
|
| 73 |
+
p.add_argument("--base_model", required=True, help="HF id of the original dense base model")
|
| 74 |
+
p.add_argument("--mask_repo", required=True, help="HF id of the released mask repo")
|
| 75 |
+
p.add_argument("--dtype", default="bfloat16")
|
| 76 |
+
args = p.parse_args()
|
| 77 |
+
|
| 78 |
+
import torch
|
| 79 |
+
|
| 80 |
+
npz_path = hf_hub_download(repo_id=args.mask_repo, filename="mask.npz")
|
| 81 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 82 |
+
args.base_model, torch_dtype=getattr(torch, args.dtype)
|
| 83 |
+
)
|
| 84 |
+
apply_patch_mask(model, npz_path)
|
| 85 |
+
|
| 86 |
+
total = sum(p.numel() for p in model.parameters())
|
| 87 |
+
nz = sum(int((p != 0).sum()) for p in model.parameters())
|
| 88 |
+
print(f"Overall model density after masking: {nz / total:.4f}")
|
| 89 |
+
return model
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
if __name__ == "__main__":
|
| 93 |
+
_main()
|
mask.npz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5cfb1e7360b3108b60ea8dcc4b6af01872eb973beb3c66c07b152908a94736d6
|
| 3 |
+
size 405350657
|