Kubernetes Distributed Serving with llm-d¶
This guide explains how to deploy Turing Engine in a Kubernetes cluster orchestrated by llm-d (CNCF Sandbox) for precise prefix-cache aware routing, P/D disaggregation, and high-density multi-pod inference.
🎯 Architecture Overview¶
graph TD
Client[Inference Client] -->|HTTP /v1/completions| Proxy[llm-d Envoy Proxy]
Proxy -->|ext_proc gRPC| EPP[Endpoint Policy Provider EPP]
subgraph Turing Pod Pool
Turing1[Turing Pod 1<br/>GPU 0]
Turing2[Turing Pod 2<br/>GPU 1]
end
Turing1 -->|ZMQ PUB 5556<br/>BlockStored / BlockRemoved| EPP
Turing2 -->|ZMQ PUB 5556<br/>BlockStored / BlockRemoved| EPP
EPP -->|Route to Pod with Matched Prefix| Proxy
Proxy -->|Forward Request| Turing1
How Prefix-Cache Aware Routing Works¶
- Real-Time KV Event Stream: Each Turing Engine pod runs a background
KVBlockEventPublisheremittingBlockStoredandBlockRemovedevents over ZeroMQ (port 5556) whenever prompt prefixes are inserted or evicted from theSpectralRadixSVDForest. - Deterministic Block Hashing: Block hashes are calculated using deterministic 64-bit hashing across sequence chunks, guaranteed across all replicas.
- EPP Cache Index: The llm-d
precise-prefix-cache-producerindexes active KV blocks per pod. When a new request arrives, llm-d routes it to the replica that already holds the maximum matching prefix tokens, skipping re-computation. - SVD-Compressed Wire Transfer: In distributed and disaggregated topologies, Turing Engine transfers KV cache blocks using Rank-64 Subspace INT8 projection via
SVDNetworkKVWireCodec, reducing network bandwidth by ~75%.
🚀 Deployment Guide¶
Prerequisites¶
- Kubernetes cluster v1.28+ with NVIDIA GPU nodes (e.g. Google Cloud GKE with NVIDIA L4 or A100 GPUs)
- Gateway API Inference Extension (GAIE) v1 CRDs installed:
- Helm 3.12+
Step 1: Install the llm-d Router¶
helm install llm-d-router oci://ghcr.io/llm-d/charts/llm-d-router-standalone \
--namespace llm-d-serving \
--create-namespace
Step 2: Deploy Turing Engine via Helm¶
Deploy Turing Engine with llmd.enabled=true:
helm install turing-llama deploy/helm/turing-serving/ \
--namespace llm-d-serving \
--set llmd.enabled=true \
--set llmd.guide=optimized-baseline \
--set llmd.engineType=turing \
--set model.name="meta-llama/Llama-3.1-70B-Instruct" \
--set model.device="cuda" \
--set replicaCount=2
Step 3: Register the InferencePool¶
Apply the InferencePool to bind the llm-d router to Turing Engine pods:
apiVersion: inference.networking.k8s.io/v1
kind: InferencePool
metadata:
name: turing-pool
namespace: llm-d-serving
spec:
selector:
matchLabels:
llm-d.ai/engine-type: "turing"
targetPorts:
- number: 8000
appProtocol: http
endpointPickerRef:
name: llm-d-router-epp
port:
number: 9002
failureMode: FailOpen
Apply the manifest:
📈 Monitoring & Telemetry¶
Turing Engine exports Prometheus metrics on GET /metrics matching llm-d EPP scorer requirements:
# HELP turing_num_requests_waiting Number of requests queued in waiting backlog (llm-d TotalQueuedRequests)
# TYPE turing_num_requests_waiting gauge
turing_num_requests_waiting 0
# HELP turing_num_requests_running Number of requests currently executing in batch (llm-d TotalRunningRequests)
# TYPE turing_num_requests_running gauge
turing_num_requests_running 1
# HELP turing_kv_cache_usage_perc Fraction of KV cache memory pool in use (llm-d KVCacheUtilization)
# TYPE turing_kv_cache_usage_perc gauge
turing_kv_cache_usage_perc 0.125
# HELP turing_cache_config_info KV cache configuration info (llm-d BlockSize and NumGPUBlocks)
# TYPE turing_cache_config_info gauge
turing_cache_config_info{block_size="64",num_gpu_blocks="1024"} 1.0
🔧 Token Render Endpoint for EPP¶
llm-d's token-producer data plugin calls /v1/completions/render or /v1/chat/completions/render to extract token IDs for exact prefix cache indexing:
curl -X POST http://localhost:8000/v1/completions/render \
-H "Content-Type: application/json" \
-d '{"prompt": "Hello world!"}'
Response: