Skip to content

Increase calibration samples and tolerance for flaky quantized op tests #7990

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
merged 1 commit into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions backends/xnnpack/test/ops/test_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import unittest

import torch
from executorch.backends.xnnpack.test.tester import Tester
from executorch.backends.xnnpack.test.tester import Quantize, Tester


class TestAdd(unittest.TestCase):
Expand Down Expand Up @@ -136,9 +136,12 @@ def test_qs8_add2(self):

def test_qs8_add3(self):
inputs = (torch.randn(1, 1, 4, 4), torch.randn(1, 1, 4, 1))
calibration_samples = [
(torch.randn(1, 1, 4, 4), torch.randn(1, 1, 4, 1)) for _ in range(100)
]
(
Tester(self.Add(), inputs)
.quantize()
.quantize(Quantize(calibration_samples=calibration_samples))
.export()
.check_count({"torch.ops.aten.add.Tensor": 4})
.check(["torch.ops.quantized_decomposed"])
Expand All @@ -152,7 +155,7 @@ def test_qs8_add3(self):
)
.to_executorch()
.serialize()
.run_method_and_compare_outputs()
.run_method_and_compare_outputs(num_runs=10, atol=0.02, rtol=0.02)
)

class AddRelu(torch.nn.Module):
Expand Down
16 changes: 13 additions & 3 deletions backends/xnnpack/test/ops/test_conv1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
from executorch.backends.xnnpack.test.test_xnnpack_utils import randomize_bn

from executorch.backends.xnnpack.test.tester import RunPasses, Tester
from executorch.backends.xnnpack.test.tester import Quantize, RunPasses, Tester
from executorch.backends.xnnpack.test.tester.tester import ToEdgeTransformAndLower
from executorch.exir.passes.constant_prop_pass import constant_prop_pass

Expand Down Expand Up @@ -98,9 +98,17 @@ def _test_conv1d(
stage=None,
skip_to_executorch=False,
):
calibration_samples = (
[tuple(torch.randn_like(inputs[i]) for i in range(len(inputs)))]
if quantized
else None
)

tester = (
(
Tester(module, inputs, dynamic_shape).quantize()
Tester(module, inputs, dynamic_shape).quantize(
Quantize(calibration_samples=calibration_samples)
)
if quantized
else Tester(module, inputs)
)
Expand All @@ -114,7 +122,9 @@ def _test_conv1d(
# For some tests we want to skip to_executorch because otherwise it will require the
# quantized operators to be loaded and we don't want to do that in the test.
if not skip_to_executorch:
tester.to_executorch().serialize().run_method_and_compare_outputs()
tester.to_executorch().serialize().run_method_and_compare_outputs(
num_runs=10, atol=0.01, rtol=0.01
)

def test_fp16_conv1d(self):
inputs = (torch.randn(2, 2, 4).to(torch.float16),)
Expand Down
10 changes: 8 additions & 2 deletions backends/xnnpack/test/tester/tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import sys
from abc import ABC, abstractmethod
from collections import Counter, OrderedDict
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type, Union

import torch
from executorch.backends.xnnpack._passes import XNNPACKPassManager
Expand Down Expand Up @@ -146,12 +146,14 @@ def __init__(
quantizer: Optional[Quantizer] = None,
quantization_config: Optional[QuantizationConfig] = None,
calibrate: bool = True,
calibration_samples: Optional[Sequence[Any]] = None,
):
self.quantizer = quantizer or XNNPACKQuantizer()
self.quantization_config = (
quantization_config or get_symmetric_quantization_config()
)
self.calibrate = calibrate
self.calibration_samples = calibration_samples

self.quantizer.set_global(self.quantization_config)

Expand All @@ -168,7 +170,11 @@ def run(

if self.calibrate:
# Calibrate prepared model to provide data to quantization observers.
prepared(*inputs)
if self.calibration_samples is not None:
for inp in self.calibration_samples:
prepared(*inp)
else:
prepared(*inputs)

converted = convert_pt2e(prepared)
self.converted_graph = converted
Expand Down
Loading