你要的增量更新来了:微软GraphRAG 0.4.0

科技   2024-11-07 10:10   北京  
微软GraphRAG自发布以来,引起了很大关注(目前18.7k star),但是一些功能却迟迟没有,比如增量更新。今天微软GraphRAG发布v0.4.0,3小时前,还是新鲜热乎的,带来两项重要更新:
  • 添加增量索引

  • 添加了 DRIFT 图推理查询模块

增量更新索引逻辑

增量更新逻辑代码在这https://www.microsoft.com/en-us/research/blog/introducing-drift-search-combining-global-and-local-search-methods-to-improve-quality-and-efficiency/
获取数据变化:get_delta_docs函数用于比较输入数据集和存储中的最终文档,识别出新增和删除的文档。这是增量更新的核心部分,只有变化的部分会被进一步处理。
async def get_delta_docs(    input_dataset: pd.DataFrame, storage: PipelineStorage) -> InputDelta:    """Get the delta between the input dataset and the final documents.
Parameters ---------- input_dataset : pd.DataFrame The input dataset. storage : PipelineStorage The Pipeline storage.
Returns ------- InputDelta The input delta. With new inputs and deleted inputs. """ final_docs = await _load_table_from_storage( "create_final_documents.parquet", storage )
# Select distinct title from final docs and from dataset previous_docs: list[str] = final_docs["title"].unique().tolist() dataset_docs: list[str] = input_dataset["title"].unique().tolist()
# Get the new documents (using loc to ensure DataFrame) new_docs = input_dataset.loc[~input_dataset["title"].isin(previous_docs)]
# Get the deleted documents (again using loc to ensure DataFrame) deleted_docs = final_docs.loc[~final_docs["title"].isin(dataset_docs)]
    return InputDelta(new_docs, deleted_docs)

更新数据框架输出:update_dataframe_outputs函数负责更新各种数据框架,包括实体、关系、文本单元、协变量、节点和社区。这个函数会调用其他函数来处理这些更新。
async def update_dataframe_outputs(    dataframe_dict: dict[str, pd.DataFrame],    storage: PipelineStorage,    update_storage: PipelineStorage,    config: PipelineConfig,    cache: PipelineCache,    callbacks: VerbCallbacks,    progress_reporter: ProgressReporter,) -> None:    """Update the mergeable outputs.
Parameters ---------- dataframe_dict : dict[str, pd.DataFrame] The dictionary of dataframes. storage : PipelineStorage The storage used to store the dataframes. """ progress_reporter.info("Updating Final Documents") final_documents_df = await _concat_dataframes( "create_final_documents", dataframe_dict, storage, update_storage )
# Update entities and merge them progress_reporter.info("Updating Final Entities") merged_entities_df, entity_id_mapping = await _update_entities( dataframe_dict, storage, update_storage, config, cache, callbacks )
# Update relationships with the entities id mapping progress_reporter.info("Updating Final Relationships") merged_relationships_df = await _update_relationships( dataframe_dict, storage, update_storage    )

DRIFT图推理查询逻辑

DRIFT搜索原理:https://www.microsoft.com/en-us/research/blog/introducing-drift-search-combining-global-and-local-search-methods-to-improve-quality-and-efficiency/
  • 在全面性方面,DRIFT 搜索的表现比local search好 78%。
  • 在多样性方面,DRIFT 搜索的表现比local search好 81%

DRIFT搜索层级的全景,突出了DRIFT搜索过程的三个核心阶段。A(预处理):DRIFT将用户查询与最语义相关的前K个社区报告进行比较,生成一个广泛的初始答案和后续问题,以引导进一步的探索。B(后续):DRIFT使用局部搜索来细化查询,产生额外的中间答案和后续问题,增强了具体性,引导引擎朝向内容丰富的信息。图中每个节点上的一个符号显示了算法继续查询扩展步骤的信心。C(输出层级):最终输出是一个按相关性排名的问题和答案的层级结构,反映了全局洞察和局部细化的平衡混合,使结果具有适应性和可理解性。


  • 预处理:当用户提交查询时,DRIFT会将其与最语义相关的前K个社区报告进行比较。这会产生一个初始答案以及几个后续问题,这些后续问题作为全局搜索的轻量级版本。为了实现这一点,我们使用假设文档嵌入(HyDE)扩展查询,以提高敏感性(召回率),嵌入查询,将查询与所有社区报告进行比对,选择前K个,然后使用这前K个尝试回答查询。目标是利用高级抽象来指导进一步的探索。

  • 后续:在预处理就绪后,DRIFT使用局部搜索变体执行每个后续问题。这会产生额外的中间答案和后续问题,形成一个持续细化的循环,直到搜索引擎满足其终止条件,目前配置为两次迭代(进一步的研究将研究奖励函数以指导终止)。这个阶段代表了全局信息引导的查询细化。使用全局数据结构,即使初始查询偏离索引角色,DRIFT也能导航到知识图中的具体、相关信息。这个后续过程使DRIFT能够根据新出现的信息调整其方法。

  • 输出层级:最终输出是按与原始查询的相关性排名的问题和答案的层级结构。这个层级结构可以定制以满足特定用户需求。在基准测试期间,一个简单的映射-归约方法聚合了所有中间答案,每个答案的权重相等。

来源 | PaperAgent

深度学习与NLP
专注深度学习、NLP相关技术、资讯,追求纯粹的技术,享受学习、分享的快乐。
 最新文章