在Knative服务中基于Fluid加速Pod启动

更新时间:2025-02-13 08:14:05

Fluid是一个开源的、Kubernetes原生的分布式数据集编排和加速引擎,主要应用于云原生场景下的数据密集型应用,例如大数据应用、AI应用等。本文介绍如何在Knative中基于Fluid加速模型推理服务Pod的启动,以提升应用响应效率。

本文示例模型使用Qwen-7B-Chat-Int8,使用的GPU规格为ecs.gn6v-c8g1.2xlarge。通过监测Pod从启动到模型Ready的过程,发现开启Fluid时耗时约为30秒,未开启时约60秒。使用Fluid可使模型Ready时间缩短近一半,有效提升了服务的响应效率。

重要

示例提供的数据仅为理论值。实际数据以您的操作环境为准。

实验流程大致如下。

  1. 完成准备工作,然后下载示例数据模型并将其上传至OSS Bucket。

  2. 基于Fluid加速模型的加载,包括配置数据集(Dataset),通过JindoRuntime加速对该Dataset的访问,并通过数据加载任务(DataLoad)对该Dataset进行预加载。

  3. 部署并访问推理服务,评估Fluid在提升启动效率方面的效果。

前提条件

步骤一:准备模型数据并上传至OSS Bucket

您可以使用OSSNAS准备模型数据。本文以OSS为例说明如何准备模型数据。

  1. 执行以下命令,安装Git。

    sudo yum install git
  2. 执行以下命令,安装Git LFS(Large File Support)插件。

    sudo yum install git-lfs
  3. 执行以下命令,将ModelScope上的Qwen-7B-Chat-Int8仓库克隆到本地。

    GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/qwen/Qwen-7B-Chat-Int8.git
  4. 执行以下命令,进入Qwen-7B-Chat-Int8仓库目录。

    cd Qwen-7B-Chat-Int8
  5. 执行以下命令,在Qwen-7B-Chat-Int8目录下,下载LFS管理的大文件。

    git lfs pull
  6. 将下载的Qwen-7B-Chat-Int8文件上传至OSS Bucket,请参见简单上传

    您可以使用命令行工具ossutil来上传文件,请参见安装ossutil安装并配置ossutil。
  7. 执行以下命令,在OSS创建名为Qwen-7B-Chat-Int8的目录。

    ossutil mkdir oss://<Your-Bucket-Name>/Qwen-7B-Chat-Int8
  8. 执行以下命令,上传模型文件至OSS。

    ossutil cp -r ./Qwen-7B-Chat-Int8 oss://<Your-Bucket-Name>/Qwen-7B-Chat-Int8
  9. 为目标集群配置名为llm-model的存储卷PV和存储声明PVC。具体操作,请参见使用OSS静态存储卷

    示例PV配置如下所示。

    配置项

    说明

    配置项

    说明

    存储卷类型

    OSS。

    名称

    llm-model。

    访问证书

    配置用于访问OSSAccessKey IDAccessKey Secret。

    Bucket ID

    选择此前创建的OSS Bucket。

    OSS Path

    选择模型所在的路径,例如/Qwen-7B-Chat-Int8。

    示例PVC配置如下所示。

    配置项

    说明

    配置项

    说明

    存储声明类型

    OSS。

    名称

    llm-model。

    分配模式

    选择已有存储卷

    已有存储卷

    单击选择已有存储卷链接,选择已创建的存储卷PV。

步骤二:基于Fluid加速模型加载

为了提升业务Pod的启动效率,在使用Fluid加速模型存储卷数据访问时,建议提前创建并准备好Jindo FUSE Pod。这样可以避免业务Pod在启动过程中仍需等待Jindo FUSE Pod就绪的情况发生,从而有效减少延迟,确保服务能够更快地响应用户请求。

  1. 参见以下示例代码配置数据集(Dataset),并配置JindoRuntime用于加速对该Dataset的访问。

    apiVersion: data.fluid.io/v1alpha1
    kind: Dataset
    metadata:
      name: qwen-7b-chat-int8-dataset
    spec:
      mounts:
        - mountPoint: pvc://llm-model #此前创建的PVC的名称。
          name: data
          path: /
      accessModes:
        - ReadOnlyMany
    ---
    apiVersion: data.fluid.io/v1alpha1
    kind: JindoRuntime
    metadata:
      name: qwen-7b-chat-int8-dataset
    spec:
      replicas: 2
      tieredstore:
        levels:
          # 配置存储介质为内存。
          - mediumtype: MEM
            volumeType: emptyDir
            path: /dev/shm
            quota: 20Gi
            high: "0.9"
            low: "0.8"

    预期输出:

    $ kubectl get datasets.data.fluid.io
    NAME                        UFS TOTAL SIZE   CACHED   CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
    qwen-7b-chat-int8-dataset   17.01GiB         0.00B    20.00GiB         0.0%                Bound   89s
    $ kubectl get pvc
    NAME                        STATUS   VOLUME                              CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    qwen-7b-chat-int8-dataset   Bound    default-qwen-7b-chat-int8-dataset   100Pi      ROX            fluid          53s
  2. 参见示例代码创建一个数据加载任务(DataLoad),对上一步创建的Dataset执行预加载。

    apiVersion: data.fluid.io/v1alpha1
    kind: DataLoad
    metadata:
      name: dataset-warmup
    spec:
      dataset:
        name: qwen-7b-chat-int8-dataset
        namespace: default
      loadMetadata: true
      target:
        - path: /
          replicas: 1

    预期输出:

    $ kubectl get dataloads
    NAME             DATASET                     PHASE      AGE     DURATION
    dataset-warmup   qwen-7b-chat-int8-dataset   Complete   2m27s   1m46s
    $ kubectl get dataset
    NAME                        UFS TOTAL SIZE   CACHED     CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
    qwen-7b-chat-int8-dataset   17.01GiB         17.01GiB   20.00GiB         100.0%              Bound   10m

步骤三:部署并访问推理服务

  1. 参见以下代码,部署模型推理服务。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      labels:
        release: qwen-test
      name: qwen-test
      namespace: default
    spec:
      template:
        metadata:
          annotations:
            autoscaling.knative.dev/metric: "concurrency" # 配置并发数为弹性伸缩指标
            autoscaling.knative.dev/target: "2" # 设置当前最大并发请求数为2
            autoscaling.knative.dev/max-scale: "3" 
          labels:
            release: qwen-test
        spec:
          containers:
          - command:
            - sh
            - -c
            - python3 -m vllm.entrypoints.openai.api_server --port 8080 --trust-remote-code
              --served-model-name qwen --model /mnt/models/Qwen-7B-Chat-Int8 --gpu-memory-utilization
              0.95 --quantization gptq --max-model-len=6144
            image: kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/vllm:0.4.1
            imagePullPolicy: IfNotPresent
            name: vllm-container
            readinessProbe:
              tcpSocket:
                port: 8080
              initialDelaySeconds: 5
              periodSeconds: 5
            resources:
              limits:
                cpu: "32"
                memory: 64Gi
                nvidia.com/gpu: "1"
              requests:
                cpu: "4"
                memory: 8Gi
                nvidia.com/gpu: "1"
            volumeMounts:
            - mountPath: /mnt/models/Qwen-7B-Chat-Int8
              name: qwen-7b-chat-int8
          volumes:
          - name: qwen-7b-chat-int8
            persistentVolumeClaim:
              claimName: qwen-7b-chat-int8-dataset # 使用DataSet创建的PVC

    预期输出:

    $kubectl get ksvc
    NAME                             URL                                                         LATESTCREATED                          LATESTREADY                            READY   REASON
    qwen-test                        http://qwen-test.default.example.com                        qwen-test-00001                        qwen-test-00001                        True
  2. 访问创建的服务。

    curl -H "Host: qwen-test.default.example.com" -H "Content-Type: application/json" http://1XX.XX.XX.XXX:80/v1/chat/completions -d '{"model": "qwen", "messages": [{"role": "user", "content": "杭州西湖"}], "max_tokens": 10, "temperature": 0.7, "top_p": 0.9, "seed": 10}'

    预期输出:

    {"id":"cmpl-c496a518436e4e99bfb36617ac56a25d","object":"chat.completion","created":1736740430,"model":"qwen","choices":[{"index":0,"message":{"role":"assistant","content":"西湖位于中国浙江省杭州市,是中国著名的风景名"},"logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":10,"total_tokens":20,"completion_tokens":10}}

    此时,Pod从启动到模型Ready的耗时约为30秒。相较于未使用Fluid的场景有效提升了服务的响应效率。

相关文档

  • 本页导读 (1)
  • 前提条件
  • 步骤一:准备模型数据并上传至OSS Bucket
  • 步骤二:基于Fluid加速模型加载
  • 步骤三:部署并访问推理服务
  • 相关文档