教程:构建提取式问答流水线
最后更新:2025 年 8 月 25 日
- 级别:入门
- 完成时间:15 分钟
- 使用的组件:
ExtractiveReader、InMemoryDocumentStore、InMemoryEmbeddingRetriever、DocumentWriter、SentenceTransformersDocumentEmbedder、SentenceTransformersTextEmbedder - 目标:完成本教程后,您将学会如何构建一个 Haystack 流水线,该流水线使用提取模型来显示查询答案在原文中的位置。
概述
什么是提取式问答?很高兴您提问!简而言之,提取式模型从文本中提取逐字答案。它适用于准确性至关重要且您需要确切知道答案来自文本何处的用例。如果您想要更多背景信息,可以阅读这篇关于提取式与生成式语言模型的深入探讨。
在本教程中,您将创建一个 Haystack 流水线,该流水线根据提供的文档提取问题的答案。
为了将数据输入提取式流水线,您还将构建一个索引流水线来获取、处理并加载 “古代世界七大奇迹”数据集的维基百科页面。
准备 Colab 环境
# 安装
%%bash
pip install haystack-ai accelerate "sentence-transformers>=4.1.0" "datasets>=2.6.1"
将数据加载到DocumentStore中
在使用提取式流水线中的这些数据之前,您将使用索引流水线来获取、处理并将其加载到文档存储中。
数据已经过清理和预处理,因此将其转换为 Haystack Documents 非常简单。
在此处使用 InMemoryDocumentStore 可以保持简单。但是,这种通用方法同样适用于Haystack 支持的任何文档存储。
SentenceTransformersDocumentEmbedder 将每个 Document 转换为向量。我们在这里使用了sentence-transformers/multi-qa-mpnet-base-dot-v1。您可以替换任何您喜欢的嵌入模型,只要在提取式流水线中使用相同的模型即可。
最后,DocumentWriter 将向量化后的文档写入 DocumentStore。
from datasets import load_dataset
from haystack import Document
from haystack import Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
from haystack.components.readers import ExtractiveReader
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack.components.writers import DocumentWriter
dataset = load_dataset("bilgeyucel/seven-wonders", split="train")
documents = [Document(content=doc["content"], meta=doc["meta"]) for doc in dataset]
model = "sentence-transformers/multi-qa-mpnet-base-dot-v1"
document_store = InMemoryDocumentStore()
indexing_pipeline = Pipeline()
indexing_pipeline.add_component(instance=SentenceTransformersDocumentEmbedder(model=model), name="embedder")
indexing_pipeline.add_component(instance=DocumentWriter(document_store=document_store), name="writer")
indexing_pipeline.connect("embedder.documents", "writer.documents")
indexing_pipeline.run({"documents": documents})
构建抽取式问答流水线
您的提取式问答流水线将由三个组件组成:嵌入器、检索器和阅读器。
-
SentenceTransformersTextEmbedder使用上面定义的相同嵌入模型将查询转换为向量。 -
向量搜索使检索器能够从文档存储中高效地返回相关文档。检索器与文档存储紧密耦合;因此,您将使用
InMemoryEmbeddingRetriever来配合InMemoryDocumentStore。 -
ExtractiveReader返回查询的答案,以及它们在源文档中的位置和置信度分数。
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
from haystack.components.readers import ExtractiveReader
from haystack.components.embedders import SentenceTransformersTextEmbedder
retriever = InMemoryEmbeddingRetriever(document_store=document_store)
reader = ExtractiveReader()
reader.warm_up()
extractive_qa_pipeline = Pipeline()
extractive_qa_pipeline.add_component(instance=SentenceTransformersTextEmbedder(model=model), name="embedder")
extractive_qa_pipeline.add_component(instance=retriever, name="retriever")
extractive_qa_pipeline.add_component(instance=reader, name="reader")
extractive_qa_pipeline.connect("embedder.embedding", "retriever.query_embedding")
extractive_qa_pipeline.connect("retriever.documents", "reader.documents")
尝试提取一些答案。
query = "Who was Pliny the Elder?"
extractive_qa_pipeline.run(
data={"embedder": {"text": query}, "retriever": {"top_k": 3}, "reader": {"query": query, "top_k": 2}}
)
ExtractiveReader:深入了解
这是一个示例答案
[ExtractedAnswer(query='Who was Pliny the Elder?', score=0.8306006193161011, data='Roman writer', document=Document(id=bb2c5f3d2e2e2bf28d599c7b686ab47ba10fbc13c07279e612d8632af81e5d71, content: 'The Roman writer Pliny the Elder, writing in the first century AD, argued that the Great Pyramid had...', meta: {'url': 'https://en.wikipedia.org/wiki/Great_Pyramid_of_Giza', '_split_id': 16}
置信度分数范围从 0 到 1。分数越高,表示模型对答案的相关性越有信心。
Reader 根据答案的概率分数对它们进行排序,概率高的排在前面。您可以通过可选的 top_k 参数来限制 Reader 返回的答案数量。
默认情况下,Reader 设置了 no_answer=True 参数。此参数返回一个文本为空的 ExtractedAnswer,并显示没有返回的答案是正确的概率。
ExtractedAnswer(query='Who was Pliny the Elder?', score=0.04606167031102615, data=None, document=None, context=None, document_offset=None, context_offset=None, meta={})]}}
在这种情况下,.0.04606167031102615 表示模型对所提供的答案是正确的非常有信心。您可以通过在初始化 ExtractiveReader 时将 no_answer 参数设置为 False 来禁用此行为,只返回答案。
总结
如果您一直关注,现在您知道如何使用 Haystack 构建提取式问答流水线了。🎉 感谢阅读!
如果您喜欢本教程,还有更多关于 Haystack 的内容可以学习。
要及时了解最新的 Haystack 开发动态,您可以注册我们的新闻通讯。
