向量技术使我们能够超越耗时耗资源的传统学习方式,并使用更加快速且高效的简单搜索。向量数据库非常适合存储高维向量数据,例如数值、文本或图像数据。像 MyScale 这样的 SQL 向量数据库,借助 SQL 的强大功能以及 MSTG 索引等出色特性,使用户无需担忧复杂的数据处理和其他后端操作。
Amazon Bedrock 是一项托管服务,允许我们使用基础模型(包括文本和图像)构建 AI 应用程序。它提供了诸如 AWS 的可扩展性、允许私下微调模型等优势,可以像使用 Scikit-learn 或 NLTK 等常规 Python 库一样轻松调用。这些服务。
本文演示了如何使用 Amazon Bedrock 和 MyScale 构建电子书的语义搜索应用程序。传统的电子阅读器(例如 Acrobat Reader、Kindle、Apple Books 或其他阅读器)通常将搜索限制为精确的关键字匹配。利用 Amazon Bedrock 的基础模型生成 embedding 向量以及 MyScale 的向量数据库功能,我们可以创建更智能的搜索功能,实现基于语义理解的检索,而不仅仅局限于关键词匹配。通过结合 Bedrock 的 AI 模型和 MyScale 的高效存储及搜索能力,用户可以在各种应用场景中增强文本搜索的有效性,从而提升整体用户体验。
conda create --name AWS python=3.12
pip install boto3 langchain-aws clickhouse-connect
import clickhouse_connectclient = clickhouse_connect.get_client(host='your-host-name-here',port=443,username='your-user-name-here',password='your-password-here')
测试连接
# 创建一个包含 128 维浮点向量的表。client.command("""CREATE TABLE default.TestTable (id UInt32,data Array(Float32),CONSTRAINT check_length CHECK length(data) = 128,date Date,label Enum8('person' = 1, 'building' = 2, 'animal' = 3))ORDER BY id""")#['0', 'chi-msc-af209a77-msc-af209a77-0-0', 'OK', '0', '0']# 获取并打印当前数据库中所有表的名称。res = client.query("SHOW TABLES").named_results()print([r['name'] for r in res])# ['TestTable']
连接 Amazon Bedrock
AWS 托管:AWS 的托管服务质量出色,可以忽略扩展性、安全性、正常运行时间等问题。
简单 API:API 使用起来非常简单。
按需付费:无需购买大型托管计划,可根据需求灵活付费
创建一个 AWS IAM 用户(在本例中为 bedrock_test)来使用 Bedrock。 获取一个访问密钥以进行终端访问。 将其下载为 .csv 文件,以防忘记访问密钥。 可以通过在终端中键入 aws configure 来验证它。它将询问凭据、默认输出格式和区域。
import boto3bedrockInterface = boto3.client(service_name="bedrock-runtime", region_name='us-east-1')
import jsonquery = "Why number 42 is so significant in the literature?"query_json = json.dumps({"inputText": query,})
output = bedrockInterface.invoke_model(modelId="amazon.titan-embed-text-v1", body=query_json)# 输出{'ResponseMetadata': {'RequestId': 'dcbcb135-8b6b-4da4-adbd-523c8c240da6','HTTPStatusCode': 200,'HTTPHeaders': {'date': 'Wed, 18 Sep 2024 03:05:53 GMT','content-type': 'application/json','content-length': '17180','connection': 'keep-alive','x-amzn-requestid': 'dcbcb135-8b6b-4da4-adbd-523c8c240da6','x-amzn-bedrock-invocation-latency': '68','x-amzn-bedrock-input-token-count': '12'},'RetryAttempts': 0},'contentType': 'application/json','body': <botocore.response.StreamingBody at 0x151b1c880>}
# 输出{'embedding': [-0.35351562,-0.3203125,-0.083496094,0.04711914,0.0034332275,0.24902344,-0.13183594,-4.798174e-06,-0.28320312,...0.7890625,...],'inputTextTokenCount': 12}
from langchain_aws import BedrockEmbeddingsembeddingOutput = BedrockEmbeddings(client=bedrockInterface)
BedrockEmbeddings 包含许多方法。其中一个是 `embed_query`,它接受一个文本字符串并返回 embedding 。由于我们使用的是 Titan 模型,因此应该预期长度为 `1536` 的 embedding 向量。
x = embeddingGenerator.embed_query("How is it going?")len(x)# 1536
client.command(""" CREATE TABLE IF NOT EXISTS BookEmbeddings (id UInt64,sentences String,embeddings Array(Float32),CONSTRAINT check_data_length CHECK length(embeddings) = 1536) ENGINE = MergeTree()ORDER BY id;""")
MyScale 的 EmbedText 功能
SELECT EmbedText('Call me Ishmael. Some years ago—never mind how long precisely—having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.', 'Bedrock', '', 'xxxxxxxx', '{"model":"amazon.titan-embed-text-v1", "region_name":"us-east-1", "access_key_id":"xxxxxx"}')
由于它是一个标量函数,因此我们得到了这个直接输出。(略过截图步骤)
现在,每次我们调用此函数时,除输入文本外的所有参数都是相同的。因此,我们可以自定义一个函数来封装 `EmbedText` 的常用参数:
CREATE FUNCTION EmbedTest AS (x) -> EmbedText(x, 'Bedrock', '', 'xxxx', '{"model":"amazon.titan-embed-text-v1", "region_name":"us-east-1", "access_key_id":"xxxxx"}')
以托尔斯泰的经典小说《安娜·卡列尼娜》为例,我们可以从 Gutenberg 网站获取原文,并将其按章节分割后生成 embedding 向量:
import requestsurl = "<https://www.gutenberg.org/files/1399/1399-0.txt>"response = requests.get(url)if response.status_code == 200:bookText = response.content.decode('utf-8-sig')start = bookText.find("CHAPTER I")end = bookText.find("End of the Project Gutenberg EBook")bookText = bookText[start:end]chapters = re.split(r'(Chapter \\d+)', book_text)splitChapters = ["".join(x) for x in zip(chapters[1::2], chapters[2::2])]embeddingsMatrix = [embeddingGenerator.embed_query(chapter) for chapter in splitChapters]import pandas as pddf = pd.DataFrame({'Text': splitChapters,'Embedding': embeddingsMatrix})df_records = df.to_records(index=True)client.insert("BookEmbeddings", df_records.tolist(), column_names=["id", "sentences", "embeddings"])
接下来,将这本书全部导入 Titan 模型,生成 embedding。
embeddingsMatrix = [embeddingGenerator.embed_query(chapter) for chapter in splitChapters]
然后这些 embedding 将被转换为 dataframe,插入表中。
import pandas as pddf = pd.DataFrame({'Text': splitChapters,'Embedding': embeddingsMatrix})df_records = df.to_records(index=True)client.insert("BookEmbeddings", df_records.tolist(), column_names=["id", "sentences", "embeddings"])
数据已成功插入,我们可以在 SQL 工作区(在 MyScale 控制台上)中确认。

索引
client.command("""ALTER TABLE BookEmbeddingsADD VECTOR INDEX dist_idx embeddingsTYPE MSTG""")
应用此索引可能需要一些时间(取决于数据量)。
query = "What happened to Levin's brother?"queryEmbeddings = embeddingGenerator.embed_query(query)results = client.command(f"""SELECT id, sentences, embeddings,distance(embeddings, {queryEmbeddings}) as distFROM BookEmbeddingsORDER BY dist LIMIT 3""")

query = "When Dolly went to meet Anna at her home?"query_embeddings = embeddingGenerator.embed_query(query)results = client.command(f"""SELECT id, sentences, embeddings,distance(embeddings, {query_embeddings}) as distFROM BookEmbeddingsORDER BY dist LIMIT 3""")

client.command("""ALTER TABLE BookEmbeddingsADD VECTOR INDEX cosine_idx embeddingsTYPE MSTG('metric_type=Cosine')""")
了解墨奇科技 点击更多资讯





