今天小李哥继续介绍国际上主流云计算平台亚马逊云科技AWS上的热门生成式AI应用开发架构。上次小李哥分享了利用谷歌云serverless代码托管服务Cloud Functions构建Gemini Pro API,这次我将介绍如何利用亚马逊的云原生服务Lambda调用OpenAI的最新模型ChatGPT 4o。由于我人在海外,平时都是利用国际上主流云计算平台帮助企业设计AI应用架构,我的文章也将集中在亚马逊、微软、谷歌和甲骨文云计算平台,目的是帮助大家打开视野,了解世界上最前沿的AI和云原生技术。
架构方案
首先我们简单介绍本方案的细节。本方案采用全托管Serverless云原生架构,涵盖了前端页面、API网关端点、后端应用和AI大语言模型托管平台。总体方案架构图如下:
前端页面:
前端页面方案使用了亚马逊云科技对象存储桶S3,我们使用S3托管前端的HTML, CSS, JS静态网页,在接收到用户请求时,S3会调用JS文件访问后端的API。
优势:使用S3的优势主要是低成本、和高扩展性,同时我们不需要维护前端基础设施。我们可以使用 S3 存储 EB 数量级的数据。S3 由亚马逊云科技托管,可以随着您增减数据的操作自动扩展和收缩。而且无需提前采购云资源,只需按实际使用量付费,具有极高性价比。同时S3具有极低的访问延迟和高吞度带宽,适用于大用户量访问。
API网关端点:
我们使用了亚马逊云科技的API Gateway作为后端API端点,用于接收前端发来的HTTPs访问请求,调用后端AI大模型生成回复,并加载到前端页面上。
优势: API Gateway支持高并发、具有高扩展性、安全性好、有效降低开发和运营成本。它同样是亚马逊云科技全托管的云原生服务,支持RESTful API和WebSocket API,特别适用于获取大模型流式响应。同时有效简化了API的创建、发布、监控、保护等。而且后端支持云原生Serverless代码托管服务lambda和容器服务ECS,帮助构建云上全云原生服务。
后端计算:
后端代码部署我们选择了大名鼎鼎的明星服务Amazon Lambda,用于接收API Gateway转发到后端的请求体,解析后调用AI大模型API,并生成响应体返回给客户端。
优势:无服务器Serverless简化运维,高扩展性、降低成本、低延时。小李哥目前在亚马逊云科技上已经不使用传统服务器开发应用了,目前只使用Lamda。主要原因就是Lambda采用全托管模式,开发人员只需要将代码上传即可运行代码,无需运维。他也可以自己作为一个网页服务器,无需搭建服务器也可以运行代码。同时采用即用即付的计费模式,根据API调用次数、运行时间和消耗资源计费。
AI大语言模型:
AI大语言模型我们使用了Open AI 5月最新发布的多模态模型 ChatGPT 4o,5月这次的发布会可谓震惊了世界,4o速度是GPT-4(特别是GPT-4 Turbo)的两倍,但价格只有一半,而且可以处理文本、视觉和音频多类型数据。
在国际上的主流基准测试中可谓是遥遥领先同类模型,如Claude Ops、Gemini 1.5等。可以完美应用于知识问答客服、文字生成、代码生成、智能助手、教育与培训多个场景。
Amazon Bedrock大语言模型平台
亚马逊云科技同时拥有自己的呀语言模型托管平台--Amazon Bedrock,它同样有非常多的优势。比如支持30多种不同AI模型厂商的大语言模型,如Amazon自家的Titan、Anthropic的Claude 3系列(Opus, Sonnet 3.5, Haiku)、AI21 Labs、Cohere多款向量模型、Meta Llama 2/3、Mistral AI、Stability AI Diffusion等,通过统一的Converse API就可以集中调用、集中管理。
另外Amazon Bedrock也提供了模型测试、知识库(RAG)、智慧体Agent、安全防护栏等多种原生服务,简化云上AI软件服务的集成和开发。同时保障企业内部数据的隐私性、安全性和合规性,训练数据、请求数据都不会用于模型的训练,支持创建企业内部的自定义私有模型,模型全生命周期加密并不会和其他用户共享。同时Amazon Bedrock 实施了自动检测滥用机制,输入不合规,如暴力、违法、仇恨、侮辱的内容,将会阻止回复和使用。
但是目前Amazon Bedrock上还没有支持OpenAI的模型,所以本次AI应用方案,小李哥没有使用该平台上的大语言模型。
2. 利用亚马逊云科技Serverless代码托管服务开发AI应用流程
1. 首先我们登录亚马逊云科技AWS,创建一个Lambda
2. 我们为Lambda函数起一个名字,如“LambdaName”。并且我们规定我们使用的开发语言和版本,如“Python3.10”,最后为Lambda分配一个调用亚马逊云科技平台上其他服务(SNS, Bedrock,S3等)的权限。在选择权限时,我们要尊从最小化权限的原则,提升应用安全。
3.下一步我们为Lambda函数创建前端调用的API端点。首先点击“Enable Function URL”,由于我们是测试环境,在Auth Type选择None,但是在真正的面相服务中,我们需要通过API Gateway在请求头添加API Key验证用户请求,提升应用安全。由于我们要通过前端页面访问后端,最后我们开启跨源资源共享CORS。
我们一般会在CORS配置中,如下图添加如下响应头。
{
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS"
}
4. 由于我们的GenAI应用会调用OpenAI API,我们需要如下操作在代码依赖中添加OpenAI SDK。
在本地创建一个文件夹
mkdir python
cd python
安装OpenAI库
pip install openai -t .
将依赖打包成zip
cd ..
zip -r openai-lambda-package.zip python
5. 打包好后,我们将依赖上传添加到Lambda中,Lambda通过Layer管理、上传代码依赖
点击Lambda的Layer功能并创建一个Layer
上传依赖并配置Layer
创建成功后,将包含依赖的layer添加到Lambda函数中,就大功告成了!
6. 接下来我们将标准的OpenAI GPT4o的API代码,复制到Lamda中。
标准API示例代码如下:
import requests
import json
import os
openai_api_key = # put yout api key here
if openai_api_key is None:
raise ValueError("OpenAI API key is not set in environment variables.")
url = "https://api.openai.com/v1/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {openai_api_key}"
}
data = {
"model": "gpt-4o",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Hello!"
}
]
}
response = requests.post(url, headers=headers, json=data)
# Check if the request was successful
if response.status_code == 200:
print("Response from OpenAI:", response.json())
print('\n')
print(response.json()['choices'][0]['message']['content'])
else:
print("Error:", response.status_code, response.text)
同时复制代码到Lambda函数中,首先从响应体中提取用户前端输入,存到定义的变量中。同时,将OpenAI API调用代码复制到“TODO implement”中,最后定义响应前端的API响应格式。
import json
def lambda_handler(event, context):
input_text = event['body'] #此处从请求体中提取用户输入
# TODO implement #复制OpenAI API代码到本行
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
} #此处定义响应头和响应数据
出于应用代码安全性的考虑,此处小李哥建议大家把OpenAI API示例代码中的openai_api_key不要存放到代码中。大家需要用亚马逊云科技的密码管理服务secret manager来储存、管理所有的密码、秘钥。Secret Manager的调用代码如下。
class GetSecretWrapper:
def __init__(self, secretsmanager_client):
self.client = secretsmanager_client
def get_secret(self, secret_name):
"""
Retrieve individual secrets from AWS Secrets Manager using the get_secret_value API.
This function assumes the stack mentioned in the source code README has been successfully deployed.
This stack includes 7 secrets, all of which have names beginning with "mySecret".
:param secret_name: The name of the secret fetched.
:type secret_name: str
"""
try:
get_secret_value_response = self.client.get_secret_value(
SecretId=secret_name #此处换成大家Secret Manager的名字
)
logging.info("Secret retrieved successfully.")
return get_secret_value_response["SecretString"]
except self.client.exceptions.ResourceNotFoundException:
msg = f"The requested secret {secret_name} was not found."
logger.info(msg)
return msg
except Exception as e:
logger.error(f"An unknown error occurred: {str(e)}.")
raise
7. 最后大家在Lambda的Function URL页面就可以获取API的URL,将URL复制到前端JS代码中,就可以搭建出基于亚马逊云科技的Open AI GenAI软件应用。
以上就是在亚马逊云科技AWS上利用OpenAI开发GenAI云服务应用的步骤和讲解,欢迎大家和我一起解锁更多的人工智能和云计算结合的最新技术和解决方案,提升AI技能和职场竞争力,成为AI技术专家!