Skip to content
ENTERPRISE Enterprise technology · Engineered for your business Enterprise Software · Managed Servers · Business E-mail · LiteSpeed + CloudLinux · Imunify360 Security · cPanel Control · Network profile up to 3 Gbps on eligible plans
AIOR

ONNX, INT8, QAT: what actually breaks when you quantize a model

Aior

Administrator

Staff member
Joined
Apr 2, 2023
Messages
929
Reaction score
2
Points
18
Age
41
Location
Turkey
Website
aior.com
Thread owner

500


Hep yanlış giden üç adımda dönüşüm pipeline'ı​

Araştırmada eğitilmiş PyTorch modelinden edge donanımda çalışan INT8 binary'ye gitmek dokümanlarda basit görünür. Pratikte her adımın kendi başarısızlık modu var.

Adım 1 — PyTorch → ONNX​

ONNX export vanilla CNN'ler için çoğunlukla çözülmüş bir problem. Yanlış gittiği yer:
  • Dinamik şekiller. Modeliniz dinamik giriş boyutları kullanıyorsa, açık dynamic_axes ile export etmelisiniz.
  • Özel op'lar. Upstream'lenmemiş torchvision'dan herhangi bir şey (DeformableConv, belirli NMS varyantları) özel sembolik fonksiyon gerektirir.
  • Control flow. Tensor değerlerine bağlı if ifadeleri Loop / If node'larına dönüşür; tüm backend'ler desteklemez.
  • Opset sürümü. Birçok hedef runtime en son opset'ten 1-2 sürüm geride. Runtime'ınızın desteklediği en düşük opset'e export edin.

ONNX export'unu hareket etmeden önce 10-100 görüntüde PyTorch modeline karşı her zaman doğrularız. Çıktılar 1e-5 içinde eşleşmeli.

Adım 2 — ONNX → optimize edilmiş graph​

ONNX Runtime, TensorRT, OpenVINO, Hailo DFC hepsi graph düzeyi optimizasyon yapar. Çoğunlukla şeffaf. Isırdığı yer:
  • Operatör destek boşlukları. TensorRT kapsamı mükemmel; Hailo daha seçici.
  • Layout transform'ları. NCHW vs NHWC önemli. Bazı runtime'lar yanlış varsayılan seçer ve %30 perf cezası yersiniz.
  • Dinamik batch boyutları. Çoğu üretim deploy batch=1; engine'i batch=1 için spesifik inşa edin.

Adım 3 — INT8'e quantization​

Doğruluk regresyonunun yaşadığı yer burası. İki tat:

Post-training quantization (PTQ). Temsili veri setinde aktivasyon dağılımlarını kalibre et, tensor başına scale/zero-point seç, tamamlandı. Hızlı (dakika). Yaygın mimarilerde sıkça %0.5-2 doğruluk kaybeder.

Quantization-aware training (QAT). Eğitim graph'ına fake-quantization op'ları enjekte et, birkaç epoch fine-tune et. Yavaş (saat, bazen gün). PTQ doğruluk regresyonunun çoğunu kurtarır.

PTQ ne zaman yeterli vs QAT ne zaman gerekli:
  • ResNet tarzı backbone'lar, büyük modeller, iyi dağıtılmış aktivasyonlar → PTQ iyi.
  • Mobil tarzı mimariler (MobileNet, EfficientNet), zaten sıkıştırılmış modeller → QAT sıkça gerekli.
  • Attention'lı, özel normalizasyonlu veya cosine-similarity skorlamalı her şey → neredeyse her zaman QAT.
  • Sabit doğruluk SLA'lı üretim hedefi → her halükarda QAT çalıştır.

Kalibrasyon veri seti seçimi — yetersiz değer verilen adım​

Kalibrasyon seti quantizer'ın gördüğü aktivasyon aralıklarını belirler. Kullanın:
  • En az 256 görüntü, ideal 1024.
  • Üretimden yakalanmış, orijinal eğitim setinden değil.
  • Gerçekten beklediğiniz aydınlatma, ürünler ve günün saati varyasyonunu kapsayan.
  • Augmentation yok. Modelin eğitildiği için değil, göreceği için quantize edin.

Kötü bir kalibrasyon seti FP32'nin %1'i içinde INT8 ile %5 regresyonlu INT8 arasındaki farktır. Bunu yeterince yanlış yöne gittiğini gördük, artık kalibrasyon seti inşasını kendi incelemesiyle ayrı bir mühendislik görevi olarak ele alıyoruz.

Doğrulama, uçtan uca​

Final binary kalibrasyon setinde değil, ayrılmış bir test setinde doğrulanmalı. Karşılaştırın:
  • FP32 PyTorch doğruluğu (baseline).
  • ONNX FP32 doğruluğu (PyTorch ile eşleşmeli).
  • ONNX INT8 doğruluğu (hedef: FP32'nin %1'i içinde).
  • Cihazdaki INT8 doğruluğu (ONNX INT8 ile eşleşmeli).

Herhangi bir adım gürültü zemininden fazla ayrışırsa bug var. Göndermeyin.

Dönüşüm yığınınız nedir? ONNX-Runtime + DirectML kullanan veya vendor toolchain'lerine sıkı sıkıya bağlı kalan var mı?


500


The conversion pipeline, in three steps that always go wrong​

Going from a research-trained PyTorch model to an INT8 binary running on edge hardware looks simple in the docs. In practice, every step has its own failure modes.

Step 1 — PyTorch → ONNX​

ONNX export is mostly a solved problem for vanilla CNNs. Where it goes wrong:
  • Dynamic shapes. If your model uses dynamic input dimensions, you have to export with explicit dynamic_axes.
  • Custom ops. Anything from torchvision that hasn't been upstreamed (DeformableConv, certain NMS variants) needs a custom symbolic function.
  • Control flow. If-statements that depend on tensor values become Loop / If nodes that not all backends support.
  • Opset version. Many target runtimes lag the latest opset by 1-2 versions. Export targeting the lowest opset your runtime supports.

We always validate the ONNX export against the PyTorch model on 10-100 images before moving on. Outputs should match to within 1e-5.

Step 2 — ONNX → optimized graph​

ONNX Runtime, TensorRT, OpenVINO, Hailo DFC all do graph-level optimization. Mostly transparent. Where it bites:
  • Operator support gaps. TensorRT's coverage is excellent; Hailo's is more selective.
  • Layout transforms. NCHW vs NHWC matters. Some runtimes pick the wrong default and you eat a 30 % perf penalty.
  • Dynamic batch sizes. Most production deployments are batch=1; build the engine for batch=1 specifically.

Step 3 — quantization to INT8​

This is where the accuracy regression lives. Two flavors:

Post-training quantization (PTQ). Calibrate the activation distributions on a representative dataset, choose scale/zero-point per tensor, done. Fast (minutes). Often loses 0.5-2 % accuracy on common architectures.

Quantization-aware training (QAT). Inject fake-quantization ops into the training graph, fine-tune for a few epochs. Slow (hours, sometimes days). Recovers most of the PTQ accuracy regression.

When PTQ is enough vs when QAT is needed:
  • ResNet-style backbones, large models, well-distributed activations → PTQ is fine.
  • Mobile-style architectures (MobileNet, EfficientNet), already-compressed models → QAT often needed.
  • Anything with attention, custom normalization, or cosine-similarity scoring → QAT, almost always.
  • Production target with fixed accuracy SLA → run QAT regardless.

Calibration dataset selection​

The calibration set determines the activation ranges the quantizer sees. Use:
  • At least 256 images, ideally 1024.
  • Captured from production, not from the original training set.
  • Covering the variation in lighting, products, and time-of-day you actually expect.
  • No augmentation. Quantize for what the model will see, not what it was trained on.

A bad calibration set is the difference between INT8 within 1 % of FP32 and INT8 with 5 % regression.

Validation, end-to-end​

The final binary should be validated on a held-out test set, not on the calibration set. Compare:
  • FP32 PyTorch accuracy (baseline).
  • ONNX FP32 accuracy (should match PyTorch).
  • ONNX INT8 accuracy (target: within 1 % of FP32).
  • On-device INT8 accuracy (should match ONNX INT8).

If any step diverges by more than the noise floor, you have a bug. Don't ship.

What's your conversion stack?
 

Forum statistics

Threads
925
Messages
932
Members
26
Latest member
Jessicawatson

Members online

No members online now.

Featured content

AIOR
AIOR TECHNOLOGY

Get a quote for all your needs

Hosting · Domain · Servers · Design · Software · Engineering · Industry Solutions

Get a quote

24/7 Support · Quick response

Back
Top