-
Notifications
You must be signed in to change notification settings - Fork 581
Reject unsupported partial-block INT4/W4A8 AWQ export #2320
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: main
Are you sure you want to change the base?
Changes from all commits
8c9001c
6905464
3f2c679
1580415
89bdde5
ffc0c3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -792,12 +792,22 @@ def process_layer_quant_config(layer_config_dict): | |
| return per_layer_config | ||
|
|
||
|
|
||
| def pack_int4_in_uint8(weight, weights_scaling_factor): | ||
| def _validate_int4_block_size(in_dim, block_size): | ||
| if not isinstance(block_size, int) or block_size <= 0: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P1] Apply this validation to compressed AWQ weights too.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BB: Is the fix valid for INT4 AWQ as well? If not can you raise similar error during AWQ export as well?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🐝 I’m checking the INT4 AWQ path and will make sure it fails clearly during export if the current guard does not cover it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The current helper covers uncompressed INT4 AWQ and W4A8 AWQ. The remaining issue is the compressed
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BB: Is there an easy way to implement this? PTAL and tell me. if this is simple to do, can you do that?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🐝
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes. This is a small export-only change: for compressed INT4/W4A8 AWQ weights, validate the logical input dimension from
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Fixed in 89bdde5: compressed INT4 and W4A8 AWQ wrappers now validate the logical input dimension before the fast return, with focused regression coverage. |
||
| raise ValueError(f"Block size must be a positive integer, got {block_size}.") | ||
| if in_dim % block_size != 0: | ||
|
realAsma marked this conversation as resolved.
|
||
| raise NotImplementedError( | ||
| f"Cannot pack weight with input dimension {in_dim} and block size {block_size}: " | ||
| "partial blocks are not supported." | ||
| ) | ||
|
realAsma marked this conversation as resolved.
realAsma marked this conversation as resolved.
|
||
|
|
||
|
|
||
| def pack_int4_in_uint8(weight, weights_scaling_factor, block_size): | ||
|
realAsma marked this conversation as resolved.
|
||
| """Packs the INT4 weights into uint8 tensor.""" | ||
| out_dim = weight.shape[-2] | ||
| assert out_dim % 2 == 0, f"Cannot pack weight. Out dimension {out_dim} is not an even number." | ||
| in_dim = weight.shape[-1] | ||
| block_size = weight.shape[-1] // weights_scaling_factor.shape[-1] | ||
| _validate_int4_block_size(in_dim, block_size) | ||
|
realAsma marked this conversation as resolved.
|
||
|
|
||
| # Scale, round, and clamp to the signed 4-bit range [-8..7]. | ||
| int8_tensor = ( | ||
|
|
@@ -852,6 +862,8 @@ def to_quantized_weight( | |
|
|
||
| # For compressed weights, we directly return the data from wrapper | ||
| if isinstance(weight, QTensorWrapper): | ||
| if quantization in [QUANTIZATION_INT4_AWQ, QUANTIZATION_W4A8_AWQ]: | ||
| _validate_int4_block_size(weight.metadata["shape"][-1], block_size) | ||
| return weight.data | ||
|
|
||
| if quantization == QUANTIZATION_FP8: | ||
|
|
@@ -912,7 +924,7 @@ def to_quantized_weight( | |
| return (weight / weights_scaling_factor[:, None]).to(torch.float8_e4m3fn) | ||
|
|
||
| if quantization in [QUANTIZATION_INT4_AWQ, QUANTIZATION_W4A8_AWQ]: | ||
| return pack_int4_in_uint8(weight, weights_scaling_factor) | ||
| return pack_int4_in_uint8(weight, weights_scaling_factor, block_size) | ||
|
|
||
| if quantization in [ | ||
| QUANTIZATION_NVFP4, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.