ms-ai-architect/skills/ms-ai-infrastructure/references/hybrid-edge/disconnected-ai-scenarios.md
Kjell Tore Guttormsen 544934dc57
refactor(examples): replace sector-specific example material with generic, fictitious examples
Reference files, test fixtures, the playground demo project and one design
document now use generic, fictitious examples (buildings, energy, water,
grants, municipal services). The playground demo (17 fixtures plus the
embedded demo state) tells one consistent story: a municipal customer
chatbot that pre-screens housing-benefit applications, classified under
Annex III point 5(a). The embedded demo copies were edited in place rather
than regenerated, because they already carry newer AI Act dates than the
fixture files.

Legal text is unchanged. Test semantics are unchanged. Four dark-theme
onboarding screenshots with outdated placeholder text are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 14:03:53 +02:00

22 KiB

Disconnected AI Scenarios

Last updated: 2026-06-24 Status: GA Category: Hybrid Cloud & Edge AI Type: reference Source: https://learn.microsoft.com/azure/azure-sovereign-clouds/private/foundry-local/disconnected-operations/concept-overview Verified: 2026-07-31 Verified by: judge-v3.1


Innhold

Introduksjon

Frakoblede (disconnected) AI-scenarioer er situasjoner der AI-arbeidsbelastninger ma kjore uten internettilkobling — enten permanent, periodisk eller i beredskapssituasjoner. For norsk offentlig sektor er dette svart relevant: Forsvaret opererer i omrader uten nettdekning, helsesektoren trenger AI-stotte i ambulanser og utposter, og kritisk infrastruktur (energi, transport) ma fungere uavhengig av skytjenester.

Microsoft tilbyr flere losninger for frakoblet AI: Microsoft Foundry Tools disconnected containers for tradisjonelle AI-tjenester (tale, tekst, bilde), Azure Stack Edge for hardware-basert edge-inferens, Azure Local med disconnected operations for storre Kubernetes-miljoer, og ONNX Runtime for helt lokale modellkjoringer uten skyavhengigheter.

Denne referansen dekker de viktigste moensterne for offline modell-deployment, datarekonsiliering, lokal caching/synkronisering og fallback-strategier — alle med fokus pa palit drift nar nettverkstilkoblingen er ustabil eller fravarende.


Spekter av tilkobling

AI-scenarioer fordeler seg langs et tilkoblingsspektrum:

┌─────────────────────────────────────────────────────┐
│  Alltid     Sporadisk    Periodisk    Helt           │
│  tilkoblet  tilkoblet    tilkoblet    frakoblet      │
│  ●──────────●────────────●────────────●              │
│  |          |            |            |              │
│  Standard   Connected    Batch sync   Air-gapped     │
│  Azure      containers   +            lokale          │
│  services   (billing)    offline ops  modeller       │
└─────────────────────────────────────────────────────┘
Modus Nettverkskrav Azure-tjenester Billing
Alltid tilkoblet Stabilt internett Alle Pay-as-you-go
Connected containers Periodisk (billing) Begrensede Bruksbasert
Periodisk synk Timer/dager mellom tilkoblinger Batch-synk Commitment tier
Helt frakoblet Ingen Kun lokale Forhndsbetalt lisens

Offline Model Deployment

Foundry Local — generativ inferens lokalt og air-gapped

To distinkte produkter under «Foundry Local»-paraplyen (verifisert 2026-06-18 mot Microsoft Learn):

Produkt Formål Azure-abonnement Status
Foundry Local (on-device) Lokal modellruntime i klientapper (Windows/macOS/Linux). SDK: C#/JS/Rust/Python. Data forlater aldri enheten. Nei Tilgjengelig
Foundry Local on Azure Local Enterprise-skala inferens på on-prem Arc-enabled Kubernetes (Azure Local, tidl. Azure Stack HCI). Ja Preview (tilgang på søknad)

Foundry Local (on-device) kjører inferens helt på enheten og fungerer offline etter at modeller er lastet ned (caches lokalt). Nettverk brukes kun til første modellnedlasting og valgfri diagnostikk. Ingen per-token-kostnad. Modellkatalog: Phi, Qwen, DeepSeek, Mistral, GPT OSS (chat), Whisper (audio).

Foundry Local on Azure Local — air-gapped/disconnected (offisielt støttet fra juni 2026, Preview): kan deployes i miljøer uten internett. Forskjeller fra connected:

Aspekt Connected Disconnected (air-gapped)
Modellkilde Foundry cloud-katalog Lokalt edgeartifacts container registry (fra expansion packs)
Extension Standard Arc-extension Expansion pack lastes ned + importeres manuelt
Sertifikater azure-cert-manager cert-manager + trust-manager (i expansion pack)
Telemetri Til Microsoft Sendes ikke
Autentisering Offentlige Entra ID-endepunkter Integrert med lokal Active Directory

Modeller forhåndsinstalleres: expansion pack lastes ned i tilkoblet miljø, overføres manuelt og importeres med PowerShell (Start-AldoExpansionPackUpload/-Installation) → publiseres til edgeartifacts. Arc er obligatorisk koblingsmekanisme, men trenger ikke løpende Azure-tilkobling i disconnected-modus. Inferens-runtimes: ONNX-GenAI (CPU/GPU) og vLLM (GPU). Multi-node Kubernetes (juni 2026) gir concurrent inferens og større modeller.

Suverenitet (norsk offentlig sektor): Foundry Local on Azure Local er del av Microsoft Sovereign Private Cloud. Disconnected-modus er eksplisitt rettet mot suverene, klassifiserte og strengt regulerte miljøer — ingen telemetri til Microsoft, data og kontrollplan innenfor virksomhetens grenser. Eligibility krever dokumentert forretnings-/regulatorisk begrunnelse. Kilder: Foundry Local · Foundry Local on Azure Local — disconnected.

Microsoft Foundry Tools Disconnected Containers

Microsofts primaere losning for AI-tjenester uten nettverkstilkobling:

Tjeneste Container Disconnected Status
Speech to Text speech-to-text Ja GA
Custom Speech to Text custom-speech-to-text Ja GA
Neural Text to Speech neural-text-to-speech Ja GA
Translator text-translation Ja GA
Language Detection text-language-detection Ja GA
Key Phrase Extraction text-keyphrase Ja GA
Named Entity Recognition text-ner Ja GA
PII Detection text-pii Ja GA
Sentiment Analysis text-sentiment Ja GA
CLU clu Ja GA
Summarization text-summarization Ja Preview
Read OCR vision-read Ja GA
Document Intelligence document-intelligence Ja GA
Content Safety (Text) contentsafety-text Ja Preview
Content Safety (Image) contentsafety-image Ja Preview
Prompt Shields contentsafety-promptshields Ja Preview

Prosess for disconnected deployment

┌─────────────────────────────────────────┐
│  1. Soknad og godkjenning               │
│     ├── Enterprise Agreement kreves     │
│     ├── Gyldig business case            │
│     └── Godkjenning innen 10 dager      │
│                                         │
│  2. Lisensnedlasting                    │
│     ├── Kjop commitment tier            │
│     ├── Last ned lisensfil              │
│     └── Lisensfil har utlopsdato        │
│                                         │
│  3. Container-nedlasting                │
│     ├── Pull fra MCR (online)           │
│     ├── Eksporter til tar               │
│     └── Overfar til offline-miljo       │
│                                         │
│  4. Offline deployment                  │
│     ├── Importer container              │
│     ├── Mount lisensfil                 │
│     └── Kjor uten nettverkstilkobling   │
└─────────────────────────────────────────┘

Lisensnedlasting og container-oppsett

# Steg 1: Last ned lisens (online maskin)
docker run --rm -it \
  -v /host/license:/license \
  mcr.microsoft.com/azure-cognitive-services/speechservices/speech-to-text \
  eula=accept \
  billing=https://my-resource.cognitiveservices.azure.com \
  apikey=<API_KEY> \
  DownloadLicense=True \
  Mounts:License=/license

# Steg 2: Eksporter container image
docker save \
  mcr.microsoft.com/azure-cognitive-services/speechservices/speech-to-text \
  -o speech-to-text.tar

# Steg 3: Overfar til offline-miljo (USB, etc.)
# Kopier speech-to-text.tar og lisensfil

# Steg 4: Importer pa offline-maskin
docker load -i speech-to-text.tar

# Steg 5: Kjor uten nettverkstilkobling
docker run --rm -it -p 5000:5000 \
  -v /host/license:/license \
  mcr.microsoft.com/azure-cognitive-services/speechservices/speech-to-text \
  eula=accept \
  Mounts:License=/license \
  Mounts:Output=/output

ONNX Runtime — helt lokale modeller

For scenarioer uten Docker- eller lisensbehov:

# Helt lokal inferens med ONNX Runtime
# Ingen skyavhengighet, ingen lisens, ingen Docker
import onnxruntime as ort
import numpy as np

# Last modell fra lokal disk
session = ort.InferenceSession(
    "/models/document-classifier.onnx",
    providers=['CPUExecutionProvider']
)

# Kjor inferens
input_name = session.get_inputs()[0].name
result = session.run(None, {
    input_name: np.array(preprocessed_data)
})

Azure Stack Edge i disconnected modus

Nkkelforskjeller offline vs online

Funksjon Online Disconnected
Azure Portal management Ja Nei — kun lokal UI
Kubernetes workloads Full Arc-stotte Lokal kubectl
Container registry Azure Container Registry Edge Container Registry
Overvaking Azure Monitor Lokalt Kubernetes dashboard
Azure Arc Full integrasjon Ikke tilgjengelig
VM-styring Arc-enabled VMs Lokalt PowerShell/UI
GPU workloads Full stotte Full stotte (forklargjort)

Forberedelse for disconnected drift

# Forbered Azure Stack Edge for offline-bruk
# (Gjores mens enheten fortsatt er online)

# 1. Aktiver enhet via Azure Portal
# 2. Enable Kubernetes
Set-AzureDataBoxEdgeRole -Name "Kubernetes" -Activated

# 3. Deploy alle nodvendige container workloads
kubectl apply -f ai-inference-deployment.yaml

# 4. Push container images til Edge Container Registry
docker tag my-model:v1 ecr.edgehostname:31001/my-model:v1
docker push ecr.edgehostname:31001/my-model:v1

# 5. Verifiser at alt kjorer
kubectl get pods -A

# 6. Koble fra nettverket

Data Reconciliation Strategies

Utfordringer med frakoblet data

Nar AI-systemer kjorer offline, oppstar det utfordringer med:

  • Data som genereres lokalt ma synkroniseres nar tilkobling gjenopprettes
  • Modellresultater fra offline-perioden ma valideres
  • Konflikter mellom lokale og sentrale data
  • Versjonshaandtering av modeller og konfigurasjoner

Rekonsilieringsmoenstre

Moenster Beskrivelse Bruksomrade
Store-and-Forward Buffer lokalt, send nar tilkoblet IoT-data, loggfiler
Event Sourcing Registrer alle hendelser, replay sentralt Audit, compliance
Last-Write-Wins Siste endring vinner ved konflikt Enkle konfigurasjoner
Merge/CRDTs Konfliktfri sammenslaing Distribuerte datasett
Manual Review Menneske loeser konflikter Kritiske beslutninger

Store-and-Forward med IoT Hub

# Lokal buffering og batch-synkronisering
import json
import os
from datetime import datetime
from pathlib import Path

class OfflineBuffer:
    def __init__(self, buffer_dir="/data/offline-buffer"):
        self.buffer_dir = Path(buffer_dir)
        self.buffer_dir.mkdir(parents=True, exist_ok=True)

    def store_result(self, inference_result, metadata):
        """Lagre inferensresultat lokalt."""
        entry = {
            "timestamp": datetime.utcnow().isoformat(),
            "result": inference_result,
            "metadata": metadata,
            "synced": False
        }
        filepath = self.buffer_dir / f"{entry['timestamp']}.json"
        filepath.write_text(json.dumps(entry))
        return filepath

    def get_unsynced(self):
        """Hent alle usynkroniserte resultater."""
        results = []
        for f in sorted(self.buffer_dir.glob("*.json")):
            entry = json.loads(f.read_text())
            if not entry.get("synced"):
                results.append((f, entry))
        return results

    async def sync_to_cloud(self, iot_client):
        """Synkroniser bufferede resultater til sky."""
        unsynced = self.get_unsynced()
        for filepath, entry in unsynced:
            try:
                await iot_client.send_message(
                    json.dumps(entry)
                )
                entry["synced"] = True
                entry["synced_at"] = datetime.utcnow().isoformat()
                filepath.write_text(json.dumps(entry))
            except Exception as e:
                # Fortsett med neste — proev igjen senere
                print(f"Sync feilet for {filepath}: {e}")
                break

Modellversjon-rekonsiliering

# model-sync-config.yaml
sync:
  strategy: "check-on-connect"
  model_registry:
    cloud: "https://ml-workspace.azureml.net/models"
    local: "/models/registry.json"
  conflict_resolution: "cloud-wins"
  validation:
    enabled: true
    test_dataset: "/data/validation/standard-test.json"
    min_accuracy: 0.95
  rollback:
    enabled: true
    keep_previous: 3

Local Cache and Sync

Flerlags cache-arkitektur

┌──────────────────────────────────────────┐
│  Lag 1: In-Memory Cache (Redis)          │
│  TTL: 1 time │ Storrelse: 2 GB           │
│  Hoyest prioritet, raskest tilgang       │
├──────────────────────────────────────────┤
│  Lag 2: Lokal Disk Cache (SSD)           │
│  TTL: 7 dager │ Storrelse: 100 GB        │
│  Modellvekter, embeddings, resultater    │
├──────────────────────────────────────────┤
│  Lag 3: Persistent Storage (S2D/NAS)     │
│  Ingen TTL │ Storrelse: 1 TB+            │
│  Full modellhistorikk, treningsdata      │
├──────────────────────────────────────────┤
│  Lag 4: Cloud Sync (Azure Blob)          │
│  Synk ved tilkobling                     │
│  Master-kopi av modeller og data         │
└──────────────────────────────────────────┘

Synkroniseringslogikk

# Intelligent sync-manager
class SyncManager:
    def __init__(self, config):
        self.local_store = LocalModelStore(config.local_path)
        self.cloud_store = AzureBlobStore(config.connection_string)
        self.sync_log = SyncLog(config.log_path)

    async def check_connectivity(self):
        """Sjekk om skytilkobling er tilgjengelig."""
        try:
            await self.cloud_store.ping()
            return True
        except Exception:
            return False

    async def sync_models(self):
        """Synkroniser modeller mellom lokal og sky."""
        if not await self.check_connectivity():
            return SyncResult(status="offline", synced=0)

        # Hent manifest fra sky
        cloud_manifest = await self.cloud_store.get_manifest()
        local_manifest = self.local_store.get_manifest()

        updates = []
        for model_id, cloud_info in cloud_manifest.items():
            local_info = local_manifest.get(model_id)

            if not local_info:
                # Ny modell — last ned
                updates.append(("download", model_id, cloud_info))
            elif cloud_info['version'] > local_info['version']:
                # Oppdatert modell — last ned ny versjon
                updates.append(("update", model_id, cloud_info))

        # Utfor oppdateringer med prioritering
        for action, model_id, info in sorted(
            updates, key=lambda x: x[2].get('priority', 99)
        ):
            try:
                await self._download_model(model_id, info)
                self.sync_log.record(action, model_id, "success")
            except Exception as e:
                self.sync_log.record(action, model_id, f"failed: {e}")

        # Last opp lokale resultater
        await self._upload_offline_results()

        return SyncResult(
            status="synced",
            synced=len(updates)
        )

Fallback Inference Patterns

Degraderingsstrategier

Strategi Nar Implementasjon
Full model → Lite model GPU svikter Fall tilbake til CPU-modell
Cloud model → Edge model Nettverk nede Bruk lokal kvantisert modell
ML-modell → Regler Modell korrupt Regelbasert fallback
Real-time → Batch Overbelastning Buffer foresporsler
AI → Manuell Alt feiler Eskalering til menneske

Implementasjon av fallback-kaskade

class ResilientInferenceEngine:
    def __init__(self):
        self.engines = [
            CloudInference(endpoint="https://foundry.azure.com"),
            LocalGPUInference(model_path="/models/full-model.onnx"),
            LocalCPUInference(model_path="/models/quantized-int8.onnx"),
            RuleBasedFallback(rules_path="/config/rules.json")
        ]

    async def infer(self, input_data, timeout=5.0):
        """Prover inferensmotorer i prioritetsrekkefoolge."""
        last_error = None

        for engine in self.engines:
            try:
                result = await asyncio.wait_for(
                    engine.predict(input_data),
                    timeout=timeout
                )
                return InferenceResult(
                    prediction=result,
                    engine=engine.name,
                    confidence=engine.confidence_level,
                    degraded=(engine != self.engines[0])
                )
            except asyncio.TimeoutError:
                last_error = f"{engine.name}: timeout"
                timeout = min(timeout * 2, 30)  # Okt timeout for neste
            except Exception as e:
                last_error = f"{engine.name}: {e}"
                continue

        # Alle motorer feilet — returner fallback
        return InferenceResult(
            prediction=None,
            engine="none",
            confidence=0,
            degraded=True,
            error=last_error
        )

Health monitoring for offline-systemer

# health-check-config.yaml
health_checks:
  model_health:
    interval: 60s
    checks:
      - name: model_loaded
        type: inference_test
        input: "test_input.json"
        expected_output_shape: [1, 10]
      - name: gpu_available
        type: nvidia_smi
        min_free_memory_mb: 1024
      - name: disk_space
        type: disk
        min_free_gb: 10

  degradation_rules:
    - condition: "gpu_available == false"
      action: "switch_to_cpu_model"
    - condition: "disk_space < 5GB"
      action: "cleanup_old_models"
    - condition: "model_loaded == false"
      action: "reload_from_cache"
      max_retries: 3

Scenarioer for norsk offentlig sektor

Forsvar og beredskap

Scenario Tilkoblingsstatus Losning
Feltoperasjoner Helt frakoblet ONNX Runtime + kvantiserte modeller
Kjoretoy/fartoy Periodisk Store-and-forward + modellsynk
Kommandoplass Begrenset Azure Stack Edge disconnected
Sambandssystemer Ustabil Fallback-kaskade med degradering

Helse

Scenario Tilkoblingsstatus Losning
Ambulanse Ustabil Lokal bildeanalyse (ONNX)
Distriktslege Periodisk Disconnected containers (tale, tekst)
Sykehus DR Beredskap Azure Local med offline-kapasitet
Feltsykehus Frakoblet Forhndslastede modeller

Transport og infrastruktur

Scenario Tilkoblingsstatus Losning
Fjellanlegg og gruver Frakoblet Edge-inferens med lokal sensorlogging
Fartsoyvervaking Ustabil Lokal objektdeteksjon
Havneanalyse Periodisk Batch-analyse med synk
Havvind og offshore Variabel Hybrid med sky-fallback

Lisens- og kostnadshensyn

Disconnected containers prismodell

Prismodell Beskrivelse Krav
Commitment tier Arlig forpliktelse Enterprise Agreement
Per-tjeneste Betal per container-tjeneste Godkjent soknad
Kalenderars-binding 12 mnd minimum Automatisk fornyelse

Viktige begrensninger

  • Lisensfil har utlopsdato — krever periodisk fornyelse
  • Enterprise Agreement eller tilsvarende er obligatorisk
  • Godkjenningsprosess tar opptil 10 virkedager
  • Ingen SLA for disconnected containers (kunde eier infrastruktur)
  • Ikke tilgjengelig i sovereign clouds (kun public cloud for opprettelse)

Oppsummering

  • Azure tilbyr et komplett spekter for frakoblet AI — fra Foundry Tools disconnected containers (tale, tekst, bilde) til helt lokale ONNX Runtime-modeller uten skyavhengighet.
  • Disconnected containers krever Enterprise Agreement og godkjenning — lisensfiler har utlopsdato og ma fornyes, men gir tilgang til de samme API-ene som sky-tjenestene.
  • Fallback-kaskader er essensielt for paalitelig edge-AI — design alltid med degraderingsstrategi: sky → lokal GPU → lokal CPU → regler → manuell.
  • Store-and-forward med rekonsilieringslogikk loser utfordringen med data som genereres offline — buffer lokalt, synkroniser ved tilkobling, hndter konflikter.
  • For norsk offentlig sektor er frakoblet AI kritisk for beredskap, forsvar og helse — Azure Stack Edge og ONNX Runtime gir funksjonskapasitet uten internett-avhengighet.