Same bulk replacement applied to plugin-internal KB, examples, fixtures, tests, and docs. Real organization names, persona names, internal system identifiers, and domain-specific terms replaced with fictional generic public-sector entity (DDT) and generic terminology. Scope: - okr/ — examples, governance, framework, integrations, sources - ms-ai-architect/ — KB references (engineering, governance, security, infrastructure, advisor), tests/fixtures, agents, docs - linkedin-thought-leadership/ — voice samples, network-builder, examples (genericized identifying headlines to "[your organization]") - llm-security/ — research notes, scan report Manual genericization beyond bulk replace: - okr SKILL.md "Primary user / Domain" — generic Norwegian public sector - linkedin-voice SKILL.md headline placeholder - network-builder.md headline placeholder - high-engagement-posts.md voice sample employer line + hashtag Phase 3 (factual-attribution review) remains: a few KB files attribute publicly known transport-sector docs/datasets (e.g. håndbok V440, NVDB) to the fictional DDT after bulk replace. Needs manual semantic review to either remove or restore correct citation without re-introducing affiliation references. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
471 lines
17 KiB
Markdown
471 lines
17 KiB
Markdown
# Latency Optimization for Azure OpenAI
|
|
|
|
**Last updated:** 2026-02
|
|
**Status:** GA
|
|
**Category:** Performance & Scalability
|
|
|
|
---
|
|
|
|
## Introduksjon
|
|
|
|
Latens er en av de mest kritiske ytelsesparameterne for AI-applikasjoner i produksjon. For norsk offentlig sektor, der innbyggertjenester krever rask respons og interne saksbehandlingssystemer må operere effektivt, er optimalisering av Azure OpenAI-latens avgjorende. Høy latens kan direkte påvirke brukeropplevelsen og redusere adopsjonen av AI-drevne tjenester.
|
|
|
|
Azure OpenAI-latens bestemmes av flere faktorer: modellvalg, prompt-storrelse, genereringsstorrelse, nettverksavstand til endepunktet, og hvordan applikasjonen er konfigurert. Forstaelse av disse faktorene og systematisk optimalisering av hver komponent er nodvendig for a oppna akseptabel ytelse i produksjonsmiljoer.
|
|
|
|
Denne referansen dekker de viktigste teknikkene for a redusere latens i Azure OpenAI-baserte applikasjoner, fra request pipeline-optimalisering til regional endepunktsplassering, med spesielt fokus pa norske deployments i North Europe og Sweden Central-regionene.
|
|
|
|
## Forstaelse av latenskomponenter
|
|
|
|
### Request Pipeline Breakdown
|
|
|
|
En Azure OpenAI-request traverserer flere stadier, og hvert stadium bidrar til total latens:
|
|
|
|
| Stadium | Beskrivelse | Typisk latens |
|
|
|---------|-------------|---------------|
|
|
| DNS-oppslag | Resolusjon av Azure OpenAI-endepunkt | 1-50 ms |
|
|
| TLS-handshake | Sikker forbindelse etableres | 20-100 ms |
|
|
| Nettverkstransport | Data sendes til Azure-regionen | 5-200 ms |
|
|
| Token-prosessering (input) | Prompt-tokens prosesseres | Varierer med storrelse |
|
|
| Token-generering (output) | Completion-tokens genereres sekvensielt | Storste latensbidraget |
|
|
| Content filtering | Sikkerhetsfiltrering av input/output | 10-50 ms |
|
|
| Responstransport | Svar sendes tilbake til klient | 5-200 ms |
|
|
|
|
### Latensmetrikker
|
|
|
|
For effektiv maling av latens bor du spore disse metrikkene:
|
|
|
|
**For non-streaming requests:**
|
|
- **End-to-end Request Time:** Total tid fra request sendt til komplett respons mottatt.
|
|
|
|
**For streaming requests:**
|
|
- **Time to First Token (TTFT):** Tid fra request sendt til forste token mottatt. Oker med prompt-storrelse.
|
|
- **Average Token Generation Rate:** Tid fra forste token til siste token, delt pa antall genererte tokens. Oker med systembelastning.
|
|
|
|
```python
|
|
import time
|
|
from openai import AzureOpenAI
|
|
|
|
client = AzureOpenAI(
|
|
azure_endpoint="https://your-resource.openai.azure.com/",
|
|
api_key="your-api-key",
|
|
api_version="2025-03-01-preview"
|
|
)
|
|
|
|
# Mal TTFT og total latens
|
|
start_time = time.perf_counter()
|
|
first_token_time = None
|
|
|
|
response = client.chat.completions.create(
|
|
model="gpt-4o",
|
|
messages=[{"role": "user", "content": "Hva er personopplysningsloven?"}],
|
|
stream=True,
|
|
max_tokens=200
|
|
)
|
|
|
|
for chunk in response:
|
|
if first_token_time is None and chunk.choices[0].delta.content:
|
|
first_token_time = time.perf_counter()
|
|
ttft = first_token_time - start_time
|
|
print(f"Time to First Token: {ttft:.3f}s")
|
|
|
|
total_time = time.perf_counter() - start_time
|
|
print(f"Total latens: {total_time:.3f}s")
|
|
```
|
|
|
|
## Request Pipeline-optimalisering
|
|
|
|
### Modellvalg for lav latens
|
|
|
|
Modellvalg har direkte innvirkning pa latens. For identiske requests varierer latens betydelig mellom modeller:
|
|
|
|
| Modell | Relativ latens | Anbefalt bruk |
|
|
|--------|---------------|----------------|
|
|
| GPT-4o mini | Lavest | Enkel klassifisering, rask sortering, chatbots |
|
|
| GPT-4o | Moderat | Generelt formalsbruk, RAG-svar |
|
|
| GPT-4.1 | Moderat-hoy | Kompleks resonnering, kodeanalyse |
|
|
| o3-mini | Hoy | Avansert resonnering med lavere tokenbruk |
|
|
|
|
**Anbefaling for norsk offentlig sektor:** Bruk GPT-4o mini for innbyggertjenester som krever rask respons (chatbots, FAQ-svar). Reserver GPT-4o og storre modeller for saksbehandlingsstotte der kvalitet er viktigere enn hastighet.
|
|
|
|
### Max Tokens-optimalisering
|
|
|
|
`max_tokens`-parameteren pavirker latens betydelig. Azure OpenAI reserverer beregningskapasitet basert pa denne verdien ved request-start:
|
|
|
|
```python
|
|
# DARLIG: For hoy max_tokens oker latens selv om faktisk output er kort
|
|
response = client.chat.completions.create(
|
|
model="gpt-4o",
|
|
messages=[{"role": "user", "content": "Svar ja eller nei: Er dette en klage?"}],
|
|
max_tokens=4096 # Reserverer kapasitet for 4096 tokens
|
|
)
|
|
|
|
# BRA: Tilpass max_tokens til forventet output-lengde
|
|
response = client.chat.completions.create(
|
|
model="gpt-4o",
|
|
messages=[{"role": "user", "content": "Svar ja eller nei: Er dette en klage?"}],
|
|
max_tokens=10 # Reserverer kun nodvendig kapasitet
|
|
)
|
|
```
|
|
|
|
**Tommelregel:** Sett `max_tokens` til 1.5x forventet output-lengde. For klassifiseringsoppgaver: 10-50 tokens. For korte svar: 100-300 tokens. For lengre generering: tilpass etter behov.
|
|
|
|
### Stop Sequences
|
|
|
|
Bruk `stop`-parameteren for a avslutte generering tidlig nar onskede data er produsert:
|
|
|
|
```python
|
|
# Stopp sa snart klassifiseringen er ferdig
|
|
response = client.chat.completions.create(
|
|
model="gpt-4o-mini",
|
|
messages=[
|
|
{"role": "system", "content": "Klassifiser henvendelsen. Svar med kun: KLAGE, SPORSMAL, eller TILBAKEMELDING"},
|
|
{"role": "user", "content": user_input}
|
|
],
|
|
max_tokens=20,
|
|
stop=["\n", "."] # Stopp etter forste linje/setning
|
|
)
|
|
```
|
|
|
|
### Separasjon av arbeidslaster
|
|
|
|
Blanding av ulike arbeidslaster pa samme endepunkt pavirker latens negativt:
|
|
|
|
1. **Batch-interferens:** Korte og lange requests batches sammen under inferens, sa korte kall ma vente pa lange completions.
|
|
2. **Cache-konkurranise:** Ulike arbeidslaster konkurrerer om prompt cache-plass.
|
|
|
|
**Anbefalt arkitektur:**
|
|
|
|
```
|
|
Innbyggerportal (chatbot) --> Deployment: gpt-4o-mini-chat (Standard, hoy TPM)
|
|
Saksbehandling (analyse) --> Deployment: gpt-4o-analyse (Standard, moderat TPM)
|
|
Dokumentgenerering --> Deployment: gpt-4o-dokument (Standard, lav TPM)
|
|
Batchprosessering --> Deployment: gpt-4o-batch (Global Batch)
|
|
```
|
|
|
|
## Connection Pooling og gjenbruk
|
|
|
|
### HTTP Connection Reuse
|
|
|
|
Opprettelse av nye HTTP-forbindelser for hver request legger til DNS-oppslag og TLS-handshake. Gjenbruk av forbindelser eliminerer dette:
|
|
|
|
```python
|
|
from openai import AzureOpenAI
|
|
import httpx
|
|
|
|
# Opprett klient EN gang og gjenbruk
|
|
# Python SDK bruker httpx med connection pooling automatisk
|
|
client = AzureOpenAI(
|
|
azure_endpoint="https://your-resource.openai.azure.com/",
|
|
api_key="your-api-key",
|
|
api_version="2025-03-01-preview",
|
|
http_client=httpx.Client(
|
|
limits=httpx.Limits(
|
|
max_connections=100, # Maks samtidige forbindelser
|
|
max_keepalive_connections=20, # Hold forbindelser levende
|
|
keepalive_expiry=30 # Sekunder for keepalive
|
|
)
|
|
)
|
|
)
|
|
|
|
# DARLIG: Ny klient per request
|
|
def process_request_bad(prompt):
|
|
client = AzureOpenAI(...) # Ny TLS-handshake hver gang
|
|
return client.chat.completions.create(...)
|
|
|
|
# BRA: Gjenbruk eksisterende klient
|
|
def process_request_good(prompt):
|
|
return client.chat.completions.create( # Gjenbruker forbindelse
|
|
model="gpt-4o",
|
|
messages=[{"role": "user", "content": prompt}]
|
|
)
|
|
```
|
|
|
|
### Async Connection Pooling
|
|
|
|
For hoy-throughput applikasjoner, bruk async-klienten:
|
|
|
|
```python
|
|
from openai import AsyncAzureOpenAI
|
|
import asyncio
|
|
|
|
async_client = AsyncAzureOpenAI(
|
|
azure_endpoint="https://your-resource.openai.azure.com/",
|
|
api_key="your-api-key",
|
|
api_version="2025-03-01-preview"
|
|
)
|
|
|
|
async def process_batch(prompts: list[str]) -> list:
|
|
"""Prosesser flere requests parallelt med connection pooling."""
|
|
tasks = [
|
|
async_client.chat.completions.create(
|
|
model="gpt-4o-mini",
|
|
messages=[{"role": "user", "content": p}],
|
|
max_tokens=200
|
|
)
|
|
for p in prompts
|
|
]
|
|
return await asyncio.gather(*tasks)
|
|
|
|
# Kjor 10 requests parallelt
|
|
results = asyncio.run(process_batch(prompts[:10]))
|
|
```
|
|
|
|
### Retry-strategi med eksponentiell backoff
|
|
|
|
Azure OpenAI SDK har innebygd retry-logikk for 429-feil (rate limiting):
|
|
|
|
```python
|
|
from openai import AzureOpenAI
|
|
|
|
# Konfigurer retry-oppforsel
|
|
client = AzureOpenAI(
|
|
azure_endpoint="https://your-resource.openai.azure.com/",
|
|
api_key="your-api-key",
|
|
api_version="2025-03-01-preview",
|
|
max_retries=5, # Standard: 2
|
|
timeout=60.0 # Standard: 10 minutter
|
|
)
|
|
|
|
# For PTU-deployments: Respekter retry-after header
|
|
# SDK gjor dette automatisk, men du kan tilpasse:
|
|
client_no_retry = AzureOpenAI(
|
|
azure_endpoint="https://your-resource.openai.azure.com/",
|
|
api_key="your-api-key",
|
|
api_version="2025-03-01-preview",
|
|
max_retries=0 # Deaktiver for a handtere selv
|
|
)
|
|
```
|
|
|
|
## Regional endepunktsvalg
|
|
|
|
### Azure-regioner for Norge
|
|
|
|
For norsk offentlig sektor er datasuverenitet og latens begge kritiske:
|
|
|
|
| Region | Latens fra Norge | Datasuverenitet | Tilgjengelige modeller |
|
|
|--------|-----------------|-----------------|----------------------|
|
|
| Sweden Central | ~10-20 ms | EU/EOS | Alle GPT-4o-modeller, PTU |
|
|
| North Europe (Irland) | ~30-50 ms | EU/EOS | De fleste modeller |
|
|
| West Europe (Nederland) | ~25-40 ms | EU/EOS | De fleste modeller |
|
|
| UK South | ~30-50 ms | Utenfor EOS | Begrenset relevans |
|
|
|
|
**Anbefaling:** Sweden Central som primaerregion for lavest latens og EU-datasuverenitet. North Europe som sekundaerregion for failover.
|
|
|
|
### Multi-region arkitektur med prioritet
|
|
|
|
For a oppna bade lav latens og hoy tilgjengelighet:
|
|
|
|
```python
|
|
# Prioritetsbasert lastbalansering med Azure API Management
|
|
# APIM-policy for smart routing:
|
|
```
|
|
|
|
```xml
|
|
<!-- Azure API Management policy for multi-region routing -->
|
|
<policies>
|
|
<inbound>
|
|
<set-variable name="primary-backend"
|
|
value="https://aoai-sweden-central.openai.azure.com/" />
|
|
<set-variable name="fallback-backend"
|
|
value="https://aoai-north-europe.openai.azure.com/" />
|
|
</inbound>
|
|
<backend>
|
|
<retry condition="@(context.Response.StatusCode == 429)"
|
|
count="1"
|
|
interval="0">
|
|
<set-backend-service base-url="@((string)context.Variables["fallback-backend"])" />
|
|
<forward-request buffer-response="false" />
|
|
</retry>
|
|
</backend>
|
|
</policies>
|
|
```
|
|
|
|
### Global vs. Regional Deployment Types
|
|
|
|
| Deployment Type | Databehandling | Latens | Bruksomrade |
|
|
|----------------|---------------|--------|-------------|
|
|
| Regional Standard | Kun i valgt region | Lavest | Produksjon, compliance-kritisk |
|
|
| Data Zone Standard | Innenfor EU/US-sone | Lav | Generelt, fleksibel kapasitet |
|
|
| Global Standard | Enhver Azure-region | Variabel | Hoy throughput, tolererer variasjon |
|
|
| Regional PTU | Kun i valgt region | Lavest og mest forutsigbar | Misjonskritisk, stabile laster |
|
|
|
|
## Time-to-First-Token-reduksjon
|
|
|
|
### Prompt Caching
|
|
|
|
Azure OpenAI prompt caching reduserer latens og kostnad for requests med identisk prefix:
|
|
|
|
```python
|
|
# Prompt caching aktiveres automatisk for stottede modeller
|
|
# Krav: Minimum 1024 tokens, identisk prefix
|
|
|
|
# System prompt som gjenbrukes pa tvers av requests
|
|
SYSTEM_PROMPT = """Du er en saksbehandlingsassistent for Direktoratet for digital tjenesteutvikling.
|
|
Du hjelper med a analysere og klassifisere innkommende henvendelser
|
|
relatert til forerkort, kjoretoysregistrering og veiprosjekter.
|
|
|
|
Folg disse retningslinjene:
|
|
1. Klassifiser henvendelsen i riktig kategori
|
|
2. Identifiser relevante lovhjemler
|
|
3. Foresla videre behandling
|
|
... (lang systemprompt over 1024 tokens)
|
|
"""
|
|
|
|
# Forste request: Ingen caching (cold start)
|
|
response1 = client.chat.completions.create(
|
|
model="gpt-4o",
|
|
messages=[
|
|
{"role": "system", "content": SYSTEM_PROMPT},
|
|
{"role": "user", "content": "Henvendelse 1..."}
|
|
]
|
|
)
|
|
# usage.prompt_tokens_details.cached_tokens = 0
|
|
|
|
# Etterfølgende requests: Caching aktiv (redusert latens)
|
|
response2 = client.chat.completions.create(
|
|
model="gpt-4o",
|
|
messages=[
|
|
{"role": "system", "content": SYSTEM_PROMPT}, # Identisk prefix
|
|
{"role": "user", "content": "Henvendelse 2..."}
|
|
]
|
|
)
|
|
# usage.prompt_tokens_details.cached_tokens = 1024+
|
|
```
|
|
|
|
**Viktige regler for prompt caching:**
|
|
- Minimum 1024 tokens i prompten
|
|
- De forste 1024 tokenene ma vaere identiske
|
|
- Etter forste 1024: cache hit for hver 128 identiske tokens
|
|
- Cache ryddes etter 5-10 minutter uten aktivitet, alltid innen 1 time
|
|
- Cacher deles IKKE mellom Azure-abonnementer
|
|
- Stottede modeller: GPT-4o, GPT-4o mini, o3-mini, GPT-4.1 og nyere
|
|
|
|
### Prompt-optimalisering for hastighet
|
|
|
|
| Teknikk | Beskrivelse | Latensreduksjon |
|
|
|---------|-------------|-----------------|
|
|
| Kompakt systemprompt | Fjern unodvendig tekst i systemprompt | 5-15% |
|
|
| Strukturerte input | JSON fremfor fritekst | 5-10% |
|
|
| Relevant kontekst | Kun relevante dokumenter i RAG | 10-30% |
|
|
| Token-effektive formater | Korte variabelnavn, kompakt format | 3-8% |
|
|
|
|
```python
|
|
# DARLIG: Verbose prompt
|
|
messages = [
|
|
{"role": "system", "content": """
|
|
Du er en hjelpesom assistent som jobber for norsk offentlig sektor.
|
|
Nar du far et sporsmal, skal du tenke noye gjennom det og gi et
|
|
grundig og gjennomtenkt svar som er presist og korrekt.
|
|
Husk a vaere hoeflig og profesjonell i all kommunikasjon.
|
|
"""},
|
|
{"role": "user", "content": f"Hele dokumentet pa 5000 ord: {document}\n\nSporsmal: Er dette en klage?"}
|
|
]
|
|
|
|
# BRA: Kompakt prompt med kun relevant kontekst
|
|
messages = [
|
|
{"role": "system", "content": "Klassifiser henvendelse. Svar: KLAGE eller IKKE_KLAGE"},
|
|
{"role": "user", "content": f"Sammendrag: {document_summary[:500]}\n\nKlassifiser:"}
|
|
]
|
|
```
|
|
|
|
### Content Filtering-optimalisering
|
|
|
|
Content filtering legger til latens men er kritisk for sikkerhet. For lavrisiko-bruksomrader kan man vurdere tilpassede filterpolicyer:
|
|
|
|
| Konfigurasjon | Latenspavirkning | Nar a bruke |
|
|
|--------------|-----------------|-------------|
|
|
| Standard filter (default) | +10-50 ms | Alle innbyggertjenester |
|
|
| Tilpasset filter (redusert) | +5-20 ms | Interne analyser, lav risiko |
|
|
| Asynkron filter | Minimal | Batch-prosessering |
|
|
|
|
**Merk:** I norsk offentlig sektor bor content filtering alltid vaere aktivert for innbyggerrettede tjenester. Vurder kun reduksjon for interne, kontrollerte miljoer.
|
|
|
|
## Provisioned Throughput Units (PTU) for forutsigbar latens
|
|
|
|
### Nar bruke PTU vs. Standard
|
|
|
|
PTU gir dedikert kapasitet og forutsigbar latens:
|
|
|
|
| Aspekt | Standard | PTU |
|
|
|--------|----------|-----|
|
|
| Latensgaranti | Ingen | Konsistent per-call latens |
|
|
| Throttling | 429 ved kvotegrense | 429 kun over 100% utnyttelse |
|
|
| Pris | Per token | Fast manedspris per PTU |
|
|
| Egnet for | Variabel last, utvikling | Produksjon, stabil last |
|
|
|
|
### PTU-kapasitetsplanlegging
|
|
|
|
Bruk Azure AI Foundry PTU-kalkulatoren:
|
|
|
|
1. Estimer input TPM (tokens per minutt) fra historiske data
|
|
2. Estimer output TPM fra historiske data
|
|
3. Beregn nodvendige PTUs via kalkulatoren
|
|
4. Legg til 20% buffer for trafikkvariasjon
|
|
|
|
```
|
|
PTU-utnyttelse = (PTUs forbrukt i perioden) / (PTUs deployet i perioden)
|
|
|
|
Mal: Hold utnyttelse under 80% for stabil latens
|
|
Over 100%: 429-feil returneres
|
|
```
|
|
|
|
### Hybrid PTU + Standard-arkitektur
|
|
|
|
```
|
|
Basislast (forutsigbar) --> PTU deployment (Sweden Central)
|
|
|
|
|
| (ved 429 / overflow)
|
|
v
|
|
Toppbelastning --> Standard deployment (North Europe, fallback)
|
|
```
|
|
|
|
## Overvaking og malinger
|
|
|
|
### Viktige Azure Monitor-metrikker
|
|
|
|
| Metrikk | Aggregering | Terskel |
|
|
|---------|-------------|---------|
|
|
| Azure OpenAI Requests | Count per minutt | Varsle ved >80% av kvote |
|
|
| Processed Inference Tokens | Sum per minutt | Spor mot TPM-grense |
|
|
| Provisioned-Managed Utilization V2 | Gjennomsnitt | Varsle ved >80% |
|
|
| Time to Response (streaming) | P95 | Varsle ved >2s TTFT |
|
|
| End-to-end Request Time | P95 | Varsle ved >5s |
|
|
|
|
### KQL-query for latensanalyse
|
|
|
|
```kusto
|
|
// Azure Monitor - Analyse av Azure OpenAI-latens
|
|
AzureDiagnostics
|
|
| where ResourceProvider == "MICROSOFT.COGNITIVESERVICES"
|
|
| where Category == "RequestResponse"
|
|
| extend latency_ms = DurationMs
|
|
| summarize
|
|
p50 = percentile(latency_ms, 50),
|
|
p95 = percentile(latency_ms, 95),
|
|
p99 = percentile(latency_ms, 99),
|
|
avg_latency = avg(latency_ms),
|
|
request_count = count()
|
|
by bin(TimeGenerated, 5m), ModelDeploymentName_s
|
|
| order by TimeGenerated desc
|
|
```
|
|
|
|
## Sjekkliste for latensoptimalisering
|
|
|
|
| Prioritet | Tiltak | Forventet effekt |
|
|
|-----------|--------|-----------------|
|
|
| 1 | Velg riktig modell for oppgaven | 30-70% reduksjon |
|
|
| 2 | Optimaliser max_tokens | 10-30% reduksjon |
|
|
| 3 | Aktiver streaming for brukerrettede tjenester | Redusert opplevd latens |
|
|
| 4 | Gjenbruk HTTP-forbindelser | 50-100 ms per request |
|
|
| 5 | Bruk naermeste Azure-region (Sweden Central) | 10-40 ms reduksjon |
|
|
| 6 | Implementer prompt caching | 10-30% reduksjon pa input |
|
|
| 7 | Separer arbeidslaster pa egne deployments | 10-20% reduksjon |
|
|
| 8 | Vurder PTU for stabile produksjonslaster | Forutsigbar latens |
|
|
|
|
## For Cosmo
|
|
|
|
- **Latens er sammensatt:** Optimaliser hele pipelinen, ikke bare modellvalget. Max tokens, connection reuse, regionvalg og prompt caching bidrar alle.
|
|
- **Sweden Central er forstevalg** for norske deployments med lavest latens (~10-20 ms) og EU-datasuverenitet. North Europe som failover.
|
|
- **PTU for produksjon:** Nar arbeidslaster er forutsigbare og latens er kritisk, gir PTU garantert kapasitet. Hybrid PTU + Standard er kostnadseffektiv arkitektur.
|
|
- **Prompt caching er gratis ytelse:** Strukturer prompts med identisk prefix (system prompt over 1024 tokens) for automatisk caching. Ingen konfigurasjon nodvendig.
|
|
- **Separasjon av arbeidslaster:** Aldri bland chatbot-trafikk med batch-prosessering pa samme deployment. Bruk dedikerte deployments per bruksomrade.
|