Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Run:ai Model Streamer liest Modelltensoren gleichzeitig und streamt sie in den GPU-Speicher, wobei Speicherlesungen mit CPU-zu-GPU-Übertragungen überlappen. Diese Funktion kann die Ladezeit des Modells verkürzen und die Leerlaufzeit der GPU beim Start und Skalieren des Inferenzservers reduzieren. Nutzen Sie sie, um SafeTensors-Modelle aus Azure Blob Storage mit vLLM zu laden, da sie direktes Laden aus dem Objektspeicher unterstützt und sich in den Modell-Loader von vLLM integriert. Für die Upstream-Integration siehe Loading models with Run:ai Model Streamer.
Durch die Verwendung verteilter Beschleunigung für Cloud-Speicher (DACS) kann dieser Ladepfad auch Modelldaten wiederverwenden, die über Workloads hinweg zwischengespeichert sind. vLLM verwendet das Azure-Backend von Run:ai, um die native DACS-Client-Bibliothek zu laden. Reads rufen zwischengespeicherte Daten ab oder holen fehlende Daten aus Blob Storage.
Dieser Artikel verwendet Run:ai Model Streamer 0.17.0, das öffentliche dacs-client==0.1.0 Paket und den v0.1.0 Server-Build. Die Hauptprozedur installiert die Abhängigkeiten in deinem Workload-Image. Es erfordert kein separates DACS-Client-Image oder Unterstützung für Kubernetes ImageVolume.
Schließen Sie Erste Schritte mit dem verteilten Beschleuniger für Cloudspeicher auf AKS ab, bevor Sie diesen Artikel lesen. Um die DACS-Clientbibliotheken bereitzustellen, ohne Ihr Workload-Image neu zusammenzustellen, finden Sie weitere Informationen unter DACS-Clientbibliotheken mit ImageVolume einbinden.
Prerequisites
- Eine bestehende DACS-Bereitstellung und deren Discovery-Service-Hostname.
- Ein AKS-GPU-Node-Pool mit kompatiblen NVIDIA-Treibern, einem Geräte-Plugin und genügend GPU-Speicher für dein Modell. Das folgende Beispiel verwendet
bfloat16, was eine kompatible GPU erfordert. - Für die Authentifizierung der Arbeitslast-Identität ein AKS-Cluster mit aktiviertem OIDC-Aussteller und aktivierter Microsoft Entra Workload ID. Siehe OIDC-Aussteller und Microsoft Entra Workload ID in einem AKS-Cluster aktivieren.
- Ein kompatibles GPU-vLLM-Image und eine Linux-Umgebung mit glibc 2.35 oder neuer. Verwende dieselbe Python-Umgebung wie deine Anwendung.
- Ein privater Blob-Container für Modelldateien.
- Ein separater Uploader-Benutzer oder eine verwaltete Identität mit Storage Blob Data Contributor für den Modellcontainer.
- Eine Inferenzidentität mit Storage Blob Data Reader für den Modellcontainer. Konfigurieren Sie eine Methode für Blob-Authentifizierung konfigurieren.
- Erlaubnis, dein Workload-Image zu erstellen und zu pushen, und Erlaubnis, dass AKS es abrufen darf.
- Azure CLI, AzCopy v10 und die Hugging Face CLI werden auf deinem Vorbereitungsrechner benötigt, falls du ein Modell hochladen musst.
Für die Modellvorbereitung ist keine GPU erforderlich. Sie können auch die Paketinstallation, das Laden der nativen Bibliotheken und die Blob-Authentifizierung an CPU-Knoten mit einem kompatiblen Anwendungsimage überprüfen. Diese Prüfungen validieren weder GPU-Planung, Speichergröße noch Inferenz.
Laden Sie Modelldateien in Blob Storage hoch
Überspringen Sie diesen Abschnitt, wenn das komplette Modell bereits in Ihrem privaten Container ist. Für einen Cold-Cache-Test verwenden Sie ein Modellpräfix, das Sie nicht über DACS gelesen haben.
Verwenden Sie für dieses Verfahren die Uploader-Identität, nicht die Inferenz-Identität. Für Rollenzuweisungen auf Containerebene siehe Zuweisen einer Azure-Rolle für den Zugriff auf Blobdaten. Azure Control Plane Owner oder Contributor allein gewährt keinen Datenzugriff auf Blob über Microsoft Entra ID.
Laden Sie das Modell herunter
Das folgende Beispiel lädt die Inferencedateien für SmolLM2-135M-Instruct bei einer festen Revision herunter. Seine Modellkarte kennzeichnet die Lizenz als Apache-2.0. Installieren Sie die Hugging Face CLI und führen Sie dann aus:
MODEL_ID="HuggingFaceTB/SmolLM2-135M-Instruct"
MODEL_REVISION="12fd25f77366fa6b3b4b768ec3050bf629380bac"
MODEL_DIR="$PWD/models/SmolLM2-135M-Instruct-$MODEL_REVISION"
hf download "$MODEL_ID" \
config.json generation_config.json model.safetensors \
tokenizer.json tokenizer_config.json special_tokens_map.json \
vocab.json merges.txt README.md \
--revision "$MODEL_REVISION" \
--local-dir "$MODEL_DIR"
Verwenden Sie optional den hf cache verify Befehl einer aktuellen CLI, um die heruntergeladenen Dateien mit Hub-Prüfsummen zu überprüfen:
hf cache verify "$MODEL_ID" \
--revision "$MODEL_REVISION" \
--local-dir "$MODEL_DIR"
Da dieser Download nur Inferenzdateien auswählt, kann die Verifikation fehlende Repository-Dateien wie ungenutzte Modellvarianten melden. Es kann auch zusätzliche lokale Metadaten zu Hugging-Face-Downloads melden. Diese Meldungen sind keine Prüfsummenfehler. Untersuchen Sie unerwartete Dateien oder Prüfsummenabweichungen, bevor Sie sie hochladen.
Für ein weiteres Modell sollten alle SafeTensors-Shards sowie alle Gewichtungsindexe, Modell- und Generationskonfigurationen, Tokenizer-Dateien sowie zutreffende Lizenz- und Attributionsdateien aufgenommen werden. Bewahren Sie die erforderliche Verzeichnisstruktur bei. Stagen Sie keine nicht zugehörigen ONNX-Varianten, Trainingscheckpoints, Optimiererdateien oder Zugangsdaten.
Mit AzCopy hochladen
Installiere AzCopy v10. Melde dich über die Azure CLI als der Benutzer an, der den Upload ausführt, und kopiere dann den Inhalt des lokalen Verzeichnisses in ein neues Blobpräfix:
TENANT_ID="<tenant-id>"
STORAGE_ACCOUNT="<storage-account>"
CONTAINER="<container>"
RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)"
MODEL_PREFIX="models/SmolLM2-135M-Instruct-${MODEL_REVISION}-${RUN_ID}"
MODEL_URL="https://${STORAGE_ACCOUNT}.blob.core.windows.net/${CONTAINER}/${MODEL_PREFIX}"
az login --tenant "$TENANT_ID"
export AZCOPY_AUTO_LOGIN_TYPE=AZCLI
export AZCOPY_TENANT_ID="$TENANT_ID"
azcopy copy "$MODEL_DIR/*" "$MODEL_URL" \
--recursive=true \
--overwrite=false \
--exclude-path ".cache;.git"
azcopy list "$MODEL_URL"
Die in Anführungszeichen gesetzte Wildcard kopiert den Inhalt des Verzeichnisses direkt in das Präfix, ohne eine Ebene des lokalen Verzeichnisses hinzuzufügen. Die Ausschlüsse schließen Download- und Git-Metadaten aus. Fahren Sie nur fort, wenn AzCopy keine fehlgeschlagenen Übertragungen mehr meldet und das Ziel alle erforderlichen Dateien enthält. Weitere Informationen finden Sie unter Inhalte eines Verzeichnisses mit AzCopy hochladen und AzCopy mit der Azure CLI autorisieren.
Bei einem Uploader, der auf einer Azure-VM ausgeführt wird, können Sie AzCopy stattdessen mit einer verwalteten Identität autorisieren. Belasse den Container privat und entferne temporäre Uploader-Rollenzuweisungen nach Abschluss der Vorbereitungen. Geben Sie neuen Rollenzuweisungen Zeit, wirksam zu werden; umgehen Sie Autorisierungsfehler nicht, indem Sie Speicherschlüssel oder Clientgeheimnisse hinzufügen.
Dokumentieren Sie die Modellrevision und die Blob-Versionen oder ETags. Der Standort des Run:ai-Modells ist az://<container>/<model-prefix>. Lassen Sie diese Dateien bei Kalt- und Warmstarts unverändert. Für einen weiteren Kalttest verwenden Sie ein weiteres neues Präfix, anstatt Daten aus einem gemeinsamen Cache zu entfernen.
Bereite das Workload-Image ohne ImageVolume vor
Installiere Abhängigkeiten während der Erstellung deines Images, nicht beim Start des Pods. Behalten Sie Ihre bestehende Anwendung, Ihr Basisimage und Ihren Entrypoint. Verwenden Sie den Paketmanager der Anwendung sowie den Requirements-/Constraints-Workflow, um kompatible Abhängigkeiten wie Torch, CUDA und NumPy zu erhalten.
Verwende ein GPU-fähiges vLLM-Image mit Torch- und CUDA-Versionen, die mit deinen GPU-Nodes und NVIDIA-Treibern kompatibel sind. Überprüfen Sie die installierten Run:ai-Core- und Azure-Backend-Pakete des Images, bevor Sie Abhängigkeiten hinzufügen; nicht jedes vLLM-Image enthält das Azure-Backend.
Lösen Sie Abhängigkeitskonflikte in Ihrem Workload-Image vor der Bereitstellung. Der Schritt pip check im folgenden Abschnitt muss erfolgreich abgeschlossen werden. Nutzen Sie die Abhängigkeitsbeschränkungen Ihrer Anwendung, um die Kompatibilität mit anderen installierten Paketen zu erhalten.
Wenn dein Image noch keine kompatiblen Run:ai Core- und Azure-Backend-Pakete enthält, füge folgende Anweisung deiner Dockerfile hinzu:
RUN python3 -m pip install --no-cache-dir "runai-model-streamer[azure]==0.17.0"Installiere das öffentliche DACS-Clientpaket, das die nativen Client-Bibliotheken bereitstellt, in derselben Python-Umgebung:
RUN python3 -m pip install --no-cache-dir "dacs-client==0.1.0" && \ python3 -m pip checkRun:ai's Azure Extra installiert die DACS-Clientbibliotheken nicht. Wenn Ihre Anwendung bereits kompatible Run:ai-Pakete hat, wird nur die Installation des DACS-Client-Pakets benötigt.
Baue und pushe mit deiner bestehenden Dockerfile und dem Build-Kontext. Führe die folgenden Befehle in Bash auf deiner Vorbereitungsmaschine aus. Dieses Beispiel wird für x86-64-Knoten erstellt:
REGISTRY_NAME="<registry-name>" REGISTRY_SERVER="$(az acr show --name "$REGISTRY_NAME" --query loginServer --output tsv)" WORKLOAD_IMAGE="$REGISTRY_SERVER/workload-runai-dacs:0.17.0-0.1.0" az acr login --name "$REGISTRY_NAME" docker build --platform linux/amd64 -t "$WORKLOAD_IMAGE" . docker push "$WORKLOAD_IMAGE"In derselben Bash-Sitzung löst man den nativen Bibliothekspfad aus dem erstellten Image auf:
docker run --rm --entrypoint python3 "$WORKLOAD_IMAGE" \ -c 'from importlib.metadata import distribution; from pathlib import Path; p=Path(distribution("dacs-client").locate_file("py_dacs_client/libStorageDirect.so")).resolve(); assert p.is_file(), p; print(p)'Verwenden Sie den gedruckten absoluten Pfad bei der Konfiguration des Workloads. Behalte die komplette Client-Installation aufrecht, einschließlich der zugehörigen nativen Bibliotheken.
Bevorzugen Sie beim Bereitstellen einen unveränderlichen Image-Digest. Das Aktualisieren des eingebauten Clients erfordert den Neuaufbau und die erneute Bereitstellung des Workload-Images.
Blob-Authentifizierung konfigurieren
Verwenden Sie die Workload-Identität von AKS für die Blob-Authentifizierung. Das Bereitstellungsbeispiel verwendet diese Methode mit Storage Blob Data Reader, der auf den Modellcontainer abgegrenzt ist. Die Schreibberechtigung des Uploaders ist für die Inferenz nicht erforderlich. Für andere Authentifizierungsmethoden siehe Azure-Authentifizierung in der Run:ai Model Streamer-Dokumentation.
Verwenden Sie die AKS-Workload-Identität
Das Bereitstellungsbeispiel verwendet den runai-reader ServiceAccount im Namensraum runai-dacs . Führen Sie die folgenden Schritte aus, bevor Sie den Workload bereitstellen:
Aktivieren Sie den OIDC-Issuer und die Microsoft Entra Workload ID auf Ihrem bestehenden AKS-Cluster, falls diese noch nicht aktiviert sind.
Erstelle eine verwaltete Identität oder wähle eine bestehende Identität aus.
Wenn der Namensraum
runai-dacsnoch nicht existiert, erstelle ihn.kubectl create namespace runai-dacsErstellen Sie ein Kubernetes ServiceAccount, das mit der Client-ID dieser Identität annotiert ist.
Erstellen der föderierten Identitätsanmeldeinformationen für den genauen Namespace und ServiceAccount. Du musst die folgenden Key Vault-Schritte nicht abschließen.
Weisen Sie der verwalteten Identität, die mit Ihrer Anwendung ServiceAccount federiert ist, die Blob-Leserrolle zu. Für ein Beispiel für eine container-scoped Zuweisung siehe Grant Read Access to Model Data, wobei diese Identität anstelle der kubelet-Identität des Quickstarts verwendet wird.
Der Pod muss das ServiceAccount verwenden und das Label azure.workload.identity/use: "true" haben. AKS fügt die Identitätseinstellungen und das projizierte Token ein. Füge Clientgeheimnisse oder Speicherkontoschlüssel nicht manuell hinzu.
Konfigurieren Sie den Image-Pull-Zugriff separat
Für private ACR-Images konfigurieren Sie die Pull-Berechtigungen der Kubelet-Identität wie in Den Client zu einem Workload-Image hinzufügen beschrieben. Verwenden Sie AcrPull für klassisches RBAC. Für eine ABAC-fähige Registry verwenden Sie Container Registry Repository Reader mit entsprechendem Repository-Zugriff. Nutze --attach-acr nicht für diese Registrierung.
Blob-Read-Zugriff auf die Identität der Anwendung gewährt dem Kubelet keinen Image-Pull-Zugriff. Für ImageVolume muss der Pull-Zugriff sowohl die Arbeitslast als auch die Client-Images abdecken, einschließlich separater Registries oder Repositories, sofern zutreffend.
Konfigurieren und stellen Sie den Workload bereit
Legen Sie diese vier Applikationsvariablen fest, bevor Sie vLLM starten. Sie sind getrennt von den Identitätseinstellungen, die von Ihrer Authentifizierungsmethode bereitgestellt werden:
| Umgebungsvariable | Purpose |
|---|---|
AZURE_STORAGE_ACCOUNT_NAME |
Speicherkonto, das das Modell enthält. |
CACHE_DISCOVERY_URL |
DACS-Discovery-Hostname, wie zum Beispiel cache-sample-discovery.<namespace>.svc.cluster.local. |
CACHE_SERVER_PORT |
Cache-Port, typischerweise 9065. |
RUNAI_STREAMER_EXPERIMENTAL_AZURE_CACHE_LIB |
Der absolute Pfad der nativen Bibliothek wurde aus deinem Workload-Image ermittelt. |
Important
Cache-Entdeckung ist nicht optional. Ein Modell kann erfolgreich geladen werden, indem Blob Storage direkt gelesen wird, wenn der Cache nicht konfiguriert ist. Mit dem Run:ai-Azure-Backend 0.17.0, spezifizieren Sie auch explizit den nativen Bibliothekspfad, anstatt auf automatische Entdeckung zu setzen.
Verwenden Sie das Modell-URI-Format von Run:ai, az://<container>/<model-prefix>, wobei das Konto über AZURE_STORAGE_ACCOUNT_NAME bereitgestellt wird. Dieses URI-Format unterscheidet sich von der kanonischen URI des nativen Python-Clients, die den Konto-Hostnamen enthält.
Ersetzen Sie die Platzhalter im folgenden Beispiel und speichern Sie es als runai-dacs-pod.yaml. Verwenden Sie das Modellpräfix aus Ihrem Upload und den nativen Bibliothekspfad, der vom erstellten Image ausgegeben wird. Das Beispiel verwendet Workload-Identität und enthält kein ImageVolume oder Init-Container:
apiVersion: v1
kind: Pod
metadata:
name: runai-dacs-vllm
namespace: runai-dacs
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: runai-reader
restartPolicy: Never
nodeSelector:
agentpool: "<gpu-nodepool-name>"
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
containers:
- name: vllm
image: "<workload-image>"
command: ["vllm", "serve"]
args:
- "az://<container>/<model-prefix>"
- "--load-format"
- "runai_streamer"
- "--served-model-name"
- "cached-model"
- "--dtype"
- "bfloat16"
- "--max-model-len"
- "1024"
env:
- name: AZURE_STORAGE_ACCOUNT_NAME
value: "<storage-account>"
- name: CACHE_DISCOVERY_URL
value: "<cache-discovery-hostname>"
- name: CACHE_SERVER_PORT
value: "9065"
- name: RUNAI_STREAMER_EXPERIMENTAL_AZURE_CACHE_LIB
value: "<dacs-native-library-path>"
- name: RUNAI_STREAMER_CHUNK_BYTESIZE
value: "8388608"
- name: SI_streamingChunkSize
value: "8388608"
resources:
requests:
cpu: "4"
memory: 16Gi
limits:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
ports:
- containerPort: 8000
readinessProbe:
httpGet:
path: /health
port: 8000
periodSeconds: 10
timeoutSeconds: 5
volumeMounts:
- name: shm
mountPath: /dev/shm
volumes:
- name: shm
emptyDir:
medium: Memory
sizeLimit: 2Gi
Diese Ressourcen zeigen ein kleines Modell, kein 30B-Modell. Bewahren Sie die erforderliche Zeitplanung, Ressourcen, Probes, geteilten Speicher und andere vLLM-Argumente Ihrer Arbeitslast. Passe GPU-Anzahl, Tensorparallelität, Modelllänge und Speichergröße für dein Modell an. Für eine Deployment oder StatefulSet wenden Sie Pod-Labels unter spec.template.metadata und Pod-Einstellungen unter spec.template.spec.
Die erste Bereitstellung startet vLLM und lädt das Modell, bevor der Pod bereit ist. Für einen Cold-Cache-Vergleich führen Sie diese Schritte in der Reihenfolge durch:
Wählen Sie Modelldaten aus, die der Cache nicht gelesen hat, wie zum Beispiel das neue Präfix aus der Upload-Prozedur. Verdrängen Sie keine Daten aus einem gemeinsam genutzten Cache.
Vor der Bereitstellung des Anwendungs-Pods erfassen Sie einen Basis-Metrik-Snapshot von jedem Cache-Server-Pod, wie in Monitor distributed accelerator for cloud storage beschrieben. Zeichnen Sie den Zeitstempel sowie
cache_server_download_request_size_bytes_sum,cache_server_cache_size_bytesundcache_server_upload_request_size_bytes_sumjedes Servers auf.Stellen Sie den akzeptierten Pod bereit und inspizieren Sie ihn:
kubectl apply --dry-run=server -f runai-dacs-pod.yaml kubectl apply -f runai-dacs-pod.yaml kubectl -n runai-dacs get pod runai-dacs-vllm -o yaml kubectl -n runai-dacs wait --for=condition=Ready pod/runai-dacs-vllm --timeout=30m
Überprüfen Sie die Workload-Laufzeit
Führen Sie diese Prüfung im vLLM-Anwendungscontainer mit der Python-ausführbaren Datei der Anwendung aus. Es überprüft die Paketkonsistenz und das Laden der nativen Bibliotheken, nicht die Blob-Authentifizierung oder die Cache-Nutzung:
kubectl -n runai-dacs exec -i runai-dacs-vllm -c vllm -- python3 - <<'PY'
import ctypes
import os
import subprocess
import sys
from importlib.metadata import version
for package in (
"vllm",
"torch",
"runai-model-streamer",
"runai-model-streamer-azure",
):
print(f"{package}: {version(package)}", flush=True)
subprocess.run([sys.executable, "-m", "pip", "check"], check=True)
path = os.environ["RUNAI_STREAMER_EXPERIMENTAL_AZURE_CACHE_LIB"]
print(f"Checking DACS native library: {path}", flush=True)
library = ctypes.CDLL(path)
print(f"DACS native library loaded: {path}")
PY
Beheben Sie Fehler, bevor Sie fortfahren. Für die GPU-Bereitstellung sollten Sie außerdem die GPU-Sichtbarkeit und die vLLM-Engine-Logs überprüfen, um die CUDA-Ausführung und den vorgesehenen Modell-Dtyp zu bestätigen. Bereitschaft oder das erfolgreiche Laden einer Bibliothek allein beweisen weder die GPU-Ausführung noch die Nutzung des DACS-Caches.
Überprüfen Sie das Verhalten des kalten und warmen Caches
Verwenden Sie die vor der Bereitstellung erfasste Baseline aus Configure and deploy the workload. Der während der Bereitstellung durchgeführte Modellladevorgang ist der Kaltladevorgang.
Überprüfen Sie die Kaltlast
Überprüfen Sie das Anwendungsprotokoll:
kubectl -n runai-dacs logs runai-dacs-vllm -c vllm
Suchen Sie nach nativ ReadChunk stats.
RemoteClient zählt Reads des Backing-Store-Gewichts; RemoteCache zählt Remote-Cache-Reads. Einige Cache-Hits während des ersten Ladens sind normal, da frühere Reads Daten füllen können.
GetProperties Cache-Hits beschreiben Metadaten, keine Treffer auf Modellgewichte.
Senden Sie eine Schlussanfrage:
kubectl -n runai-dacs exec -i runai-dacs-vllm -c vllm -- python3 - <<'PY'
import json
import urllib.request
body = json.dumps({
"model": "cached-model",
"prompt": "Once upon a time",
"max_tokens": 16,
"temperature": 0,
}).encode()
request = urllib.request.Request(
"http://127.0.0.1:8000/v1/completions", data=body,
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(request, timeout=600) as response:
result = json.load(response)
print(json.dumps(result, indent=2))
assert result["choices"][0]["text"].strip()
assert result["usage"]["completion_tokens"] > 0
PY
Bestätigen Sie nicht-null Cold Backing-Store-Lesungen. Lassen Sie den Anwendungspod laufen, während Sie die asynchrone Cache-Population überprüfen:
- Erfassen Sie alle 10 Sekunden
cache_server_upload_request_size_bytes_sumundcache_server_cache_size_bytesMesswerte von jedem Cache-Server-Pod für die ausgewählte Cache-Ressource, bis zu fünf Minuten lang. Verwenden Sie das Verfahren zum Endpunkt der Metriks. Verwenden Sie frische Proben, nicht wiederholte Kopien eines gespeicherten Scrapes. - Vergleichen Sie die Proben mit der Baseline vor der Bereitstellung. Es ist eine Erhöhung der insgesamt hochgeladenen Bytes und der Gesamtzahl der zwischengespeicherten Bytes auf diesen Servern erforderlich. Verlange nicht, dass jeder Server Daten empfängt.
- Warten Sie, bis der Upload-Byte-Zähler jedes Servers drei aufeinanderfolgende Sampling-Intervalle unverändert bleibt, nachdem der Gesamtupload gestiegen ist. Bestätigen Sie, dass kein Server neu gestartet und kein Zähler während des Vergleichs zurückgesetzt wurde.
- Speichere diese letzte Probe als Post-Cold-Snapshot, einschließlich
cache_server_download_request_size_bytes_sumvon jedem Server als Basislinie für die warme Last.
Wenn diese Bedingungen nicht innerhalb von fünf Minuten erfüllt sind, stoppen Sie den Vergleich, anstatt den Cache als warm zu behandeln. Überprüfe die Upload-Fehler des Clients, die Gesundheit des Cache-Servers und den laufenden Datenverkehr, bevor du es erneut versuchst. Größere Modelle benötigen möglicherweise ein längeres Beobachtungsfenster. Eine fehlende Metrik oder ein fehlgeschlagener Scraping ist kein Nullwert oder ein Beweis dafür, dass die Uploads abgeschlossen sind.
Stabile Zähler sind ein Bereitschaftssignal, nicht der Beweis, dass jeder Modellchunk zwischengespeichert ist. Shared-Cache-Verkehr kann ebenfalls eine Stabilisierung verhindern oder für Erhöhungen verantwortlich sein. Verwenden Sie möglichst ein ruhiges Validierungsfenster und schreiben Sie die untenstehenden fresh-Pod-Warm-Read-Prüfungen vor, um die Wiederverwendung des verteilten Caches zu bestätigen.
Überprüfen Sie einen Warmstart in einem frischen Pod
Speichere das Cold Log und die Pod-UID. Erstellen Sie nur den Anwendungspod mit denselben Modelldateien, Cache-Endpunkt, Bibliothek und Chunk-Größe erneut:
kubectl -n runai-dacs logs runai-dacs-vllm -c vllm > runai-cold.log
kubectl -n runai-dacs get pod runai-dacs-vllm -o jsonpath='{.metadata.uid}' > runai-cold.uid
kubectl -n runai-dacs delete pod runai-dacs-vllm --wait=true
kubectl apply -f runai-dacs-pod.yaml
kubectl -n runai-dacs wait --for=condition=Ready pod/runai-dacs-vllm --timeout=30m
kubectl -n runai-dacs get pod runai-dacs-vllm -o jsonpath='{.metadata.uid}' > runai-warm.uid
kubectl -n runai-dacs logs runai-dacs-vllm -c vllm > runai-warm.log
Führen Sie die Laufzeitprüfung und die Inferenzanfrage erneut aus. Anschließend erfassen Sie von jedem Cache-Server eine Metrikaufnahme nach dem Aufwärmen. Unterschiedliche Pod-UIDs, eine erhöhte Trefferrate des Remote-Source-Caches und weniger Backing-Store-Reads. Vergleichen Sie cache_server_download_request_size_bytes_sum mit dem Snapshot nach dem Kaltstart, um warme Cache-Lesungen zu verifizieren. Ein frischer Prozess vermeidet es, einen lokalen In-Memory-Prefetch mit einem verteilten Cache-Hit zu verwechseln.
Die Trefferrate der entfernten Quelle ist RemoteCache / (RemoteCache + RemoteClient), ohne lokale Prefetch. Verwenden Sie den neuesten kumulativen Snapshot für jeden nativen Prozess, jeden Mount und jede Chunk-Größe; summieren Sie keine periodischen Proben. Messungen, die durch Cache-Server-Neustarts oder Counter-Resets betroffen sind, werden ausgeschlossen. Shared-Server-Zähler bestätigen Anwendungsprotokolle, ordnen aber nicht den gesamten Datenverkehr einer einzigen Arbeitslast zu.
Metadaten können weiterhin auf Blob Storage zugreifen, selbst wenn Warm-Weight-Read-Zähler 0 Backing-Store-Lesungen anzeigen.
DACS-Client-Bibliotheken mit ImageVolume einbinden
Nutze diese Alternative nur, wenn die Node-Laufzeit ImageVolume unterstützt und du ein pullbares Client-Image hast, das aus dem öffentlichen DACS-Wheel erstellt wurde. Gehen Sie nicht davon aus, dass ein vorgeschlagenes MCR-Bild oder -Tag veröffentlicht wird. Wenn kein geeignetes Client-Image verfügbar ist, verwenden Sie das Workload-Image-Verfahren im vorherigen Abschnitt.
Ihr GPU-vLLM-Image muss bereits kompatible Run:ai-Core- und Azure-Pakete enthalten. Du musst das DACS-Clientpaket nicht in dessen Python-Umgebung installieren, da das Bildvolumen die nativen Client-Bibliotheken liefert.
Adaptiere das Pod-Beispiel wie folgt:
Behalte dein bestehendes, kompatibles vLLM-Image statt es neu zu bauen, um die DACS-Client-Bibliotheken zu installieren.
Fügen Sie ein schreibgeschütztes Client-Bildvolumen hinzu und hängen Sie es ein:
# Add to spec.volumes. - name: dacs-client image: reference: "<accessible-client-image>" pullPolicy: IfNotPresent # Add to the vLLM container's volumeMounts. - name: dacs-client mountPath: /opt/cache-client readOnly: trueSetze
RUNAI_STREAMER_EXPERIMENTAL_AZURE_CACHE_LIBauf den absoluten Pfad vonlibStorageDirect.sounter/opt/cache-client, basierend auf dem tatsächlichen Layout dieses Bildes. Bewahre die nativen Abhängigkeiten gleichgeordneter Komponenten.Stellen Sie bereit und bestätigen Sie, dass das Image-Volume und die schreibgeschützte Mount-Einbindung in der Pod-Spezifikation live erhalten bleiben. Überprüfen Sie, ob die Datei existiert, führen Sie dann dieselben Prüfungen der Laufzeit für Application-Container sowie Kalt-/Warm-Prüfungen durch.
Einige ältere Cluster können nicht unterstützte image-volume-Felder und -mounts aus dem akzeptierten Pod entfernen. Die Kubernetes-Version und der Server-Dry-Run allein reichen nicht aus. Installieren Sie keine widersprüchliche Version der DACS-Client-Bibliotheken und laden Sie keine solche Version zusammen mit dem gemounteten Client vor; ein absoluter Bibliothekspfad isoliert den Namespace nativer Abhängigkeiten nicht.
Leseleistung optimieren
Warum die Chunk-Größe anpassen? Modelle haben unterschiedliche Tensorgrößen und Lesemuster, sodass eine Chunk-Größe möglicherweise nicht für jedes Modell die beste Modellladeleistung liefert. Übergroße Chunks laden mehr Daten ab, als ein Lesen benötigt, und erhöhen das Puffern. Unterdimensionierte Stücke erhöhen die Anzahl der Anfragen und den Overhead pro Anfrage. Die Wahl einer Größe, die zu den häufig auftretenden Tensoren des Modells passt, gleicht diese Kosten aus, verbessert den effektiven Gewichtsdurchsatz und reduziert die Ladezeit des Modells, einschließlich warmer Lasten von DACs. Betrachten Sie die folgenden Empfehlungen als Ausgangspunkte und messen Sie die kalten und warmen Ladezeiten getrennt. Gewinne hängen vom Modell, der Nebenwahl des Loaders sowie der Speicher- und Netzwerkleistung ab.
Wählen Sie eine Chunk-Größe anhand folgender modellspezifischer Empfehlungen. Für andere Modelle inspizieren Sie die Tensor-Metadaten, wie im nächsten Abschnitt beschrieben, oder verwenden Sie 32 MiB , falls Metadaten-Inspektion nicht verfügbar ist.
| Model | Empfohlene Stückgröße | Wert in Bytes |
|---|---|---|
qwen3-coder-30b-a3b-instruct |
3 MiB | 3145728 |
gpt-oss-20b |
2 MiB | 2097152 |
deepseek-r1-0528 |
14 MiB | 14680064 |
deepseek-v3-0324 |
14 MiB | 14680064 |
phi-2 |
2 MiB | 2097152 |
mistral-small-4-119b-2603-nvfp4 |
2 MiB | 2097152 |
ministral-3-3b-instruct-2512 |
2 MiB | 2097152 |
ministral-3-3b-instruct (alias) |
2 MiB | 2097152 |
ministral-3-8b-instruct-2512 |
2 MiB | 2097152 |
ministral-3-8b-instruct (Alias) |
2 MiB | 2097152 |
ministral-3-14b-instruct-2512 |
2 MiB | 2097152 |
ministral-3-14b-instruct (Alias) |
2 MiB | 2097152 |
| Ausweichlösung, wenn Metadaten-Inspektion nicht verfügbar ist | 32 MiB | 33554432 |
Wählen Sie eine Chunk-Größe für ein anderes Modell
Verwenden Sie einen Safetensors-Metadaten-Viewer oder ein Header-Inspektionstool, um alle Model-Shards zu inspizieren, ohne Tensorinhalte zu laden:
- Finde die gespeicherte Größe jedes Tensors in Bytes: seinen Enddatenoffset minus den Startoffset. Den Eintrag
__metadata__ausschließen. - Behandle jede Größe über 32 MiB als 32 MiB , bevor du die Vorkommnisse zähle.
- Wählen Sie die über alle Shards hinweg am häufigsten vorkommende Größe aus. Wenn mehrere Größen gleich häufig vorkommen, wähle die größere.
- Wenn die gewählte Größe unter 2 MiB liegt, verwenden Sie 2 MiB.
Wenn beispielsweise 3-MiB-Tensoren am häufigsten nach dem Capping auftreten, verwenden Sie 3 MiB (3145728 bytes). Wenn die Metadaten-Inspektion nicht verfügbar ist, verwenden Sie 32 MiB (33554432 Byte).
Konfigurieren der Anwendung
Setzen Sie sowohl RUNAI_STREAMER_CHUNK_BYTESIZE als auch SI_streamingChunkSize auf den resultierenden Byte-Wert in der Umgebung des Anwendungscontainers. Zum Beispiel für eine 3-MiB-Empfehlung:
env:
- name: RUNAI_STREAMER_CHUNK_BYTESIZE
value: "3145728"
- name: SI_streamingChunkSize
value: "3145728"
Legen Sie diese Werte explizit fest; die Tabelle beschreibt Empfehlungen, nicht automatische Modellerkennung oder eingebaute Standardeinstellungen. Erstelle den Anwendungs-Pod nach den Änderungen neu; Cache-Server müssen nicht neu gestartet werden. Leser und Population-Jobs, die zwischengespeicherte Daten teilen, sollten die gleiche Chunk-Größe verwenden.
Die Lesegröße von Run:ai und die native Cache-Chunk-Größe sind separate Steuerungen, die oben zusammen konfiguriert sind. Teste die Empfehlung anhand deiner Arbeitslast und passe die Parallelität des Loaders separat an. Vergleiche kalte und warme Ladevorgänge unabhängig voneinander. Die Änderung der Cache-Chunk-Größe erzeugt verschiedene Cache-Schlüssel und kann die Cache-Belegung vorübergehend erhöhen. Ändern Sie jeweils eine Einstellung und messen Sie die Ladezeit, native Zähler, Cache-Metriken, CPU-, GPU- und Hostspeicher sowie die Netzwerknutzung. Die Tensorausrichtung allein garantiert keine bessere Leistung.
Warning
Das asynchrone Upload-Buffer-Budget des öffentlichen nativen Clients beträgt in 0.1.0 standardmäßig 400 GiB. Es handelt sich nicht um eine Vorallokation oder ein sicheres Pod-Speicherlimit. Eine Kältepopulation mit großem Modell kann einen kleineren Pod erschöpfen. Für speicherbeschränkte Arbeitslasten testen Sie synchrone Population (SI_cacheEnableSyncUpload=true) oder ein begrenztes asynchrones Upload-Budget (SI_cacheMaxUploadBufferSizePerProcessGB). Budgetmodell-Staging, native Upload-/Prefetch-Puffer, GPU-Speicher und /dev/shm separat. Diese Schutzmaßnahmen sind optionale, workloadspezifische Einstellungen, nicht zusätzliche Anforderungen für das Beispiel eines kleinen Modells.
Troubleshoot
| Symptom | Prüfen |
|---|---|
| Fehler beim Abrufen eines Images | Kubelet-Berechtigungen zum Pullen, Registry-Berechtigungsmodus, Image-Digest und Netzwerkzugriff. |
| Die Native-Bibliothek wird nicht geladen | Python-Umgebung der Anwendung, expliziter Pfad, glibc-Kompatibilität und benachbarte native Bibliotheken. |
| Blob-Autorisierung schlägt fehl | Ausgewählte Identität, Reader-Rolle, Rollenweitergabe, Föderation und Pod-Label. Für andere Authentifizierungsmethoden folgen Sie der oben verlinkten ursprünglichen Azure-Authentifizierungsanleitung. |
| Das Modell wird ohne Cache-Datenverkehr geladen | Sowohl Erkennungseinstellungen, das Laden von Providern, DNS-/Netzwerkerreichbarkeit als auch native Zähler für gelesene Daten. |
| Warmstarts lesen weiterhin Blob-Daten | Vervollständigung der Population, Blob-Versionen, übereinstimmende Chunk-Größen, Verdrängungen und partielle Lesevorgänge. |
| ImageVolume fehlt | Live-Pod-Felder und Node-/Laufzeitunterstützung; verwenden Sie die integrierte Methode, falls diese Unterstützung nicht verfügbar ist. |
| Pod wird OOM getötet | Modell- und Staging-Speicher, native Puffer, Dimensionierung des GPU-/KV-Caches und /dev/shm. |
Für einen separaten direkten Blobvergleich setzen Sie RUNAI_STREAMER_EXPERIMENTAL_AZURE_CACHE_ENABLED=0 und erstellen Sie einen Test-Pod neu. Wenn man es stattdessen auf 1 setzt, führen Fehler beim Laden des Providers dazu, dass der Start fehlschlägt, anstatt stillschweigend darauf zurückzufallen. Keine der beiden Einstellungen belegt Cache-Hits; prüfen Sie die Datenlesezähler.
Beispiel bereinigen
Wenn du den eigenständigen Beispiel-Pod erstellt hast, lösche ihn, wenn du fertig bist:
kubectl -n runai-dacs delete pod runai-dacs-vllm --wait=true
Entferne nur Modellpräfixe, Abbilder, Identitäten, Föderationen, Namensräume und Rollenzuweisungen, die du für dieses Beispiel erstellt hast und nicht mehr benötigst. Löschen Sie keinen bestehenden freigegebenen Cache oder eine vorhandene Identität. Gespeicherte Modelldaten sind jetzt warm; verwenden Sie ein frisches Präfix für eine weitere Cold-Cache-Validierung.