Load balancing tradisional mendistribusikan permintaan secara merata di seluruh backend, tetapi beban kerja inferensi LLM pada dasarnya tidak merata. Prompt pendek mungkin selesai dalam milidetik, sementara penyelesaian panjang dapat membebani GPU selama beberapa detik. Service Mesh (ASM) mengatasi hal ini dengan mengarahkan permintaan berdasarkan status real-time setiap backend vLLM: kedalaman antrian permintaan dan pemanfaatan cache KV. Hasilnya adalah waktu hingga token pertama (TTFT) lebih rendah, throughput lebih tinggi, serta pemanfaatan GPU yang seimbang di seluruh armada inferensi Anda.
Topik ini memandu Anda melalui penerapan layanan inferensi Llama 2 berbasis vLLM, konfigurasi routing yang sadar LLM melalui ASM, dan penyiapan dasbor observabilitas untuk memantau traffic inferensi.
Saat ini, hanya layanan inferensi LLM berbasis vLLM yang didukung.
Latar Belakang
Large language models (LLMs)
Large language models (LLMs) adalah model bahasa berbasis jaringan saraf dengan miliaran parameter, diwakili oleh GPT, Qwen, dan Llama. Model-model ini dilatih pada dataset yang beragam dan luas—termasuk teks web, literatur profesional, dan kode—dan terutama digunakan untuk tugas generasi teks seperti pelengkapan dan dialog.
Untuk memanfaatkan LLM dalam membangun aplikasi, Anda dapat:
Menggunakan layanan API LLM eksternal dari platform seperti OpenAI, Alibaba Cloud Model Studio, atau Moonshot.
Membangun layanan inferensi LLM sendiri menggunakan model dan framework open-source atau proprietary seperti vLLM, lalu menerapkannya di kluster Kubernetes. Pendekatan ini cocok untuk skenario yang memerlukan kendali atas layanan inferensi atau kustomisasi tingkat tinggi terhadap kemampuan inferensi LLM.
vLLM
vLLM adalah framework yang dirancang untuk membangun layanan inferensi LLM secara efisien dan mudah digunakan. Framework ini mendukung berbagai model bahasa besar, termasuk Qwen, serta mengoptimalkan efisiensi inferensi melalui teknik seperti PagedAttention, inferensi batch dinamis (Continuous Batching), dan kuantisasi model.
Cara kerja load balancing yang sadar LLM
Mengapa load balancing tradisional kurang optimal untuk inferensi LLM
Algoritma klasik seperti round-robin dan least-connections mengasumsikan setiap permintaan memberikan beban serupa. Inferensi LLM melanggar asumsi ini:
Waktu pemrosesan bervariasi. Setiap permintaan melewati dua fase—prefill (encoding prompt) dan decode (menghasilkan token satu per satu). Panjang fase decode tidak dapat diprediksi karena jumlah token output bervariasi per permintaan.
Kontensi memori GPU. vLLM mengalokasikan memori GPU terlebih dahulu untuk cache KV. Saat cache terisi, server mengantrikan permintaan baru atau menukarnya ke memori CPU, yang secara drastis meningkatkan latensi.
Tanpa mempertimbangkan faktor-faktor ini, permintaan menumpuk di beberapa backend sementara yang lain menganggur—meningkatkan tail latency dan membuang sumber daya GPU.
Cara ASM mengarahkan traffic LLM
ASM mengevaluasi metrik multidimensi dari setiap backend vLLM untuk membuat keputusan routing:
| Metric | Source | Routing signal |
|---|---|---|
| Kedalaman antrian permintaan | vllm:num_requests_waiting | Lebih sedikit permintaan dalam antrian menunjukkan pemrosesan lebih cepat |
| Pemanfaatan cache KV | vllm:gpu_cache_usage_perc | Pemanfaatan lebih rendah berarti lebih banyak memori GPU tersedia untuk permintaan baru |
Saat permintaan baru tiba, ASM memilih backend dengan kombinasi sinyal terbaik. Hal ini menjaga beban GPU seimbang di seluruh replika inferensi, mengurangi TTFT, dan meningkatkan throughput keseluruhan dibandingkan algoritma tradisional.
Observabilitas traffic LLM
Proxy standar mengurai Header HTTP dan path URL tetapi mengabaikan badan permintaan. Karena API inferensi LLM (format kompatibel OpenAI) membawa nama model dan parameter token dalam badan permintaan, observabilitas tradisional melewatkan dimensi penting.
ASM memperluas observabilitas untuk traffic inferensi LLM:
Log akses mencakup nama model dan jumlah token input/output per permintaan.
Metrik pemantauan menambahkan dimensi
modeluntuk analisis per model.Metrik token (
asm_llm_proxy_prompt_tokens,asm_llm_proxy_completion_tokens) melacak konsumsi token di seluruh beban kerja.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Kluster Container Service for Kubernetes (ACK) yang dikelola dengan kelompok node GPU, atau kluster Container Compute Service (ACS) di zona yang direkomendasikan untuk daya komputasi GPU
Untuk kluster ACK, lihat Buat kluster ACK yang dikelola
Untuk kluster ACS, lihat Buat kluster ACS
(Opsional) Untuk menggunakan daya komputasi GPU ACS dalam kluster ACK, instal komponen ACK Virtual Node. Lihat Daya komputasi GPU ACS dalam ACK
Instans ASM versi 1.24 atau lebih baru dengan kluster Anda ditambahkan. Lihat Tambahkan kluster ke instans ASM
Gerbang masuk dengan layanan HTTP diaktifkan pada Port 8080. Lihat Buat gerbang masuk
(Opsional) Injeksi sidecar diaktifkan di namespace
default, hanya diperlukan untuk observabilitas. Lihat Aktifkan injeksi proxy sidecar otomatis
Langkah 1: Terapkan layanan inferensi vLLM contoh
Terapkan model Llama 2 yang disajikan oleh vLLM dengan beberapa adapter LoRA. Penerapan mencakup Service Kubernetes, ConfigMap untuk templat chat, dan Deployment dengan 3 replika berbasis GPU.
Gambar kontainer memerlukan GPU dengan memori video lebih dari 16 GiB. Gunakan tipe GPU A10 untuk kluster ACK atau GPU B generasi ke-8 untuk kluster ACS. T4 (16 GiB) tidak menyediakan memori yang cukup. Untuk detail model, kirim tiket.
Gambar LLM berukuran besar. Simpan terlebih dahulu di Alibaba Cloud Container Registry (ACR) dan tarik melalui jaringan internal untuk menghindari unduhan lambat melalui titik akhir publik.
Buat file bernama
vllm-service.yamldengan konten berikut.Kluster ACK
apiVersion: v1 kind: Service metadata: name: vllm-llama2-7b-pool spec: selector: app: vllm-llama2-7b-pool ports: - protocol: TCP port: 8000 targetPort: 8000 type: ClusterIP --- apiVersion: v1 kind: ConfigMap metadata: name: chat-template data: llama-2-chat.jinja: | {% if messages[0]['role'] == 'system' %} {% set system_message = '<<SYS>>\n' + messages[0]['content'] | trim + '\n<</SYS>>\n\n' %} {% set messages = messages[1:] %} {% else %} {% set system_message = '' %} {% endif %} {% for message in messages %} {% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %} {{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }} {% endif %} {% if loop.index0 == 0 %} {% set content = system_message + message['content'] %} {% else %} {% set content = message['content'] %} {% endif %} {% if message['role'] == 'user' %} {{ bos_token + '[INST] ' + content | trim + ' [/INST]' }} {% elif message['role'] == 'assistant' %} {{ ' ' + content | trim + ' ' + eos_token }} {% endif %} {% endfor %} --- apiVersion: apps/v1 kind: Deployment metadata: name: vllm-llama2-7b-pool namespace: default spec: replicas: 3 selector: matchLabels: app: vllm-llama2-7b-pool template: metadata: annotations: prometheus.io/path: /metrics prometheus.io/port: '8000' prometheus.io/scrape: 'true' labels: app: vllm-llama2-7b-pool spec: containers: - name: lora image: "registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/llama2-with-lora:v0.2" imagePullPolicy: IfNotPresent command: ["python3", "-m", "vllm.entrypoints.openai.api_server"] args: - "--model" - "/model/llama2" - "--tensor-parallel-size" - "1" - "--port" - "8000" - '--gpu_memory_utilization' - '0.8' - "--enable-lora" - "--max-loras" - "4" - "--max-cpu-loras" - "12" - "--lora-modules" - 'sql-lora=/adapters/yard1/llama-2-7b-sql-lora-test_0' - 'sql-lora-1=/adapters/yard1/llama-2-7b-sql-lora-test_1' - 'sql-lora-2=/adapters/yard1/llama-2-7b-sql-lora-test_2' - 'sql-lora-3=/adapters/yard1/llama-2-7b-sql-lora-test_3' - 'sql-lora-4=/adapters/yard1/llama-2-7b-sql-lora-test_4' - 'tweet-summary=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_0' - 'tweet-summary-1=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_1' - 'tweet-summary-2=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_2' - 'tweet-summary-3=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_3' - 'tweet-summary-4=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_4' - '--chat-template' - '/etc/vllm/llama-2-chat.jinja' env: - name: PORT value: "8000" ports: - containerPort: 8000 name: http protocol: TCP livenessProbe: failureThreshold: 2400 httpGet: path: /health port: http scheme: HTTP initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 readinessProbe: failureThreshold: 6000 httpGet: path: /health port: http scheme: HTTP initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: limits: nvidia.com/gpu: 1 requests: nvidia.com/gpu: 1 volumeMounts: - mountPath: /data name: data - mountPath: /dev/shm name: shm - mountPath: /etc/vllm name: chat-template restartPolicy: Always schedulerName: default-scheduler terminationGracePeriodSeconds: 30 volumes: - name: data emptyDir: {} - name: shm emptyDir: medium: Memory - name: chat-template configMap: name: chat-templateKluster ACS
apiVersion: v1 kind: Service metadata: name: vllm-llama2-7b-pool spec: selector: app: vllm-llama2-7b-pool ports: - protocol: TCP port: 8000 targetPort: 8000 type: ClusterIP --- apiVersion: v1 kind: ConfigMap metadata: name: chat-template data: llama-2-chat.jinja: | {% if messages[0]['role'] == 'system' %} {% set system_message = '<<SYS>>\n' + messages[0]['content'] | trim + '\n<</SYS>>\n\n' %} {% set messages = messages[1:] %} {% else %} {% set system_message = '' %} {% endif %} {% for message in messages %} {% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %} {{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }} {% endif %} {% if loop.index0 == 0 %} {% set content = system_message + message['content'] %} {% else %} {% set content = message['content'] %} {% endif %} {% if message['role'] == 'user' %} {{ bos_token + '[INST] ' + content | trim + ' [/INST]' }} {% elif message['role'] == 'assistant' %} {{ ' ' + content | trim + ' ' + eos_token }} {% endif %} {% endfor %} --- apiVersion: apps/v1 kind: Deployment metadata: name: vllm-llama2-7b-pool namespace: default spec: replicas: 3 selector: matchLabels: app: vllm-llama2-7b-pool template: metadata: annotations: prometheus.io/path: /metrics prometheus.io/port: '8000' prometheus.io/scrape: 'true' labels: app: vllm-llama2-7b-pool alibabacloud.com/compute-class: gpu # Tentukan daya komputasi GPU alibabacloud.com/compute-qos: default alibabacloud.com/gpu-model-series: "example-model" # Ganti dengan seri model GPU Anda spec: containers: - name: lora image: "registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/llama2-with-lora:v0.2" imagePullPolicy: IfNotPresent command: ["python3", "-m", "vllm.entrypoints.openai.api_server"] args: - "--model" - "/model/llama2" - "--tensor-parallel-size" - "1" - "--port" - "8000" - '--gpu_memory_utilization' - '0.8' - "--enable-lora" - "--max-loras" - "4" - "--max-cpu-loras" - "12" - "--lora-modules" - 'sql-lora=/adapters/yard1/llama-2-7b-sql-lora-test_0' - 'sql-lora-1=/adapters/yard1/llama-2-7b-sql-lora-test_1' - 'sql-lora-2=/adapters/yard1/llama-2-7b-sql-lora-test_2' - 'sql-lora-3=/adapters/yard1/llama-2-7b-sql-lora-test_3' - 'sql-lora-4=/adapters/yard1/llama-2-7b-sql-lora-test_4' - 'tweet-summary=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_0' - 'tweet-summary-1=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_1' - 'tweet-summary-2=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_2' - 'tweet-summary-3=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_3' - 'tweet-summary-4=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_4' - '--chat-template' - '/etc/vllm/llama-2-chat.jinja' env: - name: PORT value: "8000" ports: - containerPort: 8000 name: http protocol: TCP livenessProbe: failureThreshold: 2400 httpGet: path: /health port: http scheme: HTTP initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 readinessProbe: failureThreshold: 6000 httpGet: path: /health port: http scheme: HTTP initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: limits: cpu: 16 memory: 64Gi nvidia.com/gpu: 1 requests: cpu: 8 memory: 30Gi nvidia.com/gpu: 1 volumeMounts: - mountPath: /data name: data - mountPath: /dev/shm name: shm - mountPath: /etc/vllm name: chat-template restartPolicy: Always schedulerName: default-scheduler terminationGracePeriodSeconds: 30 volumes: - name: data emptyDir: {} - name: shm emptyDir: medium: Memory - name: chat-template configMap: name: chat-templateTerapkan layanan inferensi.
kubectl apply -f vllm-service.yamlTunggu hingga ketiga replika siap. Gambar LLM berukuran besar, sehingga pengambilan awal mungkin memakan waktu beberapa menit. Ketiga Pod harus mencapai status
Runningdengan kontainer siap1/1sebelum melanjutkan.kubectl get pods -l app=vllm-llama2-7b-pool -w
Langkah 2: Konfigurasikan aturan gateway ASM
Buat resource Gateway untuk mengaktifkan traffic HTTP pada Port 8080 gerbang masuk ASM.
Buat file bernama
gateway.yamldengan konten berikut.apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: llm-inference-gateway namespace: default spec: selector: istio: ingressgateway servers: - hosts: - '*' port: name: http-service number: 8080 protocol: HTTPTerapkan sumber daya Gateway.
kubectl apply -f gateway.yaml
Langkah 3: Konfigurasikan routing dan load balancing untuk layanan inferensi LLM
Untuk membandingkan load balancing yang sadar LLM dengan load balancing tradisional, selesaikan langkah-langkah di (Opsional) Bandingkan dengan load balancing tradisional sebelum melanjutkan.
Langkah ini membuat tiga resource yang menghubungkan gateway ASM ke backend vLLM dengan routing yang sadar LLM:
| Resource | Purpose |
|---|---|
| InferencePool | Mengelompokkan Pod vLLM berdasarkan pemilih label dan menentukan port inferensi |
| InferenceModel | Memetakan nama model dari badan permintaan ke Pod backend dan menentukan distribusi traffic |
| LLMRoute | Menghubungkan gateway ASM ke InferencePool untuk routing yang sadar LLM |
Aktifkan routing inferensi LLM
Jalankan perintah berikut menggunakan kubeconfig instans ASM Anda:
kubectl patch asmmeshconfig default --type=merge \
--patch='{"spec":{"gatewayAPIInferenceExtension":{"enabled":true}}}'Buat InferencePool
InferencePool mengelompokkan Pod vLLM berdasarkan pemilih label dan menentukan port inferensi.
Buat file bernama
inferencepool.yamldengan konten berikut.Field Description .spec.targetPortNumberPort pada setiap Pod yang melayani permintaan inferensi .spec.selectorPemilih label yang sesuai dengan Pod inferensi. Kunci harus appdan nilainya harus sesuai dengan nama Service terkaitapiVersion: inference.networking.x-k8s.io/v1alpha1 kind: InferencePool metadata: name: vllm-llama2-7b-pool spec: targetPortNumber: 8000 selector: app: vllm-llama2-7b-poolTerapkan InferencePool menggunakan kubeconfig kluster bidang data.
kubectl apply -f inferencepool.yamlVerifikasi bahwa InferencePool aktif. Status harus mencakup
Accepted=TruedanResolvedRefs=Truesebelum melanjutkan.kubectl get inferencepool vllm-llama2-7b-pool -o yaml
Buat InferenceModel
InferenceModel memetakan parameter model dalam permintaan masuk ke Pod backend tertentu dan menentukan bobot distribusi traffic.
Buat file bernama
inferencemodel.yamldengan konten berikut.Field Description .spec.modelNameSesuai dengan parameter modeldalam badan permintaan.spec.targetModelsMenentukan aturan routing traffic. Dalam contoh ini, semua permintaan dengan model: tweet-summarydiarahkan ke Pod yang menjalankan model tersebutapiVersion: inference.networking.x-k8s.io/v1alpha1 kind: InferenceModel metadata: name: inferencemodel-sample spec: modelName: tweet-summary poolRef: group: inference.networking.x-k8s.io kind: InferencePool name: vllm-llama2-7b-pool targetModels: - name: tweet-summary weight: 100Terapkan InferenceModel.
kubectl apply -f inferencemodel.yamlVerifikasi bahwa InferenceModel aktif. Status harus mencakup
Accepted=TruedanResolvedRefs=True.kubectl get inferencemodel inferencemodel-sample -o yaml
Buat LLMRoute
LLMRoute menghubungkan gateway ASM ke InferencePool, meneruskan semua permintaan pada Port 8080 ke layanan inferensi dengan load balancing yang sadar LLM.
Buat file bernama
llmroute.yamldengan konten berikut.apiVersion: istio.alibabacloud.com/v1 kind: LLMRoute metadata: name: test-llm-route spec: gateways: - llm-inference-gateway host: test.com rules: - backendRefs: - backendRef: group: inference.networking.x-k8s.io kind: InferencePool name: vllm-llama2-7b-poolTerapkan LLMRoute.
kubectl apply -f llmroute.yaml
Langkah 4: Verifikasi konfigurasi
Kirim permintaan uji melalui gateway ASM untuk memastikan routing yang sadar LLM berfungsi.
curl -v \
-H "host: test.com" \
-H "Content-Type: application/json" \
http://${ASM_GATEWAY_IP}:8080/v1/completions \
-d '{
"model": "tweet-summary",
"prompt": "Write as if you were a critic: San Francisco",
"max_tokens": 100,
"temperature": 0
}'Ganti ${ASM_GATEWAY_IP} dengan alamat IP gerbang masuk ASM Anda.
Tanggapan sukses terlihat seperti ini:
{
"id": "cmpl-2fc9a351-d866-422b-b561-874a30843a6b",
"object": "text_completion",
"created": 1736933141,
"model": "tweet-summary",
"choices": [
{
"index": 0,
"text": "...",
"logprobs": null,
"finish_reason": "length",
"stop_reason": null,
"prompt_logprobs": null
}
],
"usage": {
"prompt_tokens": 2,
"total_tokens": 102,
"completion_tokens": 100,
"prompt_tokens_details": null
}
}Jalankan perintah beberapa kali untuk mengamati bahwa permintaan didistribusikan ke Pod backend berbeda berdasarkan beban real-time mereka.
(Opsional) Langkah 5: Siapkan observabilitas untuk layanan inferensi LLM
Setelah mengonfigurasi InferencePool, InferenceModel, dan LLMRoute, siapkan pemantauan untuk melacak laju permintaan inferensi, throughput token, dan kesehatan backend vLLM.
Aktifkan observabilitas traffic LLM di ASM
Aktifkan field log, metrik, dan dimensi metrik khusus LLM di konsol ASM. Lihat Observasi traffic: Kelola traffic LLM secara efisien menggunakan ASM untuk detail konfigurasi. Setelah dikonfigurasi, metrik pemantauan ASM mencakup dimensi
model. Kumpulkan metrik ini menggunakan salah satu:Tambahkan aturan scrape untuk metrik token khusus ASM (
asm_llm_proxy_prompt_tokensdanasm_llm_proxy_completion_tokens) ke konfigurasi Prometheus Anda. Lihat Konfigurasi service discovery Prometheus lainnya untuk detail penyiapan.scrape_configs: - job_name: asm-envoy-stats-llm scrape_interval: 30s scrape_timeout: 30s metrics_path: /stats/prometheus scheme: http kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: - __meta_kubernetes_pod_container_port_name action: keep regex: .*-envoy-prom - source_labels: - __address__ - __meta_kubernetes_pod_annotation_prometheus_io_port action: replace regex: ([^:]+)(?::\d+)?;(\d+) replacement: $1:15090 target_label: __address__ - action: labelmap regex: __meta_kubernetes_pod_label_(.+) - source_labels: - __meta_kubernetes_namespace action: replace target_label: namespace - source_labels: - __meta_kubernetes_pod_name action: replace target_label: pod_name metric_relabel_configs: - action: keep source_labels: - __name__ regex: asm_llm_.*
Kumpulkan metrik backend vLLM
Layanan vLLM mengekspos metrik Prometheus di /metrics pada Port 8000. Deployment contoh sudah mencakup anotasi yang diperlukan:
annotations:
prometheus.io/path: /metrics
prometheus.io/port: "8000"
prometheus.io/scrape: "true"Prometheus menemukan dan mengambil endpoint ini secara otomatis melalui mekanisme service discovery default-nya. Lihat Service discovery Pod default untuk detailnya.
Metrik vLLM utama yang perlu dipantau:
| Metric | Description |
|---|---|
vllm:gpu_cache_usage_perc | Pemanfaatan cache KV. Nilai lebih rendah menunjukkan lebih banyak memori GPU tersedia untuk permintaan baru |
vllm:request_queue_time_seconds_sum | Waktu yang dihabiskan permintaan dalam antrian sebelum penjadwal vLLM menjalankan prefill dan decode |
vllm:num_requests_running, vllm:num_requests_waiting, vllm:num_requests_swapped | Jumlah permintaan yang menjalankan inferensi, menunggu dalam antrian, atau ditukar ke memori CPU. Gunakan ini untuk menilai tekanan backend |
vllm:avg_generation_throughput_toks_per_s, vllm:avg_prompt_throughput_toks_per_s | Throughput token untuk tahap decode dan prefill per detik |
vllm:time_to_first_token_seconds_bucket | Distribusi TTFT. Mengukur seberapa cepat klien menerima token pertama setelah mengirim permintaan—metrik kunci untuk latensi yang dirasakan pengguna |
Buat Dasbor Grafana
Siapkan Dasbor Grafana yang menggabungkan metrik ASM (laju permintaan, throughput token) dengan metrik vLLM (cache GPU, kedalaman antrian, TTFT) untuk tampilan terpadu armada inferensi Anda.
Pastikan sumber data Prometheus Anda di Grafana mengumpulkan metrik ASM dan vLLM.
Impor JSON dasbor berikut ke Grafana. Unduh JSON dasbor lengkap dari halaman dokumentasi ASM (perluas Dashboard JSON di halaman tersebut untuk menyalin konten lengkapnya).
Di Grafana, buka Dashboards > Import, tempel JSON, lalu pilih sumber data Prometheus Anda.

(Opsional) Bandingkan dengan load balancing tradisional
Gunakan dasbor observabilitas untuk mengukur perbedaan antara load balancing yang sadar LLM dan load balancing tradisional. Jalankan perbandingan ini sebelum mengonfigurasi routing yang sadar LLM di Langkah 3.
Jika Anda telah menyelesaikan Langkah 3, bersihkan terlebih dahulu resource routing LLM:
kubectl delete inferencemodel --all
kubectl delete inferencepool --all
kubectl delete llmroute --allBuat VirtualService yang mengarahkan traffic menggunakan load balancing round-robin tradisional.
kubectl apply -f- <<EOF apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: llm-vs namespace: default spec: gateways: - default/llm-inference-gateway hosts: - '*' http: - name: any-host route: - destination: host: vllm-llama2-7b-pool.default.svc.cluster.local port: number: 8000 EOFJalankan uji stres terhadap layanan inferensi menggunakan tool seperti llmperf.
Hapus VirtualService, lalu selesaikan Langkah 3 untuk mengonfigurasi routing yang sadar LLM. Pastikan tidak ada resource VirtualService yang tersisa sebelum melanjutkan. Jalankan uji stres yang sama lagi.
Bandingkan hasilnya di Dasbor Grafana. Load balancing yang sadar LLM memberikan:
TTFT lebih rendah (waktu hingga token pertama)
Throughput token lebih tinggi
Pemanfaatan cache KV lebih merata di seluruh replika

Bersihkan
Untuk menghapus semua resource yang dibuat dalam tutorial ini:
# Hapus resource routing LLM
kubectl delete inferencemodel --all
kubectl delete inferencepool --all
kubectl delete llmroute --all
# Hapus gateway
kubectl delete -f gateway.yaml
# Hapus layanan inferensi
kubectl delete -f vllm-service.yaml