使用Baetyl函数计算调用文心一言

前言

当前文心一言未提供OpenAPI接入,需要使用百度智能云文心千帆的API接入,调用ERNIE-Bot或ERNIE-Bot-Turbo模型。

{"name":"qianfan","description":"","cluster":false,"labels":{},"authType":"CERT","sysApps":["baetyl-function"]}

文心千帆平台操作

文心千帆-API调用

在文心千帆平台创建完应用后,就可以拿到API访问的API Key以及Secret Key。

Baetyl操作步骤

本地新建index.py文件,

copy下面的内容,并将其中的API_KEY和SECRET_KEY替换为千帆平台中应用的实际值。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys 
sys.path.append("/var/lib/baetyl/python3") 
import requests
import json

API_KEY = ""
SECRET_KEY = ""    

def get_access_token():
    """
    使用 AK,SK 生成鉴权签名(Access Token)
    :return: access_token,或是None(如果错误)
    """
    url = "https://aip.baidubce.com/oauth/2.0/token"
    params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
    return str(requests.post(url, params=params).json().get("access_token"))

def handler(event, context):
    url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant?access_token=" + get_access_token()
    
    payload = json.dumps(event)
    headers = {
        'Content-Type': 'application/json'
    }
    
    response = requests.request("POST", url, headers=headers, data=payload)

    return json.loads(response.text)

由于我们用到了 requests 库,因此需要在配置项中引入该依赖,依赖包的创建方法可以参考自定义函数与依赖包解耦下发。上述代码中的如下两行代码,主要是用于引用依赖包函数。

import sys 
sys.path.append("/var/lib/baetyl/python3") 

创建配置项python3-request-package

为了方便各位测试,我们已经在对象存储中上传了依赖包,使用POST调用http://127.0.0.1:9004/v1/configs, 创建依赖包的配置项。需要记录返回的配置项version,用于创建应用时填入。

{
  "name": "python3-request-package",
  "data": [
    {
      "key": "python3-request.zip",
      "value": {
        "object": "python3-request.zip",
        "source": "http",
        "type": "object",
        "unpack": "zip",
        "url": "https://bie-document.gz.bcebos.com/baetyl-function/python3-request.zip"
      }
    }
  ],
  "description": ""
}

创建函数python-qianfan

使用POST调用http://127.0.0.1:9004/v1/configs, 创建函数配置项,其中key固定为index.py,在后续创建函数应用时需要填入该文件名。 value即为之前创建的index.py文件,用换行符隔开。需要记录返回的配置项version,用于创建应用时填入。

{
  "name": "python-qianfan",
  "labels": {
    "baetyl-config-type": "baetyl-function",
    "baetyl-function": ""
  },
  "data": [
    {
      "key": "index.py",
      "value": {
        "type": "kv",
        "value": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\nimport sys \nsys.path.append(\"/var/lib/baetyl/python3\") \nimport requests\nimport json\n\nAPI_KEY = \"\"\nSECRET_KEY = \"\"     \n\ndef get_access_token():\n    \"\"\"\n    使用 AK,SK 生成鉴权签名(Access Token)\n    :return: access_token,或是None(如果错误)\n    \"\"\"\n    url = \"https://aip.baidubce.com/oauth/2.0/token\"\n    params = {\"grant_type\": \"client_credentials\", \"client_id\": API_KEY, \"client_secret\": SECRET_KEY}\n    return str(requests.post(url, params=params).json().get(\"access_token\"))\n\ndef handler(event, context):\n    url = \"https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant?access_token=\" + get_access_token()\n\n    payload = json.dumps(event)\n    headers = {\n        'Content-Type': 'application/json'\n    }\n\n    response = requests.request(\"POST\", url, headers=headers, data=payload)\n\n    return json.loads(response.text)"
      }
    }
  ]
}

创建节点

使用POST调用http://127.0.0.1:9004/v1/nodes 创建节点,系统应用选择baetyl-function。

{"name":"qianfan","description":"","cluster":false,"labels":{},"authType":"CERT","sysApps":["baetyl-function"]}

创建函数应用

使用POST调用http://127.0.0.1:9004/v1/apps 创建函数应用,并将函数代码,依赖包挂载到容器中。

其中functions字段中的handler,因为python-qianfan函数的名称是index.py,函数当中定义了handler,所以此处为index.handler。

代码目录,使用点号.,表示当前目录。

{
  "name": "python-qianfan",
  "mode": "kube",
  "type": "function",
  "selector": "baetyl-node-mode=kube,baetyl-node-name=qianfan",
  "services": [
    {
      "name": "python-qianfan",
      "image": "docker.io/baetyltechtest/python3:3.7-git-2e05ea4",
      "volumeMounts": [
        {
          "name": "baetyl-function-code-python-qianfan",
          "mountPath": "/var/lib/baetyl/code",
          "readOnly": true,
          "immutable": true
        },
        {
          "name": "python3-request",
          "mountPath": "/var/lib/baetyl/python3"
        }
      ],
      "ports": [],
      "resources": {},
      "functionConfig": {
        "name": "python-qianfan",
        "runtime": "python3"
      },
      "functions": [
        {
          "name": "qiangfan",
          "handler": "index.handler",
          "codedir": "."
        }
      ],
      "replica": 1,
      "jobConfig": {
        "restartPolicy": "Never"
      },
      "type": "deployment"
    }
  ],
  "volumes": [
    {
      "name": "baetyl-function-code-python-qianfan",
      "config": {
        "name": "python-qianfan",
        "version": "3287"
      }
    },
    {
      "name": "python3-request",
      "config": {
        "name": "python3-request-package",
        "version": "3249"
      }
    }
  ],
  "cronStatus": 0,
  "dnsPolicy": "ClusterFirst",
  "replica": 1,
  "workload": "deployment",
  "jobConfig": {},
  "ota": {},
  "autoScaleCfg": {}
}

测试运行

边缘节点安装,并等待所有Pod全部运行,然后可以使用postman进行调用测试。

使用k8s pod-forward将函数应用端口暴露出来,或者参考Modbus实践中 修改baetyl-broker端口映射的方式,修改baetyl-function的映射,来将函数计算服务进行暴露。

kubectl port-forward -nbaetyl-edge-system baetyl-function-xxx 31010:50011

在postman的General配置中,关闭SSL certificate verification,使用https,访问边缘节点的31010端口,加上函数应用名称为路径,就能成功调用到文心千帆提供的文心一言模型。其中Body内容,函数计算会进行透传,内容格式可参考ERNIE-Bot-turbo API

postman测试结果