使用 Amazon Titan 和 Supabase Vector 实现语义图像搜索

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 实现图像搜索和反向图像搜索。

更多

Amazon Bedrock 和 vecs 入门

国内版supabase

相关推荐
Smile_Gently1 小时前
前端:最简单封装nmp插件(组件)过程。
前端·javascript·vue.js·elementui·vue
魔尔助理顾问2 小时前
一个简洁高效的Flask用户管理示例
后端·python·flask
李长渊哦6 小时前
使用Druid连接池优化Spring Boot应用中的数据库连接
数据库·spring boot·后端
web135085886356 小时前
【Spring Boot】Spring AOP动态代理,以及静态代理
spring boot·后端·spring
nbsaas-boot7 小时前
Go 自动升级依赖版本
开发语言·后端·golang
zzyh1234567 小时前
springcloud的组件及作用
后端·spring·spring cloud
尚学教辅学习资料8 小时前
基于SpringBoot的图书借阅小程序+LW参考示例
spring boot·后端·小程序·java毕设·图书借阅
luckycoke8 小时前
小程序立体轮播
前端·css·小程序
一 乐8 小时前
高校体育场管理系统系统|体育场管理系统小程序设计与实现(源码+数据库+文档)
前端·javascript·数据库·spring boot·高校体育馆系统
山海不说话8 小时前
从零搭建微服务项目Base(第5章——SpringBoot项目LogBack日志配置+Feign使用)
spring boot·后端·spring·spring cloud·微服务·logback