多模态评估:基线#
Multi-modal slide decks
是一个包含带有视觉内容的幻灯片组的问答对的公共数据集。
问答对是从演示文稿中的视觉内容中得出的,测试了 RAG 执行视觉推理的能力。
作为基线,我们使用基于文本的 RAG 管道评估此数据集,如下所示。
这将不会对视觉内容进行推理,而只会加载幻灯片中的文本。
先决条件#
# %pip install -U langchain langsmith langchain_benchmarks
# %pip install --quiet chromadb openai pypdf pandas
import getpass
import os
os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com"
env_vars = ["LANGCHAIN_API_KEY", "OPENAI_API_KEY"]
for var in env_vars:
if var not in os.environ:
os.environ[var] = getpass.getpass(prompt=f"Enter your {var}: ")
数据集#
我们可以浏览可用的 LangChain 基准测试数据集以进行检索。
from langchain_benchmarks import clone_public_dataset, registry
registry = registry.filter(Type="RetrievalTask")
registry
名称 | 类型 | 数据集 ID | 描述 |
---|---|---|---|
LangChain 文档问答 | RetrievalTask | 452ccafc-18e1-4314-885b-edd735f17b9d | 基于 LangChain Python 文档快照的问答。环境提供文档和检索器信息。每个示例都包含一个问题和参考答案。成功是根据答案相对于参考答案的准确性来衡量的。我们还根据模型响应相对于检索到的文档(如果有)的忠实度来衡量。 |
半结构化报告 | RetrievalTask | c47d9617-ab99-4d6e-a6e6-92b8daf85a7d | 基于包含表格和图表 PDF 的问答。该任务提供原始文档以及工厂方法,以便轻松索引它们并创建检索器。每个示例都包含一个问题和参考答案。成功是根据答案相对于参考答案的准确性来衡量的。我们还根据模型响应相对于检索到的文档(如果有)的忠实度来衡量。 |
多模态幻灯片组 | RetrievalTask | 40afc8e7-9d7e-44ed-8971-2cae1eb59731 | 此公共数据集正在开发中,并将随着时间的推移进行扩展。基于包含视觉表格和图表的幻灯片组的问答。每个示例都包含一个问题和参考答案。成功是根据答案相对于参考答案的准确性来衡量的。 |
Multi-modal slide decks
是我们任务的相关数据集。
task = registry["Multi-modal slide decks"]
task
名称 | 多模态幻灯片组 |
类型 | RetrievalTask |
数据集 ID | 40afc8e7-9d7e-44ed-8971-2cae1eb59731 |
描述 | 此公共数据集正在开发中,并将随着时间的推移进行扩展。基于包含视觉表格和图表的幻灯片组的问答。每个示例都包含一个问题和参考答案。成功是根据答案相对于参考答案的准确性来衡量的。 |
检索器工厂 | |
架构工厂 | |
get_docs | {} |
克隆数据集,使其在我们的 LangSmith 数据集中可用。
clone_public_dataset(task.dataset_id, dataset_name=task.name)
Dataset Multi-modal slide decks already exists. Skipping.
You can access the dataset at https://smith.langchain.com/o/ebbaf2eb-769b-4505-aca2-d11de10372a4/datasets/08a29acb-5ad6-42ce-a482-574c9e2e5306.
从远程缓存中获取与数据集关联的 PDF,以便我们可以执行提取。
from langchain_benchmarks.rag.tasks.multi_modal_slide_decks import get_file_names
file_names = list(get_file_names()) # PosixPath
加载#
加载并拆分用于索引的文件。
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
def load_and_split(file):
"""
Load and split PDF files
:param file: PosixPath path for pdf
:return: A list of text chunks
"""
loader = PyPDFLoader(str(file))
pdf_pages = loader.load()
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
chunk_size=100, chunk_overlap=50
)
# Get chunks
docs = text_splitter.split_documents(pdf_pages)
texts = [d.page_content for d in docs]
print(f"There are {len(texts)} text elements in {file.name}")
return texts
texts = []
for fi in file_names:
texts.extend(load_and_split(fi))
There are 98 text elements in DDOG_Q3_earnings_deck.pdf
索引#
嵌入(OpenAIEmbeddings)并将拆分存储在向量存储(Chroma)中。
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
vectorstore_baseline = Chroma.from_texts(
texts=texts, collection_name="baseline-multi-modal", embedding=OpenAIEmbeddings()
)
retriever_baseline = vectorstore_baseline.as_retriever()
RAG#
创建管道以根据与输入问题的语义相似性检索相关块。
将图像传递给 GPT-4 以进行答案合成。
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough
def rag_chain(retriever):
"""
RAG pipeline for the indexed presentations
:param retriever: PosixPath path for pdf
"""
# Prompt template
template = """Answer the question based only on the following context, which can include text and tables:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
# LLM
model = ChatOpenAI(temperature=0, model="gpt-4")
# RAG pipeline
chain = (
{
"context": retriever | (lambda x: "\n\n".join([i.page_content for i in x])),
"question": RunnablePassthrough(),
}
| prompt
| model
| StrOutputParser()
)
return chain
# Create RAG chain
chain = rag_chain(retriever_baseline)
评估#
在我们的数据集上运行评估
task.name
是我们克隆的 QA 对数据集eval_config
指定了我们数据集的 LangSmith 评估器,它将使用 GPT-4 作为评分器评分器将根据真实情况评估链生成的答案
import uuid
from langchain.smith import RunEvalConfig
from langsmith.client import Client
# Evaluator configuration
client = Client()
eval_config = RunEvalConfig(
evaluators=["cot_qa"],
)
# Experiments
chain_map = {
"baseline": chain,
}
# Run evaluation
run_id = uuid.uuid4().hex[:4]
test_runs = {}
for project_name, chain in chain_map.items():
test_runs[project_name] = client.run_on_dataset(
dataset_name=task.name,
llm_or_chain_factory=lambda: (lambda x: x["Question"]) | chain,
evaluation=eval_config,
verbose=True,
project_name=f"{run_id}-{project_name}",
project_metadata={"chain": project_name},
)
View the evaluation results for project '866f-baseline' at:
https://smith.langchain.com/o/ebbaf2eb-769b-4505-aca2-d11de10372a4/datasets/08a29acb-5ad6-42ce-a482-574c9e2e5306/compare?selectedSessions=30199d47-50d7-4c5c-a55a-e74157e05951
View all tests for Dataset Multi-modal slide decks at:
https://smith.langchain.com/o/ebbaf2eb-769b-4505-aca2-d11de10372a4/datasets/08a29acb-5ad6-42ce-a482-574c9e2e5306
[------------------------------------------------->] 10/10
实验结果
输出 | feedback.COT 上下文准确性 | 错误 | 执行时间 | |
---|---|---|---|---|
计数 | 10 | 10.000000 | 0 | 10.000000 |
唯一 | 10 | NaN | 0 | NaN |
顶部 | Datadog 共有 20 个客户。 | NaN | NaN | NaN |
频率 | 1 | NaN | NaN | NaN |
平均值 | NaN | 0.200000 | NaN | 4.674478 |
标准差 | NaN | 0.421637 | NaN | 0.864273 |
最小值 | NaN | 0.000000 | NaN | 3.307960 |
25% | NaN | 0.000000 | NaN | 4.113816 |
50% | NaN | 0.000000 | NaN | 4.700962 |
75% | NaN | 0.000000 | NaN | 5.018359 |
最大值 | NaN | 1.000000 | NaN | 6.188082 |