本文主要以LLM的应用为基础,说明LLM与数据开发、数据分析领域的相关工作以及未来可能存在的发展。
大模型能够回答较为普世的问题,但是若要服务于垂直领域,会存在知识深度和时效性不足的问题,那么企业如何抓住机会并构建垂直领域服务?
目前有两种模式,第一种是基于大模型之上做垂直领域模型的Fine Tune,这个综合投入成本较大,更新的频率也较低,并不适用于所有的企业;第二种就是在向量数据库中构建企业自有的知识资产,通过大模型+向量数据库来搭建垂直领域的深度服务,本质是使用数据库进行提示工程(Prompt Engineering)。
上图显示了使用向量数据库搭建问答系统的基本框架。
1、用户的question通过embedding后通过词向量数据库查询与之相关的信息,产生konwledge。
2、用户的question和产生的konwledge一起喂给LLM,然后产生answer。
知识库的构成则由document转为向量,然后存储在向量数据库中。
在传统数据库,搜索功能都是基于不同的索引方式(B Tree、倒排索引等)加上精确匹配和排序算法(BM25、TF-IDF)等实现的。本质还是基于文本的精确匹配,这种索引和搜索算法对于关键字的搜索功能非常合适,但对于语义搜索功能就非常弱。
例如,如果你搜索“小狗”,那么你只能得到带有“小狗”关键字相关的结果,而无法得到“柯基”、“金毛”等结果,因为“小狗”和“金毛”是不同的词,传统数据库无法识别它们的语义关系,所以传统的应用需要人为的将“小狗”和“金毛”等词之间打上特征标签进行关联,这样才能实现语义搜索,因此,向量数据库的核心在于相似性搜索(Similarity Search)。
高效的搜索算法有很多,其主要思想是通过两种方式提高搜索效率:
1、减少向量大小——通过降维或减少表示向量值的长度。
2、缩小搜索范围——可以通过聚类或将向量组织成基于树形、图形结构来实现,并限制搜索范围仅在最接近的簇中进行,或者通过最相似的分支进行过滤。
参考链接:向量数据库技术鉴赏
在实际的业务场景中,往往不需要在整个向量数据库中进行相似性搜索,而是通过部分的业务字段进行过滤再进行查询。所以存储在数据库的向量往往还需要包含元数据,例如用户 ID、文档 ID 等信息。这样就可以在搜索的时候,根据元数据来过滤搜索结果,从而得到最终的结果。
为此,向量数据库通常维护两个索引:一个是向量索引,另一个是元数据索引。然后,在进行相似性搜索本身之前或之后执行元数据过滤,但无论哪种情况下,都存在导致查询过程变慢的困难。
过滤过程可以在向量搜索本身之前或之后执行,但每种方法都有自己的挑战,可能会影响查询性能:
为了优化过滤流程,向量数据库使用各种技术,例如利用先进的索引方法来处理元数据或使用并行处理来加速过滤任务。平衡搜索性能和筛选精度之间的权衡对于提供高效且相关的向量数据库查询结果至关重要。
向量数据库 | URL | GitHub Star | Language | Cloud |
---|---|---|---|---|
chroma | https://github.com/chroma-core/chroma | 7.4K | Python | ❌ |
milvus | https://github.com/milvus-io/milvus | 21.5K | Go/Python/C++ | ✅ |
pinecone | https://www.pinecone.io/ | ❌ | ❌ | ✅ |
qdrant | https://github.com/qdrant/qdrant | 11.8K | Rust | ✅ |
typesense | https://github.com/qdrant/qdrant | 12.9K | C++ | ❌ |
weaviate | https://github.com/weaviate/weaviate | 6.9K | Go | ✅ |
Milvus 是一款云原生向量数据库,它具备高可用、高性能、易拓展的特点,用于海量向量数据的实时召回。
Milvus 基于 FAISS、Annoy、HNSW 等向量搜索库构建,核心是解决稠密向量相似度检索的问题。在向量检索库的基础上,Milvus 支持数据分区分片、数据持久化、增量数据摄取、标量向量混合查询、time travel 等功能,同时大幅优化了向量检索的性能,可满足任何向量检索场景的应用需求。通常,建议用户使用 Kubernetes 部署 Milvus,以获得最佳可用性和弹性。
Milvus 采用共享存储架构,存储计算完全分离,计算节点支持横向扩展。从架构上来看,Milvus 遵循数据流和控制流分离,整体分为了四个层次,分别为接入层(access layer)、协调服务(coordinator service)、执行节点(worker node)和存储层(storage)。各个层次相互独立,独立扩展和容灾。
角色名称 | 作用 |
---|---|
root coord | 负责处理数据定义语言(DDL)和数据控制语言(DCL)请求。比如,创建或删除 collection、partition、index 等,同时负责维护中心授时服务 TSO 和时间窗口的推进 |
query coord | 负责管理 query node 的拓扑结构和负载均衡以及从增长的 segment 移交切换到密封的 segment |
data coord | 负责管理 data node 的拓扑结构,维护数据的元信息以及触发 flush、compact 等后台数据操作 |
index coord | 负责管理 index node 的拓扑结构,构建索引和维护索引元信息 |
角色名称 | 作用 |
---|---|
Query node | 通过订阅消息存储(log broker)获取增量日志数据并转化为 growing segment,基于对象存储加载历史数据,提供标量 + 向量的混合查询和搜索功能。 |
Data node | 通过订阅消息存储获取增量日志数据,处理更改请求,并将日志数据打包存储在对象存储上实现日志快照持久化 |
Index node | 负责执行索引构建任务。Index node 不需要常驻于内存,可以通过 serverless 的模式实现 |
角色名称 | 作用 |
---|---|
meta store | 负责存储元信息的快照,比如:集合 schema 信息、节点状态信息、消息消费的 checkpoint 等。元信息存储需要极高的可用性、强一致和事务支持,因此,etcd 是这个场景下的不二选择。除此之外,etcd 还承担了服务注册和健康检查的职责。 |
log broker | 负责存储日志的快照文件、标量 / 向量索引文件以及查询的中间处理结果。Milvus 采用 MinIO 作为对象存储,另外也支持部署于 AWS S3 和 Azure Blob 这两大最广泛使用的低成本存储。但是,由于对象存储访问延迟较高,且需要按照查询计费,因此 Milvus 未来计划支持基于内存或 SSD 的缓存池,通过冷热分离的方式提升性能以降低成本。 |
object storage | 负责存储日志的快照文件、标量 / 向量索引文件以及查询的中间处理结果。Milvus 采用 MinIO 作为对象存储,另外也支持部署于 AWS S3 和 Azure Blob 这两大最广泛使用的低成本存储。但是,由于对象存储访问延迟较高,且需要按照查询计费,因此 Milvus 未来计划支持基于内存或 SSD 的缓存池,通过冷热分离的方式提升性能以降低成本。 |
现阶段存在诸多的向量数据库结合LLM进行使用,有点百家曾鸣的意思,本节以阿里云的AnalyticDB PostgreSQL作为实践案例进行说明。ChatBot模型的整体架构框架如下:
整个过程主要有两个流程:前端问答流程+后端数据处理和存储流程。底层主要依赖两个模块:基于大语言模型的推理模块+基于向量数据库的向量数据管理模块。
前端问答流程
id | Content | embedding | document |
---|---|---|---|
1 | Doris是… | [0.1, -0.1,0,1] | OLAP数据库Doris |
2 | NBA比分 湖人-篮网 | [0.2,0.1,0.2,-1] | NBA今日播报 |
3 | Doris可以帮助我们XXX | [0.2,0.1,0.2,-1] | OLAP数据库Doris |
4 | AIGC是xxx | [0.2,0.1,0.2,-1] | AIGC介绍 |
基于以下已知信息,简洁和专业的来回答用户的问题。
如果无法从中得到答案,请说"根据已知信息无法回答该问题"或"没有提供足够的相关信息",不允许在答案中添加
编造成分,答案请使用中文。
已知内容:
1.Apache Doris产生与PALO...
2.Doris可以帮助我们xxx
问题:
Doris有什么用
后端数据处理和存储流程
ADB-PG建表举例说明
假设有一个文本知识库,它是将一批文章分割成chunk再转换为embedding向量后入库的,其中chunks表包含以下字段:
字段 | 类型 | 说明 |
---|---|---|
id | serial | 编号 |
chunk | varchar(1024) | 文章切块后的文本chunk |
intime | timestamp | 文章的入库时间 |
url | varchar(1024) | 文本chunk所属文章的链接 |
feature | real[] | 文本chunk embedding向量 |
本节主要对微软在探索式数据分析(Exploratory Data Analysis,EDA)领域的研究工作进行汇总。该项研究相关成功以及发表在SIGMOD等全球顶会上,起对应的工作也已经应用于Microsoft Excel、Microsoft Power BI和Microsoft Forms等微软产品中。
探索性数据分析(EDA)与传统统计分析(Classical Analysis)的区别
论文链接:https://dl.acm.org/doi/10.1145/3299869.3314037
数据洞察(Data insight):“insight” 是指从多维数据中发现的 interesting data pattern(有趣的数据模式),它反映了数据在某种特定视角下的有趣特征。
数据模型:给定多维数据集 R ( D , M ) \R(\mathcal{D},\mathcal{M}) R(D,M),其中 D = { D 1 , … , D d } \mathcal{D}=\{D_1,…,D_d\} D={D1,…,Dd} 表示维度的集合, M \mathcal{M} M 表示度量的集合。那么, d o m ( D i ) dom(D_i) dom(Di) 表示 D i D_i Di 的空间,例如如果 D i = D_i= Di= 性别,那么 d o m ( D i ) = { 男、女 } dom(D_i)=\{男、女\} dom(Di)={男、女}
insight的定义:ℎ ≔ {(), , (),, }
下图描述了 QuickInsights 的整体工作流程。整个工作流程可分为 3 个阶段:
搜索 & 任务生成(Search & Task Generation)
主题搜索模块会尝试枚举所有可能的子空间。每个子空间会通过 AutoImpact 模块计算并被赋予重要性度量 impact。然后,通过通过函数依赖性检查器(Functional-Dependency checker)的分解维度(breakdowns)会与子空间结合,生成洞察评估任务。生成的任务被存储在优先级队列中,重要性度量 impact 数值越高,优先级越高。每个task是按照参数计算所有的聚合指标,例如:
“SELECT Aggr1(measure1), Aggr2(measure2), … GROUP BY breakdownDimension where filter = subspace”.
查询 & 评估(Query & Evaluation)
任务的计算分为 3 步。1、 队列中优先级最高的任务会被工作线程取出;2、执行数据查询,并根据任务参数对所有度量进行聚合;3、发现洞察后,进行洞察评估。
存储 & 细化(Store & Refinement)
通过检测和消除函数依赖(Functional Dependency 简称 FD)产生的 EII(Easily Inferable Insights 容易推断的洞察)来提高洞察质量。下图说明了5种可能导致Ell的FD。
以ID2为例举例:“高度类别”(Height-Category)是通过度量高度(height)来计算的
任意以高度类型作为分解维度,描述高度的洞察都是无效的。以 Outstanding No.1 洞察为例:“类型为 high 的高度在整体的类型中处于领先地位”,这个结论无论洞察的子空间是什么,都是预先确定(pre-determined)的。
论文链接:https://www.microsoft.com/en-us/research/uploads/prod/2021/03/metainsight-extended.pdf
在 QuickInsight 的框架下,数据洞察被表征为 三元组。实际分析场景中,研究员们发现这样的洞察主要适用于服务基础的分析任务。MetaInsight 是在基本数据洞察的基础上,利用多个insight subject 内部的同质关系,形成更高层面的数据洞察,从而可更有效地推动探索性数据分析。
MetaIngInsight定义:MetaInsightHDP:=
MetaInsight 把 HDP (同质数据模式 Homogeneous Data Pattern)分类为 CommSet 和异常特征 Exc,从而提供了一个结构化的知识表现形式。MetaInsight 是 EDA 中经典的假设、验证过程的具象化表示,每个 commonness 表示了一个通用知识,exceptions 被用于让用户聚焦于非同寻常的案例,并了解它与通用知识的差异。
假设有一个数据集,假设存储的表名叫 sale_table 示例如下:
下图显示了一个典型的EDA迭代。
SELECT SUM(sales) FROM sale_table WHERE city='Los Angeles' GROUP BY month
SELECT SUM(sales) FROM sale_table WHERE city='Amador' GROUP BY TO_MONTH(order_date)
注:什么是同质案例?如何获取同质案例?
一个具有显著性的案例,是从一个数据域(< filter,group by 字段,度量> 三元组)中探测出来的。那么,将这个三元组任意变更一个元素,就得到了这个数据域的衍生数据域。以上面例子来说,原始的查询是:SELECT SUM(sales) FROM sale_table WHERE city='Los Angeles' GROUP BY month
SELECT SUM(sales) FROM sale_table WHERE city='Amador' GROUP BY TO_MONTH(order_date)
。SELECT SUM(sales) FROM sale_table WHERE city='北京' GROUP BY TO_WEEK(month)
。类比 EDA 场景中,观察到洛杉矶交易额月趋势有单峰性异常,继续观察周趋势的数据分布情况。文章中限定了一个约束,扩展的 group by 字段必须是时间类型。但是推广一下,扩展的 group by 字段可以是和原有字段具有函数依赖的字段。例如,原来的字段是"city",那么就可以将group by 字段扩展为 “province”。SELECT SUM(profit) FROM sale_table WHERE city='Los Angeles' GROUP BY month
。类比 EDA 中,得到交易额的月分布后,继续探索利润及其他度量的分布情况。为了高效且交互式的 EDA,MetaInsight 挖掘过程是递进式的,在预先定义的时间窗口内,返回当前最好的结果。将挖掘过程解构成搜索 search、查询 query、评估 evaluation 3 个功能。所有合格的 MetaInsight 候选都会被存储,然后被后续的任务(例如模式索引,排序或多样化)处理。
下图是MetaInsight的工作流程。数据模式挖掘模块以多维数据作为入参,挖掘数据集中的数据模式。找到数据模式后,相关的数据域就会被扩展成几个 HDS,然后 MetaInsight 挖掘模块以此为入参,找到 MetaInsight 后将其保存下来并在时间窗到期时将其发送到排名模块。搜索功能探查所有(同质)数据域,输出对应的计算单元,并计算这些计算单元的优先级。查询功能在每个计算单元中进行,它的职责是从原始数据中查询、具体特定的(同质)数据域。评估功能执行数据模式评估及 MetaInsight 评估,用以决定数据模式及 MetaInsights 是否存在。
论文链接:https://arxiv.org/abs/2207.12718
在数据分析场景中,可解释性是固有的一个需求。人们对各种数据中的现象进行观察,总结出适用概念,提出假设性的机制来解释观测,再提供预测,等等。这些分析过程中可解释性是普遍存在的。
一个典型的场景是对异常数据进行解释。对异常的解释不仅在 MetaInsight 的使用中较为常见,而且更广泛地存在于日常数据分析的场景中。例如在销量数据中,用户希望探知某一年销量下降的原因;在游客数据中,用户希望解析出不同地域之间游客的差异。
explanation的定义:explanation := ⟨type, predicate, responsibility⟩
下图显示了XDA的一个应用场景。通过基础的数据洞察,发现A和B地区肺癌存严重程度不一样,提出问题:吸烟为患者为什么患有不同严重程度的肺癌?这是典型的因果问题。
XInsight 首先利用因果发现(causal discovery)定性地寻找数据内部变量之间的因果关系。基于定性的因果关系,XInsight 提出了 XTranslator,将因果图(causal graph)上的因果语义转化为可解释数据分析(Explainable Data Analysis,XDA)的语义。根据 XDA 层面的语义信息,XInsight 再进一步利用实际因果性(actual causality)框架定量地分析每个变量内部不同取值对数据差异的影响,最终获得解释。
通过 XInsight 可以得出一个因果关系的解释,即“吸烟”是肺癌严重程度的定性因素,并且强调“吸烟=是”(Smoking=Yes)及其作为定量解释的责任(responsibility)。用户能够据此更深入地理解不同区域患者肺癌严重程度之间的差异,并针对吸烟这一因素提出相应的干预措施,如制定更严格的烟草控制政策、推广禁烟宣传等,以达到更好的防控效果。
XInsight通过Xleaner、Xtranslator、Xplainer三个模块为可解释的数据分析提供了一个统一的框架。XInsight的工作流程如下图所示。
Demonstration of InsightPilot: An LLM-Empowered Automated Data Exploration System
论文链接:https://arxiv.org/abs/2304.00477
MetaInsight 和 XInsight 所展现出的自动化数据探索工具的巨大潜力,都是基于某个特定的数据洞察,从而触发了数据分析意图(data analysis intent),它们的输出是数据分析意图在数据中的一种体现。但是,从另一个角度来看,这表示现有的解决方案的智能程度仍存在不足,MetaInsight 和 XInsight 还需要依赖人类数据分析师来找到特定的触发条件,并且在多数情况下,单一的数据洞察往往不能满足用户的真实需求。
传统方式:
为了实现更为自动化的数据探索,InsightPilot 将数据探索的过程抽象为由 context-intent-analysis 组成的序列,即利用大语言模型(LLM)理解已有的数据洞察(context)、提出一个合理的数据分析意图(intent),并由 Insight Engine 将意图转化为具体的数据分析(analysis)。通过利用数据分析的结果对数据洞察进行更新,让 LLM 推荐新的数据分析意图,从而迭代形成若干个由 context-intent-analysis 三元组完成的序列,从而使 InsightPilot 完成整个数据探索的过程。
下图显示了Alice使用InsightPilot应用于Alice的场景。
每次LLM选择洞察和分析意图时,Insight Engine都会启动相应的IQuery来实例化分析意图。InsightPilot一共产生三种类型的IQuery:understand、summarize、explain,分别对应QuickInsight、MeatInsight、XInsight。
类型 | 方式 | 用户给定的Insight | 实例化分析Insight |
---|---|---|---|
understand | 基于所选Insight从输入数据集中提取上下文子集 | 数学成绩的增长趋势 | 上下文子集将构成“主题=数学”的行 |
summarize | 可以触发对所选见解的两种总结(数学科目、学校) | 数学成绩的增长趋势 | 1、对于大多数学校,学生的数学成绩随着时间的推移一直在增加,除了C学校 2、对于大多数科目,学生的分数随着时间的推移一直在增加 |
explain | 用于解释洞察中的意外结果 | C学校2020年数学成绩的异常值 | 2019年和2020年C学校学生数学成绩的差异是由考试表=带回家引起的。当排除考试表=拿回家时,2020年不再是一个例外。 |
为了将LLM顺利集成到InsightPilot中,需要为LLM提供一组包含指令和上下文的提示。根据InsightPilot的不同阶段,InsightPilot开发了四个提示模板,即Initialization、 Analysis intent selection、Insight selection以及Report generation。
由于LLM的容量有限,不可能将所有见解提供给LLM,为了处理这些压倒性的见解,我们采用了三种混合策略来排名和提取顶部topN见解。
博客链接:https://lilianweng.github.io/posts/2023-06-23-agent/
随着chatgpt提供的plugin和function call功能出现,激发了大家对LLM作为智能中枢架构的思考。microsoft、google基于LLM发布的copilot架构的应用程序之前陆续推出时,也是引发大家思考LLM是如何与外部复杂的系统交互的。之前在github上,有一些project实现了类似的能力,有开发脚手架的比如langchain agent,也有AutoGPT、BabyAGI这种已经有一定封装的工具。但缺乏一篇能站在更高视角,比如用人类的记忆、人类使用工具的类比映射到人工智能,去讲这套架构以及这套架构在应用层面有哪些想象空间的文章。
在基于LLM的自动agent体系里, LLM就是作为agent的大脑,其他几个能力作为补充:
思维链(Chain of thought,CoT; Wei et al. 2022)已成为提高模型在复杂任务上性能的标准提示(prompt)技术。该模型被指示需要进行“逐步思考”,从而利用更多的测试时间计算将困难任务分解为更小、更简单的步骤。思维链将大任务转化为多个可处理的任务,并对模型思考过程进行了解释。
思想树(Tree of Thoughts;Yao et al. 2023)通过在每个步骤中探索多种推理可能性来扩展思维链。它首先将问题分解为多个思考步骤,并在每个步骤中生成多个思考,从而形成一个树状结构。搜索过程可以是广度优先搜索(BFS)或深度优先搜索(DFS),每个状态都通过分类器(通过提示)或多数投票进行评估。
另一种非常独特的方法是LLM+P(Liu et al. 2023),它依赖于外部的经典规划器来进行长期规划。这种方法利用规划领域定义语言(Planning Domain Definition Language,PDDL)作为中间接口来描述规划问题。在这个过程中,LLM首先(1)将问题转化为“问题PDDL(Problem PDDL)”,然后(2)请求经典规划器基于现有的“领域PDDL(Domain PDDL)”生成一个PDDL规划,最后(3)将PDDL规划转化回自然语言。
ReAct (Yao et al. 2023) ReAct整合了推理和行动能力,他扩展了LLM,让LLM能做一些语言模型内部能力不具备的行为,也扩展了大语言模型的表达空间。他让大语言模型能够与外部环境交互(比如使用Wikipedia search API),使用外部search engine),同时再把这些与外部交互获取的结果整理后放入prompt里与LLM交互,让LLM进一步的进行推理,这样整个系统就能将大语言模型与外部系统交互、思考的整个过程进行追踪,相当于用自然语言做了logging。
Chain of Hindsight(CoH; Liu et al. 2023) 的想法是在上下文中呈现一系列逐步改进的输出历史,并训练模型跟随趋势产生更好的输出。通过带有反馈标记的历史输出序列,来鼓励模型不断改进。人类反馈(Human feedback)数据是一个集合 Dh= {(x, yi, ri, zi)} i=1-n,其中 x是提示,yi是模型的完成结果,ri是对于yi的评分,zi是对所提供回答的回顾反馈。在给定序列前缀的条件下,模型被微调为仅预测(对应最高评分),以便模型可以根据反馈序列进行自我反思,产生更好的输出。模型在测试时可以选择接收人类注释员的多轮指令。
记忆可以定义为获取、存储、保留和后续检索信息的过程。人脑中有几种类型的记忆。
最大内积搜索(Maximum Inner Product Search,MIPS)
外部存储器可以缓解有限的注意力跨度限制。一种常见的做法是将信息的嵌入表示保存到一个向量存储数据库中,该数据库可以支持快速的最大内积搜索(MIPS)。为了优化检索速度,常见的选择是使用近似最近邻(approximate nearest neighbors,ANN)算法,以在一定的准确性损失下返回大约前k个最近邻,以换取巨大的加速效果。
ChatGPT插件和OpenAI API函数调用是LLM在实践中能够使用工具的很好例子。工具API的集合可以由其他开发者提供(如插件)或自定义(如函数调用)。
HuggingGPT(Shen et al. 2023)是一个框架,利用ChatGPT作为任务规划器,根据模型描述选择HuggingFace平台上可用的模型,并根据执行结果总结回应。
该系统由4个阶段组成:
(1)任务规划(Task planning):LLM作为大脑,将用户请求解析为多个任务。每个任务都有四个属性:任务类型、ID、依赖关系和参数。他们使用少量示例(few-shot)来指导LLM进行任务解析和规划。
(2)模型选择(Model selection):LLM将任务分配给专家模型,其中请求被构建为一个多项选择题。LLM被提供了一个模型列表供选择。由于上下文长度有限,需要基于任务类型进行筛选。
(3)任务执行(Task execution):专家模型在特定任务上执行并记录结果。
(4)响应生成(Response generation):LLM接收执行结果并向用户提供总结的结果。