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.
Files changed (48) hide show
  1. quantbench_engine-0.1.1/.github/ISSUE_TEMPLATE/bug_report.yml +65 -0
  2. quantbench_engine-0.1.1/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. quantbench_engine-0.1.1/.github/ISSUE_TEMPLATE/feature_request.yml +44 -0
  4. quantbench_engine-0.1.1/.github/pull_request_template.md +28 -0
  5. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/.github/workflows/ci.yml +3 -0
  6. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/.github/workflows/release.yml +1 -1
  7. quantbench_engine-0.1.1/.pre-commit-config.yaml +18 -0
  8. quantbench_engine-0.1.1/CODE_OF_CONDUCT.md +43 -0
  9. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/PKG-INFO +5 -6
  10. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/README.md +4 -5
  11. quantbench_engine-0.1.1/SECURITY.md +31 -0
  12. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/examples/01_quant_linear_inference.py +2 -4
  13. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/pyproject.toml +78 -78
  14. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/__init__.py +1 -1
  15. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/bench/pareto.py +1 -3
  16. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/cli.py +2 -6
  17. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/algorithms/awq.py +4 -0
  18. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/algorithms/gptq.py +1 -3
  19. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/packing/sparse_pack.py +1 -6
  20. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/tests/test_packing.py +7 -4
  21. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/tests/test_primitives.py +2 -3
  22. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/tests/test_quant_linear.py +3 -6
  23. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/uv.lock +1204 -1204
  24. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/.gitignore +0 -0
  25. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/CONTRIBUTING.md +0 -0
  26. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/DEVLOG.md +0 -0
  27. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/GUIDE.md +0 -0
  28. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/LICENSE +0 -0
  29. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/examples/02_advanced_calibration.py +0 -0
  30. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/examples/03_servebench_roofline_eval.py +0 -0
  31. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/bench/__init__.py +0 -0
  32. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/eval/__init__.py +0 -0
  33. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/eval/perplexity.py +0 -0
  34. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/eval/sqnr.py +0 -0
  35. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/nn/__init__.py +0 -0
  36. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/nn/model_convert.py +0 -0
  37. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/nn/quant_linear.py +0 -0
  38. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/__init__.py +0 -0
  39. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/affine.py +0 -0
  40. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/algorithms/__init__.py +0 -0
  41. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/algorithms/smoothquant.py +0 -0
  42. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/blockwise.py +0 -0
  43. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/fp8.py +0 -0
  44. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/packing/__init__.py +0 -0
  45. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/packing/int4_pack.py +0 -0
  46. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/src/quantbench/quant/packing/ternary_pack.py +0 -0
  47. {quantbench_engine-0.1.0 → quantbench_engine-0.1.1}/tests/test_algorithms.py +0 -0
  48. {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:`).
@@ -31,5 +31,8 @@ jobs:
31
31
  - name: Run linter
32
32
  run: uv run ruff check .
33
33
 
34
+ - name: Run format check
35
+ run: uv run ruff format --check .
36
+
34
37
  - name: Run test suite with coverage
35
38
  run: uv run pytest
@@ -28,7 +28,7 @@ jobs:
28
28
  runs-on: ubuntu-latest
29
29
  environment:
30
30
  name: pypi
31
- url: https://pypi.org/p/quantbench
31
+ url: https://pypi.org/p/quantbench-engine
32
32
  permissions:
33
33
  id-token: write
34
34
  steps:
@@ -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.0
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
+ [![PyPI](https://img.shields.io/pypi/v/quantbench-engine.svg)](https://pypi.org/project/quantbench-engine/)
31
32
  [![CI](https://github.com/Prajwal7-2002/quantbench/actions/workflows/ci.yml/badge.svg)](https://github.com/Prajwal7-2002/quantbench/actions)
32
33
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
33
34
  [![Python](https://img.shields.io/badge/python-3.11%2B-blue)](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
+ [![PyPI](https://img.shields.io/pypi/v/quantbench-engine.svg)](https://pypi.org/project/quantbench-engine/)
3
4
  [![CI](https://github.com/Prajwal7-2002/quantbench/actions/workflows/ci.yml/badge.svg)](https://github.com/Prajwal7-2002/quantbench/actions)
4
5
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
5
6
  [![Python](https://img.shields.io/badge/python-3.11%2B-blue)](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.0"
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"]
@@ -1,6 +1,6 @@
1
1
  """quantbench: Unified Quantization Engine, Bit-Packing Runtime & Quality-vs-Speed Benchmark."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.1.1"
4
4
 
5
5
  from quantbench.bench import ParetoBenchmark, ParetoPoint
6
6
  from quantbench.eval import (
@@ -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)
@@ -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
- [0, 2, 1, 3],
168
- [1, 2, 0, 3],
169
- ], dtype=torch.int32)
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 # saturated at +max
171
- assert q_e4m3[3].item() == 0.0 # exact zero
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
-