quantbench-engine 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quantbench_engine-0.1.1/.github/ISSUE_TEMPLATE/bug_report.yml +65 -0
- quantbench_engine-0.1.1/.github/ISSUE_TEMPLATE/config.yml +8 -0
- quantbench_engine-0.1.1/.github/ISSUE_TEMPLATE/feature_request.yml +44 -0
- quantbench_engine-0.1.1/.github/pull_request_template.md +28 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/.github/workflows/ci.yml +3 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/.github/workflows/release.yml +1 -1
- quantbench_engine-0.1.1/.pre-commit-config.yaml +18 -0
- quantbench_engine-0.1.1/CODE_OF_CONDUCT.md +43 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/PKG-INFO +5 -6
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/README.md +4 -5
- quantbench_engine-0.1.1/SECURITY.md +31 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/examples/01_quant_linear_inference.py +2 -4
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/pyproject.toml +78 -78
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/__init__.py +1 -1
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/bench/pareto.py +1 -3
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/cli.py +2 -6
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/algorithms/awq.py +4 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/algorithms/gptq.py +1 -3
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/packing/sparse_pack.py +1 -6
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/tests/test_packing.py +7 -4
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/tests/test_primitives.py +2 -3
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/tests/test_quant_linear.py +3 -6
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/uv.lock +1204 -1204
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/.gitignore +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/CONTRIBUTING.md +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/DEVLOG.md +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/GUIDE.md +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/LICENSE +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/examples/02_advanced_calibration.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/examples/03_servebench_roofline_eval.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/bench/__init__.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/eval/__init__.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/eval/perplexity.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/eval/sqnr.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/nn/__init__.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/nn/model_convert.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/nn/quant_linear.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/__init__.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/affine.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/algorithms/__init__.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/algorithms/smoothquant.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/blockwise.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/fp8.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/packing/__init__.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/packing/int4_pack.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/packing/ternary_pack.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/tests/test_algorithms.py +0 -0
- {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/tests/test_eval_and_pareto.py +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: "🐛 Bug Report"
|
|
2
|
+
description: "Report a bug, numerical error, or bit-packing discrepancy in quantbench-engine"
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug", "triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thank you for reporting an issue in `quantbench-engine`! Please ensure you are running the latest version.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: description
|
|
13
|
+
attributes:
|
|
14
|
+
label: Description of the Bug
|
|
15
|
+
description: What went wrong during quantization, packing, or model conversion?
|
|
16
|
+
placeholder: "When quantizing a linear layer with INT4 and group_size=32..."
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: reproduction
|
|
22
|
+
attributes:
|
|
23
|
+
label: Minimal Steps to Reproduce
|
|
24
|
+
description: Exact CLI command or minimal Python code snippet reproducing the numerical or execution issue.
|
|
25
|
+
placeholder: |
|
|
26
|
+
import torch
|
|
27
|
+
from quantbench.quant.packing import pack_int4, unpack_int4
|
|
28
|
+
# ...
|
|
29
|
+
validations:
|
|
30
|
+
required: true
|
|
31
|
+
|
|
32
|
+
- type: textarea
|
|
33
|
+
id: traceback
|
|
34
|
+
attributes:
|
|
35
|
+
label: Error Traceback / Logs
|
|
36
|
+
description: Paste the console traceback inside a code block.
|
|
37
|
+
render: shell
|
|
38
|
+
validations:
|
|
39
|
+
required: false
|
|
40
|
+
|
|
41
|
+
- type: textarea
|
|
42
|
+
id: environment
|
|
43
|
+
attributes:
|
|
44
|
+
label: Environment Diagnostics
|
|
45
|
+
description: Details about your environment.
|
|
46
|
+
placeholder: |
|
|
47
|
+
- OS: Windows 11 / Ubuntu 22.04 / macOS
|
|
48
|
+
- Python Version: (e.g. 3.12.10)
|
|
49
|
+
- PyTorch Version: (e.g. 2.5.1)
|
|
50
|
+
- Device: (CUDA / CPU / MPS)
|
|
51
|
+
- quantbench-engine Version: (e.g. 0.1.2)
|
|
52
|
+
validations:
|
|
53
|
+
required: true
|
|
54
|
+
|
|
55
|
+
- type: checkboxes
|
|
56
|
+
id: confirmation
|
|
57
|
+
attributes:
|
|
58
|
+
label: Validation Checklist
|
|
59
|
+
options:
|
|
60
|
+
- label: I have verified this bug occurs on the latest `main` branch or PyPI release.
|
|
61
|
+
required: true
|
|
62
|
+
- label: I have checked open/closed issues to avoid duplicates.
|
|
63
|
+
required: true
|
|
64
|
+
- label: I am willing to submit a Pull Request to fix this.
|
|
65
|
+
required: false
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: 📖 Quantbench Documentation & Educational Guides
|
|
4
|
+
url: https://github.com/Prajwal7-2002/quantbench#readme
|
|
5
|
+
about: Read our comprehensive guides on sub-byte quantization and hardware sparsity.
|
|
6
|
+
- name: 🔒 Report a Security Vulnerability
|
|
7
|
+
url: https://github.com/Prajwal7-2002/quantbench/security/advisories/new
|
|
8
|
+
about: Privately disclose sensitive security vulnerabilities to maintainers.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: "✨ Feature Request / Quantization Scheme Proposal"
|
|
2
|
+
description: "Suggest a new sub-byte quantization scheme, calibration algorithm, or hardware backend"
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement", "proposal"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thank you for proposing a feature for `quantbench-engine`! We welcome proposals for sub-byte quantization algorithms, calibration methods, and packing runtimes.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: problem
|
|
13
|
+
attributes:
|
|
14
|
+
label: Motivation / Use Case
|
|
15
|
+
description: What quantization scheme, calibration method, or compression format does this address?
|
|
16
|
+
placeholder: "We want to support FP4 (NV-FP4 microscaling) with E2M1 representation..."
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: proposal
|
|
22
|
+
attributes:
|
|
23
|
+
label: Proposed Implementation & Bit-Packing Layout
|
|
24
|
+
description: Describe the mathematical formulation, bit-layout, and vectorized PyTorch implementation.
|
|
25
|
+
placeholder: |
|
|
26
|
+
Implement `pack_fp4` using 2 weights per byte with a per-block 8-bit scale factor...
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
29
|
+
|
|
30
|
+
- type: textarea
|
|
31
|
+
id: vectorization
|
|
32
|
+
attributes:
|
|
33
|
+
label: Vectorization & Performance Verification
|
|
34
|
+
description: Confirm this can be implemented with pure PyTorch tensor operations without Python loops.
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
|
|
38
|
+
- type: checkboxes
|
|
39
|
+
id: willingness
|
|
40
|
+
attributes:
|
|
41
|
+
label: Contribution Readiness
|
|
42
|
+
options:
|
|
43
|
+
- label: I am willing to implement this feature and submit a PR.
|
|
44
|
+
required: false
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
<!-- Briefly describe what this PR does, why it is needed, and link any related issues. -->
|
|
3
|
+
|
|
4
|
+
Fixes #(issue)
|
|
5
|
+
|
|
6
|
+
## Type of Change
|
|
7
|
+
<!-- Please check all options that apply -->
|
|
8
|
+
- [ ] 🐛 Bug fix (non-breaking change fixing an issue)
|
|
9
|
+
- [ ] ✨ New feature (new quantization scheme, calibration algorithm, or packing format)
|
|
10
|
+
- [ ] ⚡ Performance optimization (vectorization speedup or memory compression)
|
|
11
|
+
- [ ] 📚 Documentation update (guides, docstrings, README)
|
|
12
|
+
- [ ] 🧪 Tests (coverage expansion or mathematical invariant verification)
|
|
13
|
+
- [ ] 💥 Breaking change (fix or feature that breaks existing `QuantLinear` or packing contracts)
|
|
14
|
+
|
|
15
|
+
## Quantization & Bit-Packing Invariants
|
|
16
|
+
<!-- If this PR introduces or modifies a bit-packing format, packing/unpacking roundtrip tests are mandatory. -->
|
|
17
|
+
* **Precision Scheme**: (e.g. INT4 / INT8 / BitNet Ternary / FP8 / Ampere 2:4)
|
|
18
|
+
* **Packing Ratio**: `____ bits/weight` | `____ x compression vs FP16`
|
|
19
|
+
* **SQNR / Perplexity Impact**: `____ dB SQNR` | `____ perplexity on WikiText-2`
|
|
20
|
+
|
|
21
|
+
## Architectural Invariants Checklist
|
|
22
|
+
<!-- You MUST verify and check every item below before submitting -->
|
|
23
|
+
- [ ] **Exact Scalar & Tensor Roundtripping**: Packing and unpacking functions tested for bit-exact reconstruction within precision limits.
|
|
24
|
+
- [ ] **Pure PyTorch Vectorization**: Implemented with vectorized bitwise shifts/masks (`torch.bitwise_left_shift`, `torch.bitwise_right_shift`). Zero scalar loops over tensor elements.
|
|
25
|
+
- [ ] **Unit Tests & Coverage**: Ran `uv run python -m pytest` (100% pass rate, maintained >= 90% coverage).
|
|
26
|
+
- [ ] **Formatting & Linting**: Ran `uv run ruff check .` and `uv run ruff format --check .` with zero errors.
|
|
27
|
+
- [ ] **Documentation**: Updated `README.md` or docstrings if modifying CLI subcommands or quantization arguments.
|
|
28
|
+
- [ ] **Clean Commits**: Follows conventional commit format (`feat:`, `fix:`, `perf:`, `docs:`, `test:`).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-toml
|
|
9
|
+
- id: check-added-large-files
|
|
10
|
+
args: ["--maxkb=2000"]
|
|
11
|
+
- id: check-merge-conflict
|
|
12
|
+
|
|
13
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
14
|
+
rev: v0.9.3
|
|
15
|
+
hooks:
|
|
16
|
+
- id: ruff
|
|
17
|
+
args: ["--fix"]
|
|
18
|
+
- id: ruff-format
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
|
|
6
|
+
|
|
7
|
+
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
|
8
|
+
|
|
9
|
+
## Our Standards
|
|
10
|
+
|
|
11
|
+
Examples of behavior that contributes to a positive environment for our community include:
|
|
12
|
+
|
|
13
|
+
* Demonstrating empathy and kindness toward other people
|
|
14
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
15
|
+
* Giving and gracefully accepting constructive feedback
|
|
16
|
+
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
|
17
|
+
* Focusing on what is best not just for us as individuals, but for the overall community
|
|
18
|
+
|
|
19
|
+
Examples of unacceptable behavior include:
|
|
20
|
+
|
|
21
|
+
* The use of sexualized language or imagery, and sexual attention or advances of any kind
|
|
22
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
23
|
+
* Public or private harassment
|
|
24
|
+
* Publishing others' private information, such as a physical or email address, without their explicit permission
|
|
25
|
+
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
26
|
+
|
|
27
|
+
## Enforcement Responsibilities
|
|
28
|
+
|
|
29
|
+
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
|
30
|
+
|
|
31
|
+
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
|
|
32
|
+
|
|
33
|
+
## Scope
|
|
34
|
+
|
|
35
|
+
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces.
|
|
36
|
+
|
|
37
|
+
## Enforcement
|
|
38
|
+
|
|
39
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community maintainer at `prajwalpujari16@gmail.com`. All complaints will be reviewed and investigated promptly and fairly.
|
|
40
|
+
|
|
41
|
+
## Attribution
|
|
42
|
+
|
|
43
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: quantbench-engine
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: First-principles LLM quantization engine, bit-packing runtimes, 2:4 sparsity, and Quality-vs-Speed Pareto evaluation benchmark.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Prajwal7-2002/quantbench
|
|
6
6
|
Project-URL: Documentation, https://prajwal7-2002.github.io/quantbench/
|
|
@@ -28,6 +28,7 @@ Description-Content-Type: text/markdown
|
|
|
28
28
|
|
|
29
29
|
# quantbench ⚖️
|
|
30
30
|
|
|
31
|
+
[](https://pypi.org/project/quantbench-engine/)
|
|
31
32
|
[](https://github.com/Prajwal7-2002/quantbench/actions)
|
|
32
33
|
[](LICENSE)
|
|
33
34
|
[](https://www.python.org/)
|
|
@@ -102,20 +103,18 @@ Because hardware cannot address sub-byte boundaries, weights are packed into vec
|
|
|
102
103
|
|
|
103
104
|
---
|
|
104
105
|
|
|
105
|
-
---
|
|
106
|
-
|
|
107
106
|
## 📦 Installation
|
|
108
107
|
|
|
109
|
-
Install `quantbench` directly from PyPI:
|
|
108
|
+
Install `quantbench` directly from [PyPI](https://pypi.org/project/quantbench-engine/):
|
|
110
109
|
|
|
111
110
|
```bash
|
|
112
|
-
pip install quantbench
|
|
111
|
+
pip install quantbench-engine
|
|
113
112
|
```
|
|
114
113
|
|
|
115
114
|
Or using [uv](https://docs.astral.sh/uv/):
|
|
116
115
|
|
|
117
116
|
```bash
|
|
118
|
-
uv add quantbench
|
|
117
|
+
uv add quantbench-engine
|
|
119
118
|
```
|
|
120
119
|
|
|
121
120
|
To install from source for development:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# quantbench ⚖️
|
|
2
2
|
|
|
3
|
+
[](https://pypi.org/project/quantbench-engine/)
|
|
3
4
|
[](https://github.com/Prajwal7-2002/quantbench/actions)
|
|
4
5
|
[](LICENSE)
|
|
5
6
|
[](https://www.python.org/)
|
|
@@ -74,20 +75,18 @@ Because hardware cannot address sub-byte boundaries, weights are packed into vec
|
|
|
74
75
|
|
|
75
76
|
---
|
|
76
77
|
|
|
77
|
-
---
|
|
78
|
-
|
|
79
78
|
## 📦 Installation
|
|
80
79
|
|
|
81
|
-
Install `quantbench` directly from PyPI:
|
|
80
|
+
Install `quantbench` directly from [PyPI](https://pypi.org/project/quantbench-engine/):
|
|
82
81
|
|
|
83
82
|
```bash
|
|
84
|
-
pip install quantbench
|
|
83
|
+
pip install quantbench-engine
|
|
85
84
|
```
|
|
86
85
|
|
|
87
86
|
Or using [uv](https://docs.astral.sh/uv/):
|
|
88
87
|
|
|
89
88
|
```bash
|
|
90
|
-
uv add quantbench
|
|
89
|
+
uv add quantbench-engine
|
|
91
90
|
```
|
|
92
91
|
|
|
93
92
|
To install from source for development:
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Security Policy 🔒
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
| :--- | :--- |
|
|
7
|
+
| `0.1.x` | :white_check_mark: |
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Safe Tensor Guidelines
|
|
12
|
+
|
|
13
|
+
1. **Pure Tensor Math**: `quantbench-engine` performs purely arithmetic bit-packing and matrix operations. It requires zero network connectivity.
|
|
14
|
+
2. **Safe Serialization**: Saved quantized checkpoints strictly serialize standard integer and float tensor dictionaries (`state_dict`). Untrusted pickle formats should never be loaded.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Reporting a Vulnerability
|
|
19
|
+
|
|
20
|
+
If you discover a security vulnerability or numerical flaw that impacts host security:
|
|
21
|
+
|
|
22
|
+
* **Please DO NOT file a public issue.**
|
|
23
|
+
* Report the issue privately through [GitHub's Private Vulnerability Reporting](https://github.com/Prajwal7-2002/quantbench/security/advisories/new) or email maintainer Prajwal Pujari at `prajwalpujari16@gmail.com`.
|
|
24
|
+
|
|
25
|
+
### Submission Checklist
|
|
26
|
+
Please include:
|
|
27
|
+
1. Clear description of the vulnerability.
|
|
28
|
+
2. Minimal reproduction script.
|
|
29
|
+
3. Potential security impact.
|
|
30
|
+
|
|
31
|
+
You will receive an acknowledgment within 48 hours, followed by updates on the fix and coordinated disclosure.
|
|
@@ -56,8 +56,7 @@ def main() -> None:
|
|
|
56
56
|
print("\n[3] Converted to QuantLinear (BitNet 1.58b {-1, 0, +1}):")
|
|
57
57
|
print(f" Packed Buffer : {list(q_ternary.packed_weight.shape)} (4 weights/byte)")
|
|
58
58
|
print(
|
|
59
|
-
f" Memory Footprint : {mb_t:.2f} MB "
|
|
60
|
-
f"({r_t_fp32:.2f}x vs FP32, {r_t_fp16:.2f}x vs FP16)"
|
|
59
|
+
f" Memory Footprint : {mb_t:.2f} MB ({r_t_fp32:.2f}x vs FP32, {r_t_fp16:.2f}x vs FP16)"
|
|
61
60
|
)
|
|
62
61
|
|
|
63
62
|
# 3. Ampere 2:4 Structured Sparsity QuantLinear
|
|
@@ -71,8 +70,7 @@ def main() -> None:
|
|
|
71
70
|
print(f" Condensed Buffer : {list(q_sparse.condensed_weight.shape)} (50% non-zeros)")
|
|
72
71
|
print(f" Index Metadata : {list(q_sparse.packed_metadata.shape)} (2-bit column nibbles)")
|
|
73
72
|
print(
|
|
74
|
-
f" Memory Footprint : {mb_s:.2f} MB "
|
|
75
|
-
f"({r_s_fp32:.2f}x vs FP32, {r_s_fp16:.2f}x vs FP16)"
|
|
73
|
+
f" Memory Footprint : {mb_s:.2f} MB ({r_s_fp32:.2f}x vs FP32, {r_s_fp16:.2f}x vs FP16)"
|
|
76
74
|
)
|
|
77
75
|
|
|
78
76
|
# 4. Verify Forward Pass & Reconstruction SQNR
|
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["hatchling"]
|
|
3
|
-
build-backend = "hatchling.build"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "quantbench-engine"
|
|
7
|
-
version = "0.1.
|
|
8
|
-
description = "First-principles LLM quantization engine, bit-packing runtimes, 2:4 sparsity, and Quality-vs-Speed Pareto evaluation benchmark."
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
license = "Apache-2.0"
|
|
11
|
-
license-files = ["LICENSE"]
|
|
12
|
-
requires-python = ">=3.11"
|
|
13
|
-
authors = [{ name = "Prajwal Pujari", email = "prajwalpujari16@gmail.com" }]
|
|
14
|
-
keywords = [
|
|
15
|
-
"llm",
|
|
16
|
-
"quantization",
|
|
17
|
-
"inference",
|
|
18
|
-
"awq",
|
|
19
|
-
"gptq",
|
|
20
|
-
"smoothquant",
|
|
21
|
-
"int4",
|
|
22
|
-
"int8",
|
|
23
|
-
"fp8",
|
|
24
|
-
"bitnet",
|
|
25
|
-
"sparsity",
|
|
26
|
-
"benchmark",
|
|
27
|
-
"serving",
|
|
28
|
-
"petaflop",
|
|
29
|
-
]
|
|
30
|
-
classifiers = [
|
|
31
|
-
"Programming Language :: Python :: 3",
|
|
32
|
-
"Programming Language :: Python :: 3.11",
|
|
33
|
-
"Programming Language :: Python :: 3.12",
|
|
34
|
-
"Operating System :: OS Independent",
|
|
35
|
-
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
36
|
-
"Topic :: System :: Benchmark",
|
|
37
|
-
"Topic :: System :: Hardware",
|
|
38
|
-
]
|
|
39
|
-
dependencies = [
|
|
40
|
-
"torch>=2.4.0",
|
|
41
|
-
"typer>=0.12",
|
|
42
|
-
"rich>=13",
|
|
43
|
-
"pydantic>=2.6",
|
|
44
|
-
"safetensors>=0.4.3",
|
|
45
|
-
"numpy>=1.26",
|
|
46
|
-
]
|
|
47
|
-
|
|
48
|
-
[dependency-groups]
|
|
49
|
-
dev = [
|
|
50
|
-
"pytest>=8",
|
|
51
|
-
"pytest-cov>=5",
|
|
52
|
-
"ruff>=0.5",
|
|
53
|
-
]
|
|
54
|
-
|
|
55
|
-
[project.scripts]
|
|
56
|
-
quantbench = "quantbench.cli:app"
|
|
57
|
-
|
|
58
|
-
[project.urls]
|
|
59
|
-
Homepage = "https://github.com/Prajwal7-2002/quantbench"
|
|
60
|
-
Documentation = "https://prajwal7-2002.github.io/quantbench/"
|
|
61
|
-
Repository = "https://github.com/Prajwal7-2002/quantbench.git"
|
|
62
|
-
Issues = "https://github.com/Prajwal7-2002/quantbench/issues"
|
|
63
|
-
|
|
64
|
-
[tool.hatch.build.targets.wheel]
|
|
65
|
-
packages = ["src/quantbench"]
|
|
66
|
-
|
|
67
|
-
[tool.pytest.ini_options]
|
|
68
|
-
testpaths = ["tests"]
|
|
69
|
-
addopts = "-v --cov=src/quantbench --cov-report=term-missing"
|
|
70
|
-
pythonpath = ["src"]
|
|
71
|
-
|
|
72
|
-
[tool.ruff]
|
|
73
|
-
line-length = 100
|
|
74
|
-
target-version = "py311"
|
|
75
|
-
|
|
76
|
-
[tool.ruff.lint]
|
|
77
|
-
select = ["E", "F", "W", "B", "I"]
|
|
78
|
-
ignore = ["B008"]
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "quantbench-engine"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "First-principles LLM quantization engine, bit-packing runtimes, 2:4 sparsity, and Quality-vs-Speed Pareto evaluation benchmark."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.11"
|
|
13
|
+
authors = [{ name = "Prajwal Pujari", email = "prajwalpujari16@gmail.com" }]
|
|
14
|
+
keywords = [
|
|
15
|
+
"llm",
|
|
16
|
+
"quantization",
|
|
17
|
+
"inference",
|
|
18
|
+
"awq",
|
|
19
|
+
"gptq",
|
|
20
|
+
"smoothquant",
|
|
21
|
+
"int4",
|
|
22
|
+
"int8",
|
|
23
|
+
"fp8",
|
|
24
|
+
"bitnet",
|
|
25
|
+
"sparsity",
|
|
26
|
+
"benchmark",
|
|
27
|
+
"serving",
|
|
28
|
+
"petaflop",
|
|
29
|
+
]
|
|
30
|
+
classifiers = [
|
|
31
|
+
"Programming Language :: Python :: 3",
|
|
32
|
+
"Programming Language :: Python :: 3.11",
|
|
33
|
+
"Programming Language :: Python :: 3.12",
|
|
34
|
+
"Operating System :: OS Independent",
|
|
35
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
36
|
+
"Topic :: System :: Benchmark",
|
|
37
|
+
"Topic :: System :: Hardware",
|
|
38
|
+
]
|
|
39
|
+
dependencies = [
|
|
40
|
+
"torch>=2.4.0",
|
|
41
|
+
"typer>=0.12",
|
|
42
|
+
"rich>=13",
|
|
43
|
+
"pydantic>=2.6",
|
|
44
|
+
"safetensors>=0.4.3",
|
|
45
|
+
"numpy>=1.26",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[dependency-groups]
|
|
49
|
+
dev = [
|
|
50
|
+
"pytest>=8",
|
|
51
|
+
"pytest-cov>=5",
|
|
52
|
+
"ruff>=0.5",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[project.scripts]
|
|
56
|
+
quantbench = "quantbench.cli:app"
|
|
57
|
+
|
|
58
|
+
[project.urls]
|
|
59
|
+
Homepage = "https://github.com/Prajwal7-2002/quantbench"
|
|
60
|
+
Documentation = "https://prajwal7-2002.github.io/quantbench/"
|
|
61
|
+
Repository = "https://github.com/Prajwal7-2002/quantbench.git"
|
|
62
|
+
Issues = "https://github.com/Prajwal7-2002/quantbench/issues"
|
|
63
|
+
|
|
64
|
+
[tool.hatch.build.targets.wheel]
|
|
65
|
+
packages = ["src/quantbench"]
|
|
66
|
+
|
|
67
|
+
[tool.pytest.ini_options]
|
|
68
|
+
testpaths = ["tests"]
|
|
69
|
+
addopts = "-v --cov=src/quantbench --cov-report=term-missing"
|
|
70
|
+
pythonpath = ["src"]
|
|
71
|
+
|
|
72
|
+
[tool.ruff]
|
|
73
|
+
line-length = 100
|
|
74
|
+
target-version = "py311"
|
|
75
|
+
|
|
76
|
+
[tool.ruff.lint]
|
|
77
|
+
select = ["E", "F", "W", "B", "I"]
|
|
78
|
+
ignore = ["B008"]
|
|
@@ -82,9 +82,7 @@ class ParetoBenchmark:
|
|
|
82
82
|
stride=self.stride,
|
|
83
83
|
)
|
|
84
84
|
|
|
85
|
-
base_bytes = sum(
|
|
86
|
-
p.numel() * 2 for p in self.base_model.parameters()
|
|
87
|
-
)
|
|
85
|
+
base_bytes = sum(p.numel() * 2 for p in self.base_model.parameters())
|
|
88
86
|
base_mb = base_bytes / (1024 * 1024)
|
|
89
87
|
|
|
90
88
|
points: List[ParetoPoint] = []
|
|
@@ -257,9 +257,7 @@ def pareto_cmd(
|
|
|
257
257
|
model = DemoTransformer(vocab=vocab_size, dim=hidden_dim)
|
|
258
258
|
tokens = generate_synthetic_corpus(vocab_size=vocab_size, seq_length=seq_len, seed=1)
|
|
259
259
|
|
|
260
|
-
bench = ParetoBenchmark(
|
|
261
|
-
base_model=model, test_tokens=tokens, window_size=64, stride=32
|
|
262
|
-
)
|
|
260
|
+
bench = ParetoBenchmark(base_model=model, test_tokens=tokens, window_size=64, stride=32)
|
|
263
261
|
console.print(
|
|
264
262
|
"[bold yellow]Running Pareto sweep across all precision runtimes...[/bold yellow]"
|
|
265
263
|
)
|
|
@@ -279,9 +277,7 @@ def pareto_cmd(
|
|
|
279
277
|
for p in points:
|
|
280
278
|
grp = str(p.group_size) if p.group_size > 0 else "None"
|
|
281
279
|
delta_str = (
|
|
282
|
-
f"+{p.perplexity_delta:.3f}"
|
|
283
|
-
if p.perplexity_delta > 0
|
|
284
|
-
else f"{p.perplexity_delta:.3f}"
|
|
280
|
+
f"+{p.perplexity_delta:.3f}" if p.perplexity_delta > 0 else f"{p.perplexity_delta:.3f}"
|
|
285
281
|
)
|
|
286
282
|
table.add_row(
|
|
287
283
|
p.name,
|
|
@@ -103,11 +103,13 @@ def search_best_awq_scale(
|
|
|
103
103
|
- best_alpha: Optimal alpha hyperparameter.
|
|
104
104
|
"""
|
|
105
105
|
if quant_fn is None:
|
|
106
|
+
|
|
106
107
|
def default_quant(w: torch.Tensor) -> torch.Tensor:
|
|
107
108
|
q_b, s_b, zp_b, meta = quantize_blockwise(
|
|
108
109
|
w, group_size=min(128, w.shape[1]), num_bits=4
|
|
109
110
|
)
|
|
110
111
|
return dequantize_blockwise(q_b, s_b, zp_b, meta)
|
|
112
|
+
|
|
111
113
|
quant_fn = default_quant
|
|
112
114
|
|
|
113
115
|
# Reference unquantized linear output
|
|
@@ -169,11 +171,13 @@ def awq_quantize_weights(
|
|
|
169
171
|
Tuple of (dequantized_weight, scale).
|
|
170
172
|
"""
|
|
171
173
|
if quant_fn is None:
|
|
174
|
+
|
|
172
175
|
def default_quant(w: torch.Tensor) -> torch.Tensor:
|
|
173
176
|
q_b, s_b, zp_b, meta = quantize_blockwise(
|
|
174
177
|
w, group_size=min(128, w.shape[1]), num_bits=4
|
|
175
178
|
)
|
|
176
179
|
return dequantize_blockwise(q_b, s_b, zp_b, meta)
|
|
180
|
+
|
|
177
181
|
quant_fn = default_quant
|
|
178
182
|
|
|
179
183
|
w_scaled = weight * scale.unsqueeze(0)
|
|
@@ -132,9 +132,7 @@ def gptq_quantize_weights(
|
|
|
132
132
|
def quantize_dequantize_cols(col_w: torch.Tensor) -> torch.Tensor:
|
|
133
133
|
# col_w: (out_features, num_cols)
|
|
134
134
|
if group_size > 0:
|
|
135
|
-
q_b, s_b, zp_b, meta = quantize_blockwise(
|
|
136
|
-
col_w, group_size=group_size, num_bits=bits
|
|
137
|
-
)
|
|
135
|
+
q_b, s_b, zp_b, meta = quantize_blockwise(col_w, group_size=group_size, num_bits=bits)
|
|
138
136
|
return dequantize_blockwise(q_b, s_b, zp_b, meta)
|
|
139
137
|
else:
|
|
140
138
|
q, scale = quantize_absmax(col_w, num_bits=bits, dim=0)
|
{quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/packing/sparse_pack.py
RENAMED
|
@@ -48,12 +48,7 @@ def pack_2_4_indices(indices: torch.Tensor) -> torch.Tensor:
|
|
|
48
48
|
idx2 = i32[..., 2::4]
|
|
49
49
|
idx3 = i32[..., 3::4]
|
|
50
50
|
|
|
51
|
-
packed = (
|
|
52
|
-
(idx0 & 0x03)
|
|
53
|
-
| ((idx1 & 0x03) << 2)
|
|
54
|
-
| ((idx2 & 0x03) << 4)
|
|
55
|
-
| ((idx3 & 0x03) << 6)
|
|
56
|
-
)
|
|
51
|
+
packed = (idx0 & 0x03) | ((idx1 & 0x03) << 2) | ((idx2 & 0x03) << 4) | ((idx3 & 0x03) << 6)
|
|
57
52
|
return packed.to(torch.uint8)
|
|
58
53
|
|
|
59
54
|
|
|
@@ -163,10 +163,13 @@ class TestSparse24Packing:
|
|
|
163
163
|
|
|
164
164
|
def test_index_packing_roundtrip(self) -> None:
|
|
165
165
|
"""Test packing and unpacking of 2-bit column position indices."""
|
|
166
|
-
indices = torch.tensor(
|
|
167
|
-
[
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
indices = torch.tensor(
|
|
167
|
+
[
|
|
168
|
+
[0, 2, 1, 3],
|
|
169
|
+
[1, 2, 0, 3],
|
|
170
|
+
],
|
|
171
|
+
dtype=torch.int32,
|
|
172
|
+
)
|
|
170
173
|
|
|
171
174
|
packed = pack_2_4_indices(indices)
|
|
172
175
|
assert packed.dtype == torch.uint8
|
|
@@ -167,8 +167,8 @@ def test_fp8_analytical_emulator():
|
|
|
167
167
|
# E4M3 (max 448.0)
|
|
168
168
|
q_e4m3 = _emulate_fp8(x, exp_bits=4, mantissa_bits=3, bias=7, max_val=448.0)
|
|
169
169
|
assert q_e4m3[0].item() == -448.0 # saturated at -max
|
|
170
|
-
assert q_e4m3[6].item() == 448.0
|
|
171
|
-
assert q_e4m3[3].item() == 0.0
|
|
170
|
+
assert q_e4m3[6].item() == 448.0 # saturated at +max
|
|
171
|
+
assert q_e4m3[3].item() == 0.0 # exact zero
|
|
172
172
|
|
|
173
173
|
# E5M2 (max 57344.0)
|
|
174
174
|
q_e5m2 = _emulate_fp8(x, exp_bits=5, mantissa_bits=2, bias=15, max_val=57344.0)
|
|
@@ -203,4 +203,3 @@ def test_cli_runner():
|
|
|
203
203
|
# Test invalid format
|
|
204
204
|
res_err = runner.invoke(app, ["pack-inspect", "--format", "invalid_format"])
|
|
205
205
|
assert res_err.exit_code != 0
|
|
206
|
-
|