5.3.17MLOps & Deployment

Edge deployment and ONNX

2,230 words10 min readdifficulty · medium

WHY does edge deployment exist?

Break down the four forces (the 80/20 of why edge):

Force Cloud pain Edge win
Latency network RTT + queue local compute only
Privacy raw data leaves device data never leaves
Cost pay per inference call one-time device cost
Availability needs connectivity works offline

WHAT is ONNX?

Figure — Edge deployment and ONNX

HOW does the ONNX pipeline work?

Think of it as Train → Export → Optimize → Run.

  1. Train in PyTorch/TF/sklearn.
  2. Export to a .onnx graph (trace the ops).
  3. Optimize for the target: quantization, operator fusion, constant folding.
  4. Run with ONNX Runtime (ORT), which picks an Execution Provider (CPU, CUDA, TensorRT, CoreML, NNAPI...).

The 80/20 win: Quantization


Common mistakes (Steel-man + fix)


Active recall

Recall Feynman: explain to a 12-year-old

Imagine you drew a recipe (your model). Normally only your kitchen (framework) can cook it. ONNX is like translating the recipe into a language every kitchen understands — so a tiny food truck (your phone) can cook it too. And quantization is like rounding "2.37 grams of salt" to "2 grams": the dish tastes almost the same, but now you can carry way fewer measuring tools. Running it on the food truck instead of mailing ingredients to a giant restaurant across town = edge deployment: faster, private, works even with no phone signal.


Connections

What does ONNX stand for and what is it?
Open Neural Network Exchange — an open, framework-agnostic file format storing a model as a static computation graph (nodes, weights, typed IO).
Why does ONNX reduce integration complexity from O(N×M) to O(N+M)?
Hub-and-spoke: each framework needs one exporter TO ONNX (N) and each runtime one importer FROM ONNX (M), instead of custom glue for every pair.
What are the 4 forces favoring edge over cloud?
Lower latency, better privacy, lower per-inference cost, offline availability.
Derive the int8 scale S.
Assume affine r=S(q−Z); match endpoints: r_max−r_min = S(q_max−q_min) ⇒ S=(r_max−r_min)/(q_max−q_min).
What is the zero-point Z and why does it matter?
Z = q_min − r_min/S; it is the integer that real 0 maps to (set r=0 ⇒ q0=Z), critical for exact ReLU/padding.
Max error introduced by quantization rounding?
|r̂ − r| ≤ S/2, so smaller scale (tighter range) means less error.
Why does torch.onnx.export need a dummy input?
Export TRACES the executed ops; without a real-shaped input there is no execution to record into a graph.
What is an Execution Provider in ONNX Runtime?
The backend that actually computes the ops (CPU, CUDA, TensorRT, CoreML, NNAPI...); ORT dispatches graph nodes to it.
Why can't you assume bit-identical outputs across runtimes?
Different EPs use different kernels/fusion/FP ordering; results agree only within a tolerance, so validate with np.allclose.
What is opset_version and its failure mode?
The operator-set version the model requires; if the target runtime doesn't support it, loading fails. Use the lowest opset that covers your ops.
QAT vs post-training quantization — why prefer QAT?
QAT simulates rounding during training so weights adapt to quantization noise, preserving accuracy better than post-hoc PTQ.
What is dynamic_axes used for?
Declaring dimensions (e.g. batch) that can vary at runtime, avoiding shape-mismatch errors in production.

Concept Map

suffers

solves

wins when net cost exceeds compute penalty

enables

stores model as

reduces glue to

export step

produces

feeds

runs on

selects

Edge deployment

Cloud round-trip

ONNX format

Latency Privacy Cost Availability

Static compute graph

Hub-and-spoke O of N plus M

Train PyTorch TF sklearn

Export to .onnx

Optimize quantize fuse

ONNX Runtime

Execution Provider CPU CUDA TensorRT

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, edge deployment ka matlab hai model ko wahin chalana jahan data banta hai — phone, camera, ya sensor par — cloud ke door server par bhejne ke bajaye. Iska fayda? Cloud path me har prediction ke liye data upload karo, wait karo, phir answer download karo — yeh latency, bandwidth cost, aur privacy teeno kharab karta hai, aur agar network down ho toh sab thap. Edge par yeh transfer waale terms zero ho jaate hain, isliye chhota chip thoda slow hone ke bawajood overall fast aur reliable nikalta hai. Formal condition: edge tab jeetta hai jab chhote chip ka compute penalty (t_infer_edge − t_infer_cloud) network+queue cost (t_up + t_down + t_queue) se kam ho.

Ab ONNX ek "sabki samajh me aane waali file format" hai — model ko ek static computation graph (nodes = operators jaise Conv/MatMul, plus weights, plus typed inputs/outputs) ke roop me store karta hai. Isse framework (PyTorch) aur runtime (phone ka NNAPI) decouple ho jaate hain. Bina ONNX ke aapko har framework × runtime pair ke liye alag glue likhna padta (N×M kaam). ONNX hub-and-spoke bana deta hai: har framework ek exporter, har runtime ek importer — total N+M kaam. Pipeline yaad rakho: Train → Export → Optimize → Run.

Sabse bada 80/20 trick hai quantization: float32 weight 4 byte ka hota hai, use int8 (1 byte) me convert karo toh model 4x chhota aur memory-bandwidth bottleneck kam. Formula khud derive hota hai: maan lo affine map r=S(qZ)r = S(q-Z), endpoints match karke S=(rmaxrmin)/(qmaxqmin)S = (r_{max}-r_{min})/(q_{max}-q_{min}). Zero-point ZZ nikalne ke liye real 0 ko affine map me daalo (r=0 ⇒ q0=Z), yani ZZ hi wo integer hai jo real 0 ko represent karta hai — ReLU/padding ke liye zaroori. Rounding error zyada se zyada S/2S/2 hota hai.

Common galtiyan: (1) "export karo toh har jagah bilkul same output" — nahi, alag Execution Providers ke kernels alag hote hain, sirf tolerance ke andar match hota hai, np.allclose se check karo. (2) "quantization free accuracy" — nahi, calibration data ya QAT use karo. (3) "opset jitna naya utna accha" — nahi, runtime jo support kare wahi opset lo. Bas yeh samajh lo toh interview aur production dono clear.

Go deeper — visual, from zero

Test yourself — MLOps & Deployment

Connections