Evaluation
Last updated
Last updated
평가와 벤치마킹은 LLM 개발에서 매우 중요한 개념입니다. LLM 앱(RAG, Agents))의 성능을 개선하려면 이를 측정할 수 있는 방법이 있어야 합니다.
LlamaIndex는 생성된 결과의 품질을 측정할 수 있는 주요 모듈을 제공합니다. 또한 검색 품질을 측정하기 위한 주요 모듈도 제공합니다.
응답 평가(Response Evaluation): 응답이 검색된 컨텍스트와 일치하나요? 쿼리와도 일치하는가? 참조 답변 또는 가이드라인과 일치하는가?
검색 평가(Retrieval Evaluation): 검색된 소스가 쿼리와 관련이 있는가?이 섹션에서는 LlamaIndex 내의 평가 구성요소가 어떻게 작동하는지 설명합니다.
LlamaIndex는 결과의 품질을 측정하기 위해 LLM 기반 평가 모듈을 제공합니다. 이는 LLM(예: GPT-4)을 사용하여 다양한 방식으로 예측된 정답의 정답 여부를 결정합니다.
이러한 최신 평가 모듈 중 상당수는 실측값 레이블이 필요하지 않습니다. 평가는 쿼리, 컨텍스트, 응답을 조합하여 수행할 수 있으며, 이를 LLM 호출과 결합할 수도 있습니다.
이러한 평가 모듈은 다음과 같은 형태입니다:
Correctness: 생성된 답변이 쿼리에 주어진 참조 답변의 답변과 일치하는지 여부(레이블 필요).
Semantic Similarity: 예측된 답변이 참조 답변과 의미적으로 유사한지 여부(레이블 필요).
Faithfulness: 충실도: 답변이 검색된 문맥에 충실한지(즉, 환각이 있는지 여부) 평가합니다.
Context Relevancy: 검색된 문맥이 쿼리와 관련이 있는지 여부입니다.
Answer Relevancy: 생성된 답변이 쿼리와 관련이 있는지 여부입니다.
Guideline Adherence: 예측된 답변이 특정 가이드라인을 준수하는지 여부입니다.
Question Generation 기능 제공
LlamaIndex는 쿼리를 평가하는 것 외에도 데이터를 사용하여 평가할 질문을 생성할 수도 있습니다. 즉, 자동으로 질문을 생성한 다음 평가 파이프라인을 실행하여 LLM이 데이터를 사용하여 실제로 질문에 정확하게 답변할 수 있는지 테스트할 수 있습니다.
EvaluationResult
예시FaithfulnessEvaluator
답변이 검색된 문맥에 충실한지(즉, 환각이 있는지 여부)를 평가합니다.
from llama_index.core import VectorStoreIndex
from llama_index.llms.openai import OpenAI
from llama_index.core.evaluation import FaithfulnessEvaluator
# create llm
llm = OpenAI(model="gpt-4", temperature=0.0)
# build index
...
# define evaluator
evaluator = FaithfulnessEvaluator(llm=llm)
# query index
query_engine = vector_index.as_query_engine()
response = query_engine.query(
"What battles took place in New York City in the American Revolution?"
)
eval_result =
evaluator.evaluate_response(response=response)
print(str(eval_result.passing))
각 소스 컨텍스트를 개별적으로 평가하도록 선택할 수도 있습니다:
from llama_index.core import VectorStoreIndex
from llama_index.llms.openai import OpenAI
from llama_index.core.evaluation import FaithfulnessEvaluator
# create llm
llm = OpenAI(model="gpt-4", temperature=0.0)
# build index
...
# define evaluator
evaluator = FaithfulnessEvaluator(llm=llm)
# query index
query_engine = vector_index.as_query_engine()
response = query_engine.query(
"What battles took place in New York City in the American Revolution?"
)
response_str = response.response
for source_node in response.source_nodes:
eval_result = evaluator.evaluate(
response=response_str, contexts=[source_node.get_content()]
)
print(str(eval_result.passing))
RelevancyEvaluator
는 검색된 컨텍스트와 답변이 주어진 쿼리에 대해 관련성이 있고 일관성이 있는지 평가합니다.
이 평가자는 응답 객체 외에 query
를 전달해야 한다는 점에 유의하세요.
from llama_index.core import VectorStoreIndex
from llama_index.llms.openai import OpenAI
from llama_index.core.evaluation import RelevancyEvaluator
# create llm
llm = OpenAI(model="gpt-4", temperature=0.0)
# build index
...
# define evaluator
evaluator = RelevancyEvaluator(llm=llm)
# query index
query_engine = vector_index.as_query_engine()
query = "What battles took place in New York City in the American Revolution?"
response = query_engine.query(query)
eval_result = evaluator.evaluate_response(query=query, response=response)
print(str(eval_result))
마찬가지로 특정 소스 노드에서 평가할 수도 있습니다.
from llama_index.core import VectorStoreIndex
from llama_index.llms.openai import OpenAI
from llama_index.core.evaluation import RelevancyEvaluator
# create llm
llm = OpenAI(model="gpt-4", temperature=0.0)
# build index
...
# define evaluator
evaluator = RelevancyEvaluator(llm=llm)
# query index
query_engine = vector_index.as_query_engine()
query = "What battles took place in New York City in the American Revolution?"
response = query_engine.query(query)
response_str = response.response
for source_node in response.source_nodes:
eval_result = evaluator.evaluate(
query=query,
response=response_str,
contexts=[source_node.get_content()],
)
print(str(eval_result.passing))
LlamaIndex는 데이터를 사용하여 답변할 질문을 생성할 수도 있습니다. 위의 평가기와 함께 사용하면 데이터에 대한 완전 자동화된 평가 파이프라인을 만들 수 있습니다.
from llama_index.core import SimpleDirectoryReader
from llama_index.llms.openai import OpenAI
from llama_index.core.llama_dataset.generator import RagDatasetGenerator
# create llm
llm = OpenAI(model="gpt-4", temperature=0.0)
# build documents
documents = SimpleDirectoryReader("./data").load_data()
# define generator, generate questions
dataset_generator = RagDatasetGenerator.from_documents(
documents=documents,
llm=llm,
num_questions_per_chunk=10, # set the number of questions per nodes
)
rag_dataset = dataset_generator.generate_questions_from_nodes()
questions = [e.query for e in rag_dataset.examples]
또한 여러 질문에 걸쳐 평가자 세트를 실행할 수 있는 일괄 평가 러너를 제공합니다.
from llama_index.core.evaluation import BatchEvalRunner
runner = BatchEvalRunner(
{"faithfulness": faithfulness_evaluator, "relevancy": relevancy_evaluator},
workers=8,
)
eval_results = await runner.aevaluate_queries(
vector_index.as_query_engine(), queries=questions
)
DeepEval은 독자적인 평가 메트릭으로 구동되는 6개의 평가기(리트리버 및 발전기 평가를 위한 3개의 RAG 평가기 포함)를 제공합니다.
pip install -U deepeval
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from deepeval.integrations.llama_index import DeepEvalAnswerRelevancyEvaluator
documents = SimpleDirectoryReader("YOUR_DATA_DIRECTORY").load_data()
index = VectorStoreIndex.from_documents(documents)
rag_application = index.as_query_engine()
# An example input to your RAG application
user_input = "What is LlamaIndex?"
# LlamaIndex returns a response object that contains
# both the output string and retrieved nodes
response_object = rag_application.query(user_input)
evaluator = DeepEvalAnswerRelevancyEvaluator()
evaluation_result = evaluator.evaluate_response(
query=user_input, response=response_object
)
print(evaluation_result)
6개의 평가자를 모두 deepeval에서 가져오는 방법은 다음과 같습니다:
from deepeval.integrations.llama_index import (
DeepEvalAnswerRelevancyEvaluator,
DeepEvalFaithfulnessEvaluator,
DeepEvalContextualRelevancyEvaluator,
DeepEvalSummarizationEvaluator,
DeepEvalBiasEvaluator,
DeepEvalToxicityEvaluator,
)
LlamaIndex는 검색을 독립적으로 평가하는 데 도움이 되는 모듈도 제공합니다.
Retrieval evaluation라는 개념은 새로운 것이 아니며, 질문의 데이터 세트와 실제 순위가 주어지면 평균 상호 순위(mean-reciprocal rank, MRR), 적중률(hit-rate), 정확도(precision) 등과 같은 순위 메트릭을 사용하여 검색기를 평가할 수 있습니다.
Retrieval evaluation 단계는 다음을 중심으로 이루어집니다:
Dataset generation: 비정형 텍스트 코퍼스가 주어지면 (질문, 문맥) 쌍을 합성적으로 생성합니다.
rieval Evaluation: 검색기와 질문 세트가 주어지면 순위 메트릭을 사용하여 검색된 결과를 평가합니다.
RetrieverEvaluator
예시검색기가 주어진 단일 쿼리 + 실측 데이터 문서 세트에 대한 평가를 실행합니다.표준 관행은 from_metrics
로 유효한 메트릭 집합을 지정하는 것입니다.
from llama_index.core.evaluation import RetrieverEvaluator
# define retriever somewhere (e.g. from index)
# retriever = index.as_retriever(similarity_top_k=2)
retriever = ...
retriever_evaluator = RetrieverEvaluator.from_metric_names(
["mrr", "hit_rate"], retriever=retriever
)
retriever_evaluator.evaluate(
query="query", expected_ids=["node_id1", "node_id2"]
)
질문 + 노드 ID로 구성된 검색 평가 데이터 세트를 수동으로 큐레이션할 수 있습니다. 또한, generate_question_context_pairs
를 통해 기존 텍스트 코퍼스를 통한 합성 데이터 세트 생성도 제공합니다:
from llama_index.core.evaluation import generate_question_context_pairs
qa_dataset = generate_question_context_pairs(
nodes, llm=llm, num_questions_per_chunk=2
)
반환된 결과는 (queries
, relevant_docs
, and corpus
를 포함하는) EmbeddingQAFinetuneDataset
객체입니다.
RetrieverEvaluator
플러그인 하기
일괄 모드에서 데이터 세트에 대해 RetrieverEvaluator
를 실행할 수 있는 편리한 기능을 제공합니다.
eval_results = await retriever_evaluator.aevaluate_dataset(qa_dataset)
이렇게 하면 각 쿼리에서 .evaluate
를 개별적으로 호출하는 것보다 훨씬 빠르게 실행됩니다.