多模态评估:基线#

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 文档问答RetrievalTask452ccafc-18e1-4314-885b-edd735f17b9d基于 LangChain Python 文档快照的问答。环境提供文档和检索器信息。每个示例都包含一个问题和参考答案。成功是根据答案相对于参考答案的准确性来衡量的。我们还根据模型响应相对于检索到的文档(如果有)的忠实度来衡量。
半结构化报告RetrievalTaskc47d9617-ab99-4d6e-a6e6-92b8daf85a7d基于包含表格和图表 PDF 的问答。该任务提供原始文档以及工厂方法,以便轻松索引它们并创建检索器。每个示例都包含一个问题和参考答案。成功是根据答案相对于参考答案的准确性来衡量的。我们还根据模型响应相对于检索到的文档(如果有)的忠实度来衡量。
多模态幻灯片组RetrievalTask40afc8e7-9d7e-44ed-8971-2cae1eb59731此公共数据集正在开发中,并将随着时间的推移进行扩展。基于包含视觉表格和图表的幻灯片组的问答。每个示例都包含一个问题和参考答案。成功是根据答案相对于参考答案的准确性来衡量的。

Multi-modal slide decks 是我们任务的相关数据集。

task = registry["Multi-modal slide decks"]
task
名称多模态幻灯片组
类型RetrievalTask
数据集 ID40afc8e7-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