| 573 | |
| 574 | |
| 575 | class TestQuantize4BitFunctional: |
| 576 | @pytest.mark.parametrize("device", get_available_devices()) |
| 577 | @pytest.mark.parametrize("dtype", [torch.float32, torch.float16, torch.bfloat16], ids=describe_dtype) |
| 578 | @pytest.mark.parametrize("quant_type", ["fp4", "nf4"]) |
| 579 | @pytest.mark.parametrize( |
| 580 | "blocksize", |
| 581 | [32, 64, 128, 256, 512, 1024, 2048, 4096], |
| 582 | ) |
| 583 | def test_4bit_quant(self, device, dtype, quant_type, blocksize): |
| 584 | if device == "hpu" and not is_supported_on_hpu(quant_type, dtype): |
| 585 | pytest.skip("This configuration is not supported on HPU.") |
| 586 | |
| 587 | A1 = torch.randn(1024, 1024, device=device, dtype=dtype) |
| 588 | qa, SA = F.quantize_4bit(A1, blocksize=blocksize, quant_type=quant_type) |
| 589 | d = SA.as_dict() |
| 590 | SA = F.QuantState.from_dict(d, device=torch.device(device)) |
| 591 | A2 = F.dequantize_4bit(qa, SA, blocksize=blocksize, quant_type=quant_type) |
| 592 | del qa, SA |
| 593 | |
| 594 | assert A2.dtype == dtype |
| 595 | |
| 596 | err = (A1 - A2).abs().float() |
| 597 | del A2 |
| 598 | |
| 599 | relerr = (err / (A1.abs().float() + 1e-8)).mean() |
| 600 | err = err.mean() |
| 601 | |
| 602 | # Expected (mean, std) per configuration, from 200 samples on RTX 4090. |
| 603 | # Thresholds are set at mean + N_SIGMA * std to avoid flaky failures |
| 604 | # while still catching real regressions. Worst-case std across dtypes is used. |
| 605 | N_SIGMA = 7 |
| 606 | error_stats = { |
| 607 | "fp4": { |
| 608 | "err": { |
| 609 | 32: (0.088925, 0.000091), |
| 610 | 64: (0.096543, 0.000111), |
| 611 | 128: (0.102969, 0.000134), |
| 612 | 256: (0.108684, 0.000182), |
| 613 | 512: (0.114115, 0.000234), |
| 614 | 1024: (0.119333, 0.000320), |
| 615 | 2048: (0.124556, 0.000455), |
| 616 | 4096: (0.129536, 0.000612), |
| 617 | }, |
| 618 | "rel_err": { |
| 619 | 32: (0.242443, 0.000330), |
| 620 | 64: (0.260125, 0.000379), |
| 621 | 128: (0.275817, 0.000433), |
| 622 | 256: (0.289831, 0.000497), |
| 623 | 512: (0.302881, 0.000583), |
| 624 | 1024: (0.315000, 0.000757), |
| 625 | 2048: (0.326607, 0.000955), |
| 626 | 4096: (0.337169, 0.001239), |
| 627 | }, |
| 628 | }, |
| 629 | "nf4": { |
| 630 | "err": { |
| 631 | 32: (0.067746, 0.000069), |
| 632 | 64: (0.072798, 0.000074), |
nothing calls this directly
no outgoing calls
no test coverage detected