前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >TiDB Vector 抢先体验之用 TiDB 实现以图搜图

TiDB Vector 抢先体验之用 TiDB 实现以图搜图

作者头像
HOHO
发布于 2024-04-24 00:14:27
发布于 2024-04-24 00:14:27
18400
代码可运行
举报
运行总次数:0
代码可运行

本文首发自 TiDB 社区专栏:https://tidb.net/blog/0c5672b9 转载请注明出处!

前言

最早知道 TiDB 要支持向量化的消息应该是在23年10月份左右,到第一次见到 TiDB Vector 的样子是在今年1月初,当时 dongxu 在朋友圈发了一张图:

去年我研究了一段时间的向量数据库,一直对 TiDB 向量特性非常期待,看到这张图真的就激动万分,于是第一时间提交了 waitlist 等待体验 private beta。

苦等几个月,它终于来了(目前只对 TiDB Serverless 开放)。迫不及待做个小应用尝尝鲜。

waitlist申请入口:https://tidb.cloud/ai 体验入口:https://tidbcloud.com/

创建 TiDB Vector 实例

在收到体验邀请邮件后,恭喜你可以开始 TiDB Vector 之旅了。

TiDB Serverless 提供了免费试用额度,对于测试用途绰绰有余,只需要注册一个 TiDB Cloud 账号即可。

创建 TiDB Vector 实例和普通的 TiDB 实例并没有太大区别,在创建集群页面可以看到加入了如下开关:

不过要注意的是目前 TiDB Vector 只在 AWS 的eu-central-1可用区开放,选到了其他可用区就看不到这个开关。

这里只需要填一个集群名称就可以开始创建,创建成功后的样子如下所示:

下面开始进入正题。

关于向量的那些事

一些基础概念

  • 向量:向量就是一组浮点数,在编程语言中通常体现为 float 数组,数组的长度叫做维度(dim),维度越大精度越高,向量的数学表示是多维坐标系中的一个点。例如RGB颜色表示法就是一个简单的向量示例。
  • embedding:中文翻译叫嵌入,感觉不好理解,实质上就是把非结构化数据(文本、语音、图片、视频等)通过一系列算法加工变成向量的过程,这里面的算法叫做模型(model)。
  • 向量检索:计算两个向量之间的相似度。

向量检索初体验

连接到 TiDB Serverless 后,就可以体验文章开头图片中的向量操作。

创建一张带有向量字段的表,长度是3维。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE vector_table (
    id int PRIMARY KEY,
    doc TEXT,
    embedding vector < float > (3)
  );

往表中插入向量数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
INSERT INTO vector_table VALUES (1, 'apple', '[1,1,1]'), (2, 'banana', '[1,1,2]'), (3, 'dog', '[2,2,2]');

根据指定的向量做搜索:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT *, vec_cosine_distance(embedding, '[1,1,3]') as distance FROM vector_table ORDER BY distance LIMIT 3;

+-----------------------+-----------------------+---------------------+
| id      | doc         | embedding             | distance            |
+-----------------------+-----------------------+---------------------+
| 2       | banana      | [1,1,2]               | 0.015268072165338209|
| 3       | dog         | [2,2,2]               | 0.1296117202215108  |
| 1       | apple       | [1,1,1]               | 0.1296117202215108  |
+---------+-------------+-----------------------+---------------------+

这里的distance就是两个向量之间的相似度,这个相似度是用vec_cosine_distance函数计算出来的,意味着两个向量之间的夹角越小相似性越高,夹角大小用余弦值来衡量。

还有以一种常用的相似度计算方法是比较两个向量之间的直线距离,称为欧式距离。

这也意味着不管两个向量是否有关联性,总是能计算出一个相似度,distance越小相似度越高。

向量检索原理

前面大概也提到了两种常用的向量检索方式:余弦相似度和欧式距离,不妨从从最简单的二维向量开始推导一下计算过程。

二维向量对应一个平面坐标系,一个向量就是坐标系中任意一点,要计算两点之间的直线距离用勾股定理很容易就能得出,两点夹角的余弦值也有公式能直接算出来。

拓展到三维坐标系,还是套用上一步的数学公式,只是多了一个坐标。

以此类推到n维也是一样的方法。

以上内容来自我去年讲的向量数据库公开课:https://www.bilibili.com/video/BV1YP411t7Do

可以发现维数越多,对算力的要求就越高,计算时间就越长。

第一个 TiDB AI 应用:以图搜图

基础实现

借助前面介绍的理论知识,一个以图搜图的流程应该是这样子:

下面我用最简洁直白的代码演示整个流程,方便大家理解。

首先肯定是先连接到 TiDB 实例,目前官方提供了python SDKtidb_vector,对SQLAlchemyPeewee这样的 ORM 框架也有支持,具体可参考https://github.com/pingcap/tidb-vector-python

这里简单起见直接用pymysql手写 SQL 操作,以下连接参数都可以从 TiDB Cloud 控制台获取:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import pymysql

def GetConnection():
    connection = pymysql.connect(
        host = "xxx.xxx.prod.aws.tidbcloud.com",
        port = 4000,
        user = "xxx.root",
        password = "xxx",
        database = "test",
        ssl_verify_cert = True,
        ssl_verify_identity = True,
        ssl_ca = "C:\\Users\\59131\\Downloads\\isrgrootx1.pem"
    )
    return connection

再借助 Towhee 来简化 embedding 的处理,里面包含了常用的非结构化数据到向量数据的转换模型,用流水线(pipeline)的形式清晰构建整个处理过程。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from towhee import ops,pipe,AutoPipes,AutoConfig,DataCollection

image_pipe = AutoPipes.pipeline('text_image_embedding')

这里使用默认配置构建了一个text_image_embedding流水线,它专门用于对文本和图片做向量转换,从引用的源码中可以看到它使用的模型是clip_vit_base_patch16,默认模态是image

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@AutoConfig.register
class TextImageEmbeddingConfig(BaseModel):
    model: Optional[str] = 'clip_vit_base_patch16'
    modality: Optional[str] = 'image'
    customize_embedding_op: Optional[Any] = None
    normalize_vec: Optional[bool] = True
    device: Optional[int] = -1

clip_vit_base_patch16是一个512维的模型,因此需要在 TiDB 中创建512维的向量字段。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create table if not exists img_list 
(
    id int PRIMARY KEY, 
    path varchar(200) not null, 
    embedding vector<float>(512)
);

我准备了3000张各种各样的动物图片用于测试,把它们依次加载到 TiDB 中,完整代码为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def LoadImage(connection):
    cursor = connection.cursor() 
    cursor.execute("create table if not exists img_list (id int PRIMARY KEY, path varchar(200) not null, embedding vector<float>(512));")
    img_dir='D:\\\\test\\\\'
    files = os.listdir(img_dir)
    for i in range(len(files)):
        path=os.path.join(img_dir, files[i])
        embedding = image_pipe(path).get()[0]
        cursor.execute("INSERT INTO img_list VALUE ("+str(i)+",'"+path+"' , '"+np.array2string(embedding, separator=',')+"');")
    connection.commit()

如果用 ORM 框架的话这里对数据库和向量加工操作会简单些,不需要数组到字符串之间的手工转换。

加载完成后的数据:

下一步定义出根据指定向量在 TiDB 中检索的函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def SearchInTiDB(connection,vector):
    cursor = connection.cursor() 
    begin_time = datetime.datetime.now()
    cursor.execute("select id,path,vec_cosine_distance(embedding, '"+np.array2string(vector, separator=',')+"') as distance from img_list order by distance limit 3;")
    end_time=datetime.datetime.now()
    print("Search time:",(end_time-begin_time).total_seconds())
    df =pd.DataFrame(cursor.fetchall())
    return df[1]

这里根据余弦相似度取出结果最相近的3张图片,返回它们的文件路径用于预览显示。

下一步用相同的 image pipeline 给指定图片做 embedding 得到向量,把这个向量传到 TiDB 中去搜索,最后把搜索结果输出显示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def read_images(img_paths):
    imgs = []
    op = ops.image_decode.cv2_rgb()
    for p in img_paths:
        imgs.append(op(p))
    return imgs
    
def ImageSearch(connection,path):    
    emb = image_pipe(path).get()[0]
    res = SearchInTiDB(connection,emb)
    p = (
        pipe.input('path','search_result')
        .map('path', 'img', ops.image_decode.cv2('rgb'))
        .map('search_result','prev',read_images)
        .output('img','prev')
    )
    DataCollection(p(path,res)).show()

看一下最终搜索效果如何。先看一张已经在图片库存在的图(左边是待搜索的图,右边是搜索结果,按相似度由高到低):

不能说非常相似,只能说是一模一样,准确度非常高!再看一下不在图片库的搜索效果:

图片库里有几十种动物,能够准确搜索出需要的是狗,特别是第一张从图片色彩、画面角度、动作神态上来说都非常相似。

使用向量索引优化

没错,向量也能加索引,但这个索引和传统的 B+ Tree 索引有些区别。前面提到向量相似度计算是一个非常消耗 CPU 的过程,如果每次计算都采用全量暴力搜索的方式那么无疑效率非常低。上一节演示的案例就是用指定的向量与表里的3000个向量逐一计算,最简单粗暴的办法。

向量索引牺牲了一定的准确度来提升性能,通常采用 ANN(近似最近邻搜索) 算法,HNSW 是最知名的算法之一。TiDB Vector 目前对它已经有了支持:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create table if not exists img_list_hnsw 
(
    id int PRIMARY KEY, 
    path varchar(200) not null, 
    embedding vector<float>(512) COMMENT "hnsw(distance=cosine)"
);

重新把3000张图片加载到新的img_list_hnsw表做搜索测试。

以下分别是不带索引和带索引的查询耗时,第二次明显要快很多,如果数据量越大这个差距会越明显,只是目前还无法通过执行计划或其他方式区分出索引使用情况。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
E:\GitLocal\AITester>python tidb_vec.py
Search time: 0.320241
+------------------------------------+------------------------------------------------------------------------------------------------------+
| img                                | prev                                                                                                 |
+====================================+======================================================================================================+
| Image shape=(900, 900, 3) mode=RGB | [Image shape=(84, 84, 3) mode=RGB,Image shape=(84, 84, 3) mode=RGB,Image shape=(84, 84, 3) mode=RGB] |
+------------------------------------+------------------------------------------------------------------------------------------------------+

E:\GitLocal\AITester>python tidb_vec.py
Search time: 0.239746
+------------------------------------+------------------------------------------------------------------------------------------------------+
| img                                | prev                                                                                                 |
+====================================+======================================================================================================+
| Image shape=(900, 900, 3) mode=RGB | [Image shape=(84, 84, 3) mode=RGB,Image shape=(84, 84, 3) mode=RGB,Image shape=(84, 84, 3) mode=RGB] |
+------------------------------------+------------------------------------------------------------------------------------------------------+

实际在本次测试中发现,使用 HNSW 索引对搜索结果准确度没有任何影响。

自然语言实现图片搜索

本来到这里测试目的已经达到了,突发奇想想试一下用自然语言也来实现图片搜索。于是对代码稍加改造:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def TextSearch(connection,text):
    text_conf = AutoConfig.load_config('text_image_embedding')
    text_conf.modality = 'text'

    text_pipe = AutoPipes.pipeline('text_image_embedding', text_conf)
    embedding = text_pipe(text).get()[0]
    
    res=SearchInTiDB(connection,embedding)
    p = (
        pipe.input('text','search_result')
        .map('search_result','prev',read_images)
        .output('text','prev')
    )
    DataCollection(p(text,res)).show()

还是用的clip_vit_base_patch16模型,只是使用模态改成了文本。通过对文本做 embedding 后得到向量数据送到 TiDB 中进行搜索,流程和前面基本一样。

看一下最终效果:

可以发现英文的搜索效果要很多,这个主要是因为模型对于中文理解能力比较差,英文语义下 TiDB 的向量搜索准确度依然非常高。

基于 TiDB Vector,前后不到100行代码就实现了以图搜图和自然语言搜图。

未来展望

反正第一时间体验完的感受就是:太香了,强烈推荐给大家!

在以往,想在关系型数据库中对非结构化数据实现搜索是一件不敢想象的事,哪怕是号称无所不能的 PostgreSQL 在向量插件的加持下也没有获得太多关注,这其中有场景、性能、生态等各方面的因素制约。而如今在 AI 大浪潮中,应用场景变得多样化,生态链变得更丰富,TiDB Vector 的诞生恰逢其时。

但是不可忽视的是,传统数据库集成向量化的能力已经是大势所趋,哪怕是 Redis 这样的产品也拥有了向量能力。前有专门的向量数据库阻击,后有各种传统数据库追赶,这注定是一个惨烈的赛道,希望 TiDB 能深度打磨产品,突围成功。

期待的功能:更多的索引类型、GPU加速等。

当然了,最大的愿望必须是 TiDB On-Premises 中能尽快看到 Vector 的身影。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
RAG 实战|用 StarRocks + DeepSeek 构建智能问答与企业知识库
RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合外部知识检索与 AI 生成的技术,弥补了传统大模型知识静态、易编造信息的缺陷,使回答更加准确且基于实时信息。
StarRocks
2025/04/19
1830
RAG 实战|用 StarRocks + DeepSeek 构建智能问答与企业知识库
多模态RAG应用之实现文本检索视频内容
现如今无论是谷歌百度搜索知识学习,还是淘宝京东购物都离不开文字关键词的搜索。但现在很多平台或者应用有大量的视频,还有某些跟视频打交道的应用比如视频编辑器,视频自动化处理工具等,这些工具如果只有简单的文本搜索就远远不够用了,搜索体验肯定会大打折扣;由此引出我们今天的主题:
郑子铭
2025/01/07
1670
多模态RAG应用之实现文本检索视频内容
腾讯词向量实战:通过Annoy进行索引和快速查询
上周《玩转腾讯词向量:词语相似度计算和在线查询》推出后,有同学提到了annoy,我其实并没有用annoy,不过对annoy很感兴趣,所以决定用annoy试一下腾讯 AI Lab 词向量。
AINLP
2019/06/03
3.4K0
【腾讯云云上实验室-向量数据库】Tencent Cloud VectorDB为非结构化数据查询插上飞翔的翅膀——以企业知识库为例
以前我曾疑惑,对于非结构化的内容,如一张图片或一段视频,如何实现搜索呢?图片或视频作为二进制文件,我们如何将其转化为可搜索的数据并存储起来,然后在搜索时将其还原呢?
拿我格子衫来
2023/11/25
4740
【腾讯云云上实验室-向量数据库】Tencent Cloud VectorDB为非结构化数据查询插上飞翔的翅膀——以企业知识库为例
RAG实战|向量数据库LanceDB指南
LanceDB是一个开源的用 Rust 实现的向量数据库(https://github.com/lancedb/lancedb),它的主要特点是:
用户1904552
2025/03/31
1710
RAG实战|向量数据库LanceDB指南
Dify + TiDB Vector,快速构建你的AI Agent
随着人工智能技术的蓬勃发展,AI Agent 不再只是科技巨头的专属。如今,每个人都可以成为 AI 的创造者和使用者。
PingCAP
2024/07/07
1.8K0
图片相似度检索设计
相似度检索的应用场景颇多,不管是互联网生态下的内容理解还是工业界质量检、人脸对比等,向量相似度检索技术的核心是通过向量表征的感兴趣区域并通过向量距离计算衡量输入样本的相似度。针对图片的相似度检索,主要包含图片裁剪、特征提取、PCA、聚类计算、相似度距离计算6个步骤,通常业界有6类常具有代表性的向量表征算法,他们是Word2vec,Doc2vec,DeepWalk,Graph2Vec,Asm2Vec,Log2Vec。本文基于公司的业务驱动,具体聊聊CV领域图片相似度检索技术的原理和实践案例。
liddytang
2024/08/26
3540
python图像识别---------图片相似度计算
要识别两张图片是否相似,首先我们可能会区分这两张图是人物照,还是风景照等......对应的风景照是蓝天还是大海......做一系列的分类。
andrew_a
2019/07/30
11.6K0
python图像识别---------图片相似度计算
【腾讯云云上实验室】《手把手带你 5 分钟构建以图搜图系统》
向量在数学中是一个可以表示多个维度或特性的对象。在我们日常生活中,也可以用来描述一个物体的多个属性。
码农学习联盟
2023/11/24
7450
【腾讯云云上实验室】《手把手带你 5 分钟构建以图搜图系统》
机器学习-11-基于多模态特征融合的图像文本检索
本系列是机器学习课程的系列课程,主要介绍机器学习中图像文本检索技术。此技术把自然语言处理和图像处理进行了融合。
用户2225445
2024/04/19
7370
机器学习-11-基于多模态特征融合的图像文本检索
大模型RAG向量检索原理深度解析
常规的知识库检索通常使用的是关键字与词条匹配,随着AGI的爆发,越来越多的知识库检索开始使用向量检索技术,特别是在RAG领域,增强型的生成式问答检索正在大面积应用和推广。
大脚攀爬
2024/04/18
1.8K0
大模型RAG向量检索原理深度解析
使用 TiDB Vector 搭建 RAG 应用 - TiDB 文档问答小助手
继上一次《TiDB Vector抢先体验之用TiDB实现以图搜图》后,就迫不及待的想做一些更复杂的应用。上一篇在 TiDB 社区专栏发布以后还是有很多社区朋友不明白向量的应用场景到底是什么,这次用一个更直观的场景来体现向量检索在 AI 应用开发的重要性。
HOHO
2024/06/05
2850
使用 TiDB Vector 搭建 RAG 应用 - TiDB 文档问答小助手
无所不能的Embedding 1 - Word2vec模型详解&代码实现
word2vec是google 2013年提出的,从大规模语料中训练词向量的模型,在许多场景中都有应用,信息提取相似度计算等等。也是从word2vec开始,embedding在各个领域的应用开始流行,所以拿word2vec来作为开篇再合适不过了。本文希望可以较全面的给出Word2vec从模型结构概述,推导,训练,和基于tf.estimator实现的具体细节。完整代码戳这里 https://github.com/DSXiangLi/Embedding
风雨中的小七
2020/08/11
1.8K0
无所不能的Embedding 1 - Word2vec模型详解&代码实现
Milvus:为存储和检索高维向量设计而生的 AI 时代数据库
在当今的大数据时代,非结构化数据正以指数级的速度增长,包括文本、图像、音频和视频等形式。要在这些数据中进行快速高效的搜索和管理,传统的关系型数据库往往显得力不从心。这种背景下,Milvus 作为一款专门为大规模向量搜索设计的开源数据库,得到了广泛应用。最新版本 Milvus 2.4 进一步巩固了它在行业中的领先地位。
编程小妖女
2025/01/06
3370
Milvus:为存储和检索高维向量设计而生的 AI 时代数据库
向量检索(RAG)之向量数据库研究
研究内容主要包括:是否开源,支持的功能有哪些(是否支持暴力检索,支持哪些索引),是否有可视化界面,是否支持标量过滤。
码之有理
2025/03/05
6950
Java开发者的Python快速实战指南:探索向量数据库之图像相似搜索-文字版
首先,我要向大家道个歉。原本我计划今天向大家展示如何将图片和视频等形式转换为向量并存储在向量数据库中,但是当我查看文档时才发现,腾讯的向量数据库尚未完全开发完成。因此,今天我将用文本形式来演示相似图片搜索。如果您对腾讯的产品动态不太了解,可以查看官方网址:https://cloud.tencent.com/document/product/1709/95477
努力的小雨
2023/12/05
4622
使用 SemanticKernel 进行 vector 的存储与检索
先祝大家 2025 新年好。 在 2024 年落地的 LLM 应用来看,基本上都是结合 RAG 技术来使用的。因为绝大多数人跟公司是没有 fine-turning 的能力的。不管是在难度还是成本的角度看 RAG 技术都友好的多。
郑子铭
2025/02/27
970
使用 SemanticKernel 进行 vector 的存储与检索
手把手教你使用CLIP和VectorDB构建一个以图搜图的工具
在传统的图像搜索引擎中,您通常使用文本查询来查找图像,搜索引擎根据与这些图像关联的关键字返回结果。另一方面,在图像到图像搜索中,您从图像作为查询开始,系统会检索在视觉上类似于查询图像的图像。
Color Space
2024/02/01
6860
手把手教你使用CLIP和VectorDB构建一个以图搜图的工具
利用OpenAI CLIP、Claude Sonnet 3.5和pgvector构建一个AI图库
本文探讨了使用 OpenAI CLIP、Claude Sonnet 3.5 和 pgvector 构建 AI 驱动的图片库的 RAG 应用挑战。
云云众生s
2024/10/01
1460
利用OpenAI CLIP、Claude Sonnet 3.5和pgvector构建一个AI图库
微信向量检索分析一体化数仓探索:OLAP For Embedding
在过去的一年里,大型语言模型 (LLM) 以及 ChatGPT 等产品吸引了全世界的想象力,推动新一轮技术浪潮。embedding 和 vector search(向量搜索)的概念是支持推荐、问答、图像搜索等功能的核心。我们发现社区中“向量搜索”的兴趣显著增加;具体来说,大家感兴趣了解的是:何时需要专门向量数据库,何时不需要?相比于语义性检索引擎(ES)与专业的高性能检索服务,OLAP 数仓的向量检索能力在场景有何区别?
腾讯技术工程官方号
2023/10/27
1K0
微信向量检索分析一体化数仓探索:OLAP For Embedding
推荐阅读
相关推荐
RAG 实战|用 StarRocks + DeepSeek 构建智能问答与企业知识库
更多 >
LV.1
DigitalChinaTiDB交付团队负责人
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验