利用谷歌云serverless代码托管服务Cloud Functions构建Gemini Pro API
谷歌在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“,然后复制代码直接写到Cldou Functions里。
参考代码如下:
import base64
import vertexai
from vertexai.generative_models import GenerativeModel, Part, FinishReason
import vertexai.preview.generative_models as generative_modelsdef 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。由于我们的测试环境,在请求验证选项就点击不对请求验证,但是真实的应用安全设计中,我们是需要对请求通过API Key进行验证的。之后点击左下角的Next。
4. 进入Code编辑界面,选择Python版本号(建议3.12),并且将刚复制的Vertex AI代码替换掉下方红框部分。并且大家需要根据自己请求体和响应体格式,对应修改参考代码中的18和23行(已标注)。
参考代码如下:
import functions_frameworkfrom 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 aResponse 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.argsif 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 requestif request.method == "OPTIONS":# Allows GET requests from any origin with the Content-Type# header and caches preflight response for an 3600sheaders = {"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 requestheaders = {"Access-Control-Allow-Origin": "*"}return ("Hello World!", 200, headers)
6.最后点击左下方的deploy就完成Gemini 1.5 pro API的创建了。
7. 大家可以通过在Cloud Functions中”TRIGGER“页面获取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架构设计场景,欢迎大家持续关注。
相关文章:

利用谷歌云serverless代码托管服务Cloud Functions构建Gemini Pro API
谷歌在2024年4月发布了全新一代的多模态模型Gemini 1.5 Pro,Gemini 1.5 Pro不仅能够生成创意文本和代码,还能理解、总结上传的图片、视频和音频内容,并且支持高达100万tokens的上下文。在多个基准测试中表现优异,性能超越了ChatGP…...
极狐GitLab 17.0 重磅发布,100+ DevSecOps功能更新来啦~【一】
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab :https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署…...

python实现符文加、解密
在历史悠久的加密技术中,恺撒密码以其简单却有效的原理闻名。通过固定的字母位移,明文可以被转换成密文,而解密则是逆向操作。这种技术不仅适用于英文字母,还可以扩展到其他语言的字符体系,如日语的平假名或汉语的拼音…...

【解释】i.MX6ULL_IO_电气属性说明
【解释】i.MX6ULL_IO_电气属性说明 文章目录 1 Hyst1.1 迟滞(Hysteresis)是什么?1.2 GPIO的Hyst. Enable Field 参数1.3 应用场景 2 Pull / Keep Select Field2.1 PUE_0_Keeper — Keeper2.2 PUE_1_Pull — Pull2.3 选择Keeper还是Pull 3 Dr…...

02-《石莲》
石 莲 石莲(学名:Sinocrassula indica A.Berger),别名因地卡,为二年生草本植物,全株无毛,具须根。花茎高15-60厘米,直立,常被微乳头状突起。茎生叶互生,宽倒披…...

MySQL之聚簇索引和非聚簇索引
1、什么是聚簇索引和非聚簇索引? 聚簇索引,通常也叫聚集索引。 非聚簇索引,指的是二级索引。 下面看一下它们的含义: 1.1、聚集索引选取规则 如果存在主键,主键索引就是聚集索引。如果不存在主键,将使…...

Web后端开发之前后端交互
http协议 http ● 超文本传输协议 (HyperText Transfer Protocol)服务器传输超文本到本地浏览器的传送协议 是互联网上应用最为流行的一种网络协议,用于定义客户端浏览器和服务器之间交换数据的过程。 HTTP是一个基于TCP/IP通信协议来传递数据. HTT…...
520. 检测大写字母 Easy
我们定义,在以下情况时,单词的大写用法是正确的: 全部字母都是大写,比如 "USA" 。 单词中所有字母都不是大写,比如 "leetcode" 。 如果单词不只含有一个字母,只有首字母大写࿰…...
vue的跳转传参
1、接收参数使用route,route包含路由信息,接收参数有两种方式,params和query path跳转只能使用query传参,name跳转都可以 params:获取来自动态路由的参数 query:获取来自search部分的参数 写法 path跳,query传 传参数 import { useRout…...
docker配置镜像源
1)打开 docker配置文件 sudo nano /etc/docker/daemon.json 2)添加 国内镜像源 {"registry-mirrors": ["https://akchsmlh.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc…...

MySQL高级-SQL优化-insert优化-批量插入-手动提交事务-主键顺序插入
文章目录 1、批量插入1.1、大批量插入数据1.2、启动Linux中的mysql服务1.3、客户端连接到mysql数据库,加上参数 --local-infile1.4、查询当前会话中 local_infile 系统变量的值。1.5、开启从本地文件加载数据到服务器的功能1.6、创建表 tb_user 结构1.7、上传文件到…...

认识100种电路之振荡电路
在电子电路领域,振荡是一项至关重要的功能。那么,为什么电路中需要振荡?其背后的原理是什么?让我们一同深入探究。 【为什么需要振荡电路】 简单来说,振荡电路的存在是为了产生周期性的信号。在众多电子设备中&#…...

SSH 无密登录配置流程
一、免密登录原理 非对称加密: 由于对称加密的存在弊端,就产生了非对称加密,非对称加密中有两个密钥:公钥和私钥。公钥由私钥产生,但却无法推算出私钥;公钥加密后的密文,只能通过对应的私钥来解…...

Python自动化运维 系统基础信息模块
1.系统信息的收集 系统信息的收集,对于服务质量的把控,服务的监控等来说是非常重要的组成部分,甚至是核心的基础支撑部分。我们可以通过大量的核心指标数据,结合对应的检测体系,快速的发现异常现象的苗头,进…...
如何安装和配置Monit
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 关于 Monit Monit 是一个有用的程序,可以自动监控和管理服务器程序,以确保它们不仅保持在线,而且文…...
【redis】redis分片集群基础知识
1、基本概念 1.1定义 分片:数据按照某种规则(比如哈希)被分割成多个片段(或分片),每个片段被称为一个槽(slot)。槽是Redis分片集群中数据的基本单元。节点:Redis分片集…...

Python 面试【★★★★】
欢迎莅临我的博客 💝💝💝,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

Knife4j 2.2.X 版本 swagger彻底禁用
官方文档配置权限:https://doc.xiaominfo.com/v2/documentation/accessControl.html#_3-5-1-%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E5%B1%8F%E8%94%BD%E8%B5%84%E6%BA%90 通常有时候我们碰到的问题如下: 在开发Knife4j功能时,同很多开发者经常讨论的问…...
linux下mysql的定时备份
备份是容灾的基础,是指为了防止系统出现操作或系统故障导致数据丢失,而将全部或部分数据集合从应用主机的硬盘或阵列复制到其他的存储介质的过程为什么备份 硬件故障软件故障误操作病毒入侵保留历史记录灾难性事件 存储介质 光盘磁带硬盘磁盘阵列DAS:直接…...
【13】地址-比特币区块链的地址
1. 比特币区块链的地址 这就是一个真实的比特币地址:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa。这是史上第一个比特币地址,据说属于中本聪。 比特币地址是完全公开的,如果你想要给某个人发送币,只需要知道他的地址就可以了。实际上,所谓的地址,只不过是将公钥表示成人类可读…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...

JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除
目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作…...