亚马逊AWS官方博客

Amazon MemoryDB 的向量搜索现已正式推出

今天,我们宣布 Amazon MemoryDB 的向量搜索正式上线,这是一项新功能,可用于存储、编索引、检索和搜索向量,以开发具有内存性能和多可用区耐久性的实时机器学习(ML)和生成式人工智能(生成式 AI)应用程序。

通过此次发布,Amazon MemoryDB 在 Amazon Web Services(AWS)的流行向量数据库中以最高的查全率提供了最快的向量搜索性能。您不必继续在吞吐量、查全率和延迟等传统上相互矛盾的因素之间做出权衡取舍。

现在,您可以使用一个 MemoryDB 数据库存储应用程序数据和数百万个向量,以最高的查全率实现个位数毫秒的查询和更新响应时间。由此可简化您的生成式人工智能应用程序架构,同时提供峰值性能,减少许可成本、运营负担和提供数据见解所需的时间。

通过对 Amazon MemoryDB 进行向量搜索,您可以使用现有的 MemoryDB API 来实现生成式人工智能用例,例如检索增强生成(RAG)、异常(欺诈)检测、文档检索和实时推荐引擎。您还可以使用 Amazon BedrockAmazon SageMaker 等人工智能和机器学习(AI/ML)服务生成向量嵌入,并将其存储在 MemoryDB 中。

哪些用例将从 MemoryDB 的向量搜索中受益最大?
对于以下特定用例,您可以对 MemoryDB 使用向量搜索:

1.检索增强生成(RAG)的实时语义搜索
您可以使用向量搜索从大型数据语料库中检索相关段落,以增强大型语言模型(LLM)。具体做法是获取您的文档语料库,将其分成离散的文本存储桶,然后使用嵌入模型(例如 Amazon Titan 多模态嵌入 G1 模型)为每个区块生成向量嵌入,然后将这些向量嵌入加载到 Amazon MemoryDB 中来完成的。

使用 RAG 和 MemoryDB,您可以构建实时生成式人工智能应用程序,通过将项目表示为向量来查找相似的产品或内容,也可以通过将文本文档表示为捕捉语义含义的密集向量来搜索文档。

2.低延迟耐用语义缓存
语义缓存是通过将基础模型(FM)的先前结果存储在内存中来降低计算成本的过程。您可以将先前推断的答案与问题的向量表示形式一起存储在 MemoryDB 中,并重复使用它们,而不是从 LLM 中推断出另一个答案。

如果根据定义的与前一个问题的相似度分数,用户的查询在语义上相似,则 MemoryDB 将返回前一个问题的答案。此用例将使您的生成式人工智能应用程序能够以更低的成本更快地响应 FM 的新请求,并为您的客户提供更快的用户体验。

3.实时异常(欺诈)检测
您可以使用向量搜索进行异常(欺诈)检测,通过存储由向量表示的交易数据以及表示这些交易是否被识别为欺诈或有效的元数据,对基于规则的批量机器学习流程进行补充。

当净新交易与代表欺诈交易的向量高度相似时,机器学习过程可以检测出用户的欺诈性交易。通过对 MemoryDB 进行向量搜索,您可以根据批量 ML 模型对欺诈性交易进行建模,然后将正常和欺诈性交易加载到 MemoryDB 中,通过主成分分析(PCA)等统计分解技术生成其向量表示,从而检测欺诈行为。

当入站交易流经前端应用程序时,您可以通过 PCA 生成交易的向量表示,对 MemoryDB 进行向量搜索,如果该交易与过去检测到的欺诈交易高度相似,则可以在个位数毫秒内拒绝该交易,以最大限度地降低欺诈风险。

Amazon MemoryDB 的向量搜索入门
下面,我们来看看如何在 MemoryDB 上使用向量搜索实施简单的语义搜索应用程序。

步骤 1.创建集群以支持向量搜索
您可以创建 MemoryDB 集群以在 MemoryDB 控制台中启用向量搜索。创建或更新集群时,在集群设置中选择启用向量搜索。向量搜索可用于 MemoryDB 版本 7.1 和单分片配置。

步骤 2.使用 Amazon Titan 嵌入模型创建向量嵌入
您可以使用 Amazon Titan 文本嵌入或其他嵌入模型来创建向量嵌入,Amazon Bedrock 中提供了这一功能。您可以使用与 AWS 服务集成的 LangChain 库的单一 API 加载您的 PDF 文件、将文本拆分为多个块并获取向量数据。

import redis
import numpy as np
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import BedrockEmbeddings

# 加载 PDF 文件并拆分文档
loader = PyPDFLoader(file_path=pdf_path)
        pages = loader.load_and_split()
        text_splitter = RecursiveCharacterTextSplitter(
            separators=["\n\n", "\n", ".", " "],
            chunk_size=1000,
            chunk_overlap=200,
        )
        chunks = loader.load_and_split(text_splitter)

# 创建 MemoryDB 向量存储数据块和嵌入细节
client = RedisCluster(
        host=' mycluster.memorydb.us-east-1.amazonaws.com',
        port=6379,
        ssl=True,
        ssl_cert_reqs="none",
        decode_responses=True,
    )

embedding =  BedrockEmbeddings (
           region_name="us-east-1",
 endpoint_url=" https://bedrock-runtime.us-east-1.amazonaws.com",
    )

#使用 hset 将嵌入和元数据保存到 MemoryDB 集群中
for id, dd in enumerate(chucks*):
     y = embeddings.embed_documents([dd])
     j = np.array(y, dtype=np.float32).tobytes()
     client.hset(f'oakDoc:{id}', mapping={'embed': j, 'text': chunks[id] } )

使用 Amazon Titan 文本嵌入模型生成向量嵌入后,即可连接到 MemoryDB 集群,并使用 MemoryDB HSET 命令保存这些嵌入。

步骤 3.创建向量索引
要查询向量数据,请使用 FT.CREATE 命令创建向量索引。向量索引也在 MemoryDB 密钥空间的子集上构造和维护。向量可以保存为 JSON 或 HASH 数据类型,对向量数据的任何修改都会自动更新到向量索引的键空间中。

from redis.commands.search.field import TextField, VectorField

index = client.ft(idx:testIndex).create_index([
        VectorField(
            "embed",
            "FLAT",
            {
                "TYPE": "FLOAT32",
                "DIM": 1536,
                "DISTANCE_METRIC": "COSINE",
            }
        ),
        TextField("text")
        ]
    )

在 MemoryDB 中,您可以使用四种类型的字段:数字字段、标签字段、文本字段和向量字段。向量场支持使用平面搜索(FLAT)和分层可导航小世界(HNSW)算法,对固定大小的向量进行 K 最近邻搜索(KNN)。此功能支持几个距离指标,如欧几里得、余弦和内积。我们将使用欧几里得距离,来衡量向量空间中两点间的角度距离。欧几里得距离越小,向量间距离越近。

步骤 4.搜索向量空间
您可以使用 FT.SEARCHFT.AGGREGATE 命令来查询向量数据。每个运算符使用索引中的一个字段来标识索引中键的子集。您可以根据某些预定义的阈值(RADIUS),按照 MemoryDB 中的向量场和查询向量之间的距离来查询和查找筛选结果。

from redis.commands.search.query import Query

# 查询向量数据
query = (
    Query("@vector:[VECTOR_RANGE $radius $vec]=>{$YIELD_DISTANCE_AS: score}")
     .paging(0, 3)
     .sort_by("vector score")
     .return_fields("id", "score")     
     .dialect(2)
)

# 查找查询向量 0.8 范围内的所有向量
query_params = {
    "radius": 0.8,
    "vec": np.random.rand(VECTOR_DIMENSIONS).astype(np.float32).tobytes()
}

results = client.ft(index).search(query, query_params).docs

例如,使用余弦相似度时,RADIUS 值的范围从 0 到 1,其中值接近 1 表示找到与搜索中心更相似的向量。

以下是查找查询向量 0.8 范围内所有向量的示例结果。

[Document {'id': 'doc:a', 'payload': None, 'score': '0.243115246296'},
 Document {'id': 'doc:c', 'payload': None, 'score': '0.24981123209'},
 Document {'id': 'doc:b', 'payload': None, 'score': '0.251443207264'}]

要了解更多信息,您可以查看使用 RAG 和 MemoryDB 作为向量存储的生成式人工智能应用程序示例

正式发行版新增功能
在 re: Invent 2023 上,我们在预览版中发布了 MemoryDB 的向量搜索功能。根据客户的反馈,以下是现在可用的新功能和改进:

  • VECTOR_RANGE 允许 MemoryDB 作为低延迟耐用语义缓存运行,从而为生成式人工智能应用程序实现成本优化和性能改进。
  • SCORE 可在进行向量搜索时更好地筛选相似度。
  • 共享内存,避免内存中向量重复。向量存储在 MemoryDB 键空间中,向量的指针存储在向量索引中。
  • 在高筛选速率下提升性能,为性能最密集的生成式人工智能应用程序提供动力。

现已推出
向量搜索在 MemoryDB 当前可用的所有区域中都可使用。在 AWS 文档中了解有关 Amazon MemoryDB 向量搜索的更多信息。

MemoryDB 控制台中立即试用,并将反馈发送至 AWS re:Post for Amazon MemoryDB 或通过您通常的 AWS Support 联系方式发送反馈。

Channy