Gerçek Zaman Görüşü Kısıtlama
Type: Learn + Build
Languages: Python
Prerequisites: Phase 4 Lesson 04 (Image Classification), Phase 10 Lesson 11 (Quantization)
Time: ~75 minutes
Öğrenme Hedefleri
- Herhangi bir PyTorch modeli için sonuç geçiciliği, en yüksek hafıza ve geçiş ölçümleri ve FLOPs / params / latency trade-off'u okuyun
- PyTorch'ın eğitim sonrası kuantitasyonunu kullanarak bir görme modelini INT8'e kadar kuantite edin ve doğruluk kaybını < 1%'e doğru tutun
- ONNX'e ihraç ve ONNX Runtime veya TensorRT ile oluşturmak; en yaygın üç ihraç hata ve onların düzeltmeleri
- Kenar kısıtlama için MobileNetV3, EfficientNet-Lite, ConvNeXt-Tiny veya MobileViT'yi ne zaman seçmeyi açıklayın
Sorun
Eğitim zamanında görme modeli yüzen nokta canavarıdır. 100M parametreleri, ileri geçiş başına 10 GFLOP, 2 GB VRAM. Bunların hiçbiri bir telefona, bir aracın infotainment birimine, endüstriyel bir kameraya veya bir drone'a uymamaktadır. Görme sistemini göndermek aynı tahminleri 100 kat daha küçük bir bütçeye uymak anlamına gelir.
İşin büyük kısmını üç düğme yapar: model seçimi (aynı tarifle daha küçük bir mimarlık), kuantitasyon (FP32 yerine INT8) ve sonuç çalıştırma süresi (ONNX Runtime, TensorRT, Core ML, TFLite).
Bu ders önce ölçüm disiplini ayarlar ( ölçemediğiniz şeyi optimize edemezsiniz), sonra üç düğmeyi yürütür. Amaç her kenar çalıştırma zamanını öğrenmek değil, hangi kaldıraçların olduğunu bilmek ve her birinin düşündüğünüz şeyi nasıl yaptığını nasıl doğrulayacağınızı bilmek.
Anlaşım
Üç bütçe
flowchart LR
M["Model"] --> LAT["Latency<br/>ms per image"]
M --> MEM["Memory<br/>peak MB"]
M --> PWR["Power<br/>mJ per inference"]
LAT --> SHIP["Ship / no-ship<br/>decision"]
MEM --> SHIP
PWR --> SHIP
style LAT fill:#fecaca,stroke:#dc2626
style MEM fill:#fef3c7,stroke:#d97706
style PWR fill:#dbeafe,stroke:#2563eb- LatencyOrtalama sadece p50'de gerçek zamanlı sistemler için önemli olan kuyruğu davranışları gizlenir.
- Peak memoryBu, cihazın gördüğü maksimum, sabit durum ortalaması değil.
- Power / energyBatarya ile çalışan bir cihazda: her sonuca göre millijoules.
Bir kenar kararının alınması için bir tablo (model, gecikme, bellek, doğruluk) kullanılır. Her hücre hedef cihazda ölçülür, iş istasyonunda değil.
Ölçüm disiplinleri
Her kenar profili takip etmesi gereken üç kural:
- Warm upBu nedenle, bu testlerin en önemli sonuçları, ölçümden önce 5-10 numara ileriye geçiş yaparak elde edilebilir.
- SynchroniseGPU iş yükleri
torch.cuda.synchronize()Bu olmadan çekirdek gönderisini ölçersiniz, çekirdek yürütmesini değil. - Fix input sizes224x224'de gecikme 512x512'de gecikme değil.
FLOPs bir vekil olarak
FLOPs (doğru sonuçlar için kayarak nokta işlemleri) gecikme için ucuz, cihaz bağımsız bir vekildir. Mimarlık karşılaştırması için yararlı, mutlak duvar saati gibi yanıltıcıdır. %10 daha fazla FLOP'li bir model, donanım dostu ops kullanıldığı için pratikte 2 kat daha hızlı olabilir ( derinlik konvoyları iyi bir şekilde oluşturur, büyük 7x7 konvoyları değil).
Kural: mimarlık aramaları için FLOP'ler kullanın, yerleştirme kararları için cihazda gecikme kullanın.
Bir paragrafdaki miktar
Model boyutu 4x düşer, bellek bant genişliği 4x düşer, hesaplama INT8 çekirdekleri olan donanımlarda 2-4x düşer (her modern mobil SoC, Tensor Cores ile her NVIDIA GPU). Görme görevlerinde doğruluk kaybı tipik olarak eğitim sonrası statik kvantizasyonla 0.1-1 yüzde puan.
Tipler:
- Dynamic INT8'e kadar kuantit ağırlıkları, FP'de hesaplanan aktivasyonlar.
- Static (post-training) kuantit ağırlıkları + kalibrasyon aktivasyonu aralıkları küçük bir kalibrasyon seti üzerinde.
- Quantisation-aware training (QAT) eğitim sırasında kuantitasyonu simüle etmek, böylece model etrafında öğrenir.
Görme için, eğitim sonrası statik kvantizasyon, çabaların %5'inde %95'iyle fayda sağlar.
Kesim ve destilasyon
- Pruning önemli olmayan ağırlıkları (büyüklük tabanlı) veya kanalları (strüküratürlü) kaldırmak.
- Distillation küçük bir öğrenciyi büyük bir öğretmenin logitlerini taklit etmek için eğitmek. Genellikle modelin küçültülmesiyle kaybedilen doğrulukun çoğunu geri kazanır.
Sonuçlama çalışma zamanları
- PyTorch eager yavaş, kullanımı için değil.
- TorchScript mirası.
torch.compileve ONNX ihracatı. - ONNX RuntimeCPU, CUDA, CoreML, TensorRT, OpenVINO hepsi ONNX sağlayıcıları var.
- TensorRTNVIDIA'nın en iyi gecikme süresi (workstation ve Jetson). ONNX Runtime veya standalone ile entegre.
- Core ML Apple'ın iOS/macOS için çalıştırma zamanı.
.mlmodelveya.mlpackage- Evet . - TFLite Google'ın Android/ARM için çalıştırma zamanı. Gereksinimler
.tflite- Evet . - OpenVINO Intel'in CPU/VPU çalıştırma süresi.
.xml+.bin- Evet .
Uygulama: PyTorch -> ONNX -> export. ONNX, hedef için çalıştırma zamanı seçin.
Kenar mimarlık seçicisi
| Budget | Model | Why |
|---|---|---|
| < 3M params | MobileNetV3-Small | Compiles everywhere, good baseline |
| 3-10M | EfficientNet-Lite-B0 | Best accuracy per param on TFLite |
| 10-20M | ConvNeXt-Tiny | Best accuracy-per-param, CPU-friendly |
| 20-30M | MobileViT-S or EfficientViT | Transformer with ImageNet accuracy |
| 30-80M | Swin-V2-Tiny | If stack supports window attention |
Tüm bunları INT8'e kadar miktarlandırın, eğer yapmamaya kesin bir nedeniniz yoksa.
Yapın
Adım 1: Gecikme sürelerini doğru bir şekilde ölçün
pythonimport time
import torch
def measure_latency(model, input_shape, device="cpu", warmup=10, iters=50):
model = model.to(device).eval()
x = torch.randn(input_shape, device=device)
with torch.no_grad():
for _ in range(warmup):
model(x)
if device == "cuda":
torch.cuda.synchronize()
times = []
for _ in range(iters):
if device == "cuda":
torch.cuda.synchronize()
t0 = time.perf_counter()
model(x)
if device == "cuda":
torch.cuda.synchronize()
times.append((time.perf_counter() - t0) * 1000)
times.sort()
return {
"p50_ms": times[len(times) // 2],
"p95_ms": times[int(len(times) * 0.95)],
"p99_ms": times[int(len(times) * 0.99)],
"mean_ms": sum(times) / len(times),
} time.perf_counter()- Rapor yüzdeleri, sadece kötü değil.
Adım 2: Parametr ve FLOP sayıları
pythondef parameter_count(model):
return sum(p.numel() for p in model.parameters())
def flops_estimate(model, input_shape):
"""
Rough FLOP count for a conv/linear-only model. For production use `fvcore` or `ptflops`.
"""
total = 0
def conv_hook(m, inp, out):
nonlocal total
c_out, c_in, kh, kw = m.weight.shape
h, w = out.shape[-2:]
total += 2 * c_in * c_out * kh * kw * h * w
def linear_hook(m, inp, out):
nonlocal total
total += 2 * m.in_features * m.out_features
hooks = []
for m in model.modules():
if isinstance(m, torch.nn.Conv2d):
hooks.append(m.register_forward_hook(conv_hook))
elif isinstance(m, torch.nn.Linear):
hooks.append(m.register_forward_hook(linear_hook))
model.eval()
with torch.no_grad():
model(torch.randn(input_shape))
for h in hooks:
h.remove()
return totalGerçek projeler için kullanmak fvcore.nn.FlopCountAnalysisveya ptflops; her modül türünü doğru şekilde ele alırlar.
Adım 3: Eğitim sonrası statik miktarlandırma
pythondef quantise_ptq(model, calibration_loader, backend="x86"):
import torch.ao.quantization as tq
model = model.eval().cpu()
model.qconfig = tq.get_default_qconfig(backend)
tq.prepare(model, inplace=True)
with torch.no_grad():
for x, _ in calibration_loader:
model(x)
tq.convert(model, inplace=True)
return modelÜç adım: yapılandırma, hazırlama (güzülmüş gözlemciler ekle), gerçek verilerle kalibrasyon, dönüştürme (füz + kuantit).Conv -> BN -> ReLU-> ConvBnReLU), ki torch.ao.quantization.fuse_modulesElleri.
4. Adım: ONNX'e ihracat
pythondef export_onnx(model, sample_input, path="model.onnx"):
model = model.eval()
torch.onnx.export(
model,
sample_input,
path,
input_names=["input"],
output_names=["output"],
dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}},
opset_version=17,
)
return pathopset_version=172026'da güvenli bir default.dynamic_axesONNX modelini kendiliğinden seri boyutları ile çalıştırmak için.
Adım 5: Sistemi değerlendir ve karşılaştır
pythonimport torch.nn as nn
from torchvision.models import mobilenet_v3_small
def compare_regimes():
model = mobilenet_v3_small(weights=None, num_classes=10)
params = parameter_count(model)
flops = flops_estimate(model, (1, 3, 224, 224))
lat_fp32 = measure_latency(model, (1, 3, 224, 224), device="cpu")
print(f"FP32 MobileNetV3-Small: {params:,} params {flops/1e9:.2f} GFLOPs "
f"p50={lat_fp32['p50_ms']:.2f}ms p95={lat_fp32['p95_ms']:.2f}ms")Aynı işlevi için çalıştırresnet50- Evet .efficientnet_v2_sveconvnext_tinyve yerleşim kararı için ihtiyacınız olan karşılaştırma tablosu var.
Kullan
Üretim yığınları üç yoldan birinde birleşti:
- Web / serverlessPyTorch -> ONNX -> ONNX Runtime (CPU veya CUDA sağlayıcısı).
- NVIDIA edge (Jetson, GPU server)En iyi gecikme, en büyük mühendislik çabaları.
- MobilePyTorch -> ONNX -> Core ML (iOS) veya TFLite (Android).
Ölçüm için, torch-tb-profiler- Evet .nvprof- Ne ?nsys, ve macOS'taki araçlar katman-katman ayrıntıları verir. benchmark_app(OpenVINO) ve trtexec(TensorRT) bağımsız CLI numaraları verin.
Gönder
Bu ders şunları ortaya çıkarır:
outputs/prompt-edge-deployment-planner.mdomurganı, kuantitasyon stratejisini ve hedef cihaz ve gecikme SLA'yı verilen çalıştırma zamanını seçen bir istek.outputs/skill-latency-profiler.md
Egzersizler
- (Easy) için p50 gecikme ölçüm
resnet18- Evet .mobilenet_v3_small- Evet .efficientnet_v2_sveconvnext_tinyCPU'da 224x224'e göre. Tabloyu rapor edin ve hangi mimarinin en iyi doğruluğu olduğunu belirleyin. - (Medium)
mobilenet_v3_small. CIFAR-10 veya benzeri bir alt kümede FP32 vs INT8 gecikme ve doğruluk kaybını bildirin. - (Hard)Dışarıya Çekilme
convnext_tinyONNX'e, geçin.onnxruntime- ... ...CPUExecutionProvider, ve gecikmeyi PyTorch'ın istekli tabanına karşılaştırın. ONNX çalıştırma süresi daha hızlı olan ilk katmanı belirleyin ve nedenini açıklayın.
Anahtar Terimler
| Term | What people say | What it actually means |
|---|---|---|
| Latency | "How fast" | Time from input to output; p50/p95/p99 percentiles, not mean |
| FLOPs | "Model size" | Floating-point ops per forward pass; rough proxy for compute cost |
| INT8 quantisation | "8-bit" | Replace FP32 weights/activations with 8-bit integers; ~4x smaller, 2-4x faster |
| PTQ | "Post-training quantisation" | Quantise a trained model without retraining; easy, usually enough |
| QAT | "Quantisation-aware training" | Simulate quantisation during training; best accuracy, requires labelled data |
| ONNX | "The neutral format" | Model exchange format supported by every mainstream inference runtime |
| TensorRT | "NVIDIA compiler" | Compiles ONNX into an optimised engine for NVIDIA GPUs |
| Distillation | "Teacher -> student" | Train a small model to mimic a big model's logits; recovers most lost accuracy |
Daha Fazla Okumak
- EfficientNet (Tan & Le, 2019) verimli mimariler için bileşik ölçeklendirme
- MobileNetV3 (Howard et al., 2019) H-swish ve squeeze-excite ile mobil ilk mimarisi
- Accelerating Inference Up to 6x Faster in PyTorch with Torch-TensorRT (NVIDIA) Kağıtdaki geçiş sayısını nasıl elde edebilirsiniz
- ONNX Runtime docs Kvantisaj, grafik optimizasyonu, tedarikçi seçimi
This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.
Browse the complete course catalog or open this lesson on GitHub.