全部產品
Search
文件中心

Container Service for Kubernetes:使用精準模式的首碼緩衝感知路由能力

更新時間:Oct 23, 2025

精準模式的首碼緩衝感知路由專為產生式AI推理情境設計,基於KV Cache事件感知推理引擎中KV Cache的分布,動態分配請求至最優計算節點,可以顯著提升大語言模型(LLM)服務效率。本文介紹如何使用Gateway with Inference Extension組件實現精準模式的首碼緩衝感知路由能力。

背景資訊

vLLM

vLLM是一個高效易用流行的構建LLM推理服務的架構,支援包括通義千問在內的多種常見大語言模型。vLLM通過PagedAttention最佳化、動態批量推理(Continuous Batching)模型量化等最佳化技術,可以取得較好的大語言模型推理效率。

KV Cache

在推理過程中,通過將模型產生的“鍵”(Key)和“值”(Value)進行緩衝,來快速存取歷史請求的上下文資訊,從而提高模型產生文本的效率。通過使用 KV Cache,模型能夠避免重複計算,顯著加快推理速度,減少響應延遲。

vLLM的自動首碼緩衝

vLLM支援自動首碼緩衝特性。自動首碼緩衝(APC)會緩衝vLLM已經計算過請求的KV Cache,這樣如果新的請求與某個歷史請求具有相同的首碼,就可以直接複用現有的KV Cache,從而使新請求得以跳過共用首碼部分的KV Cache計算,從而加速對LLM推理請求的處理流程。

精準模式和估算模式的首碼緩衝感知路由關係

精準模式的首碼緩衝感知路由是指如下所屬的負載平衡路由策略:

每個vLLM工作負載將自身緩衝的KV Cache塊資訊通過事件訊息的方式上報給Gateway with Inference Extension,通過感知每個vLLM工作負載對KV Cache塊的緩衝資訊,在新請求到來時、根據請求內容將請求調度到快取命中率最高的vLLM工作負載,從而最大化首碼快取命中率,減少請求回應時間。此策略主要適用於有大量共用首碼請求的情境,請根據您的實際業務情境進行判斷。

與估算模式的首碼緩衝感知路由的目的相同,精準模式的首碼緩衝感知路由也是利用推理服務架構的首碼緩衝機制、儘可能提高首碼快取命中率。

  • 精準模式的首碼緩衝感知路由由於能夠直接接收KV Cache塊分布資訊,可以更精準地確定KV Cache緩衝情況、最大化首碼快取命中率;但需要推理服務使用vLLM v0.10.0及以上版本架構、並在啟動時配置KV Cache事件上報資訊。

  • 估算模式的首碼緩衝感知路由與推理引擎解耦,但無法實現對KV Cache分布情況的精準感知。

重要

使用精準模式的首碼緩衝感知路由,您的推理服務必須使用vLLM v0.10.0及以上版本架構構建,並在vLLM啟動參數中指定KV Cache事件相關參數,詳細設定請參考本文樣本說明。

前提條件

部署模型服務

步驟一:準備Qwen3-32B模型檔案

  1. 從ModelScope下載Qwen-32B模型。

    請確認是否已安裝git-lfs外掛程式,如未安裝可執行yum install git-lfs或者apt-get install git-lfs安裝。更多的安裝方式,請參見安裝git-lfs
    git lfs install
    GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/Qwen/Qwen3-32B.git
    cd Qwen3-32B/
    git lfs pull
  2. 在OSS中建立目錄,將模型上傳至OSS。

    關於ossutil工具的安裝和使用方法,請參見安裝ossutil
    ossutil mkdir oss://<your-bucket-name>/Qwen3-32B
    ossutil cp -r ./Qwen3-32B oss://<your-bucket-name>/Qwen3-32B
  3. 建立PV和PVC。為目的地組群配置名為llm-model的儲存卷PV和儲存聲明PVC。具體操作,請參見使用ossfs 1.0靜態儲存卷

    1. 建立llm-model.yaml檔案,該該YAML檔案包含Secret、靜態卷PV、靜態卷PVC等配置。

      apiVersion: v1
      kind: Secret
      metadata:
        name: oss-secret
      stringData:
        akId: <your-oss-ak> # 配置用於訪問OSS的AccessKey ID
        akSecret: <your-oss-sk> # 配置用於訪問OSS的AccessKey Secret
      ---
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: llm-model
        labels:
          alicloud-pvname: llm-model
      spec:
        capacity:
          storage: 30Gi 
        accessModes:
          - ReadOnlyMany
        persistentVolumeReclaimPolicy: Retain
        csi:
          driver: ossplugin.csi.alibabacloud.com
          volumeHandle: llm-model
          nodePublishSecretRef:
            name: oss-secret
            namespace: default
          volumeAttributes:
            bucket: <your-bucket-name> # bucket名稱
            url: <your-bucket-endpoint> # Endpoint資訊,如oss-cn-hangzhou-internal.aliyuncs.com
            otherOpts: "-o umask=022 -o max_stat_cache_size=0 -o allow_other"
            path: <your-model-path> # 本樣本中為/Qwen3-32B/
      ---
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: llm-model
      spec:
        accessModes:
          - ReadOnlyMany
        resources:
          requests:
            storage: 30Gi
        selector:
          matchLabels:
            alicloud-pvname: llm-model
    2. 建立Secret、建立靜態卷PV、建立靜態卷PVC。

      kubectl create -f llm-model.yaml

步驟二:部署vLLM推理服務

  1. 建立vllm.yaml檔案。

    展開查看YAML內容

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: qwen3
      name: qwen3
    spec:
      progressDeadlineSeconds: 600
      replicas: 3
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: qwen3
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          annotations:
            prometheus.io/path: /metrics
            prometheus.io/port: '8000'
            prometheus.io/scrape: 'true'
          creationTimestamp: null
          labels:
            app: qwen3
        spec:
          containers:
            - command:
                - sh
                - '-c'
                - >-
                  vllm serve /models/Qwen3-32B --served-model-name Qwen3-32B
                  --trust-remote-code --port=8000 --max-model-len 8192
                  --gpu-memory-utilization 0.95 --enforce-eager --kv-events-config
                  "{\"enable_kv_cache_events\":true,\"publisher\":\"zmq\",\"endpoint\":\"tcp://epp-default-qwen-inference-pool.envoy-gateway-system.svc.cluster.local:5557\",\"topic\":\"kv@${POD_IP}@Qwen3-32B\"}"
                  --prefix-caching-hash-algo sha256_cbor_64bit --block-size 64
              env:
                - name: POD_IP
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: status.podIP
                - name: PYTHONHASHSEED
                  value: '42'
              image: 'registry-cn-hangzhou.ack.aliyuncs.com/dev/vllm:0.10.0'
              imagePullPolicy: IfNotPresent
              name: vllm
              ports:
                - containerPort: 8000
                  name: restful
                  protocol: TCP
              readinessProbe:
                failureThreshold: 3
                initialDelaySeconds: 30
                periodSeconds: 30
                successThreshold: 1
                tcpSocket:
                  port: 8000
                timeoutSeconds: 1
              resources:
                limits:
                  nvidia.com/gpu: '1'
                requests:
                  nvidia.com/gpu: '1'
              terminationMessagePath: /dev/termination-log
              terminationMessagePolicy: File
              volumeMounts:
                - mountPath: /models/Qwen3-32B
                  name: model
                - mountPath: /dev/shm
                  name: dshm
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30
          volumes:
            - name: model
              persistentVolumeClaim:
                claimName: llm-model
            - emptyDir:
                medium: Memory
                sizeLimit: 30Gi
              name: dshm
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: qwen3
      name: qwen3
    spec:
      ports:
        - name: http-serving
          port: 8000
          protocol: TCP
          targetPort: 8000
      selector:
        app: qwen3
      type: ClusterIP

    以下為部分啟動參數和環境變數說明:

    啟動參數/環境變數

    說明

    --kv-events-config

    KV Cache事件發布相關配置。應為有效 JSON 字串或單獨傳遞的 JSON 鍵。

    樣本值為:

    {"enable_kv_cache_events":true,"publisher":"zmq","endpoint":"tcp://epp-default-qwen-inference-pool.envoy-gateway-system.svc.cluster.local:5557","topic":"kv@${POD_IP}@Qwen3-32B"}

    其中:

    • endpoint:需要指定為推理擴充的zmq服務端點,命名規則為tcp://epp-<InferencePool命名空間>-<InferencePool名稱>.envoy-gateway-system.<叢集本地區名>:5557。本文樣本中,將在default命名空間下建立名為qwen-inference-poolInferencePool,因此endpoint設定為tcp://epp-default-qwen-inference-pool.envoy-gateway-system.svc.cluster.local:5557

    • topic:命名規則為kv@${POD_IP}@<提供服務的模型名稱>。本文樣本中,由於vLLM指定了--served-model-name Qwen3-32B啟動參數,因此topic設定為kv@${POD_IP}@Qwen3-32B

    --prefix-caching-hash-algo

    計算KV Cache首碼緩衝塊雜湊值使用的演算法,必須指定為sha256_cbor_64bit

    --block-size

    每個KV Cache首碼緩衝Block Storage的Token數量大小,本樣本中指定為64

    PYTHONHASHSEED

    Python執行雜湊演算法時使用的種子,需要指定為非0值,本樣本中指定為42

  2. 部署vLLM推理服務。

    kubectl create -f vllm.yaml

部署推理路由

步驟一:部署推理路由策略

  1. 建立inference-policy.yaml。

    # InferencePool為工作負載聲明開啟推理路由
    apiVersion: inference.networking.x-k8s.io/v1alpha2
    kind: InferencePool
    metadata:
      name: qwen-inference-pool
    spec:
      targetPortNumber: 8000
      selector:
        app: qwen3
    ---
    # InferenceTrafficPolicy 指定了針對InferencePool應用的具體流量策略
    apiVersion: inferenceextension.alibabacloud.com/v1alpha1
    kind: InferenceTrafficPolicy
    metadata:
      name: inference-policy
    spec:
      poolRef:
        name: qwen-inference-pool
      profile: 
        single: # 指定後端推理服務為單機vLLM部署
          trafficPolicy: # 指定針對推理服務的負載平衡策略
            prefixCache:
              mode: tracking # 開啟KVCache感知的負載平衡
              trackingConfig:
                indexerConfig:
                  tokenProcessorConfig:
                    blockSize: 64 # 與vLLM的block-size啟動參數保持一致
                    hashSeed: 42  # 與vLLM的PYTHONHASHSEED環境變數保持一致
                    model: Qwen/Qwen3-32B # 指定推理服務模型在modelscope中的官方名稱
  2. 部署推理路由策略。

    kubectl apply -f inference-policy.yaml

步驟二:部署網關和網關路由規則

  1. 建立inference-gateway.yaml。其中包含了網關、網關路由規則、以及網關後端逾時規則。

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: inference-gateway
    spec:
      gatewayClassName: ack-gateway
      listeners:
      - name: http-llm
        protocol: HTTP
        port: 8080
    ---
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: inference-route
    spec:
      parentRefs:
      - name: inference-gateway
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /v1
        backendRefs:
        - name: qwen-inference-pool
          kind: InferencePool
          group: inference.networking.x-k8s.io
    ---
    apiVersion: gateway.envoyproxy.io/v1alpha1
    kind: BackendTrafficPolicy
    metadata:
      name: backend-timeout
    spec:
      timeout:
        http:
          requestTimeout: 24h
      targetRef:
        group: gateway.networking.k8s.io
        kind: Gateway
        name: inference-gateway
  2. 部署網關和路由規則。

    kubectl apply -f inference-gateway.yaml

步驟三:驗證路由規則

  1. 建立round1.txt和round2.txt。在兩個txt檔案中都包含了一段相同的一段content,通過先後將round1.txt和round2.txt作為LLM請求的Body,然後查看推理擴充的日誌內容,來驗證精準模式的首碼緩衝感知路由功能是否工作。

    round1.txt:

    echo '{"max_tokens":24,"messages":[{"content":"Hi, here'\''s some system prompt: hi hi hi hi hi hi hi hi hi hi.For user 3, here are some other context: hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi.I would like to test your intelligence. for this purpose I would like you to play zork. you can interact with the game by typing in commands. I will forward these commands to the game and type in any response. are you ready?","role":"user"}],"model":"Qwen3-32B","stream":true,"stream_options":{"include_usage":true},"temperature":0}' > round1.txt

    round2.txt:

    echo '{"max_tokens":3,"messages":[{"content":"Hi, here'\''s some system prompt: hi hi hi hi hi hi hi hi hi hi.For user 3, here are some other context: hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi.I would like to test your intelligence. for this purpose I would like you to play zork. you can interact with the game by typing in commands. I will forward these commands to the game and type in any response. are you ready?","role":"user"},{"content":"Hi there! It looks like you're setting up a fun test. I'm ready to play Zork! You can","role":"assistant"},{"content":"% zork\nWelcome to Dungeon. This version created 11-MAR-91.\nYou are in an open field west of a big white house with a boarded\nfront door.\nThere is a small mailbox here.\n>","role":"user"},{"content":"Great!","role":"assistant"},{"content":"Opening the mailbox reveals:\n A leaflet.\n>","role":"user"}],"model":"Qwen3-32B","stream":true,"stream_options":{"include_usage":true},"temperature":0}' > round2.txt
  2. 擷取網關的公網IP。

    export GATEWAY_IP=$(kubectl get gateway/inference-gateway -o jsonpath='{.status.addresses[0].value}')
  3. 發起兩次會話請求,類比多輪對話情境。

    curl -X POST $GATEWAY_IP:8080/v1/chat/completions -H 'Content-Type: application/json' -d @./round1.txt
    curl -X POST $GATEWAY_IP:8080/v1/chat/completions -H 'Content-Type: application/json' -d @./round2.txt
  4. 查看日誌,確認首碼負載平衡是否生效。

    kubectl logs deploy/epp-default-qwen-inference-pool -n envoy-gateway-system|grep "handled"

    預期輸出:

    2025-08-19T10:16:12Z	LEVEL(-2)	requestcontrol/director.go:278	Request handled	{"x-request-id": "00d5c24e-b3c8-461d-9848-7bb233243eb9", "model": "Qwen3-32B", "resolvedTargetModel": "Qwen3-32B", "criticality": "Critical", "model": "Qwen3-32B", "targetModel": "Qwen3-32B", "endpoint": "{NamespacedName:default/qwen3-779c54544f-9c4vz Address:10.0.0.5 Labels:map[app:qwen3 pod-template-hash:779c54544f]}"}
    2025-08-19T10:16:19Z	LEVEL(-2)	requestcontrol/director.go:278	Request handled	{"x-request-id": "401925f5-fe65-46e3-8494-5afd83921ba5", "model": "Qwen3-32B", "resolvedTargetModel": "Qwen3-32B", "criticality": "Critical", "model": "Qwen3-32B", "targetModel": "Qwen3-32B", "endpoint": "{NamespacedName:default/qwen3-779c54544f-9c4vz Address:10.0.0.5 Labels:map[app:qwen3 pod-template-hash:779c54544f]}"}

    可以看到,擁有相同首碼的兩個請求被轉寄到同一工作負載,說明精準模式的首碼緩衝感知路由已生效。