Disconnected AI Scenarios
Last updated: 2026-02
Status: GA
Category: Hybrid Cloud & Edge AI
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: Azure AI 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
Azure AI 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 |
| Tunneler |
Frakoblet |
Edge-inferens med kamerasystem |
| Fartsoyvervaking |
Ustabil |
Lokal objektdeteksjon |
| Trafikkanalyse |
Periodisk |
Batch-analyse med synk |
| Fergedrift |
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)
For Cosmo
- 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.