数据库 基于向量检索服务与 TextEmbedding 实现语义搜索

DashVector · 2024年05月23日 · 20 次阅读

本教程演示如何使用向量检索服务(DashVector),结合灵积模型服务上的Embedding API,来从 0 到 1 构建基于文本索引的构建 + 向量检索基础上的语义搜索能力。具体来说,我们将基于 QQ 浏览器搜索标题语料库(QBQTC:QQ Browser Query Title Corpus)进行实时的文本语义搜索,查询最相似的相关标题。

什么是 Embedding

简单来说,Embedding 是一个多维向量的表示数组,通常由一系列数字组成。Embedding 可以用来表示任何数据,例如文本、音频、图片、视频等等,通过 Embedding 我们可以编码各种类型的非结构化数据,转化为具有语义信息的多维向量,并在这些向量上进行各种操作,例如相似度计算、聚类、分类和推荐等。

整体流程概述

image.png

  • Embedding :通过 DashScope 提供的通用文本向量模型,对语料库中所有标题生成对应的 embedding 向量。

  • 构建索引服务和查询

    • 通过 DashVector 向量检索服务对生成 embedding 向量构建索引。
    • 将查询文本 embedding 向量作为输入,通过 DashVector 搜索相似的标题。

具体操作流程

前提条件

1、环境安装

说明

需要提前安装 Python3.7 及以上版本,请确保相应的 python 版本。

pip3 install dashvector dashscope

2、数据准备

QQ 浏览器搜索相关性数据集(QBQTC, QQ Browser Query Title Corpus),是 QQ 浏览器搜索引擎目前针对大搜场景构建的一个融合了相关性、权威性、内容质量、时效性等维度标注的学习排序(LTR)数据集,广泛应用在搜索引擎业务场景中。作为 CLUE-beanchmark 的一部分,QBQTC 数据集可以直接从 github 上下载(训练集路径为 dataset/train.json)。

git clone https://github.com/CLUEbenchmark/QBQTC.git
wc -l QBQTC/dataset/train.json

数据集中的训练集(train.json)其格式为 json:

{
  "id": 0, 
  "query": "小孩咳嗽感冒", 
  "title": "小孩感冒过后久咳嗽该吃什么药育儿问答宝宝树", 
  "label": "1"
}

我们将从这个数据集中提取 title,方便后续进行 embedding 并构建检索服务。

import json

def prepare_data(path, size):
    with open(path, 'r', encoding='utf-8') as f:
        batch_docs = []
        for line in f:
            batch_docs.append(json.loads(line.strip()))
            if len(batch_docs) == size:
                yield batch_docs[:]
                batch_docs.clear()

        if batch_docs:
            yield batch_docs

3、通过 DashScope 生成 Embedding 向量

DashScope 灵积模型服务通过标准的 API 提供了多种模型服务。其中支持文本 Embedding 的模型中文名为通用文本向量,英文名为 text-embedding-v1。我们可以方便的通过 DashScope API 调用来获得一段输入文本的 embedding 向量。

说明

需要使用您的 api-key 替换示例中的 your-dashscope-api-key ,代码才能正常运行。

import dashscope
from dashscope import TextEmbedding

dashscope.api_key='{your-dashscope-api-key}'


def generate_embeddings(text):
    rsp = TextEmbedding.call(model=TextEmbedding.Models.text_embedding_v1,
                             input=text)

    embeddings = [record['embedding'] for record in rsp.output['embeddings']]
    return embeddings if isinstance(text, list) else embeddings[0]


# 查看下embedding向量的维数,后面使用 DashVector 检索服务时会用到,目前是1536
print(len(generate_embeddings('hello')))

4、通过 DashVector 构建检索:向量入库

DashVector 向量检索服务上的数据以集合(Collection)为单位存储,写入向量之前,我们首先需要先创建一个集合来管理数据集。创建集合的时候,需要指定向量维度,这里的每一个输入文本经过 DashScope 上的 text_embedding_v1 模型产生的向量,维度统一均为 1536。

DashVector 除了提供向量检索服务外,还提供倒排过滤功能 和 scheme free 功能。所以我们为了演示方便,可以写入数据时,可以将 title 内容写入 DashVector 以便召回。写入数据还需要指定 id,我们可以直接使用 QBQTC 中 id。

说明

需要使用您的 api-key 替换示例中的 your-dashvector-api-key ,以及您的 Cluster Endpoint 替换示例中的 your-dashvector-cluster-endpoint ,代码才能正常运行。

from dashvector import Client, Doc


# 初始化 DashVector client
client = Client(
  api_key='{your-dashvector-api-key}',
  endpoint='{your-dashvector-cluster-endpoint}'
)

# 指定集合名称和向量维度
rsp = client.create('sample', 1536)
assert rsp

collection = client.get('sample')
assert collection

batch_size = 10
for docs in list(prepare_data('QBQTC/dataset/train.json', batch_size)):
    # 批量 embedding
    embeddings = generate_embeddings([doc['title'] for doc in docs])

    # 批量写入数据
    rsp = collection.insert(
        [
            Doc(id=str(doc['id']), vector=embedding, fields={"title": doc['title']}) 
            for doc, embedding in zip(docs, embeddings)
        ]
    )
    assert rsp

5、语义检索:向量查询

在把 QBQTC 训练数据集里的 title 内容都写到 DashVector 服务上的集合里后,就可以进行快速的向量检索,实现"语义搜索"的能力。继续上面代码的例子,假如我们要搜索有多少和'应届生 招聘'相关的 title 内容,可以通过在 DashVector 上去查询'应届生 招聘',即可迅速获取与该查询语义相近的内容,以及对应内容与输入之间的相似指数。

# 基于向量检索的语义搜索
rsp = collection.query(generate_embeddings('应届生 招聘'), output_fields=['title'])

for doc in rsp.output:
    print(f"id: {doc.id}, title: {doc.fields['title']}, score: {doc.score}")
id: 0, title: 实习生招聘-应届生求职网, score: 2523.1582
id: 6848, title: 应届生求职网校园招聘yingjieshengcom中国领先的大学生求职网站, score: 3053.7095
id: 8935, title: 北京招聘求职-前程无忧, score: 5100.5684
id: 5575, title: 百度招聘实习生北京实习招聘, score: 5451.4155
id: 6500, title: 中公教育招聘信息网-招聘岗位-近期职位信息-中公教育网, score: 5656.128
id: 7491, title: 张家口招聘求职-前程无忧, score: 5834.459
id: 7520, title: 前程无忧网北京前程无忧网招聘, score: 5874.412
id: 3214, title: 乡镇卫生院招聘招聘乡镇卫生院招聘信息+-58同城, score: 6005.207
id: 6507, title: 赶集网招聘实习生北京实习招聘, score: 6424.9927
id: 5431, title: 实习内容安排百度文库, score: 6505.735
此话题已暂时被管理员屏蔽。

以下几种情况的帖子可能会被屏蔽:

  1. 标题/正文描述不清不楚;
  2. 无意义的发帖;
  3. 存在广告嫌疑;
  4. 招聘信息描述不清楚,未按照招聘节点的要求发帖,或职位信息不符合社区用户群需求;
  5. 新注册的帐号发布产品推广贴是不允许的哦,付出和回报是相等的,当然如果你的产品确实非常有意思,或是和 Ruby 有关的东西,是不会进入这个栏目的。
  6. 太过弱的提问会被直接转移到此节点,请在提问前多尝试,多搜索;
  7. 理论上,不允许发布 QQ 群、微信群之类讨论群。

如果你发现你的帖子被屏蔽,请自我检查反省,并修改帖子内容。


招聘贴被屏蔽原因

警告: 以后招聘贴不符合要求,直接屏蔽,管理员不再回复,如认真阅读,继续新发同样格式的贴,将会被禁用账号!

  • 排版请按 Ruby China 的 Markdown 格式要求,具体请认真阅读: 排版指导,并参考 这篇招聘 的排版;
  • 招聘内容过少,缺少公司介绍,产品介绍,职位介绍,或待遇,工作地,联系方式等必要信息;
  • 重复发帖(一家公司每月限制只能发一次招聘);
  • 专业不对口(个别不对口,但有特点的,我们会放过);

如果你有时间,请阅读 招聘栏目详细说明


学会如何合理提问,请阅读:https://ruby-china.org/topics/24325

当你修改好以后,可以回帖 @huacnlee@Rei@lgn21st 任何一人,我们将会审核,通过以后才可恢复到其他节点。

注!多次发现广告嫌疑的帐号,将会被禁用帐号。

huacnlee 屏蔽了此话题:不允许新注册的账号或未参与社区讨论的账号发布产品推广贴 05月23日 10:53
需要 登录 后方可回复, 如果你还没有账号请 注册新账号