Quantize a tensor in blocks of values. The input tensor is quantized by dividing it into blocks of `blocksize` values. The the absolute maximum value within these blocks is calculated for scaling the non-linear quantization. Args: A (`torch.Tensor`): The input tensor. Suppo
(
A: torch.Tensor,
code: Optional[torch.Tensor] = None,
absmax: Optional[torch.Tensor] = None,
out: Optional[torch.Tensor] = None,
blocksize=4096,
nested=False,
)
| 611 | |
| 612 | |
| 613 | def quantize_blockwise( |
| 614 | A: torch.Tensor, |
| 615 | code: Optional[torch.Tensor] = None, |
| 616 | absmax: Optional[torch.Tensor] = None, |
| 617 | out: Optional[torch.Tensor] = None, |
| 618 | blocksize=4096, |
| 619 | nested=False, |
| 620 | ) -> tuple[torch.Tensor, QuantState]: |
| 621 | """Quantize a tensor in blocks of values. |
| 622 | |
| 623 | The input tensor is quantized by dividing it into blocks of `blocksize` values. |
| 624 | The the absolute maximum value within these blocks is calculated for scaling |
| 625 | the non-linear quantization. |
| 626 | |
| 627 | Args: |
| 628 | A (`torch.Tensor`): The input tensor. Supports `float16`, `bfloat16`, or `float32` datatypes. |
| 629 | code (`torch.Tensor`, *optional*): |
| 630 | A mapping describing the low-bit data type. Defaults to a signed 8-bit dynamic type. |
| 631 | For more details, see (8-Bit Approximations for Parallelism in Deep Learning)[https://arxiv.org/abs/1511.04561]. |
| 632 | absmax (`torch.Tensor`, *optional*): A tensor to use to store the absmax values. |
| 633 | out (`torch.Tensor`, *optional*): A tensor to use to store the result. |
| 634 | blocksize (`int`, *optional*): |
| 635 | The size of the blocks. Defaults to 4096. |
| 636 | Valid values are 64, 128, 256, 512, 1024, 2048, and 4096. |
| 637 | nested (`bool`, *optional*): Whether to additionally quantize the absmax values. Defaults to False. |
| 638 | |
| 639 | Raises: |
| 640 | ValueError: Raised when the input data type is not supported. |
| 641 | |
| 642 | Returns: |
| 643 | `Tuple[torch.Tensor, QuantState]`: A tuple containing the quantization results. |
| 644 | - `torch.Tensor`: The quantized tensor. |
| 645 | - [`QuantState`]: The state object used to undo the quantization. |
| 646 | """ |
| 647 | |
| 648 | if blocksize <= 0: |
| 649 | raise ValueError(f"blocksize must be positive, got {blocksize}") |
| 650 | if A.dtype not in (torch.float32, torch.float16, torch.bfloat16): |
| 651 | raise ValueError(f"Blockwise quantization only supports 16/32-bit floats, but got {A.dtype}") |
| 652 | |
| 653 | if code is None: |
| 654 | if "dynamic" not in name2qmap: |
| 655 | name2qmap["dynamic"] = create_dynamic_map().to(A.device) |
| 656 | code = name2qmap["dynamic"] |
| 657 | |
| 658 | _out, _absmax = torch.ops.bitsandbytes.quantize_blockwise.default( |
| 659 | A, |
| 660 | code.to(A.device), |
| 661 | blocksize, |
| 662 | ) |
| 663 | |
| 664 | if nested: |
| 665 | offset = _absmax.mean() |
| 666 | _absmax -= offset |
| 667 | qabsmax, state2 = quantize_blockwise(_absmax, blocksize=blocksize, nested=False) |
| 668 | quant_state = QuantState( |
| 669 | absmax=qabsmax, |
| 670 | code=code.to(A.device, copy=True), |
no test coverage detected