毫秒级!千万人脸库快速比对,上亿商品图片检索,背后的极速检索用了什么神器? ⛵
💡 作者:韩信子@ShowMeAI
📘 机器学习实战系列:https://www.showmeai.tech/tutorials/41
📘 深度学习实战系列:https://www.showmeai.tech/tutorials/42
📘 本文地址:https://www.showmeai.tech/article-detail/299
📢 声明:版权所有,转载请联系平台与作者并注明出处
📢 收藏ShowMeAI查看更多精彩内容
💡 前言
📌 结构化数据 V.S. 非结构化数据
互联网发展的数十年来,技术在飞速前进,伴随着海量结构化表格数据的存储,结构化数据上的商业智能分析挖掘发展,也有海量的非结构化数据散布于各个互联网平台:
超过 80-90% 的数据是非结构化信息,例如文本、视频、音频、Web 服务器日志、社交媒体等
📌非结构化数据的挑战
因为非结构化数据没有标准的行列结构,因此与结构化数据的存储和分析挖掘及查询都是截然不同的,我们没办法将非结构化数据的内容存储在关系数据库中,针对它们的应用有以下挑战:
- 存储: 常规关系数据库非常适合保存结构化数据,但不适合非结构化数据。
- 表示: 我们需要将非结构化数据转换为一些有效的向量或嵌入表征,才能完成后续任务。
- 查询: 结构化数据的检索与查询,无法像结构化数据一样通过 SQL 匹配查询,我们通常要进行向量级别的比对与排序等。
📌非结构化数据的表征
为了让计算机理解、处理和表征非结构化数据,我们通常将它们转换为密集向量,通常称为嵌入。如上图所示。
近代的算法技术有很多神经网络的方法可以把非结构化数据表征为嵌入向量,例如卷积神经网络(CNN)可以对图像进行特征抽取与向量表示,而 LSTM 和 Transformer 等模型可以很方便地对文本数据进行向量化表征。
📌非结构化数据的挑战
完成非结构化数据的表征仅仅是第1步,我们仅仅有这些嵌入向量是不够的,还需要能够查询和找出相似的向量。
大家在日常使用到的 APP 中,看到的很多多媒体智能应用都依赖于海量矢量数据中的相似性检索 AI 技术,包括百度和淘宝的视觉(图像)搜索/以图搜图、抖音视频的推荐系统、QQ音乐的听曲识歌等,也包括安防系统天眼等的人脸比对识别等。
💡 向量检索工具
海量向量数据的存储、管理和查询并不是一项简单的任务,我们会依赖专门的工具来完成这项工作,现代 AI 领域有非常好用的向量数据库,在本文中 ShowMeAI 将给大家详细介绍,主要覆盖以下几个方面:
- 向量和向量相似性搜索
- 向量数据库
- 顶级向量数据库 Milvus
- Milvus 视觉图像搜索案例
💡 向量和向量相似性搜索
📌 向量
刚才我们说到了,因为计算机只能理解和计算数值,我们要将图像和文本等非结构化数据表示为浮点数向量,它们表示相应的数据(图像、文本等)。
下列涉及到的 NLP 和 CV 模型技术,可以通过ShowMeAI的下述图解教程做更全面的学习:
在自然语言处理(NLP)领域,我们有许多词嵌入模型,例如 Word2Vec、GloVe 和 FastText ,它们可以帮助将词表示为数值向量。后来新技术的推进,我们有了强大的 📘 Transformer 模型 📘 BERT,它可以用来学习上下文嵌入向量以及对整个句子和段落的向量化表示。
在计算机视觉(CV)领域,我们有像 📘 卷积神经网络(CNN)的模型,它可以帮助从图像和视频中学习向量化表示。随着 Transformer 的兴起,我们也有了 📘 Vision Transformers,有更好的视觉表征能力。
有了这些强大的向量表征方法,我们就可以利用它们来解决现实世界的问题,例如以图搜图,我们上传图片就可以检索返回视觉上相似图像检索结果。Google 的『以图搜图』是非常流行的应用,如下图所示。
你可以把每张图片想象成一个具有 D 维数的向量,我们可以使用『欧氏距离』或者其他距离度量(如『汉明距离』或『余弦距离』)来找出两个数据点(图片)之间的远近距离,可以量化地衡量2个样本的接近程度。例如,二维平面中两点之间的『欧氏距离』如下图所示。
📌 向量相似性搜索
矢量相似度搜索,也称为最近邻(NN)搜索,基本上是计算检索样本和现有(数据库中)样本集合中的样本距离,并返回前『k』个最近邻,也即前『k』个最相似的样本。计算这种相似度的关键部分是相似度度量,有不同的形式,包括欧氏距离、内积、余弦距离、汉明距离等。距离越小,我们认为2个向量越相似。
精确最近邻(NN)搜索是非常耗时的,每次都需要计算 N 个距离(假设有 N 个需要比对的数据库样本)才可以排序得到结果。
为了加快计算速度,我们通常利用近似最近邻搜索(ANN 搜索),它会以近似的方式来匹配和完成检索任务。典型的 ANN 索引方法包括:
- 向量变换: 使用如降维(例如 PCA \ t-SNE)、旋转等方法把向量降维以加速计算
- 矢量编码: 使用如局部敏感散列(LSH)、量化、树等方式,对数据重新映射或组织,从而更快地检索相似样本
- 非穷举搜索方法: 使用如邻域图、倒排索引等方法,非穷举的方式完成搜索
所有这些提到的方法,都指向我们即将介绍的向量数据库,它是具备以上 ANN 的数据库实现,功能强大!
💡 向量数据库
向量数据库是可扩展的数据平台,用于存储、索引和查询使用深度学习模型从非结构化数据(图像、文本等)生成的嵌入向量。最好和最先进的向量数据库,可以做到在数百万或数十亿个目标向量中插入、索引和搜索,并且可以选择和灵活配置索引算法和相似性度量方式。
如果是面向企业的健壮高效数据库系统,要同时具备以下关键要求:
- 可扩展性:向量数据库应该能支撑数十亿个嵌入向量的索引建立并运行近似最近邻搜索
- 稳定度:向量数据库应该能够处理内部故障而不会丢失数据,有好的容错性
- 高效率:查询和写入速度对于矢量数据库很重要。对于像 小红书 和 微博 这样每秒可以上传成百上千张新图片的平台来说,速度成为一个非常重要的因素。
向量数据库除了存储向量数据,还需要完成高效的数据索引构建,以便快速检索,还需要支持 CRUD(创建、读取、更新和删除)操作,以及支持属性过滤(即基于元数据字段/标量字段进行过滤)。
一个简单的例子是淘宝场景下,根据指定品牌的图像向量检索相似的鞋子,这里的品牌就是过滤的属性。
我们即将给大家介绍到 Milvus 向量数据库,上图展示了 Milvus 属性过滤的过程,Milvus 在过滤机制中引入了位掩码的概念,在满足特定属性过滤器的基础上,保留位掩码为 1 的相似向量。
💡 顶级向量数据库 Milvus
📘 Milvus 是一个开源的向量数据库管理平台,专为海量向量数据和简化机器学习操作(MLOps)而构建。
Milvus 具有广泛的应用,包括药物发现、计算机视觉、推荐系统、聊天机器人等等。Milvus 包含以下特性和功能:
- 万亿向量数据集上的超快搜索速度: 万亿向量数据集上向量搜索和检索的平均延迟已达毫秒级别。
- 简化的非结构化数据管理:Milvus 拥有丰富的 API,专为数据科学工作流程而设计。
- 可靠稳定: Milvus 内置的备份和故障转移/故障恢复功能确保数据和应用程序可以始终保持业务连续性。
- 高度可扩展性: 组件级可扩展性可以很好地支撑按需扩展和缩减。
- 混合搜索: 除了向量之外,Milvus 还支持布尔、字符串、整数、浮点数等数据类型。Milvus 将标量过滤与强大的向量相似性搜索结合起来(如前面提到的属性过滤)。
- 统一的 Lambda 结构: Milvus 结合流和批处理进行数据存储,平衡时效性和效率。
- 社区支持和行业认可: 1000+名企的选择,📘 GitHub 开源并有活跃的开源社区。
❌ 其他工具库及局限
构建基于向量相似性搜索的 AI 系统,常见的工具库实现也都是基于近似最近邻搜索(ANNS)的,例如:
- Facebook AI 相似度搜索(FAISS):FAISS框架支持高效的相似度搜索和密集向量的聚类,包含在任意大小的向量搜索的算法。它支持索引功能,如倒排多索引和量化。
- Spotify's Annoy(Approximate Nearest Neighbors Oh Yeah):Annoy 框架使用随机投影并构建树结构以在大规模密集向量上实现ANNS。
- Google 的 ScaNN(Scalable Nearest Neighbors): ScaNN 框架支持在大规模数据上高效执行向量相似性搜索。核心技术包括最大内积搜索(MIPS)的搜索空间修剪和量化。
这些也都是一些可选用的向量数据检索库,但这些工具库相比于 Milvus 这样成熟的向量数据管理系统,有一些弱点和局限性。
- 灵活性: 上述工具通常将所有数据存储在主内存中,无法支撑多台机器上的分布式模式,不适合处理海量数据集
- 动态数据处理: 一旦输入工具库,数据通常被视作静态的,对动态数据处理没有很好的支持
- 高级查询处理: 大多数工具库不支持高级查询处理(例如,属性过滤、混合搜索和多向量查询)
- 异构计算优化: 除了FAISS,很少有工具在 CPU 和 GPU 上为异构系统架构提供优化,会有明显的效率损失。
📌 Milvus 的优势
📘 Milvus 针对上述问题优化,具备以下优势:
- 它通过提供对各种应用程序接口(包括 Python、Java、Go、C++ 和 RESTful API 中的 SDK)的支持来增强灵活性
- 它支持多种向量索引类型(例如,基于量化的索引和基于图的索引),以及高级查询处理
- Milvus 使用日志结构的合并树(LSM 树)处理动态向量数据,保持数据插入和删除的效率,对实时搜索支持也很好
- Milvus 针对现代 CPU 和 GPU 上的异构计算架构提供优化,我们可以灵活针对特定场景、数据集和应用环境调整系统
Milvus 的向量执行引擎 Knowhere 是一个操作接口,用于访问系统上层的服务和系统下层的Faiss、Hnswlib、Annoy 等向量相似度搜索库。此外,Knowhere 还负责异构计算。Knowhere 控制在哪些硬件(例如 CPU 或 GPU)上执行索引构建和搜索请求。这就是 Knowhere 得名的原因——知道在哪里执行操作。未来版本将支持更多类型的硬件,包括 DPU 和 TPU。
Milvus 中的计算主要涉及向量和标量运算。上图展示了 Milvus 中的 Knowhere 架构:
- 最底层是系统硬件
- 第三方索引库位于硬件之上
- 上方Knowhere 通过 CGO 与顶部的索引节点和查询节点进行交互
Knowhere 不仅进一步扩展了 Faiss 的功能,还优化了性能,支持 BitsetView、支持更多相似指标、支持 AVX512 指令集、自动 SIMD 指令选择。
📌Milvus整体架构
上图展示了 📘 Milvus平台的整体架构。Milvus 将数据流与控制流分离,分为四层,在可扩展性和容灾方面是独立的。
- 接入层: 接入层由一组无状态代理组成,作为系统的前端和用户的端点。
- 协调器服务: 协调器服务负责集群拓扑节点管理、负载均衡、时间戳生成、数据声明、数据管理。
- 工作节点: 工作节点(执行节点)执行协调器服务发出的指令和代理发起的数据操作语言(DML)命令。Milvus 中的工作节点类似于 📘 Hadoop 和 HBase 中的区域服务器。
- 存储: 这是 Milvus 的基石,负责数据的持久化。存储层由元存储、日志代理和对象存储构成。
💡 Milvus 视觉图像搜索案例
一个典型的应用是基于 Milvus 构建图像检索系统。开发者可以使用预训练的 AI 模型将自有图像数据集转换为向量,然后利用 Milvus 实现以图搜图功能,匹配和返回相似图片结果。如下为基于 Milvus 的『以图搜图』架构图。
数据处理流程部分可以结合开源框架 📘 towhee,它利用像 ResNet-50 这样的预训练 CNN 模型,从图像中提取表征向量,再基于 Milvus 存储和索引这些向量,并将图像 ID 映射到 MySQL 数据库中的实际图片。Milvus 构建完索引后,可以轻松根据上传的新图像,进行大规模图像搜索。
下图为视觉图像搜索的示例图:
参考链接
- 📘 深度学习教程:吴恩达专项课程 · 全套笔记解读:https://www.showmeai.tech/tutorials/35
- 📘 自然语言处理教程:斯坦福CS224n课程 · 课程带学与全套笔记解读:https://www.showmeai.tech/tutorials/36
- 📘 深度学习与计算机视觉教程:斯坦福CS231n · 全套笔记解读:https://www.showmeai.tech/tutorials/37
- 📘 Transformer:https://arxiv.org/abs/1706.03762
- 📘 BERT:https://jalammar.github.io/illustrated-bert/
- 📘 卷积神经网络 CNN:https://proceedings.neurips.cc/paper/2012/file/c399862d3b9d6b76c8436e924a68c45b-Paper.pdf
- 📘 Vision Transformers:https://arxiv.org/abs/2010.11929
- 📘 Milvus 官网:https://milvus.io/
- 📘 Milvus GitHub:https://github.com/milvus-io/milvus
- 📘 Facebook AI 相似度搜索(FAISS):https://ai.facebook.com/tools/faiss/
- 📘 Spotify's Annoy (Approximate Nearest Neighbors Oh Yeah):https://github.com/spotify/annoy
- 📘 Google 的 ScaNN (Scalable Nearest Neighbors):https://github.com/google-research/google-research/tree/master/scann
- 📘 Hadoop:https://hadoop.apache.org/
- 📘 towhee:https://github.com/towhee-io/towhee