使用 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

相关推荐
玩电脑的辣条哥2 小时前
Python如何播放本地音乐并在web页面播放
开发语言·前端·python
ew452182 小时前
ElementUI表格表头自定义添加checkbox,点击选中样式不生效
前端·javascript·elementui
suibian52352 小时前
AI时代:前端开发的职业发展路径拓宽
前端·人工智能
Moon.92 小时前
el-table的hasChildren不生效?子级没数据还显示箭头号?树形数据无法展开和收缩
前端·vue.js·html
垚垚 Securify 前沿站2 小时前
深入了解 AppScan 工具的使用:筑牢 Web 应用安全防线
运维·前端·网络·安全·web安全·系统安全
m0_748256144 小时前
SpringBoot
java·spring boot·后端
多想和从前一样5 小时前
Django 创建表时 “__str__ ”方法的使用
后端·python·django
工业甲酰苯胺5 小时前
Vue3 基础概念与环境搭建
前端·javascript·vue.js
涛粒子6 小时前
Spring Bean 生命周期的执行流程
java·后端·spring
mosquito_lover16 小时前
怎么把pyqt界面做的像web一样漂亮
前端·python·pyqt