为了账号安全,请及时绑定邮箱和手机立即绑定

在GKE上利用开源模型Gemma并集成LangChain的实战指南

在我的最近的帖子中,我们探讨了如何使用 LangChain 简化 AI 应用程序开发以及如何在 GKE 上部署基于 Gemini 的 LangChain 应用程序。现在,让我们来看一种略有不同的方法来运行:直接在你的 GKE 集群中运行 Gemma,也就是 Google 的开源大型语言模型,并将其与 LangChain 进行集成。

为什么选择在 GKE 上的 Gemma?

使用像Gemini这样的大型语言模型端点虽然很方便,但你在GKE集群上运行像Gemma 2这样的开放模型可以带来一些好处。

  • 控制: 您可以完全控制模型、其资源及其缩放。这对于具有严格性能或安全要求的应用程序来说尤为重要。
  • 自定义: 您可以使用自己的数据集对模型进行微调,以针对特定任务或领域进行优化。
  • 成本优化: 对于高用量使用情况,自行运行实例可能比使用API更具成本效益。
  • 数据本地性: 将数据和模型保留在您的受控环境中,这对于合规性和隐私至关重要。
  • 实验: 您可以不受API功能限制地尝试最新的研究和方法。
在 GKE 上部署 Gemma 服务

在 GKE 上部署 Gemma 包括几个步骤,从设置您的 GKE 集群到配置 LangChain 使用您的 Gemma 实例作为其 LLM。

配置凭证信息

要使用Gemma 2模型,首先得有个Hugging Face账户。如果没有的话,请先注册一个,然后在设置页面生成一个带有read权限的token。记得记下这个token,我们稍后会用到。

然后,前往Gemma 2 模型许可页面同意使用该模型的条款和条件。之后,我们就准备好部署模型了。

搭建你的 GKE 集群

如果你还没有 GKE 集群的话,可以通过 Google Cloud Console 或使用 gcloud 命令行工具来创建一个。确保你选择的机器类型有足够的资源来运行 Gemma,例如包含附带 NVIDIA L4 GPU 的 g2-standard 型号。为了简化这个过程,也可以直接创建一个 GKE Autopilot 集群

    gcloud container clusters create-auto langchain-cluster \
      --project=PROJECT_ID \
      --region=us-central1

全屏模式 退出全屏

部署 Gemma 2

对于这个示例,我们将使用vLLM镜像配置的Gemma 2指令微调实例进行部署。以下描述了gemma-2-2b-it模型及其服务的部署。请把HUGGINGFACE_TOKEN换成您之前生成的令牌。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gemma-deployment
spec:
  副本数: 1
  选择器:
    匹配标签:
      app: gemma-server
  模板:
    元数据:
      标签:
        app: gemma-server
        ai.gke.io/model: gemma-2-2b-it
        ai.gke.io/inference-server: vllm
        examples.ai.gke.io/source: model-garden
    spec:
      容器:
      - name: inference-server
        image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250114_0916_RC00_maas
        resources:
          请求:
            cpu: 2
            memory: 34Gi
            ephemeral-storage: 10Gi
            nvidia.com/gpu: 1
          限制:
            cpu: 2
            memory: 34Gi
            ephemeral-storage: 10Gi
            nvidia.com/gpu: 1
        args:
        - python
        - -m
        - vllm.entrypoints.api_server
        - --host=0.0.0.0
        - --port=8000
        - --model=google/gemma-2-2b-it
        - --tensor-parallel-size=1
        - --swap-space=16
        - --gpu-memory-utilization=0.95
        - --enable-chunked-prefill
        - --disable-log-stats
        env:
        - name: MODEL_ID
          value: google/gemma-2-2b-it
        - name: DEPLOY_SOURCE
          value: "UI_NATIVE_MODEL"
        - name: HUGGING_FACE_HUB_TOKEN
          valueFrom:
            secretKeyRef:
              name: hf-secret
              key: hf_api_token
        volumeMounts:
        - mountPath: /dev/shm
          name: dshm
      卷:
      - name: dshm
        emptyDir:
          medium: Memory
      节点选择器:
        cloud.google.com/gke-accelerator: nvidia-l4
---
apiVersion: v1
kind: Service
metadata:
  name: llm-service
spec:
  选择器:
    app: gemma-server
  类型: ClusterIP
  端口:
  - 协议: TCP
    port: 8000
    targetPort: 8000
---
apiVersion: v1
kind: Secret
metadata:
  name: hf-secret
type: Opaque
stringData:
  hf_api_token: HUGGINGFACE_TOKEN

全屏模式,退出全屏

保存名为 gemma-2-deployment.yaml 的文件,然后在你的集群上部署它:

kubectl apply -f gemma-2-deployment.yaml # 这个命令用于应用名为 gemma-2-deployment.yaml 的配置文件

全屏 退出全屏

在 GKE 上部署 LangChain 应用。

现在我们已经有了GKE集群和Gemma的部署,接下来需要创建我们的LangChain应用并进行部署。如果你之前看过我的文章,你会发现这些步骤几乎是相同的。主要的区别是我们让LangChain连接到Gemma,而不是Gemini,并且我们的LangChain应用使用了一个自定义LLM类来连接我们本地的Gemma实例。

将你的LangChain应用容器化

首先,我们需要将我们的LangChain应用程序打包成Docker镜像。这需要创建一个指定应用环境和依赖项的Dockerfile。下面是一个使用了LangChain和Gemma的Python应用app.py

    from langchain_core.callbacks.manager import CallbackManagerForLLMRun
    from langchain_core.language_models.llms import LLM
    from langchain_core.prompts import ChatPromptTemplate
    from typing import Any, Optional
    from flask import Flask, request
    import requests

    class VLLMServerLLM(LLM):
        vllm_url: str
        model: Optional[str] = None
        temperature: float = 0.0
        max_tokens: int = 2048

        @property
        def _llm_type(self) -> str:
            return "vllm_server"

        def _call(
            self,
            prompt: str,
            run_manager: Optional[CallbackManagerForLLMRun] = None,
            **kwargs: Any,
        ) -> str:
            headers = {"Content-Type": "application/json"}
            payload = {
                "prompt": prompt,
                "temperature": self.temperature,
                "max_tokens": self.max_tokens,
                **kwargs
            }

            if self.model:
              payload["model"] = self.model

            try:
                response = requests.post(self.vllm_url, headers=headers, json=payload, timeout=120)
                response.raise_for_status()
                json_response = response.json()

                if isinstance(json_response, dict) and "predictions" in json_response.keys():
                  text = json_response["predictions"][0]
                else:
                  raise ValueError(f"从vLLM服务器接收到了意外的响应格式:{json_response}")

                return text

            except requests.exceptions.RequestException as e:
                raise ValueError(f"与vLLM服务器通信时出错:{e}")
            except (KeyError, TypeError) as e:
              raise ValueError(f"解析vLLM服务器响应时出错:{e},响应如下:{json_response}")

    llm = VLLMServerLLM(vllm_url="http://llm-service:8000/generate", temperature=0.7, max_tokens=512)

    prompt = ChatPromptTemplate.from_messages(
        [
            (
                "system",
                "你是一个乐于助人的助手,会回答关于给定主题的问题。",
            ),
            ("human", "{input}"),
        ]
    )

    chain = prompt | llm

    def create_app():
        app = Flask(__name__)

        @app.route("/ask", methods=['POST'])
        def talkToGemini():
            user_input = request.json['input']
            response = chain.invoke({"input": user_input})
            return response

        return app

    if __name__ == "__main__":
        app = create_app()
        app.run(host='0.0.0.0', port=80)

切换到全屏模式,退出全屏模式

然后,创建一个 Dockerfile 来定义构建我们镜像的方法。

    # 使用官方的 Python 运行时作为基础镜像
    FROM python:3-slim

    # 设置工作目录为 /app
    WORKDIR /app

    # 复制当前目录内容到 /app
    COPY . /app

    # 安装 requirements.txt 文件中指定的依赖包
    RUN pip install -r requirements.txt

    # 公开容器的 80 端口
    EXPOSE 80

    # 容器启动时运行 app.py
    CMD [ "python", "app.py" ]

全屏模式 退出全屏

对于我们的依赖项,创建一个包含LangChain和Flask框架的requirements.txt文件。

    langchain
    flask

全屏(按ESC退出全屏)

最后,构建容器镜像并推送到 Artifact Registry。不要忘了用你的 Google Cloud 项目 ID 替换 PROJECT_ID

# 使用 gcloud 登录 Google Cloud
gcloud auth login

# 创建仓库
gcloud artifacts repositories create images \
  --repository-format=docker \
  --location=us

# 配置 Docker 登录所需的权限
gcloud auth configure-docker us-docker.pkg.dev/PROJECT_ID/images

# 构建镜像
docker build -t us-docker.pkg.dev/PROJECT_ID/images/my-langchain-app:v1 .

# 推送镜像
docker push us-docker.pkg.dev/PROJECT_ID/images/my-langchain-app:v1

全屏模式。退出全屏。

几秒钟之后,您的容器镜像应该已经保存在Artifact Registry仓库中。

将应用部署到 GKE,

创建一个 YAML 文件,包含你的 Kubernetes 部署和 服务的 YAML 描述。并将其命名为 deployment.yaml,并用你的项目 ID 替换 PROJECT_ID

apiVersion: apps/v1
kind: Deployment
metadata:
  name: langchain-deployment
spec:
  replicas: 3 # 根据需要调整副本数量
  selector: # 此处添加选择器
    matchLabels:
      app: langchain-app
  template:
    metadata:
      labels:
        app: langchain-app
    spec:
      containers:
      - name: langchain-container
        image: us-docker.pkg.dev/PROJECT_ID/images/my-langchain-app:v1
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: langchain-service
spec:
  selector:
    app: langchain-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer # 对外暴露服务

全屏模式,全屏退出

将这个 manifest 应用于您的集群 :

# 获取集群的认证信息
gcloud container clusters get-credentials langchain-cluster --region us-central1

# 部署部署文件
kubectl apply -f deployment.yaml

进入全屏/退出全屏

这将创建一个部署,包含三个你的 LangChain 应用的副本,并通过负载均衡器对外公开访问。你可以根据预期的负载需求来调整副本的数量。

与您的已部署应用进行交互

一旦服务部署完成,你可以通过获取应用的外网IP地址:

    export EXTERNAL_IP=`kubectl get service/langchain-service \
      --output jsonpath='{.status.loadBalancer.ingress[0].ip}'`

点击这里切换到全屏模式,结束后退出全屏

你现在可以在GKE上运行的LangChain应用上发送请求了。比如:

    curl -X POST -H "Content-Type: application/json" \
      -d '{"input": "给我讲一个关于蜂鸟的有趣事实"}' \
      http://$EXTERNAL_IP/ask

点击全屏切换到全屏模式,点击退出全屏结束全屏模式

考虑因素及改进
  • 扩展性: 您可以根据模型生成的负载独立地扩展 Gemma 部署,而不依赖于 LangChain 应用程序的扩展需求。
  • 监控: 使用 Cloud MonitoringCloud Logging 跟踪 Gemma 和您的 LangChain 应用程序的性能。关注错误率、延迟和资源使用情况。
  • 微调: 考虑在自己的数据集上对 Gemma 进行微调,以提高其在具体应用场景中的表现。
  • 安全性: 采取适当的安全措施,例如网络策略和身份验证,以保护您的 Gemma 实例。
结论:

在 GKE 上部署 Gemma 并将其与 LangChain 集成,提供了一种强大且灵活的方式来构建 AI 驱动的应用程序。在保持对模型和基础设施的精细控制的同时,还可以利用 LangChain 的开发者友好特性。这种方法让您能够根据具体需求来定制设置,不论是追求性能优化、成本节约还是增强控制。

下一步是,

  • 查阅Gemma文档以了解更多关于该模型及其功能的详细信息。
  • 查看LangChain文档以了解高级用例和集成。
  • 深入了解GKE文档,了解如何运行生产工作负载。

在接下来的文章中,我们将探讨如何使用LangServe来简化LangChain的部署过程。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消