-
Notifications
You must be signed in to change notification settings - Fork 12
Refactor circuit functions into gadgets/hints, improve quantization docs, and fix lint #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from 165 commits
Commits
Show all changes
180 commits
Select commit
Hold shift + click to select a range
7ee9b05
old benchmarking files added
dc20c8b
benchmark_runner updated
tmfreiberg 366bb4f
breadth sweep onnx models go in breadth directory
tmfreiberg d63e9cf
prettifying benchmark commands
tmfreiberg c4cb632
fixes
tmfreiberg fe72efd
fix
tmfreiberg 89c8957
eye candy added
tmfreiberg 8704e73
eye candy edits
tmfreiberg f1a316c
refactor benchmark_runner
tmfreiberg 88675af
refactor gen_and_bench
tmfreiberg a735a5d
refactor benchmarking_helpers
tmfreiberg 1b27530
CLI jstprove -> jst part one
tmfreiberg 7d7d393
CLI jstprove -> jst part two (documentation)
tmfreiberg 539eae4
capture ecc output
tmfreiberg 6a93c99
capture ecc output
tmfreiberg a6103ca
capture ecc output
tmfreiberg 85e147b
summary card formatting
tmfreiberg 1582015
summary card formatting
tmfreiberg 4ead1fd
adjusting default depth parameters
tmfreiberg 9aa47e0
adding fixed benchmarking model (lenet)
tmfreiberg d5a4b47
benchmarking md added; --summarize flag removed from cli
tmfreiberg 5dc5357
added jsonl to gitignore
tmfreiberg c55d523
jst bench lenet fix
tmfreiberg a807c90
lenet bench fix 2
tmfreiberg c962831
lenet bench fix 3
tmfreiberg 067dd0c
jst bench lenet fix continued
tmfreiberg ad92160
lenet_fixed jsonl -> lenet jsonl
tmfreiberg 988d936
Merge branch 'main' into benchmarking
jsgold-1 32c00ba
removed legacy lazy gen_and_bench import from cli
738bdb5
Linting/formatting
jsgold-1 b18e9f9
fixed text formatting errors arising from linter conformity
aef5e0a
Add other model choice to benchmarking CLI (#68)
jsgold-1 4d3cd41
Refactor cli and merge with main
jsgold-1 5da3877
Slight messaging chang
jsgold-1 5453012
Refactor bench, move helper functinos, add decorator for optional pat…
HudsonGraeme 5d23561
Avoid top-level import from model registry
HudsonGraeme dd5d45a
Add constants, update ensure parent dir
HudsonGraeme 00e9252
Minor docs changes
jsgold-1 2917ba5
Bring in tests from quantizer_tests and linting/formatting
jsgold-1 aa75b91
Merge branch 'main' into single_layer_tests
jsgold-1 458df51
Add base fix
jsgold-1 6859cfe
Minor test improvements
jsgold-1 cdbc74f
Add quantization to original layer comp checks
jsgold-1 bfa988a
Refactor layer_tests
jsgold-1 c2fd8dc
Add e2e tests + scalability, ensuring each layer has an e2e test
jsgold-1 2796e05
Fix maxpool
jsgold-1 1705a09
Change absence of --model flag in pytest e2e run
jsgold-1 c42a694
Add tests
jsgold-1 7047160
adding max layer
tmfreiberg f3f241d
singular API fix
tmfreiberg 620768f
as type errors addressed
tmfreiberg 6599c98
more errors
tmfreiberg 16147f2
more errors
tmfreiberg 0472503
more errors
tmfreiberg 1861947
more errors
tmfreiberg 624ad37
more errors
tmfreiberg e460f31
more errors
tmfreiberg b309068
more errors
tmfreiberg 73839df
more errors
tmfreiberg 1f7089c
more errors
tmfreiberg 0ab5745
more errors
tmfreiberg cb2e4ef
more errors
tmfreiberg cc98084
more errors
tmfreiberg c00d2fd
Quantization refactoring
jsgold-1 d58e6d4
Rework w and b loading
jsgold-1 6cff583
Fix multi inputs, quantization refactor and add Add layer
jsgold-1 bf6f6b7
Add multi-input layer support
jsgold-1 0a7c0f4
Finalize support for multi-inputs/outputs and add add with initialize…
jsgold-1 4a9cd8f
Broadcasting and scalar support for Add
jsgold-1 e315b8b
Docs update
jsgold-1 2549278
Docs update
jsgold-1 1c81c24
starting simple with no quantization for max layer
tmfreiberg f695e58
forgot imports in max.py
tmfreiberg 3e042cf
Merge with main changes
jsgold-1 d5b3a6f
Merge changes from main/single_layer_tests
jsgold-1 becdc36
Merge branch 'quantization_refactor' into single_layer_tests_v2
tmfreiberg 41d9673
fix post test_end_to_end_quantization_accuracy update
tmfreiberg 55e8e28
First review fixes and testing update
jsgold-1 8889a45
Secondary review changes
jsgold-1 1bf57d3
missing scale error
tmfreiberg afcbe3e
whoops
tmfreiberg 990e568
mirror add
tmfreiberg 743feaf
min copy max
tmfreiberg 9dfc1f5
More review updates
jsgold-1 67001f9
min tweak consistent with max
tmfreiberg b0aaa05
trying clip layer
tmfreiberg 6ce605e
fix import location
tmfreiberg 83ba2d6
Fix review comments
jsgold-1 362d021
Minor code review changes
jsgold-1 9b67e84
Merge quantization_refactor into single_layer_tests_v2
tmfreiberg ef3a601
max layer rust side
tmfreiberg 0d36064
import MaxLayer in layer_kinds.rs
tmfreiberg 459191d
whoops MaxLayer lives in max no maxpool
tmfreiberg 7fd5cd2
finishing min layer on rust side
tmfreiberg 090cbeb
refactor max, min, maxpool, core_math
tmfreiberg 578c9c5
remove unused imports in maxpool.rs
tmfreiberg 2a2de4d
doc edits. max and min e2e work. clip not yet. about to refactor with…
tmfreiberg 9669787
range check gadget added, refactor constrained_max, constrained_min (…
tmfreiberg f73104d
clip rust side
tmfreiberg 1cb6340
rem_bits unused variable; prefix underscore
tmfreiberg 9cfa4e1
UtilsError -> CircuitError in signature of range_check_pow2 function
tmfreiberg 5341215
clip_config made proper
tmfreiberg d9a8aa1
forgot to register Clip in onnx_op_quantizer
tmfreiberg b0e6ebc
clip config update address scalar tensor versus non scalar shapes issue
tmfreiberg e2708d9
get_test_specs in clip_config updated
tmfreiberg 0fe4450
type mismatch float/int clip addressed
tmfreiberg 2f0386c
address empty input shape problem in clip_config
tmfreiberg 8a6beb4
rename MaxMinAssertionContext to ShiftRangeContext
tmfreiberg 2ebad68
Merge branch 'main' into single_layer_tests_v2
tmfreiberg 9dbb68c
Cleaned up redundant assignments, fixed docstring, updated tests
tmfreiberg ba2ad5e
addressing errors
tmfreiberg 043eef6
Code Rabbit nits
tmfreiberg b7641d5
Address ruff/clippy/pre-commit feedback for clip/max/min
tmfreiberg 36748be
closing delimiters added (linter's fault!)
tmfreiberg df93713
logup added to core_math
tmfreiberg e7e8f52
added hints.rs
tmfreiberg 8290b04
added logup code to main_runner
tmfreiberg a02ad22
remove EMptyHintCaller import in main_runner
tmfreiberg c16ee61
added CircuitField import to main_runner
tmfreiberg 2414c09
one-shot logup step 1 core_math
tmfreiberg 9e3836b
one-shot logup step 2
tmfreiberg 80b7acc
corrections after step 2
tmfreiberg 26a5acf
extending logup to all range checks (except in quantize)
tmfreiberg bef0797
closing delimiter in min.rs apply
tmfreiberg d021bd0
syntax error min.rs
tmfreiberg 31bf84c
using logup for rescaling remainder check etc. in quantization
tmfreiberg 0389ee0
debugging rescale
tmfreiberg e55c5ac
use LogUp for all range checks in quantization process
tmfreiberg 5acbfe2
moving hints.rs
tmfreiberg 7dc731f
refactor move hints
tmfreiberg 41e07b1
move unconstrained_max
tmfreiberg 945a985
move unconstrained_max
tmfreiberg 65c760c
no layerkind in unconstrained_max, hints shouldn't know about ONNX
tmfreiberg a48aa43
whoops max_min_clip module imported twice in hints mod
tmfreiberg a7fb66a
moved unconstrained_min and unconstrained_clip to hints/max_min_clip
tmfreiberg 9dd7307
forgot to import to core_math from hints
tmfreiberg 17f862d
forgot to change layerkind error unconstrained_min
tmfreiberg 7b2d6cc
renaming and moving bit operations
tmfreiberg 8976596
fix imports
tmfreiberg 4af9078
Field trait -> bits
tmfreiberg 86504b6
field::FieldTrait
tmfreiberg f1d6a0b
fix FieldArith import issue
tmfreiberg 99c2bb4
moving logup/range check functions from core_math to range_check
tmfreiberg 8fd8c6f
fixing imports
tmfreiberg 4df8d18
still fixing imports
tmfreiberg 677eb7f
still fixing imports
tmfreiberg bd19d31
last remnants of core_math moved to max_min_clip
tmfreiberg 06a7a04
address warning no unconstrained_clip
tmfreiberg 51e9b58
relu layer uses logup
tmfreiberg 3e26a1e
fix errors
tmfreiberg 3fb2b71
gradually improving import organisation and docstrings
tmfreiberg c40c151
gadget and hint import organising and docstrings
tmfreiberg 989265a
starting to standardize docstrings for gadgets
tmfreiberg 6632adf
more docstring revision
tmfreiberg 279ab3e
docstrings, clippy
tmfreiberg bf1eae7
clip x_bc deref to variable
tmfreiberg 2e1d83a
docstrings format
tmfreiberg 8082e7b
time trailing whitespace/fix end of files
tmfreiberg 532c680
Clean up lint issues and update poetry.lock
tmfreiberg e56e7a3
silence clippy on docstring nits
tmfreiberg d7ea66e
Merge remote-tracking branch 'origin/main' into logup_v2
tmfreiberg c8ae9cf
remove Cast handler registration
tmfreiberg a1a216d
put model_quant.onnx under tmp_path in out_path for quantized model i…
tmfreiberg 148872f
updated empty_tensor test case
tmfreiberg f223b64
revised incomplete error message in bits.rs
tmfreiberg f4c5c31
fixed error message in unconstrained_min (copy-pasted from unconstrai…
tmfreiberg 89e02ca
Verify bounds checking for layer.inputs access
tmfreiberg fb012db
forgot to save min.rs
tmfreiberg b476e19
Fix MaxQuantizer.__init__ to honor BaseOpQuantizer’s new_initializers…
tmfreiberg 04fc017
added tmp_path: Path to signature of test_tiny_conv
tmfreiberg 9a1acde
Specify float32 dtype for ONNX compatibility in initializer overrides
tmfreiberg fe06eda
address overflow concerns
tmfreiberg 38e11bf
fix layerkind typo
tmfreiberg 8f0f7c4
Remove poetry.lock from tracking
tmfreiberg b81502c
Apply dtype cast consistently to all initializer overrides.
tmfreiberg 3028d4b
Testing fixes
jsgold-1 93a8246
Linting final touches
jsgold-1 61aa418
added initializer test to e2e tests
tmfreiberg f271075
added e2e tests for broadcasting
tmfreiberg 1a9fafd
corrected off-by-one error
tmfreiberg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,16 @@ | ||
| import importlib | ||
| import pkgutil | ||
| import os | ||
| from pathlib import Path | ||
|
|
||
| # Get the package name of the current module | ||
| package_name = __name__ | ||
|
|
||
| # Dynamically import all .py files in this package directory (except __init__.py) | ||
| package_dir = os.path.dirname(__file__) | ||
| package_dir = Path(__file__).parent | ||
|
|
||
| __all__ = [] | ||
| __all__: list[str] = [] | ||
|
|
||
| for _, module_name, is_pkg in pkgutil.iter_modules([package_dir]): | ||
| if not is_pkg and (module_name != "custom_helpers"): | ||
| importlib.import_module(f"{package_name}.{module_name}") | ||
| __all__.append(module_name) | ||
| __all__.append(str(module_name)) # noqa: PYI056 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
python/core/model_processing/onnx_quantizer/layers/clip.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from typing import TYPE_CHECKING, ClassVar | ||
|
|
||
| if TYPE_CHECKING: | ||
| import onnx | ||
|
|
||
| from python.core.model_processing.onnx_quantizer.layers.base import ( | ||
| BaseOpQuantizer, | ||
| QuantizerBase, | ||
| ScaleConfig, | ||
| ) | ||
|
|
||
|
|
||
| class QuantizeClip(QuantizerBase): | ||
| """ | ||
| Quantization traits for ONNX Clip. | ||
| Semantics: | ||
| - X is already scaled/cast to INT64 at the graph boundary by the converter. | ||
| - Clip is elementwise + broadcasting. | ||
| - The bound inputs (min, max) should live in the *same* fixed-point scale | ||
| as X so that Clip(alpha*x; alpha*a, alpha*b) matches the original Clip(x; a, b). | ||
| Implementation: | ||
| - Treat inputs 1 and 2 (min, max) like "WB-style" slots: we let the | ||
| QuantizerBase machinery rescale / cast those inputs using the same | ||
| global scale factor. | ||
| - No extra internal scaling input is added (USE_SCALING = False). | ||
| """ | ||
|
|
||
| OP_TYPE = "Clip" | ||
| DOMAIN = "" # standard ONNX domain | ||
|
|
||
| # We DO want WB-style handling so that min/max initializers get quantized: | ||
| USE_WB = True | ||
|
|
||
| # Clip does not introduce its own scale input; it just runs in the | ||
| # existing fixed-point scale. | ||
| USE_SCALING = False | ||
|
|
||
| # Scale-plan for WB-style slots: | ||
| # - Input index 1: min | ||
| # - Input index 2: max | ||
| # Each should be scaled once by the global alpha (same as activations). | ||
| SCALE_PLAN: ClassVar = {1: 1, 2: 1} | ||
|
|
||
|
|
||
| class ClipQuantizer(BaseOpQuantizer, QuantizeClip): | ||
| """ | ||
| Quantizer for ONNX Clip. | ||
| - Keeps the node op_type as "Clip". | ||
| - Ensures that any bound inputs (min, max), whether they are dynamic | ||
| inputs or initializers, are converted to the same INT64 fixed-point | ||
| representation as A. | ||
| """ | ||
|
|
||
| def __init__( | ||
| self, | ||
| new_initializers: dict[str, onnx.TensorProto] | None = None, | ||
| ) -> None: | ||
| # Match Max/Min/Add: we simply share the new_initializers dict | ||
| # with the converter so any constants we add are collected. | ||
| self.new_initializers = new_initializers | ||
tmfreiberg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| def quantize( | ||
| self, | ||
| node: onnx.NodeProto, | ||
| graph: onnx.GraphProto, | ||
| scale_config: ScaleConfig, | ||
| initializer_map: dict[str, onnx.TensorProto], | ||
| ) -> list[onnx.NodeProto]: | ||
| # Delegate to the shared QuantizerBase logic, which will: | ||
| # - keep X as-is (already scaled/cast by the converter), | ||
| # - rescale / cast min/max according to SCALE_PLAN, | ||
| # - update initializers as needed. | ||
| return QuantizeClip.quantize(self, node, graph, scale_config, initializer_map) | ||
|
|
||
| def check_supported( | ||
| self, | ||
| node: onnx.NodeProto, | ||
| initializer_map: dict[str, onnx.TensorProto] | None = None, | ||
| ) -> None: | ||
| """ | ||
| Minimal support check for Clip: | ||
| - Clip is variadic elementwise with optional min/max as inputs or attrs. | ||
| - We accept both forms; if attrs are present, ORT enforces semantics. | ||
| - Broadcasting is ONNX-standard; we don't restrict further here. | ||
| """ | ||
| _ = node, initializer_map | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # python/core/model_processing/onnx_quantizer/layers/max.py | ||
| from __future__ import annotations | ||
|
|
||
| from typing import TYPE_CHECKING, ClassVar | ||
|
|
||
| if TYPE_CHECKING: | ||
| import onnx | ||
|
|
||
| from python.core.model_processing.onnx_quantizer.layers.base import ( | ||
| BaseOpQuantizer, | ||
| QuantizerBase, | ||
| ScaleConfig, | ||
| ) | ||
|
|
||
|
|
||
| class QuantizeMax(QuantizerBase): | ||
| OP_TYPE = "Max" | ||
| DOMAIN = "" | ||
| USE_WB = True | ||
| USE_SCALING = False | ||
| SCALE_PLAN: ClassVar = {1: 1} | ||
|
|
||
|
|
||
| class MaxQuantizer(BaseOpQuantizer, QuantizeMax): | ||
| def __init__( | ||
| self, | ||
| new_initializers: dict[str, onnx.TensorProto] | None = None, | ||
| ) -> None: | ||
| self.new_initializers = new_initializers | ||
|
|
||
| def quantize( | ||
| self, | ||
| node: onnx.NodeProto, | ||
| graph: onnx.GraphProto, | ||
| scale_config: ScaleConfig, | ||
| initializer_map: dict[str, onnx.TensorProto], | ||
| ) -> list[onnx.NodeProto]: | ||
| # Delegate to the shared QuantizerBase logic | ||
| return QuantizeMax.quantize(self, node, graph, scale_config, initializer_map) | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| def check_supported( | ||
| self, | ||
| node: onnx.NodeProto, | ||
| initializer_map: dict[str, onnx.TensorProto] | None = None, | ||
| ) -> None: | ||
| # If later we want to enforce/relax broadcasting, add it here. | ||
| pass | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.