-
Notifications
You must be signed in to change notification settings - Fork 112
AIMIGRAPHX-351 Update quantization to support dynamic shapes with single dynamic dimension #4467
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
base: develop
Are you sure you want to change the base?
Conversation
I dont think thats a good assumption to make. |
| {split_single_dyn_dim{}, | ||
| dead_code_elimination{}, | ||
| simplify_dyn_ops{}, | ||
| dead_code_elimination{}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do these passes need to be ran?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
split_single_dyn_dim will create the submodules but won't simplify other ops further. So simplify_dyn_ops is used to get rid of things like 2-input multibroadcasts and slices. Awhile back I've found from testing models that this was needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems we should be able to quantize without needing to convert dynamic shapes which is a decision that should be made by the backend target.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that should be the case, but currently optimize_module will fail as soon as a matcher tries to interact with a dynamic shape.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR enhances quantization passes to properly support dynamic shapes with single dynamic dimensions. The changes ensure that the split_single_dyn_dim pass runs before quantization, and that quantization operations are performed on submodules rather than the main module when dynamic shapes are involved.
Key changes:
- Adds
split_single_dyn_dimpreprocessing to all quantization entry points - Implements select_module detection to skip processing already-transformed main modules
- Ensures convert operations are inserted in submodules for proper dynamic shape handling
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/truncate_float.cpp | Adds select_module check to skip main module and copyright year update to 2025 |
| src/split_single_dyn_dim.cpp | Adds early return when select_module exists, indicating pass already ran |
| src/quantize_8bits.cpp | Adds select_module checks in both quantize_8bits_pass and capture_arguments_pass to skip main module |
| src/quantization.cpp | Adds split_single_dyn_dim preprocessing sequence to all quantization functions (fp16, bf16, int8, int4) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
| static void | ||
| quantize_module(module& m, const std::vector<std::string>& ins_names, shape::type_t float_type) | ||
| { | ||
| // skip main module that contains select_module | ||
| if(any_of(m.begin(), m.end(), [](auto ins) { return ins.name() == "select_module"; })) |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check for select_module is duplicated across multiple files (truncate_float.cpp, quantize_8bits.cpp twice, and split_single_dyn_dim.cpp). Consider extracting this into a helper function to improve maintainability and ensure consistent behavior. For example:
// In a common utility header
inline bool module_has_select_module(const module& m) {
return any_of(m.begin(), m.end(), [](auto ins) { return ins.name() == "select_module"; });
}This would reduce code duplication and make future changes easier.
| static void | |
| quantize_module(module& m, const std::vector<std::string>& ins_names, shape::type_t float_type) | |
| { | |
| // skip main module that contains select_module | |
| if(any_of(m.begin(), m.end(), [](auto ins) { return ins.name() == "select_module"; })) | |
| // Helper function to check for select_module | |
| static inline bool module_has_select_module(const module& m) | |
| { | |
| return any_of(m.begin(), m.end(), [](auto ins) { return ins.name() == "select_module"; }); | |
| } | |
| static void | |
| quantize_module(module& m, const std::vector<std::string>& ins_names, shape::type_t float_type) | |
| { | |
| // skip main module that contains select_module | |
| if(module_has_select_module(m)) |
| {split_single_dyn_dim{}, | ||
| dead_code_elimination{}, | ||
| simplify_dyn_ops{}, | ||
| dead_code_elimination{}, | ||
| normalize_ops{}, |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pass sequence {split_single_dyn_dim{}, dead_code_elimination{}, simplify_dyn_ops{}, dead_code_elimination{}} is repeated four times in this file (lines 73-76, 87-90, 107-110, 211-214). Consider extracting this into a named constant or helper function to improve maintainability:
static std::vector<pass> get_dyn_shape_preprocessing_passes() {
return {split_single_dyn_dim{},
dead_code_elimination{},
simplify_dyn_ops{},
dead_code_elimination{}};
}This would make the code DRYer and ensure consistent preprocessing across all quantization functions.
| // skip main module that contains select_module (meaning this pass already ran) | ||
| if(any_of(mm->begin(), mm->end(), [](auto ins) { return ins.name() == "select_module"; })) | ||
| { | ||
| return true; | ||
| } |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic change here modifies the behavior of any_sm_next to return true when the module contains select_module, effectively treating it the same as if a parameter outputs to select_module. This seems inconsistent with the function's documented purpose which is to check if "any of the parameters outputs to a select_module operator".
Consider either:
- Renaming this function to better reflect its new behavior (e.g.,
should_skip_module), or - Moving this check out of the function and into the caller, to keep the function focused on its original purpose.
| {split_single_dyn_dim{}, | ||
| dead_code_elimination{}, | ||
| simplify_dyn_ops{}, | ||
| dead_code_elimination{}, | ||
| normalize_ops{}, | ||
| optimize_module{{"quantizelinear", "dequantizelinear"}}, | ||
| truncate_float_pass{ins_names, shape::half_type}, | ||
| optimize_module{{"quantizelinear", "dequantizelinear"}}}, |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes add support for dynamic shapes with single dynamic dimensions in quantization passes, but there are no tests verifying this new functionality. Consider adding tests that combine dynamic shapes with quantization to ensure the new behavior works correctly, such as:
- Test
quantize_fp16with a dynamic shape input - Test
quantize_bf16with a dynamic shape input - Test
quantize_int8with a dynamic shape input - Test
quantize_int4_weightswith a dynamic shape input
This is especially important given that the PR description mentions "The matchers will error out otherwise" without this change.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #4467 +/- ##
===========================================
- Coverage 92.21% 92.20% -0.01%
===========================================
Files 561 561
Lines 27228 27254 +26
===========================================
+ Hits 25107 25127 +20
- Misses 2121 2127 +6
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
I'm open to other suggestions. In the past, I tried to include an additional attribute to the program indicating it's already completed the Right now we don't have any other way to insert a |
Motivation
Current quantization passes don't properly split single dynamic dimensions before running on dynamic shapes. The matchers will error out otherwise.
Technical Details
select_moduleis an indicator thatsplit_single_dyn_dimpass has already ran on the main module.truncate_floatpass andquantize_8bitsalso need this change so that converts are in the submodule. Otherwise other passes will attempt to perform optimizations/compile the converts in the main module. But they'll fail when hitting dynamic shapes.Changelog Category