Initial addition of ms-ai-architect plugin to the open-source marketplace. Private content excluded: orchestrator/ (Linear tooling), docs/utredning/ (client investigation), generated test reports and PDF export script. skill-gen tooling moved from orchestrator/ to scripts/skill-gen/. Security scan: WARNING (risk 20/100) — no secrets, no injection found. False positive fixed: added gitleaks:allow to Python variable reference in output-validation-grounding-verification.md line 109. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
16 KiB
Edge AI Inferencing Patterns
Last updated: 2026-02 Status: GA Category: Hybrid Cloud & Edge AI
Introduksjon
Edge AI-inferens handler om a kjore maskinlaeringsmodeller naermest mulig der data oppstar — pa enheter, gateways, lokale servere eller Azure Local-klynger. For norsk offentlig sektor er dette relevant i scenarioer som sanntids videoanalyse, dokumentbehandling i felt, naturspraakbehandling offline, og autonome systemer i omrader med begrenset nettverkstilkobling.
Microsoft tilbyr et bredt spekter av verktoy for edge-inferens: ONNX Runtime som universell inferensmotor, Azure IoT Edge for container-baserte modeller, Azure Stack Edge for hardware-akselerert inferens, og KAITO for LLM-deployment pa Kubernetes. Valget av moenster avhenger av modellstorrelse, latenskrav, tilgjengelig hardware og tilkoblingsstatus.
Denne referansen dekker de viktigste moensterne for modelloptimalisering, akselerasjon, caching og batching/streaming — alle med fokus pa Microsoft Azure-okosystemet og relevans for offentlig sektor.
Model Quantization og Compression
Hva er kvantisering?
Kvantisering reduserer presisjonen til modellvekter fra hoyere til lavere bit-representasjoner, noe som reduserer modellstorrelse og oker inferenshastighet med minimalt noyaktighetstap.
| Presisjon | Bits | Storrelse (7B modell) | Hastighet | Noyaktighet |
|---|---|---|---|---|
| FP32 | 32 | ~28 GB | Baseline | 100% |
| FP16 | 16 | ~14 GB | 2x | ~99.9% |
| BF16 | 16 | ~14 GB | 2x | ~99.9% |
| INT8 | 8 | ~7 GB | 3-4x | ~99% |
| INT4 | 4 | ~3.5 GB | 5-8x | ~97% |
Kvantiseringsmetoder i Azure-okosystemet
| Metode | Verktoy | Best for | Presisjon |
|---|---|---|---|
| Post-Training Quantization (PTQ) | ONNX Runtime, Olive | Rask konvertering | INT8/INT4 |
| Quantization-Aware Training (QAT) | PyTorch + Azure ML | Hoyest noyaktighet | INT8 |
| GPTQ | HuggingFace + KAITO | LLM-kvantisering | INT4 |
| AWQ | HuggingFace + KAITO | LLM-kvantisering | INT4 |
| Dynamic Quantization | ONNX Runtime | CPU-inferens | INT8 |
ONNX Runtime-kvantisering
# Kvantiser ONNX-modell til INT8
from onnxruntime.quantization import quantize_dynamic, QuantType
quantize_dynamic(
model_input="model_fp32.onnx",
model_output="model_int8.onnx",
weight_type=QuantType.QInt8,
optimize_model=True
)
Olive — Microsofts modelloptimalisering
Olive er Microsofts verktoy for helhetlig modelloptimalisering:
# olive_config.json
{
"input_model": {
"type": "OnnxModel",
"model_path": "model.onnx"
},
"systems": {
"local_system": {
"type": "LocalSystem",
"accelerators": [{"device": "npu"}]
}
},
"passes": {
"quantization": {
"type": "OnnxQuantization",
"config": {
"quant_mode": "static",
"quant_format": "QDQ",
"calibration_data_reader": "CalibrationDataReader"
}
},
"perf_tuning": {
"type": "OrtPerfTuning",
"config": {
"data_dir": "./calibration_data"
}
}
},
"engine": {
"search_strategy": {
"execution_order": "joint",
"search_algorithm": "exhaustive"
},
"output_dir": "./optimized"
}
}
Modellkomprimering
| Teknikk | Beskrivelse | Storrelsereduksjon | Noyaktighetstap |
|---|---|---|---|
| Pruning | Fjerner uvesentlige vekter | 30-70% | 1-3% |
| Knowledge Distillation | Laerer liten modell fra stor | 50-90% | 2-5% |
| Weight Sharing | Deler vekter mellom lag | 20-40% | <1% |
| Low-Rank Factorization | Dekomponerer vektmatriser | 30-50% | 1-2% |
Real-time Inference Acceleration
ONNX Runtime Execution Providers
ONNX Runtime stotter flere hardware-akseleratorer gjennom Execution Providers (EP):
| Execution Provider | Hardware | Best for | Latens |
|---|---|---|---|
| CPU EP | x86/ARM CPU | Universell | Basis |
| CUDA EP | NVIDIA GPU | GPU-inferens | 5-50x raskere |
| TensorRT EP | NVIDIA GPU | Optimalisert GPU | 10-100x raskere |
| OpenVINO EP | Intel CPU/GPU/VPU | Intel-optimalisert | 3-20x raskere |
| DirectML EP | Windows GPU/NPU | Windows-enheter | 5-30x raskere |
| QNN EP | Qualcomm NPU | Snapdragon-enheter | 10-50x raskere |
GPU-akselerert inferens med ONNX Runtime
import onnxruntime as ort
# Konfigurasjon for NVIDIA GPU (TensorRT)
session_options = ort.SessionOptions()
session_options.graph_optimization_level = \
ort.GraphOptimizationLevel.ORT_ENABLE_ALL
providers = [
('TensorrtExecutionProvider', {
'trt_max_workspace_size': 2147483648, # 2 GB
'trt_fp16_enable': True,
'trt_engine_cache_enable': True,
'trt_engine_cache_path': './trt_cache'
}),
('CUDAExecutionProvider', {
'device_id': 0,
'arena_extend_strategy': 'kSameAsRequested',
'gpu_mem_limit': 4 * 1024 * 1024 * 1024, # 4 GB
'cudnn_conv_algo_search': 'DEFAULT'
}),
'CPUExecutionProvider'
]
session = ort.InferenceSession(
"model_fp16.onnx",
sess_options=session_options,
providers=providers
)
# Inferens
result = session.run(None, {"input": input_data})
OpenVINO Model Server (OVMS) pa Edge
For Azure Arc/Azure Local-miljoer der Intel-hardware brukes:
# ovms-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ovms-inference
spec:
replicas: 2
template:
spec:
containers:
- name: ovms
image: openvino/model_server:latest
ports:
- containerPort: 9000 # gRPC
- containerPort: 8000 # REST
volumeMounts:
- name: model-store
mountPath: /models
env:
- name: MODELS_CONFIG
value: "/models/config.json"
resources:
limits:
cpu: "4"
memory: "8Gi"
volumes:
- name: model-store
persistentVolumeClaim:
claimName: model-pvc
vLLM for LLM-inferens
KAITO bruker vLLM som standard inferensmotor for LLM-er:
| Funksjon | Beskrivelse | Fordel |
|---|---|---|
| PagedAttention | Effektiv KV-cache-haandtering | 2-4x gjennomstromning |
| Continuous batching | Dynamisk batching av foresporsler | Redusert latens |
| Tensor parallelism | Fordel modell over GPUer | Storre modeller |
| Quantization support | AWQ, GPTQ, SqueezeLLM | Lavere minnebruk |
| OpenAI-compatible API | Standard API-format | Enkel integrasjon |
Caching Patterns for Edge
Modellcaching-strategier
| Strategi | Implementasjon | Bruksomrade |
|---|---|---|
| Model preloading | Last modell i minne ved oppstart | Sanntids inferens |
| TensorRT engine cache | Cach kompilerte TRT-motorer | GPU-inferens |
| ONNX session cache | Gjenbruk ORT-sesjoner | Repetitive inferenser |
| Result caching | Redis/memcached for resultater | Identiske inputs |
| Embedding cache | Cach vektorrepresentasjoner | RAG pa edge |
Resultatchaching med Redis pa Edge
# redis-cache-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: inference-cache
spec:
template:
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
resources:
limits:
memory: "2Gi"
args:
- "--maxmemory"
- "1.5gb"
- "--maxmemory-policy"
- "allkeys-lru"
# Inferens med caching
import redis
import hashlib
import json
cache = redis.Redis(host='inference-cache', port=6379)
def cached_inference(model_session, input_data, ttl=3600):
# Generer cache-nokkel fra input
cache_key = hashlib.sha256(
json.dumps(input_data, sort_keys=True).encode()
).hexdigest()
# Sjekk cache
cached = cache.get(cache_key)
if cached:
return json.loads(cached)
# Kjor inferens
result = model_session.run(None, input_data)
# Lagre i cache
cache.setex(cache_key, ttl, json.dumps(result.tolist()))
return result
KV-cache for LLM-er
For LLM-inferens pa edge er KV-cache (key-value cache) kritisk:
| Teknikk | Beskrivelse | Minnebesparelse |
|---|---|---|
| Standard KV-cache | Full cache for alle tokens | Baseline |
| Sliding window | Begrens cache til siste N tokens | 50-80% |
| Grouped-query attention | Faerre KV-hoder | 4-8x |
| PagedAttention (vLLM) | Sidert minnehaandtering | Dynamisk |
Batching vs. Streaming Inference
Sammenligning
| Egenskap | Batch Inference | Streaming Inference |
|---|---|---|
| Latens | Hoyere (venter pa batch) | Lavere (umiddelbar) |
| Gjennomstromning | Hoyere (GPU-utnyttelse) | Lavere (per request) |
| GPU-utnyttelse | Optimal (fyller batch) | Variabel |
| Bruksomrade | Dokumentanalyse, batch-scoring | Chat, real-time |
| Skalering | Horisontal (flere workers) | Vertikal (GPU-kapasitet) |
Beslutningstre
Trenger du sanntidssvar (<100ms)?
├── Ja → Streaming inference
│ ├── Enkelt request → Single request pipeline
│ └── Flere samtidige → Continuous batching (vLLM)
└── Nei → Batch inference
├── <1000 elementer → Micro-batch pa GPU
└── >1000 elementer → Azure ML Batch Endpoints
Batch Inference pa Edge
import numpy as np
from collections import deque
import threading
import time
class EdgeBatchInferencer:
def __init__(self, session, batch_size=8, max_wait_ms=50):
self.session = session
self.batch_size = batch_size
self.max_wait = max_wait_ms / 1000
self.queue = deque()
self.lock = threading.Lock()
def infer(self, input_data):
"""Legg til i koe og vent pa batch-resultat."""
event = threading.Event()
result_container = {}
with self.lock:
self.queue.append((input_data, event, result_container))
# Trigger batch hvis full
if len(self.queue) >= self.batch_size:
self._process_batch()
# Vent pa resultat (med timeout)
event.wait(timeout=self.max_wait * 2)
return result_container.get('result')
def _process_batch(self):
"""Prosesser akkumulerte inputs som en batch."""
with self.lock:
items = []
while self.queue and len(items) < self.batch_size:
items.append(self.queue.popleft())
if not items:
return
# Kombiner inputs til batch
batch_input = np.stack([item[0] for item in items])
# Kjor batch-inferens
batch_results = self.session.run(
None, {"input": batch_input}
)
# Distribuer resultater
for i, (_, event, container) in enumerate(items):
container['result'] = batch_results[0][i]
event.set()
Streaming Inference for LLM pa Edge
# Streaming med vLLM-kompatibelt API (KAITO)
import requests
import json
def stream_inference(prompt, service_ip, max_tokens=500):
"""Stream tokens fra lokal LLM pa edge."""
response = requests.post(
f"http://{service_ip}/v1/completions",
json={
"model": "phi-4-mini-instruct",
"prompt": prompt,
"max_tokens": max_tokens,
"stream": True
},
stream=True
)
for line in response.iter_lines():
if line:
data = line.decode('utf-8')
if data.startswith('data: '):
chunk = json.loads(data[6:])
if chunk.get('choices'):
token = chunk['choices'][0].get('text', '')
yield token
IoT Edge ML Inference Pattern
Azure IoT Edge med dynamisk modellasting
┌─────────────────────────────────────────┐
│ Azure Cloud │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ Blob │ │ IoT Hub │ │
│ │ Storage │ │ (Device Twins) │ │
│ │ (Models) │ │ │ │
│ └────┬─────┘ └────────┬─────────┘ │
└───────┼───────────────────┼─────────────┘
│ │
│ ┌───────────────▼──────────┐
│ │ IoT Edge Runtime │
│ │ ┌─────────────────────┐ │
└───┼─►│ Model Loader Module │ │
│ └──────────┬──────────┘ │
│ ┌──────────▼──────────┐ │
│ │ Inference Module │ │
│ │ (ONNX/LiteRT) │ │
│ └──────────┬──────────┘ │
│ ┌──────────▼──────────┐ │
│ │ Local Storage │ │
│ │ (Model Cache) │ │
│ └─────────────────────┘ │
└──────────────────────────┘
Device Twin-basert modellstyring
# Motta modelloppdatering via IoT Edge Device Twin
from azure.iot.device import IoTHubModuleClient
async def twin_update_handler(patch):
if 'model_version' in patch:
model_url = patch['model_url']
model_version = patch['model_version']
checksum = patch['model_checksum']
# Last ned ny modell
await download_model(model_url, checksum)
# Hot-swap modell uten nedetid
await reload_model(model_version)
# Rapporter tilbake
reported = {
"active_model_version": model_version,
"model_loaded_at": datetime.utcnow().isoformat()
}
client.patch_twin_reported_properties(reported)
Ytelsesreferanser
Typiske inferenstider pa Microsoft edge-hardware
| Hardware | Modell | Oppgave | Latens (ms) |
|---|---|---|---|
| Azure Stack Edge Pro GPU (T4) | YOLOv8 | Objektdeteksjon | 8-15 |
| Azure Stack Edge Pro GPU (T4) | ResNet-50 | Bildeklassifisering | 3-5 |
| Azure Local (A2) | Phi-3-mini-4k | Tekst (128 tokens) | 200-400 |
| Azure Local (L4) | Phi-4-mini | Tekst (128 tokens) | 80-150 |
| Azure Local (L40S) | Mistral-7B | Tekst (128 tokens) | 50-100 |
| Intel CPU (Xeon) + OpenVINO | BERT-base | NER | 5-10 |
| CPU (ONNX Runtime) | DistilBERT | Sentiment | 3-8 |
For Cosmo
- ONNX Runtime er universalmotoren for edge-inferens — stotter CPU, GPU, NPU via Execution Providers, med TensorRT for NVIDIA og OpenVINO for Intel som de viktigste akseleratorene.
- Kvantisering (INT8/INT4) er den enkleste og mest effektive optimaliseringen — reduserer modellstorrelse 2-8x med minimalt noyaktighetstap, spesielt viktig for edge-enheter med begrenset minne.
- Velg batching for gjennomstromning, streaming for latens — continuous batching (vLLM/KAITO) gir det beste av begge for LLM-inferens pa edge Kubernetes-klynger.
- Caching pa flere nivaer er essensielt for edge-ytelse — TensorRT engine cache, resultat-cache (Redis), og KV-cache for LLM-er reduserer bade latens og GPU-belastning.
- IoT Edge med Device Twins gir skalerbar modellstyring for distribuerte edge-enheter — modellversjonering, inkrementell oppdatering og hot-swap uten nedetid.