NOTE: The Jupyter Notebook below is included in the Chimera SDK and can be run interactively by running the following CLI command:
$ quadric sdk notebook
From the Jupyter Notebook window in your browser, select the notebook named /quadric/sdk-cli/examples/quantization/ViTQuantization.ipynb.
from pathlib import Path
from typing import Dict
get_ipython().run_line_magic("matplotlib", "inline")
import matplotlib.pyplot as plt
import numpy as np
import onnx
import onnxruntime
from matplotlib.gridspec import GridSpec
from onnxruntime.tools.onnx_model_utils import make_input_shape_fixed, fix_output_shapes
from PIL import Image
from torch.utils.data import DataLoader, Subset
from torchvision.transforms import CenterCrop, Compose, Normalize, Resize, ToTensor
from tvm.contrib.epu.chimera_job.constants import DEFAULT_ONNX_OPSET
from sdk_cli.lib.quantize import (
QuantizationExperiment,
QuantizedONNXModel,
quantize_onnx_model,
run_quantization_experiment,
)
from sdk_cli.utils.dataloaders import CalibrationDataLoader
from sdk_cli.utils.datasets import ImageNet_Mini_Quadric, QuadricCalibration
from sdk_cli.utils.datasets.ImageNet import OPTIMIZED_IMAGENET_1K_LABELS
from sdk_cli.utils.performance_trackers import ClassifierPerformanceTracker
from sdk_cli.visualizers.layouter import ClassifierLayouter
## Download the ViT image classification model
!mkdir -p vit_float32
!python3 -m optimum.exporters.onnx -m=google/vit-base-patch16-224 --framework pt vit_float32 --atol=0.01 --opset={DEFAULT_ONNX_OPSET}
2026-07-18 12:14:58.890589: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
2026-07-18 12:14:58.891215: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.
2026-07-18 12:14:58.893916: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.
2026-07-18 12:14:58.930256: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 AVX512F AVX512_VNNI AVX512_BF16 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
2026-07-18 12:14:59.650475: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT
Automatic task detection to image-classification.
Fast image processor class <class 'transformers.models.vit.image_processing_vit_fast.ViTImageProcessorFast'> is available for this model. Using slow image processor class. To use the fast image processor class set `use_fast=True`.
/usr/local/lib/python3.10/dist-packages/transformers/models/vit/feature_extraction_vit.py:28: FutureWarning: The class ViTFeatureExtractor is deprecated and will be removed in version 5 of Transformers. Please use ViTImageProcessor instead.
warnings.warn(
Using the export variant default. Available variants are:
- default: The default ONNX variant.
Fast image processor class <class 'transformers.models.vit.image_processing_vit_fast.ViTImageProcessorFast'> is available for this model. Using slow image processor class. To use the fast image processor class set `use_fast=True`.
Using framework PyTorch: 2.6.0+cpu
/usr/local/lib/python3.10/dist-packages/transformers/models/vit/modeling_vit.py:172: TracerWarning: Converting a tensor to a Python boolean might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!
if num_channels != self.num_channels:
/usr/local/lib/python3.10/dist-packages/transformers/models/vit/modeling_vit.py:178: TracerWarning: Converting a tensor to a Python boolean might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!
if height != self.image_size[0] or width != self.image_size[1]:
Post-processing the exported models...
Deduplicating shared (tied) weights...
Validating ONNX model vit_float32/model.onnx...
-[✓] ONNX model output names match reference model (logits)
- Validating ONNX Model output "logits":
-[✓] (2, 1000) matches (2, 1000)
-[✓] all values close (atol: 0.01)
The ONNX export succeeded and the exported model was saved at: vit_float32
## Load the ONNX model exported by `optimum`
exported_onnx_model_path = Path("vit_float32/model.onnx")
model = onnx.load(str(exported_onnx_model_path))
## Fix the input shape to `224x224`
input_name = "pixel_values"
input_tensor_shape = (1, 3, 224, 224)
make_input_shape_fixed(model.graph, input_name, input_tensor_shape)
fix_output_shapes(model)
fixed_shape_onnx_model_path = "vit_float32_fixed_shape.onnx"
onnx.save(model, fixed_shape_onnx_model_path)
## Run `onnxruntime`'s quantization preprocessing
optimized_onnx_model_path = "vit_float32_optimized.onnx"
onnxruntime.quantization.shape_inference.quant_pre_process(
fixed_shape_onnx_model_path, optimized_onnx_model_path
)
transforms = Compose(
[
Resize((224, 224)),
CenterCrop((224, 224)),
ToTensor(),
Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
]
)
## Path to directory containing data to use for for numerical range calibration during quantization
## Data is used also used to compare accuracy of fp32 and int8 models
dataset = ImageNet_Mini_Quadric.Dataset(transform=transforms)
subset_of_dataset = Subset(dataset, range(100))
calibration_dataloader = CalibrationDataLoader(
DataLoader(subset_of_dataset, batch_size=1, shuffle=True), ["pixel_values"]
)
## To achieve the best accuracy remove the Softmax, residual add and normalization bias nodes from quantization
## The dynamic range of values is very large for the residual add chain in ViT, especially in later layers, so
## it cannot be quantized
onnx_node_names_to_exclude = (
[f"/vit/encoder/layer.{i}/output/Add" for i in range(12)]
+ [f"/vit/encoder/layer.{i}/Add" for i in range(12)]
+ [f"/vit/encoder/layer.{i}/intermediate/intermediate_act_fn/Add" for i in range(12)]
+ [f"/vit/encoder/layer.{i}/layernorm_before/Add" for i in range(12)]
+ [f"/vit/encoder/layer.{i}/layernorm_after/Add" for i in range(12)]
+ [f"/vit/encoder/layer.{i}/layernorm_before/Add_1" for i in range(12)]
+ [f"/vit/encoder/layer.{i}/layernorm_after/Add_1" for i in range(12)]
+ [f"/vit/encoder/layer.{i}/layernorm_before/Mul" for i in range(12)]
+ [f"/vit/encoder/layer.{i}/layernorm_after/Mul" for i in range(12)]
+ ["/vit/layernorm/Add"]
)
quantized_onnx_model: QuantizedONNXModel = quantize_onnx_model(
optimized_onnx_model_path,
dataset,
asymmetric_activation=False,
onnx_node_types_to_exclude=["Softmax"],
onnx_node_names_to_exclude=onnx_node_names_to_exclude,
)
2026-07-18 12:15 - INFO - sdk - quantize - ONNX model shapes inferred.
2026-07-18 12:15 - DEBUG - sdk - quantize - Forcing node types: []
2026-07-18 12:15 - DEBUG - sdk - quantize - ONNX Node types excluded from quantization: ['Softmax', 'Sigmoid', 'QuadricCustomOp', 'Softmax']
2026-07-18 12:15 - DEBUG - sdk - quantize - ONNX Node names excluded from quantization: ['/vit/encoder/layer.3/layernorm_before/Div', 'vit.encoder.layer.9.layernorm_before.bias', 'vit.encoder.layer.11.layernorm_after.weight', '/vit/encoder/layer.1/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.1/attention/attention/Softmax', '/vit/encoder/layer.7/layernorm_before/Add', '/vit/encoder/layer.2/layernorm_before/Add', 'vit.encoder.layer.1.layernorm_before.bias', '/vit/encoder/layer.10/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.4/layernorm_after/Mul', '/vit/encoder/layer.8/layernorm_after/Sqrt', '/vit/encoder/layer.5/intermediate/intermediate_act_fn/Erf', 'vit.encoder.layer.4.layernorm_before.bias', 'vit.encoder.layer.10.layernorm_after.bias', '/vit/encoder/layer.10/layernorm_after/Sqrt', '/vit/encoder/layer.4/Add', '/vit/encoder/layer.11/layernorm_after/Add', '/vit/encoder/layer.10/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.9/intermediate/intermediate_act_fn/Mul_1', 'vit.encoder.layer.1.layernorm_after.weight', '/vit/encoder/layer.8/layernorm_after/Pow', '/vit/encoder/layer.1/layernorm_before/Pow', '/vit/encoder/layer.9/Add', '/vit/encoder/layer.3/output/Add', 'vit.encoder.layer.7.layernorm_before.weight', '/vit/encoder/layer.11/intermediate/intermediate_act_fn/Div', '/vit/encoder/layer.7/layernorm_after/Add', '/vit/encoder/layer.10/layernorm_before/ReduceMean', '/vit/encoder/layer.6/layernorm_after/Mul', '/vit/encoder/layer.8/layernorm_before/Div', '/vit/encoder/layer.1/layernorm_after/Mul', '/vit/encoder/layer.5/layernorm_before/Add_1', '/vit/encoder/layer.8/layernorm_after/Add_1', 'vit.encoder.layer.10.layernorm_before.weight', '/vit/encoder/layer.7/layernorm_after/Div', '/vit/layernorm/Mul', '/vit/encoder/layer.11/Add', '/vit/encoder/layer.1/layernorm_after/Sub', '/vit/encoder/layer.7/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.0/layernorm_after/ReduceMean_1', '/vit/encoder/layer.5/layernorm_before/Sub', '/vit/encoder/layer.7/attention/attention/Softmax', '/vit/encoder/layer.0/output/Add', '/vit/encoder/layer.6/layernorm_before/Pow', '/vit/encoder/layer.5/layernorm_after/Pow', '/vit/encoder/layer.9/layernorm_after/ReduceMean_1', '/vit/encoder/layer.9/layernorm_before/Add_1', '/vit/encoder/layer.10/layernorm_before/Sub', '/vit/encoder/layer.4/layernorm_before/ReduceMean', '/vit/encoder/layer.11/layernorm_before/ReduceMean_1', '/vit/encoder/layer.5/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.1/layernorm_before/ReduceMean', '/vit/encoder/layer.0/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.7/layernorm_after/Sub', '/vit/encoder/layer.11/intermediate/intermediate_act_fn/Add', '/vit/encoder/layer.4/layernorm_after/Add_1', '/vit/encoder/layer.5/layernorm_before/Pow', '/vit/encoder/layer.5/layernorm_before/Div', '/vit/encoder/layer.10/intermediate/intermediate_act_fn/Constant_output_0', '/vit/encoder/layer.2/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.4/layernorm_before/Pow', 'vit.encoder.layer.0.layernorm_after.weight', '/vit/encoder/layer.5/layernorm_after/ReduceMean', '/vit/encoder/layer.6/layernorm_before/Sqrt', '/vit/encoder/layer.4/layernorm_after/Div', '/vit/encoder/layer.7/layernorm_before/Add_1', '/vit/encoder/layer.0/layernorm_before/Sqrt', '/vit/layernorm/ReduceMean', '/vit/encoder/layer.0/intermediate/intermediate_act_fn/Div', '/vit/encoder/layer.5/intermediate/intermediate_act_fn/Div', '/vit/encoder/layer.11/layernorm_before/Pow', '/vit/encoder/layer.9/intermediate/intermediate_act_fn/Add', '/vit/encoder/layer.4/layernorm_before/Sqrt', 'vit.encoder.layer.2.layernorm_before.weight', '/vit/encoder/layer.2/layernorm_before/Sub', '/vit/encoder/layer.0/layernorm_before/Sub', '/vit/encoder/layer.6/output/Add', '/vit/encoder/layer.7/layernorm_before/Div', '/vit/layernorm/Constant_1_output_0', '/vit/encoder/layer.9/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.9/layernorm_after/Pow', '/vit/encoder/layer.1/layernorm_before/Div', '/vit/encoder/layer.1/layernorm_after/Add', '/vit/encoder/layer.9/layernorm_after/Sqrt', '/vit/encoder/layer.8/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.9/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.9/layernorm_before/Add', 'vit.encoder.layer.3.layernorm_after.bias', '/vit/encoder/layer.2/layernorm_before/ReduceMean_1', '/vit/encoder/layer.3/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.3/attention/attention/Softmax', '/vit/encoder/layer.1/intermediate/intermediate_act_fn/Div', '/vit/encoder/layer.4/layernorm_before/Mul', '/vit/encoder/layer.2/layernorm_after/ReduceMean', '/vit/encoder/layer.7/layernorm_before/Mul', '/vit/encoder/layer.3/layernorm_before/Pow', '/vit/encoder/layer.10/layernorm_after/Sub', '/vit/encoder/layer.4/attention/attention/Softmax', '/vit/encoder/layer.9/layernorm_after/ReduceMean', '/vit/encoder/layer.9/layernorm_before/Pow', '/vit/encoder/layer.11/attention/attention/Softmax', '/vit/encoder/layer.11/layernorm_before/Mul', '/vit/encoder/layer.8/layernorm_before/Add', '/vit/encoder/layer.7/output/Add', '/vit/encoder/layer.7/layernorm_before/Sqrt', '/vit/encoder/layer.6/layernorm_before/ReduceMean', '/vit/encoder/layer.9/output/Add', '/vit/encoder/layer.6/layernorm_before/ReduceMean_1', '/vit/encoder/layer.3/layernorm_after/Add', '/vit/encoder/layer.9/layernorm_after/Add', '/vit/encoder/layer.6/layernorm_after/ReduceMean', '/vit/encoder/layer.9/layernorm_before/Sub', '/vit/encoder/layer.11/layernorm_after/ReduceMean_1', 'vit.encoder.layer.11.layernorm_before.weight', '/vit/layernorm/Pow', '/vit/encoder/layer.1/Add', '/vit/encoder/layer.4/layernorm_after/Add', '/vit/encoder/layer.10/layernorm_before/ReduceMean_1', '/vit/encoder/layer.1/layernorm_before/Mul', '/vit/encoder/layer.4/layernorm_before/Add_1', '/vit/encoder/layer.11/layernorm_before/Sub', '/vit/encoder/layer.2/intermediate/intermediate_act_fn/Add', 'vit.encoder.layer.6.layernorm_after.weight', '/vit/encoder/layer.3/layernorm_before/Mul', '/vit/encoder/layer.10/intermediate/intermediate_act_fn/Div', '/vit/encoder/layer.10/layernorm_after/Pow', '/vit/encoder/layer.2/layernorm_after/Mul', '/vit/encoder/layer.0/Add', '/vit/encoder/layer.2/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.4/layernorm_before/Sub', '/vit/encoder/layer.6/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.4/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.1/intermediate/intermediate_act_fn/Add', '/vit/encoder/layer.1/layernorm_after/Sqrt', '/vit/encoder/layer.0/layernorm_before/Add_1', 'vit.encoder.layer.9.layernorm_after.bias', '/vit/encoder/layer.5/layernorm_after/Add_1', '/vit/encoder/layer.4/output/Add', 'vit.encoder.layer.1.layernorm_after.bias', '/vit/encoder/layer.1/layernorm_after/Add_1', '/vit/encoder/layer.6/layernorm_before/Sub', '/vit/encoder/layer.2/intermediate/intermediate_act_fn/Div', '/vit/encoder/layer.3/layernorm_after/ReduceMean_1', '/vit/encoder/layer.8/intermediate/intermediate_act_fn/Add', 'vit.encoder.layer.5.layernorm_before.bias', '/vit/encoder/layer.11/layernorm_before/Add', '/vit/encoder/layer.2/layernorm_after/Div', '/vit/encoder/layer.5/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.5/layernorm_before/ReduceMean', 'vit.layernorm.bias', '/vit/encoder/layer.5/layernorm_before/Sqrt', 'vit.encoder.layer.6.layernorm_before.weight', '/vit/encoder/layer.1/layernorm_after/Pow', '/vit/encoder/layer.0/layernorm_after/ReduceMean', '/vit/encoder/layer.6/intermediate/intermediate_act_fn/Div', '/vit/encoder/layer.2/layernorm_after/ReduceMean_1', '/vit/encoder/layer.5/layernorm_after/Sqrt', '/vit/encoder/layer.6/layernorm_after/ReduceMean_1', '/vit/encoder/layer.9/layernorm_before/ReduceMean', '/vit/encoder/layer.2/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.2/layernorm_before/Div', '/vit/encoder/layer.0/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.6/layernorm_before/Add_1', '/vit/encoder/layer.7/layernorm_before/Pow', '/vit/encoder/layer.11/layernorm_after/Constant_output_0', 'vit.encoder.layer.10.layernorm_after.weight', '/vit/encoder/layer.1/layernorm_before/Add', '/vit/encoder/layer.6/Add', '/vit/encoder/layer.3/layernorm_before/ReduceMean', '/vit/encoder/layer.6/layernorm_after/Sqrt', '/vit/encoder/layer.6/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.0/layernorm_after/Div', '/vit/encoder/layer.7/intermediate/intermediate_act_fn/Add', 'vit.encoder.layer.5.layernorm_before.weight', '/vit/encoder/layer.7/intermediate/intermediate_act_fn/Div', '/vit/encoder/layer.3/intermediate/intermediate_act_fn/Add', '/vit/encoder/layer.8/intermediate/intermediate_act_fn/Div', 'vit.encoder.layer.8.layernorm_before.weight', '/vit/encoder/layer.11/layernorm_after/Sqrt', '/vit/encoder/layer.3/layernorm_after/Sub', '/vit/encoder/layer.9/layernorm_before/Mul', '/vit/encoder/layer.3/layernorm_after/Pow', '/vit/encoder/layer.5/layernorm_after/ReduceMean_1', '/vit/encoder/layer.6/layernorm_after/Sub', '/vit/encoder/layer.5/layernorm_before/Mul', 'vit.encoder.layer.6.layernorm_after.bias', '/vit/encoder/layer.0/intermediate/intermediate_act_fn/Add', '/vit/encoder/layer.0/layernorm_before/Pow', 'vit.encoder.layer.7.layernorm_before.bias', '/vit/encoder/layer.7/Add', 'vit.encoder.layer.4.layernorm_after.weight', '/vit/layernorm/Sqrt', '/vit/encoder/layer.2/Add', '/vit/encoder/layer.5/layernorm_after/Div', '/vit/encoder/layer.4/layernorm_after/ReduceMean_1', '/vit/encoder/layer.4/layernorm_after/Sqrt', '/vit/encoder/layer.10/layernorm_after/Mul', '/vit/encoder/layer.2/layernorm_after/Pow', '/vit/encoder/layer.10/layernorm_after/Add_1', '/vit/encoder/layer.9/layernorm_before/Div', 'vit.encoder.layer.6.layernorm_before.bias', '/vit/encoder/layer.9/layernorm_after/Add_1', '/vit/encoder/layer.8/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.0/layernorm_before/ReduceMean', '/vit/encoder/layer.5/layernorm_after/Add', '/vit/encoder/layer.6/layernorm_after/Div', '/vit/encoder/layer.2/layernorm_before/Mul', '/vit/encoder/layer.8/layernorm_before/ReduceMean', '/vit/encoder/layer.11/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.1/layernorm_after/Div', '/vit/encoder/layer.1/layernorm_before/Sqrt', '/vit/encoder/layer.2/layernorm_before/Pow', '/vit/encoder/layer.6/layernorm_before/Div', '/vit/encoder/layer.4/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.0/layernorm_after/Sub', '/vit/encoder/layer.6/layernorm_after/Pow', '/vit/encoder/layer.0/layernorm_after/Sqrt', '/vit/encoder/layer.6/layernorm_after/Add_1', '/vit/encoder/layer.6/intermediate/intermediate_act_fn/Add', 'vit.encoder.layer.2.layernorm_before.bias', '/vit/encoder/layer.9/layernorm_after/Sub', 'vit.encoder.layer.2.layernorm_after.weight', '/vit/encoder/layer.8/layernorm_after/ReduceMean_1', '/vit/encoder/layer.11/layernorm_after/Div', '/vit/encoder/layer.7/layernorm_after/Add_1', '/vit/encoder/layer.11/intermediate/intermediate_act_fn/Constant_1_output_0', '/vit/encoder/layer.7/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.3/layernorm_after/ReduceMean', '/vit/encoder/layer.5/layernorm_after/Sub', '/vit/encoder/layer.0/layernorm_before/Add', '/vit/encoder/layer.10/layernorm_after/ReduceMean', 'vit.encoder.layer.8.layernorm_before.bias', '/vit/encoder/layer.5/output/Add', '/vit/encoder/layer.8/layernorm_after/Add', '/vit/encoder/layer.10/intermediate/intermediate_act_fn/Add', 'vit.encoder.layer.9.layernorm_after.weight', '/vit/encoder/layer.6/attention/attention/Softmax', '/vit/encoder/layer.7/layernorm_after/Mul', '/vit/encoder/layer.10/attention/attention/Softmax', '/vit/encoder/layer.2/layernorm_after/Sub', '/vit/layernorm/Sub', '/vit/encoder/layer.1/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.11/layernorm_before/Add_1', '/vit/encoder/layer.3/layernorm_after/Sqrt', '/vit/encoder/layer.7/layernorm_before/Sub', 'vit.encoder.layer.4.layernorm_after.bias', 'vit.encoder.layer.9.layernorm_before.weight', 'vit.encoder.layer.0.layernorm_after.bias', '/vit/encoder/layer.7/layernorm_before/ReduceMean_1', '/vit/encoder/layer.4/layernorm_before/Add', '/vit/encoder/layer.11/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.1/layernorm_before/ReduceMean_1', '/vit/encoder/layer.0/intermediate/intermediate_act_fn/Constant_2_output_0', 'vit.encoder.layer.5.layernorm_after.bias', '/vit/encoder/layer.4/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.11/layernorm_before/ReduceMean', '/vit/encoder/layer.8/Add', '/vit/encoder/layer.8/output/Add', 'vit.encoder.layer.0.layernorm_before.weight', '/vit/encoder/layer.10/layernorm_before/Div', '/vit/encoder/layer.7/layernorm_after/ReduceMean', '/vit/encoder/layer.1/intermediate/intermediate_act_fn/Mul', '/vit/layernorm/Add_1', '/vit/encoder/layer.5/attention/attention/Softmax', '/vit/encoder/layer.8/attention/attention/Softmax', '/vit/encoder/layer.1/layernorm_before/Sub', '/vit/encoder/layer.10/layernorm_before/Sqrt', '/vit/encoder/layer.7/layernorm_after/ReduceMean_1', 'vit.encoder.layer.11.layernorm_before.bias', '/vit/encoder/layer.11/layernorm_after/Add_1', 'vit.encoder.layer.11.layernorm_after.bias', '/vit/encoder/layer.2/output/Add', '/vit/encoder/layer.0/layernorm_after/Add_1', 'vit.encoder.layer.5.layernorm_after.weight', '/vit/encoder/layer.11/intermediate/intermediate_act_fn/Mul', 'vit.encoder.layer.8.layernorm_after.bias', '/vit/encoder/layer.5/layernorm_before/ReduceMean_1', '/vit/encoder/layer.10/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.3/layernorm_after/Div', '/vit/encoder/layer.3/layernorm_before/Add_1', '/vit/encoder/layer.9/intermediate/intermediate_act_fn/Div', '/vit/encoder/layer.10/layernorm_before/Pow', '/vit/encoder/layer.2/layernorm_after/Sqrt', '/vit/encoder/layer.1/layernorm_after/ReduceMean', '/vit/encoder/layer.6/layernorm_before/Add', '/vit/encoder/layer.9/attention/attention/Softmax', 'vit.encoder.layer.3.layernorm_after.weight', '/vit/encoder/layer.11/layernorm_after/Mul', '/vit/encoder/layer.7/layernorm_after/Pow', '/vit/encoder/layer.2/layernorm_before/ReduceMean', '/vit/layernorm/Div', '/vit/encoder/layer.4/layernorm_before/ReduceMean_1', '/vit/encoder/layer.11/layernorm_after/Sub', '/vit/encoder/layer.2/layernorm_after/Add', '/vit/encoder/layer.0/layernorm_before/Mul', '/vit/encoder/layer.8/layernorm_after/Mul', '/vit/encoder/layer.7/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.11/layernorm_after/ReduceMean', '/vit/encoder/layer.2/layernorm_before/Sqrt', '/vit/encoder/layer.2/attention/attention/Softmax', '/vit/encoder/layer.0/layernorm_after/Mul', '/vit/encoder/layer.0/layernorm_after/Pow', '/vit/encoder/layer.0/layernorm_after/Add', 'vit.encoder.layer.1.layernorm_before.weight', '/vit/encoder/layer.1/layernorm_before/Add_1', 'vit.encoder.layer.7.layernorm_after.weight', '/vit/encoder/layer.5/Add', '/vit/encoder/layer.8/layernorm_before/Sub', 'vit.layernorm.weight', '/vit/encoder/layer.10/layernorm_before/Mul', '/vit/encoder/layer.5/intermediate/intermediate_act_fn/Add', 'vit.encoder.layer.7.layernorm_after.bias', '/vit/encoder/layer.10/layernorm_before/Add_1', '/vit/encoder/layer.10/Add', '/vit/encoder/layer.10/layernorm_after/Div', '/vit/encoder/layer.5/layernorm_before/Add', '/vit/encoder/layer.3/layernorm_before/Add', '/vit/encoder/layer.4/layernorm_after/Pow', '/vit/encoder/layer.8/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.4/layernorm_after/Sub', '/vit/encoder/layer.0/layernorm_before/ReduceMean_1', '/vit/encoder/layer.3/intermediate/intermediate_act_fn/Div', 'vit.encoder.layer.10.layernorm_before.bias', '/vit/encoder/layer.3/layernorm_before/Sub', '/vit/encoder/layer.3/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.8/layernorm_after/ReduceMean', '/vit/encoder/layer.3/layernorm_before/Sqrt', '/vit/encoder/layer.11/layernorm_before/Div', '/vit/encoder/layer.3/layernorm_before/ReduceMean_1', '/vit/encoder/layer.1/layernorm_after/ReduceMean_1', '/vit/layernorm/ReduceMean_1', '/vit/encoder/layer.4/layernorm_before/Div', '/vit/encoder/layer.10/output/Add', 'vit.encoder.layer.8.layernorm_after.weight', '/vit/encoder/layer.10/layernorm_before/Add', '/vit/encoder/layer.3/Add', '/vit/encoder/layer.8/layernorm_before/Pow', '/vit/encoder/layer.1/output/Add', '/vit/encoder/layer.6/layernorm_after/Add', '/vit/encoder/layer.0/intermediate/intermediate_act_fn/Erf', '/vit/encoder/layer.7/layernorm_after/Sqrt', '/vit/encoder/layer.3/layernorm_after/Add_1', '/vit/encoder/layer.6/intermediate/intermediate_act_fn/Mul', '/vit/encoder/layer.9/layernorm_before/Sqrt', '/vit/encoder/layer.8/layernorm_before/Sqrt', '/vit/encoder/layer.0/layernorm_before/Div', 'vit.encoder.layer.3.layernorm_before.bias', '/vit/encoder/layer.3/layernorm_after/Mul', '/vit/layernorm/Add', '/vit/encoder/layer.10/layernorm_after/Add', '/vit/encoder/layer.11/output/Add', '/vit/encoder/layer.8/layernorm_after/Sub', '/vit/encoder/layer.8/layernorm_before/Add_1', '/vit/encoder/layer.6/layernorm_before/Mul', '/vit/encoder/layer.11/layernorm_before/Sqrt', 'vit.encoder.layer.2.layernorm_after.bias', '/vit/encoder/layer.2/layernorm_after/Add_1', '/vit/encoder/layer.8/layernorm_before/ReduceMean_1', '/vit/encoder/layer.9/layernorm_after/Div', '/vit/encoder/layer.8/layernorm_after/Div', '/vit/encoder/layer.5/layernorm_after/Mul', '/vit/encoder/layer.11/layernorm_after/Pow', '/vit/encoder/layer.2/layernorm_before/Add_1', 'vit.encoder.layer.4.layernorm_before.weight', '/vit/encoder/layer.4/intermediate/intermediate_act_fn/Div', 'vit.encoder.layer.0.layernorm_before.bias', 'vit.encoder.layer.3.layernorm_before.weight', '/vit/encoder/layer.8/layernorm_before/Mul', '/vit/encoder/layer.7/layernorm_before/ReduceMean', '/vit/encoder/layer.4/layernorm_after/ReduceMean', '/vit/encoder/layer.0/attention/attention/Softmax', '/vit/encoder/layer.9/layernorm_after/Mul', '/vit/encoder/layer.10/layernorm_after/ReduceMean_1', '/vit/encoder/layer.4/intermediate/intermediate_act_fn/Add', '/vit/encoder/layer.3/intermediate/intermediate_act_fn/Mul_1', '/vit/encoder/layer.9/layernorm_before/ReduceMean_1']
2026-07-18 12:15 - INFO - sdk - quantize - Starting quantization...
WARNING:root:Please use QuantFormat.QDQ for activation type QInt8 and weight type QInt8. Or it will lead to bad performance on x64.
2026-07-18 12:29 - INFO - sdk - quantize - Quantization completed! Quantized model saved to /quadric/sdk-cli/examples/quantization/vit_optimized_OpSet16_optimized_sym_int8_q.onnx
2026-07-18 12:29 - INFO - sdk - quantize - ONNX full precision model size: 330.47MB
2026-07-18 12:29 - INFO - sdk - quantize - ONNX quantized model size: 83.04MB
2026-07-18 12:29 - INFO - sdk - quantize - ONNX model shapes inferred.
2026-07-18 12:29 - INFO - sdk - quantize - ONNX Model with well-defined shapes has been saved at `/quadric/sdk-cli/examples/quantization/vit_optimized_OpSet16_optimized_sym_int8_q_shaped.onnx`.
2026-07-18 12:29 - DEBUG - sdk - quantize - Checking for FLOAT/FLOAT16 types...
2026-07-18 12:29 - INFO - sdk - quantize - Checking for remaining FLOAT/FLOAT16 types.
2026-07-18 12:29 - INFO - sdk - quantize - Model still has FLOAT/FLOAT16 types after quantization. Creating ranges for floating point tensors using calibration data...
2026-07-18 12:49 - INFO - sdk - quantize - Saved computed tensor ranges to /quadric/sdk-cli/examples/quantization/vit_optimized_OpSet16_optimized_sym_int8_q_shaped.tranges.
2026-07-18 12:49 - INFO - sdk - quantize -
╒═══════════════════════════════════════════════════════════════════════════════════════════════╤══════════════════════════════════════════════════════════════════════════════════════════════════╕
│ Quantized ONNX Model │ Tensor Ranges File │
╞═══════════════════════════════════════════════════════════════════════════════════════════════╪══════════════════════════════════════════════════════════════════════════════════════════════════╡
│ /quadric/sdk-cli/examples/quantization/vit_optimized_OpSet16_optimized_sym_int8_q_shaped.onnx │ /quadric/sdk-cli/examples/quantization/vit_optimized_OpSet16_optimized_sym_int8_q_shaped.tranges │
╘═══════════════════════════════════════════════════════════════════════════════════════════════╧══════════════════════════════════════════════════════════════════════════════════════════════════╛
MAX_NUM_SAMPLES_FOR_ACCURACY_CALCULATION = 1
quantization_experiment = QuantizationExperiment(
floating_point_onnx_model_path=optimized_onnx_model_path,
quantized_onnx_model=quantized_onnx_model,
performance_tracker=ClassifierPerformanceTracker(),
)
## Set `export_path` if you'd like to save a copy of your experiment's results to disk
## E.g. `export_path=resnet50_quantization_experiment_report.txt`
run_quantization_experiment(
quantization_experiment,
calibration_dataloader,
export_path=None,
max_num_samples=MAX_NUM_SAMPLES_FOR_ACCURACY_CALCULATION,
)
1: FP32100.00% <> INT8100.00%: 100%|█████████████| 1/1 [00:00<00:00, 2.67it/s]
Used 1 image samples for model accuracy comparison.
Original FP32 model accuracy (Top-1): 100.00%
Quantized INT8 model accuracy (Top-1): 100.00%
Change in Top-1 model accuracy due to quantization: 0.00%
## NOTE: `ToTensor` is needed at a minimum to convert from `PIL.Image` to `torch.Tensor`
dataset_without_transforms = QuadricCalibration.Dataset(transform=Compose([ToTensor()]))
calibration_dataloader = CalibrationDataLoader(
DataLoader(dataset_without_transforms, batch_size=1, shuffle=True), ["pixel_values"]
)
quantization_experiment = QuantizationExperiment(
floating_point_onnx_model_path=optimized_onnx_model_path,
quantized_onnx_model=quantized_onnx_model,
performance_tracker=ClassifierPerformanceTracker(),
)
def recover_original_image_from_onnxruntime_format(
image_formatted_for_onnxruntime: Dict[str, np.ndarray]
) -> Image:
"""Recover the original image loaded from disk as a PIL.Image from the onnxruntime formatted numpy array."""
original_image_as_numpy = np.moveaxis(
np.uint8(image_formatted_for_onnxruntime["pixel_values"][0] * 255.0), 0, -1
)
return Image.fromarray(original_image_as_numpy)
## NOTE: Code below is a near identical copy to the source code of the `run_quantization` function
## Only differences are we are performing the transformations outside of the CalibrationDataloader so that we
## can visualize the original image
num_samples_to_display = 6
while len(quantization_experiment) < num_samples_to_display:
# Load and unpack next sample
next_sample = calibration_dataloader.get_next(return_targets=True)
image_formatted_for_onnxruntime: Dict[str, np.ndarray] = next_sample[0]
ground_truth_label = int(next_sample[1])
original_image = recover_original_image_from_onnxruntime_format(image_formatted_for_onnxruntime)
# Perform image transforms outside of the dataloader so that we may visualize the original image
transformed_image = np.expand_dims(transforms(original_image).numpy(), axis=0)
transformed_image_formatted_for_onnxruntime = {"pixel_values": transformed_image}
# Run inference
quantization_experiment.run(
([], transformed_image_formatted_for_onnxruntime),
ground_truth_label=ground_truth_label,
ground_truth_class_map=OPTIMIZED_IMAGENET_1K_LABELS.class_map,
)
quantization_experiment_report = quantization_experiment.report(
labels=list(OPTIMIZED_IMAGENET_1K_LABELS.class_map.keys()),
target_names=list(OPTIMIZED_IMAGENET_1K_LABELS.class_map.values()),
)
classifier_layouter = ClassifierLayouter(original_image, "", "extraction")
for order, infer_type in enumerate(["Original FP32", "Quantized INT8"]):
classifier_layouter.add_data(
quantization_experiment_report[order + 5][-1],
f"{infer_type} Model - onnxruntime top5 %",
)
classifier_layouter.display()





