ktg-plugin-marketplace/plugins/ms-ai-architect/skills/ms-ai-infrastructure/references/hybrid-edge/edge-ai-inferencing-patterns.md
Kjell Tore Guttormsen 6a7632146e feat(ms-ai-architect): add plugin to open marketplace (v1.5.0 baseline)
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>
2026-04-07 17:17:17 +02:00

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.