পাঠ ২০ · ৩৩-এর মধ্যে · মডিউল ৩
Home / AI Courses / MLOps / Model optimization

Model optimization — quantization

Optimization — quantization, pruning, distillation
৭ মিনিট পড়া উচ্চ · Advanced Python

এই পাঠে যা শিখবেন

  • Quantization — types, trade-offs, calibration
  • Pruning ও knowledge distillation
  • ONNX export + runtime optimization
  • LLM quantization (GPTQ, AWQ, GGUF) overview

১ · কেন optimize

Production deployment-এ:

  • Latency: 100ms model → 30ms quantized — UX win.
  • Cost: GPU memory smaller → fewer GPUs needed.
  • Edge: mobile-এ 50 MB max — quantization essential.
  • Energy: battery, server cooling.

২ · Quantization types

  • FP32 → FP16: half precision, ~2× speedup, virtually no accuracy loss. Default for modern GPUs.
  • FP32 → BF16: brain float, similar to FP16 but better range. A100/H100 native.
  • FP32 → INT8: 4× memory + speed; calibration needed; accuracy drop 0.1-2%.
  • FP32 → INT4: 8× memory; accuracy drop measurable; LLM-popular.

৩ · Quantization-aware training (QAT) vs Post-training (PTQ)

  • PTQ: trained model directly quantize. Calibration data দিয়ে scale/zero-point compute. Easy, but accuracy drop sometimes.
  • QAT: training-time fake quantization simulate. More work, better accuracy.

৪ · PyTorch dynamic quantization example

Python · PyTorch quantization
import torch
import torch.quantization

# Original FP32 model
model_fp32 = torch.load("model.pt").eval()

# 1. Dynamic quantization — easiest
# Quantize Linear/LSTM layers; activations dynamic
model_int8 = torch.quantization.quantize_dynamic(
    model_fp32,
    {torch.nn.Linear, torch.nn.LSTM},
    dtype=torch.qint8,
)

# Save smaller model
torch.save(model_int8.state_dict(), "model_int8.pt")

# Compare sizes
import os
fp32_size = os.path.getsize("model.pt") / 1024 / 1024
int8_size = os.path.getsize("model_int8.pt") / 1024 / 1024
print(f"FP32: {fp32_size:.1f} MB; INT8: {int8_size:.1f} MB ({fp32_size/int8_size:.1f}× smaller)")

# 2. Verify accuracy on validation set
import torch.utils.benchmark as benchmark
sample = torch.randn(1, 768)
t_fp32 = benchmark.Timer(stmt="m(x)", globals={"m": model_fp32, "x": sample}).timeit(100)
t_int8 = benchmark.Timer(stmt="m(x)", globals={"m": model_int8, "x": sample}).timeit(100)
print(f"FP32: {t_fp32.mean*1000:.2f}ms; INT8: {t_int8.mean*1000:.2f}ms")

    
Dynamic quantization easiest — no calibration data needed. CPU-এ ভাল ROI. GPU-এ TensorRT static quantization preferred.

৫ · Pruning

Many neural network weights ~zero — removing them no accuracy loss. Sparsity 70-90%-এ অনেক model-এ acceptable.

  • Magnitude pruning: smallest absolute value weights remove.
  • Structured pruning: entire neuron/channel remove — hardware-friendly.
  • Lottery ticket hypothesis: small sub-network exists at init that trains as well.

৬ · Knowledge distillation

Large "teacher" model trained. Small "student" trained to match teacher's output (soft labels). DistilBERT — BERT-এর 40% size, 60% faster, 97% accuracy retained.

৭ · ONNX runtime optimization

PyTorch/TF model → ONNX → ONNX Runtime. Cross-platform, optimized kernels, often 2-3× speedup.

Python · ONNX export
import torch
import onnxruntime as ort
import numpy as np

# Export PyTorch → ONNX
sample_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(
    model,
    sample_input,
    "model.onnx",
    input_names=["input"],
    output_names=["output"],
    dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}},
    opset_version=17,
)

# Inference with ONNX Runtime
session = ort.InferenceSession(
    "model.onnx",
    providers=["CUDAExecutionProvider", "CPUExecutionProvider"],
)
out = session.run(None, {"input": sample_input.numpy()})

# INT8 quantize ONNX model
from onnxruntime.quantization import quantize_dynamic, QuantType
quantize_dynamic(
    "model.onnx",
    "model_int8.onnx",
    weight_type=QuantType.QInt8,
)

    
ONNX = framework-agnostic format. ONNX Runtime mobile/edge-এও চলে। Quantization built-in tools.

৮ · LLM quantization

  • GPTQ: post-training INT4 — minimal accuracy loss, popular for LLaMA/Mistral.
  • AWQ: Activation-aware Weight Quantization — better than GPTQ usually.
  • GGUF (formerly GGML): CPU-optimized, llama.cpp ecosystem. 4-bit-এ phone-এ চলে।
  • BitsAndBytes: easy 8-bit/4-bit loading via Hugging Face Transformers.

LLaMA-7B FP16 = 14 GB; INT4 GPTQ = 4 GB. Single GPU fit possible.

Quantization — accuracy vs size/speed trade-off FP32 100% accuracy 100 MB 100ms latency Default no optimization FP16/BF16 ~99.9% accuracy 50 MB (2× smaller) ~50ms (2× faster) Easy win no calibration INT8 ~99% accuracy 25 MB (4× smaller) ~30ms (3× faster) Calibration needed Production sweet spot INT4 ~95-98% accuracy 12 MB (8× smaller) ~20ms LLM popular GPTQ, AWQ Lower precision = more compression + speed; accuracy slowly degrades. Validation always required after quantization.
Quantization spectrum — FP32 baseline; FP16 free win; INT8 production sweet spot; INT4 for LLM with calibration.
Bangladesh GPU-cost-conscious — quantization adoption growing. Bangla LLM serving INT4 typical. Mobile app on-device — INT8 essential.

ভাবনার প্রশ্ন

প্র ০১"INT8 calibration data কী, কতটুকু লাগে?"

INT8 quantization-এ activation distribution-এর scale/zero-point compute করতে representative data দরকার।

Calibration purpose:

  • Float-এর range [min, max] discover.
  • INT8 [-128, 127] map করার scale calculate.
  • Per-layer or per-channel.

How much data:

  • Typical: ১০০-১০০০ samples enough.
  • More — diminishing returns.
  • Quality matter more than quantity — distribution-representative.

Strategies:

  • MinMax: simplest — observed min/max use.
  • Entropy/KL: minimize information loss; better accuracy.
  • Percentile: ignore outliers (e.g., 99.99 percentile).

BD context — Bangla NLP:

  • Bangla text variation high; cover formal + informal + dialect.
  • Calibration set 500 sample diverse texts.

Pitfall:

  • Calibration on training data — production drift mismatch.
  • Better: real production sample (recent week).

মূল উপলব্ধি: Calibration accuracy-quantized model-এর key. Production-representative data; few hundred sample enough; quality matter most.

প্র ০২"Mobile (Bangla keyboard) — কোন quantization?"

On-device deployment unique constraints.

Constraints:

  • App size — Bangla keyboard 30 MB target.
  • RAM — budget Android 2-4 GB; model 50 MB max.
  • Inference speed — type during keystroke, < 50ms required.
  • Battery — heavy compute drains.

Approach:

  • Distill large LM → small student.
  • INT8 quantize via TF Lite.
  • Model size 5-15 MB target.
  • Latency 10-30ms typical.

Tools:

  • TF Lite — Android first-class.
  • TF Lite GPU delegate — newer phones GPU/NPU acceleration.
  • ONNX Runtime mobile — alternative.
  • MediaPipe — Google's prebuilt blocks.

Bangla-specific:

  • Tokenization — Bangla ZWJ/ZWNJ tricky on small models.
  • Character-level often better than subword for low-resource.
  • Embedding sharing — input/output tied.

Update strategy:

  • App store update slow; over-the-air model update via API.
  • Fallback to bundled if download fails.

মূল উপলব্ধি: Mobile = aggressive optimization mandatory. Distill + INT8 + TF Lite. Bangla-specific tokenization care.

প্র ০৩"Pruning vs distillation — কোনটা কখন?"

দু'টি orthogonal techniques, complementary.

Pruning:

  • Existing model weights remove.
  • No retraining needed (sometimes fine-tune).
  • Architecture intact, sparsity introduced.
  • Hardware support varies (NVIDIA Ampere structured sparsity hardware-accelerated).

Distillation:

  • New smaller architecture from scratch trained mimic teacher.
  • Architecture-level optimization.
  • Significant training cost.
  • Better accuracy retention generally.

Combine:

  • Distill first (architecture compression).
  • Then quantize student (precision compression).
  • Then prune within layers (sparsity compression).
  • Compounded gains.

BD context:

  • Distillation training-cost-heavy — only invest if model used long-term.
  • Pruning quick win for existing models.
  • Quantization easiest first try.

মূল উপলব্ধি: Order: quantize → prune → distill (cost ascending). Stop at sufficient gain.

প্র ০৪"LLM 4-bit quantization production-safe?"

LLM 4-bit (GPTQ/AWQ) — surprising effective, but caveats.

Accuracy retention:

  • LLaMA-2 7B FP16 vs 4-bit GPTQ — perplexity ~1% increase.
  • Most benchmarks (MMLU, HellaSwag) — within 1-2%.
  • "User won't notice" generally.

Failure modes:

  • Long-tail rare token — worse accuracy.
  • Code generation — sometimes degraded.
  • Multi-language — high-resource OK, low-resource (Bangla) more drop.

Production validation:

  • Domain-specific eval set.
  • Compare FP16 vs 4-bit side-by-side.
  • If user-facing — A/B test.

Methods:

  • GPTQ — original; calibration data needed.
  • AWQ — newer, better; activation-aware.
  • GGUF (llama.cpp) — CPU-optimized; phone-deployable.
  • BitsAndBytes 4-bit — easy HF integration.

Hardware support:

  • 4-bit native: H100, latest GPU.
  • Older GPU: 4-bit-from-INT8 emulation; less benefit.

BD context — Bangla LLM:

  • Self-hosted Bangla LLM — 4-bit GPU memory enable.
  • Validation Bangla benchmark (LLM evaluation Lesson 30) essential.
  • Quality drop tolerable for cost saving usually.

মূল উপলব্ধি: LLM 4-bit — generally production-safe with validation. Bangla underspecified low-resource — extra care. Not blanket apply; verify.

অনুশীলন

  1. Quantize: একটি sample sklearn/PyTorch model FP16/INT8-এ convert. Latency + accuracy compare.

    উপরের code use. FP32 vs FP16 vs INT8 — table form.

  2. ONNX: Same model ONNX export + ONNX Runtime দিয়ে inference. Speedup measure.

    torch.onnx.export; onnxruntime.InferenceSession. Generally 1.5-3× faster.

  3. চিন্তা: bKash low-end phone fraud check — optimization stack design করুন।
    • Distill heavy server model → small mobile model.
    • INT8 quantize via TF Lite.
    • Phone GPU delegate enable.
    • Server fallback for low-confidence cases.

আরও পড়ুন

পূর্ববর্তী পাঠ
পাঠ ১৯ · Batch vs online