Квантование — процесс преобразования весов и активаций модели из
формата с высокой точностью (например, float32) в более
компактные типы данных, такие как int8. Цель квантования —
снизить объем модели и ускорить вычисления без значительной потери
точности. В ONNX Runtime Web поддерживаются методы
статического и динамического
квантования, позволяющие оптимизировать работу модели на
клиентской стороне в браузере.
Перед квантованием необходимо:
Статическое квантование подразумевает вычисление статических
коэффициентов масштабирования (scale) и смещения (zero-point)
для весов и активаций до выполнения инференса. Эти коэффициенты
фиксируются в модели, что позволяет браузеру выполнять операции с
int8 без дополнительной арифметики преобразования на
лету.
Калибровка на примерах данных: Для каждого тензора активации вычисляются минимальные и максимальные значения, по которым строятся шкалы квантования.
Применение квантования к весам и активациям:
Используется формула: [ q = ()] где f — исходное значение
float32, q — значение после квантования в
int8.
Сохранение коэффициентов в модели ONNX: ONNX Runtime Web может использовать эти коэффициенты напрямую при выполнении инференса.
Пример применения статического квантования через Python (для подготовки модели к вебу):
from onnxruntime.quantization import quantize_static, CalibrationDataReader, QuantType
class DummyDataReader(CalibrationDataReader):
def __init__(self, data):
self.data = data
self.iterator = iter(data)
def get_next(self):
try:
return next(self.iterator)
except StopIteration:
return None
quantize_static(
model_input="model_float.onnx",
model_output="model_int8.onnx",
calibration_data_reader=DummyDataReader(calibration_data),
quant_format=QuantType.QOperator
)
Динамическое квантование выполняется на лету во время
инференса. Весовые коэффициенты квантуются заранее, а активации
преобразуются в int8 по мере прохождения через слои модели.
Это снижает необходимость предоставления больших наборов данных для
калибровки.
from onnxruntime.quantization import quantize_dynamic, QuantType
quantize_dynamic(
model_input="model_float.onnx",
model_output="model_dynamic_int8.onnx",
weight_type=QuantType.QInt8
)
ONNX Runtime Web предоставляет API для выполнения инференса квантованных моделей в браузере. Основные шаги:
import * as ort from 'onnxruntime-web';
const session = await ort.InferenceSession.create('model_int8.onnx');
const inputTensor = new ort.Tensor('float32', inputData, [batchSize, inputSize]);
const feeds = { input: inputTensor };
const results = await session.run(feeds);
console.log(results.output.data);
Conv,
MatMul, Gemm, Add,
Relu и др.float32 на int8 стоит
контролировать точность предсказаний и при
необходимости корректировать коэффициенты калибровки.Хорошая практика — профилировать производительность модели как до, так и после квантования, чтобы убедиться, что снижение точности находится в допустимых пределах, а ускорение инференса оправдано.