Amazon Bedrock 是一项完全托管的服务,提供来自 AI21 Labs、Anthropic、Cohere、Meta、Mistral AI、Stability AI 和 Amazon 等领先 AI 公司的高性能基础模型 (FM) 选项。每个模型都可以通过一个通用的 API 访问,该 API 实现了一组广泛的功能,以帮助构建具有安全性、隐私性和负责任的 AI 的生成式 AI 应用程序。
Amazon Titan 是一系列基础模型 (FM),用于文本和图像生成、摘要、分类、开放式问答、信息提取以及文本或图像搜索。
在这篇文章中,我们将了解如何使用 Amazon Titan 多模态模型和 vecs客户端在 Python 中开始使用 Amazon Bedrock 和Supabase Vector。
您可以在 GitHub上以 Python Poetry 项目的形式找到完整的应用程序代码。
使用 Poetry 创建新的 Python 项目
Poetry为 Python 提供打包和依赖项管理。如果您还没有,请通过 pip 安装poetry :
pip install poetry
然后初始化一个新项目:
arduino
poetry new aws_bedrock_image_search
使用 pgvector 启动 Postgres 数据库
如果您还没有,请转到 database.new 并创建一个新项目。每个 Supabase 项目都带有一个完整的 Postgres 数据库和预先配置的 pgvector 扩展。
创建项目时,请务必记下数据库密码,因为在下一步中构造DB_URL将需要它。
您可以在 Supabase Dashboard 数据库设置中找到数据库连接字符串。选择"使用连接池"和"模式:会话"以直接连接到 Postgres 数据库。它看起来像这样:
ini
postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[REGION].pooler.supabase.com:5432/postgres
安装依赖项
我们需要将以下依赖项添加到我们的项目中:
- vecs:Supabase Vector Python 客户端。
- boto3:适用于 Python 的 AWS 开发工具包。
- matplotlib:用于显示我们的图像结果。
csharp
poetry add vecs boto3 matplotlib
导入必要的依赖项
在主 python 脚本的顶部,导入依赖项并将上面的数据库 URL 存储在一个变量中:
python
import sys
import boto3
import vecs
import json
import base64
from matplotlib import pyplot as plt
from matplotlib import image as mpimg
from typing import Optional
DB_CONNECTION = "postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[REGION].pooler.supabase.com:5432/postgres"
接下来,获取 AWS 账户的凭证并实例化 boto3 客户端:
ini
bedrock_client = boto3.client(
'bedrock-runtime',
region_name='us-west-2',
# Credentials from your AWS account
aws_access_key_id='<replace_your_own_credentials>',
aws_secret_access_key='<replace_your_own_credentials>',
aws_session_token='<replace_your_own_credentials>',
)
为图像创建嵌入
在项目的根目录中,创建一个名为 images 的新文件夹并添加一些图像。您可以在 GitHub上使用示例项目中的图像,也可以在 unsplash上找到免许可图像。
要将图像发送到 Amazon Bedrock API,我们需要将它们编码为 base64 字符串。创建以下帮助程序方法:
python
def readFileAsBase64(file_path):
"""Encode image as base64 string."""
try:
with open(file_path, "rb") as image_file:
input_image = base64.b64encode(image_file.read()).decode("utf8")
return input_image
except:
print("bad file name")
sys.exit(0)
def construct_bedrock_image_body(base64_string):
"""Construct the request body.
https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-embed-mm.html
"""
return json.dumps(
{
"inputImage": base64_string,
"embeddingConfig": {"outputEmbeddingLength": 1024},
}
)
def get_embedding_from_titan_multimodal(body):
"""Invoke the Amazon Titan Model via API request."""
response = bedrock_client.invoke_model(
body=body,
modelId="amazon.titan-embed-image-v1",
accept="application/json",
contentType="application/json",
)
response_body = json.loads(response.get("body").read())
print(response_body)
return response_body["embedding"]
def encode_image(file_path):
"""Generate embedding for the image at file_path."""
base64_string = readFileAsBase64(file_path)
body = construct_bedrock_image_body(base64_string)
emb = get_embedding_from_titan_multimodal(body)
return emb
接下来,创建一个种子方法,该方法将创建一个新的 Supabase Vector Collection,为您的图像生成嵌入,并将嵌入更新到您的数据库中:
ini
def seed():
# create vector store client
vx = vecs.create_client(DB_CONNECTION)
# get or create a collection of vectors with 1024 dimensions
images = vx.get_or_create_collection(name="image_vectors", dimension=1024)
# Generate image embeddings with Amazon Titan Model
img_emb1 = encode_image('./images/one.jpg')
img_emb2 = encode_image('./images/two.jpg')
img_emb3 = encode_image('./images/three.jpg')
img_emb4 = encode_image('./images/four.jpg')
# add records to the *images* collection
images.upsert(
records=[
(
"one.jpg", # the vector's identifier
img_emb1, # the vector. list or np.array
{"type": "jpg"} # associated metadata
), (
"two.jpg",
img_emb2,
{"type": "jpg"}
), (
"three.jpg",
img_emb3,
{"type": "jpg"}
), (
"four.jpg",
img_emb4,
{"type": "jpg"}
)
]
)
print("Inserted images")
# index the collection for fast search performance
images.create_index()
print("Created index")
将此方法添加为 pyproject.toml 文件中的脚本:
ini
[tool.poetry.scripts]
seed = "image_search.main:seed"
search = "image_search.main:search"
使用 poetry shell 激活虚拟环境后,您现在可以通过 poetry run seed 运行您的种子脚本。您可以通过访问表编辑器、选择 vecs 模式和 image_vectors 表来检查 Supabase 仪表板中生成的嵌入。
从文本查询执行图像搜索
使用 Supabase Vector,我们可以轻松查询我们的嵌入。我们可以使用图像作为搜索输入,也可以从字符串输入生成嵌入并将其用作查询输入:
ini
def search(query_term: Optional[str] = None):
if query_term is None:
query_term = sys.argv[1]
# create vector store client
vx = vecs.create_client(DB_CONNECTION)
images = vx.get_or_create_collection(name="image_vectors", dimension=1024)
# Encode text query
text_emb = get_embedding_from_titan_multimodal(json.dumps(
{
"inputText": query_term,
"embeddingConfig": {"outputEmbeddingLength": 1024},
}
))
# query the collection filtering metadata for "type" = "jpg"
results = images.query(
data=text_emb, # required
limit=1, # number of records to return
filters={"type": {"$eq": "jpg"}}, # metadata filters
)
result = results[0]
print(result)
plt.title(result)
image = mpimg.imread('./images/' + result)
plt.imshow(image)
plt.show()
通过将查询限制为一个结果,我们可以向用户显示最相关的图像。最后,我们使用 matplotlib 向用户显示图像结果。
就是这样,继续通过poetry run search
搜索来测试它,您将看到"红砖墙前的自行车"的图像。
结论
只需几行 Python,您就可以使用 Amazon Titan 多模态模型和 Supabase Vector 实现图像搜索和反向图像搜索。