谷歌在2024年4月发布了全新一代的多模态模型Gemini 1.5 Pro,Gemini 1.5 Pro不仅能够生成创意文本和代码,还能理解、总结上传的图片、视频和音频内容,并且支持高达100万tokens的上下文。在多个基准测试中表现优异,性能超越了ChatGPT 4。
Gemini 1.5 Pro既然功能这么强大,那如何将Gemini 1.5 Pro集成到在谷歌云上或者本地运行的AI软件应用中呢?今天小李哥给大家带来的是一个非常简单的场景,利用谷歌云serverless代码托管服务Cloud Functions构建Gemini Pro 1,5 对外暴露的API。首先小李哥带大家了解一些关于谷歌云的背景信息。
背景信息:
1. Vertex AI
Vertex AI 是一个谷歌云托管的机器学习平台,利用该服务可以训练和部署机器学习模型,以及基础模型(foundation Model)和自定义大型语言模型 (LLM)构建 生成式AI 应用。Vertex AI 集成了多种机器学习工具和服务,赋能开发者整个机器学习生命周期,让开发人员和数据科学家能够专注于应用程序的开发。
该平台包含许多重要功能。比较特色的如 AutoML 功能,这项功能可以通过低代码/无代码的形式来创建机器学习模型,降低AI/ML模型训练门槛。此外还有Vertex AI Studio,可以让开发者在其上直接使用多模态的Google Gemini大语言模型并且对模型进行微调,目前Vertex AI支持以下4种基础模型。在Google AI Studio开发平台中,用户可以免费试用Gemini 1.5 Pro,并且它支持中文提示,可以更好的构建中文语言的生成式AI应用。
2. Cloud Functions
Cloud Functions是由谷歌云托管的,运行代码的serverless(无服务器)服务。相对于传统的服务器如compute engine, 开发者无需维护底层基础设施,比如谷歌云会根据请求量自动扩容底层基础设施,让开发者将精力专注于应用程序开发,提升开发的效率。同时使用Cloud Functions还可以节约成本,Cloud Functions采用即用即付的付费模式,通过API技术和应用运行时间收费,避免传统的长期开启服务器产生的费用浪费。
利用Cloud Function构建Gemini 1.5 Pro公网API的步骤
1. 首先我们进入谷歌云Vertex AI中,获取调用Gemini 1.5 Pro的API调用代码。Vertex AI服务中可以给开发者自动生成调用大模型的API示例代码,大家点击图1中的”Get Code“,然后复制代码,后续我们会直接把他写到Cloud Functions里。
参考代码如下:
import base64
import vertexai
from vertexai.generative_models import GenerativeModel, Part, FinishReason
import vertexai.preview.generative_models as generative_models
def generate():
vertexai.init(project="mystic-fountain-365517", location="us-central1")
model = GenerativeModel(
"gemini-1.5-pro-001",
system_instruction=["""Write system prompt here"""]
)
responses = model.generate_content(
["""Write user prompt here"""],
generation_config=generation_config,
safety_settings=safety_settings,
stream=True,
)
for response in responses:
print(response.text, end="")
generation_config = {
"max_output_tokens": 8192,
"temperature": 1,
"top_p": 0.95,
}
safety_settings = {
generative_models.HarmCategory.HARM_CATEGORY_HATE_SPEECH: generative_models.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
generative_models.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: generative_models.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
generative_models.HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: generative_models.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
generative_models.HarmCategory.HARM_CATEGORY_HARASSMENT: generative_models.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
}
generate()
2.创建一个Cloud Functions。进入Cloud Functions中,并开启Cloud Functions创建需要的谷歌云API(会自动弹出,直接点击enable即可)。
3. 接下来配置Cloud Functions的参数。为其选择一个服务用户所在地的区域,并且选择API的类型HTTPS。由于我们的测试环境,在请求验证的选项就点击不对请求验证(Allow Unauthenticated Invocations),但是在真实的应用安全设计中,我们需要对访问请求通过API Key进行验证。之后点击左下角的Next。
同时我们要使用GCP上的service account对Cloud Functions进行授权以访问Vertex AI上的Gemini pro大模型。Cloud Functions默认使用的权限是创建GCP账户时自带的service account:Compute Engine default service accoun,内含账户层级的基础权限,可以访问Vertex AI。但是小李哥强烈建议在真正开发应用时,新创建一个自定义的service account,并只添加应用所需的最小权限,以满足应用安全。
4. 进入Code编辑界面,选择Python版本号(建议3.12),并且将刚复制的Vertex AI代码替换掉下方红框部分。并且大家需要根据自己请求体和响应体格式,对应修改参考代码中的19和24行(已标注)。如果大家希望通过取键值”name“的方式从请求体中取出字符,记得在客户端侧的请求体中加入name的键和值。
参考代码如下:
import functions_framework
from markupsafe import escape
@functions_framework.http
def hello_http(request):
"""HTTP Cloud Function.
Args:
request (flask.Request): The request object.
<https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
Returns:
The response text, or any set of values that can be turned into a
Response object using `make_response`
<https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
"""
request_json = request.get_json(silent=True)
request_args = request.args
if request_json and "name" in request_json:
name = request_json["name"] #根据前端调用的请求体修改的key值获取请求数据
elif request_args and "name" in request_args:
name = request_args["name"]
else:
name = "World"
return f"Hello {escape(name)}!" #根据前端可以接收的响应体格式修改此处响应数据
5.如果大家需要从前端UI中调用该Cloud Function API,需要如下图添加跨源资源共享CORS的配置代码。
参考代码:
import functions_framework
@functions_framework.http
def cors_enabled_function(request):
# For more information about CORS and CORS preflight requests, see:
# https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
# Set CORS headers for the preflight request
if request.method == "OPTIONS":
# Allows GET requests from any origin with the Content-Type
# header and caches preflight response for an 3600s
headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET",
"Access-Control-Allow-Headers": "Content-Type",
"Access-Control-Max-Age": "3600",
}
return ("", 204, headers)
# Set CORS headers for the main request
headers = {"Access-Control-Allow-Origin": "*"}
return ("Hello World!", 200, headers)
6.最后点击左下方的deploy就完成Gemini 1.5 pro API的创建了。
7. 大家可以通过在Cloud Functions中”TRIGGER“页面获取API的URL, 我们可以在客户端利用POST方法调用API
和AWS的serverless代码运行服务Lambda的使用心得比较
1. 开发体验
小李哥使用的语言是Python,两款产品的编辑器UI基本是相同的没有什么太大的区别,谷歌云的优势是可以直接可以把需要安装的依赖写到编辑器内的requirement.txt文件中,部署代码的时候自动下载,简化了安装依赖的操作难度。AWS需要自己提前在本地封装,上传到云端,这里谷歌云使用更便利。
由于开发GenAI应用过程中,都会写很长的提示词Prompt,需要把编辑器中的文字自动换行,可以更容易的修改提示词。AWS Lambda提供了word wrap的功能(下图),在编辑代码的编辑器里可以自动换行。
但是谷歌云的Cloud Functions里暂时没找到这个功能,修改提示词目前只能在VSCode里修改后,粘贴到Cloud Functions编辑器里,不能把开发流程沉浸在GCP环境中。
2. 部署速度
对于相同的代码部署到AWS Lambda和GCP Cloud Functions中,小李哥做了测试。AWS Lambda基本是几秒内就可以完成。但是对于GCP Cloud Functions,整个代码build构建和部署的时间加在一起要1分钟。在部署速度上AWS体验更好。我觉得这个也是谷歌云用requirement.txt简化依赖安装带来的副作用,AWS的本地封装上传可以大大降低部署的时间。
3. CORS配置
在AWS Lambda中CORS的配置是通过在控制台上配置的,采用无代码的形式,帮助开发者简化代码开发的工作量。
对于谷歌云来说,CORS的配置是写到代码中的,更接近利用Flask框架开发web server的本地开发的习惯。两家的CORS配置方式各有优势,针对不同人群。
4.测试stdout输出延时
在部署代码功能测试的阶段,谷歌云stdout输出日志的速度可以明显感觉到延迟,一般要在Cloud Logging中刷新几次才能找到刚刚测试运行的结果。AWS的日志输出速度基本上是感觉不到延迟的,优化的更好。
以上就是关于利用谷歌云Cloud Functions开发服务端Gemini Pro 1.5对外API的整体流程和步骤,未来小李哥也将分享更多关于谷歌云和AWS上的应用开发方案和生成式AI架构设计场景,欢迎大家持续关注。