LLM as Judge 평가¶
- Generate or Curate the QA Set
- Automation Evalution
Generate DataSet from ChatGPT¶
- 현존 가장 똑똑하다고 알려진 모델을 이용해서 데이터셋을 생성합니다.
- ChatGPT, 데이터 셋 생성 대화
- My GPT, 프롬프팅 & Knowledge 기능을 이용한 데이터 셋 생성 대화
- 참고 - 삼국지피티
In [1]:
Copied!
import pandas as pd
data = {
"Input": [
"삼국지연의의 저자는 누구입니까?",
"유비의 자는 무엇입니까?",
"조조의 자는 무엇입니까?",
"제갈량의 별명은 무엇입니까?",
"유비의 두 번째 부인의 이름은 무엇입니까?",
"관우의 무기는 무엇입니까?",
"장비의 무기는 무엇입니까?",
"삼국지연의에서 오나라를 세운 사람은 누구입니까?",
"조조의 아들 중 황제가 된 사람은 누구입니까?",
"조운의 자는 무엇입니까?",
"유비가 유일하게 패배한 전투는 무엇입니까?",
"조조의 정적 중 하나로 유명한 인물은 누구입니까?",
"관우가 죽음을 맞이한 곳은 어디입니까?",
"동탁의 양자는 누구입니까?",
"삼국지연의에서 유비의 의형제는 누구입니까?",
"제갈량이 북벌을 할 때 자주 사용한 계책은 무엇입니까?",
"육손이 활약한 전투는 무엇입니까?"
],
"Output": [
"나관중",
"현덕",
"맹덕",
"와룡",
"손부인",
"청룡언월도",
"장팔사모",
"손권",
"조비",
"자룡",
"이릉대전",
"원소",
"맥성",
"여포",
"관우, 장비",
"공성계",
"이릉대전"
]
}
df = pd.DataFrame(data)
df.to_csv('qa_dataset_match.csv', index=False, encoding='utf-8')
import pandas as pd
data = {
"Input": [
"삼국지연의의 저자는 누구입니까?",
"유비의 자는 무엇입니까?",
"조조의 자는 무엇입니까?",
"제갈량의 별명은 무엇입니까?",
"유비의 두 번째 부인의 이름은 무엇입니까?",
"관우의 무기는 무엇입니까?",
"장비의 무기는 무엇입니까?",
"삼국지연의에서 오나라를 세운 사람은 누구입니까?",
"조조의 아들 중 황제가 된 사람은 누구입니까?",
"조운의 자는 무엇입니까?",
"유비가 유일하게 패배한 전투는 무엇입니까?",
"조조의 정적 중 하나로 유명한 인물은 누구입니까?",
"관우가 죽음을 맞이한 곳은 어디입니까?",
"동탁의 양자는 누구입니까?",
"삼국지연의에서 유비의 의형제는 누구입니까?",
"제갈량이 북벌을 할 때 자주 사용한 계책은 무엇입니까?",
"육손이 활약한 전투는 무엇입니까?"
],
"Output": [
"나관중",
"현덕",
"맹덕",
"와룡",
"손부인",
"청룡언월도",
"장팔사모",
"손권",
"조비",
"자룡",
"이릉대전",
"원소",
"맥성",
"여포",
"관우, 장비",
"공성계",
"이릉대전"
]
}
df = pd.DataFrame(data)
df.to_csv('qa_dataset_match.csv', index=False, encoding='utf-8')
In [2]:
Copied!
import csv
qa_dataset = [
{"Input": "유비는 누구의 후손인가?", "Output": "유비는 한나라 경제의 후손입니다."},
{"Input": "도원결의는 무엇인가?", "Output": "도원결의는 유비, 관우, 장비가 의형제를 맺은 사건입니다."},
{"Input": "삼국지연의의 주요 세력 세 가지는?", "Output": "촉나라, 위나라, 오나라입니다."},
{"Input": "제갈량이 유비에게 제시한 세 가지 전략은 무엇인가?", "Output": "형주를 차지하고, 익주를 취하고, 천하를 경영하라는 전략입니다."},
{"Input": "조조가 제일 처음 출사한 관직은?", "Output": "낙양 북부도위입니다."},
{"Input": "적벽대전에서 누가 화공을 사용했는가?", "Output": "주유와 황개가 화공을 사용했습니다."},
{"Input": "장비의 별명은 무엇인가?", "Output": "장비의 별명은 익덕입니다."},
{"Input": "관우가 살해된 장소는?", "Output": "관우는 맥성에서 살해되었습니다."},
{"Input": "유비가 죽은 장소는?", "Output": "백제성에서 죽었습니다."},
{"Input": "삼국지연의의 저자는?", "Output": "나관중입니다."},
{"Input": "유비가 초기에 세운 나라는?", "Output": "유비는 촉한을 세웠습니다."},
{"Input": "조조가 세운 나라는?", "Output": "조조는 위나라를 세웠습니다."},
{"Input": "손권이 세운 나라는?", "Output": "손권은 오나라를 세웠습니다."},
{"Input": "관우의 무기는 무엇인가?", "Output": "관우의 무기는 청룡언월도입니다."},
{"Input": "황건적의 난을 진압한 인물은?", "Output": "황건적의 난을 진압한 인물은 황보숭과 주준입니다."},
{"Input": "제갈량의 아내 이름은?", "Output": "제갈량의 아내는 황씨입니다."},
{"Input": "유비가 제갈량을 세 번 찾아간 일화는 무엇인가?", "Output": "삼고초려입니다."},
{"Input": "조조의 아들 중 황제가 된 인물은?", "Output": "조비입니다."},
{"Input": "제갈량의 별명은?", "Output": "제갈량의 별명은 와룡입니다."},
{"Input": "삼국지연의에서 마지막으로 멸망한 나라는?", "Output": "오나라입니다."}
]
with open('qa_dataset_sentence.csv', 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['Input', 'Output']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for qa in qa_dataset:
writer.writerow(qa)
import csv
qa_dataset = [
{"Input": "유비는 누구의 후손인가?", "Output": "유비는 한나라 경제의 후손입니다."},
{"Input": "도원결의는 무엇인가?", "Output": "도원결의는 유비, 관우, 장비가 의형제를 맺은 사건입니다."},
{"Input": "삼국지연의의 주요 세력 세 가지는?", "Output": "촉나라, 위나라, 오나라입니다."},
{"Input": "제갈량이 유비에게 제시한 세 가지 전략은 무엇인가?", "Output": "형주를 차지하고, 익주를 취하고, 천하를 경영하라는 전략입니다."},
{"Input": "조조가 제일 처음 출사한 관직은?", "Output": "낙양 북부도위입니다."},
{"Input": "적벽대전에서 누가 화공을 사용했는가?", "Output": "주유와 황개가 화공을 사용했습니다."},
{"Input": "장비의 별명은 무엇인가?", "Output": "장비의 별명은 익덕입니다."},
{"Input": "관우가 살해된 장소는?", "Output": "관우는 맥성에서 살해되었습니다."},
{"Input": "유비가 죽은 장소는?", "Output": "백제성에서 죽었습니다."},
{"Input": "삼국지연의의 저자는?", "Output": "나관중입니다."},
{"Input": "유비가 초기에 세운 나라는?", "Output": "유비는 촉한을 세웠습니다."},
{"Input": "조조가 세운 나라는?", "Output": "조조는 위나라를 세웠습니다."},
{"Input": "손권이 세운 나라는?", "Output": "손권은 오나라를 세웠습니다."},
{"Input": "관우의 무기는 무엇인가?", "Output": "관우의 무기는 청룡언월도입니다."},
{"Input": "황건적의 난을 진압한 인물은?", "Output": "황건적의 난을 진압한 인물은 황보숭과 주준입니다."},
{"Input": "제갈량의 아내 이름은?", "Output": "제갈량의 아내는 황씨입니다."},
{"Input": "유비가 제갈량을 세 번 찾아간 일화는 무엇인가?", "Output": "삼고초려입니다."},
{"Input": "조조의 아들 중 황제가 된 인물은?", "Output": "조비입니다."},
{"Input": "제갈량의 별명은?", "Output": "제갈량의 별명은 와룡입니다."},
{"Input": "삼국지연의에서 마지막으로 멸망한 나라는?", "Output": "오나라입니다."}
]
with open('qa_dataset_sentence.csv', 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['Input', 'Output']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for qa in qa_dataset:
writer.writerow(qa)
Dataset 을 Langsmith에 올리기¶
- web interface 에서 직접 해도 됩니다.
- 코드로도 올려봅시다.
- 수정을 하면 version 이 생기고, tag 를 달 수도 있습니다.
- "유비의 의형제" 문제를 정답이 하나의 단어가 되도록 수정하고 태그를 달아봅시다. (LangSmith Web Interface 로만 가능합니다.)
In [ ]:
Copied!
!pip install -U langsmith openai
!pip install -U langsmith openai
In [4]:
Copied!
import os
os.environ["LANGCHAIN_TRACING_V2"]="true"
os.environ["LANGCHAIN_API_KEY"]=""
import os
os.environ["LANGCHAIN_TRACING_V2"]="true"
os.environ["LANGCHAIN_API_KEY"]=""
In [5]:
Copied!
from langsmith import Client
import os
client = Client()
from langsmith import Client
import os
client = Client()
In [7]:
Copied!
csv_file = './qa_dataset_match.csv'
input_keys = ["Input"] # replace with your input column names
output_keys = ["Output"] # replace with your output column names
dataset = client.upload_csv(
csv_file=csv_file,
input_keys=input_keys,
output_keys=output_keys,
name="threekingdoms-qa-words",
description="",
data_type="kv"
)
csv_file = './qa_dataset_match.csv'
input_keys = ["Input"] # replace with your input column names
output_keys = ["Output"] # replace with your output column names
dataset = client.upload_csv(
csv_file=csv_file,
input_keys=input_keys,
output_keys=output_keys,
name="threekingdoms-qa-words",
description="",
data_type="kv"
)
Evaluate various models¶
- 삼국지 퀴즈를 데이터셋으로 자동 평가 테스트를 구축합니다
- 평가할 모델 (LLM) 을 생성합니다.
- 평가 방법 (= 채점 함수) 을 생성합니다.
- 자동 평가를 수행하고, 결과를 관찰합니다.
In [ ]:
Copied!
!pip install openai
!pip install openai
In [9]:
Copied!
os.environ["OPENAI_API_KEY"]=""
os.environ["OPENAI_API_KEY"]=""
In [10]:
Copied!
from langsmith import traceable, wrappers
from openai import Client
openai = wrappers.wrap_openai(Client())
@traceable
def label_text(text, model="gpt-4o-mini"):
messages = [
{
"role": "system",
"content": "Please read the user query below and answer the question in 1 word.",
},
{"role": "user", "content": text},
]
result = openai.chat.completions.create(
messages=messages, model=model, temperature=0
)
return result.choices[0].message.content
from langsmith import traceable, wrappers
from openai import Client
openai = wrappers.wrap_openai(Client())
@traceable
def label_text(text, model="gpt-4o-mini"):
messages = [
{
"role": "system",
"content": "Please read the user query below and answer the question in 1 word.",
},
{"role": "user", "content": text},
]
result = openai.chat.completions.create(
messages=messages, model=model, temperature=0
)
return result.choices[0].message.content
In [ ]:
Copied!
In [11]:
Copied!
from langsmith.schemas import Example, Run
def correct_label(root_run: Run, example: Example) -> dict:
score = root_run.outputs.get("output") == example.outputs.get("Output")
return {"score": int(score), "key": "correct_label"}
from langsmith.schemas import Example, Run
def correct_label(root_run: Run, example: Example) -> dict:
score = root_run.outputs.get("output") == example.outputs.get("Output")
return {"score": int(score), "key": "correct_label"}
In [ ]:
Copied!
from langsmith.evaluation import evaluate
dataset_name = "threekingdoms-qa-words"
results = evaluate(
lambda inputs: label_text(inputs["Input"], "gpt-4o-mini"),
data=dataset_name,
evaluators=[correct_label],
experiment_prefix="threekingdoms-qa-words",
description="Testing the system.", # optional
)
from langsmith.evaluation import evaluate
dataset_name = "threekingdoms-qa-words"
results = evaluate(
lambda inputs: label_text(inputs["Input"], "gpt-4o-mini"),
data=dataset_name,
evaluators=[correct_label],
experiment_prefix="threekingdoms-qa-words",
description="Testing the system.", # optional
)
In [ ]:
Copied!
Evalutaion Functions¶
LangChain 에서 제공하는 평가 방법들을 사용해 봅시다.
참조: https://docs.smith.langchain.com/reference/sdk_reference/langchain_evaluators
QA evaluators : Correctness 평가
- qa, context_qa, cot_qa 3가지의 qa 평가 함수가 있습니다.
- 정답과 오답 그 사이에 있는 답변들을 각각의 evaluator 들이 어떻게 매겼는지 살펴봅시다.
In [ ]:
Copied!
!pip install langchain langchain-openai langchain-community
!pip install langchain langchain-openai langchain-community
In [ ]:
Copied!
from langsmith.evaluation import LangChainStringEvaluator, evaluate
from langchain_openai import ChatOpenAI
eval_llm = ChatOpenAI(temperature=0.0, model="gpt-4o-mini")
qa_evaluator = LangChainStringEvaluator("qa", config={"llm": eval_llm})
context_qa_evaluator = LangChainStringEvaluator("context_qa", config={"llm": eval_llm})
cot_qa_evaluator = LangChainStringEvaluator("cot_qa", config={"llm": eval_llm})
results = evaluate(
lambda inputs: label_text(inputs["Input"], "gpt-4o-mini"),
data=dataset_name,
evaluators=[correct_label, qa_evaluator, context_qa_evaluator, cot_qa_evaluator],
experiment_prefix="threekingdoms-qa-words",
description="Testing the system.", # optional
)
from langsmith.evaluation import LangChainStringEvaluator, evaluate
from langchain_openai import ChatOpenAI
eval_llm = ChatOpenAI(temperature=0.0, model="gpt-4o-mini")
qa_evaluator = LangChainStringEvaluator("qa", config={"llm": eval_llm})
context_qa_evaluator = LangChainStringEvaluator("context_qa", config={"llm": eval_llm})
cot_qa_evaluator = LangChainStringEvaluator("cot_qa", config={"llm": eval_llm})
results = evaluate(
lambda inputs: label_text(inputs["Input"], "gpt-4o-mini"),
data=dataset_name,
evaluators=[correct_label, qa_evaluator, context_qa_evaluator, cot_qa_evaluator],
experiment_prefix="threekingdoms-qa-words",
description="Testing the system.", # optional
)
In [ ]:
Copied!
Sentence Q&A Evaluation¶
- 단답형이 아닌 주관식 답변에 대해서도 채점을 해봅시다!
In [18]:
Copied!
csv_file = './qa_dataset_sentence.csv'
input_keys = ["Input"] # replace with your input column names
output_keys = ["Output"] # replace with your output column names
dataset = client.upload_csv(
csv_file=csv_file,
input_keys=input_keys,
output_keys=output_keys,
name="threekingdoms-qa-sentences",
description="",
data_type="kv"
)
csv_file = './qa_dataset_sentence.csv'
input_keys = ["Input"] # replace with your input column names
output_keys = ["Output"] # replace with your output column names
dataset = client.upload_csv(
csv_file=csv_file,
input_keys=input_keys,
output_keys=output_keys,
name="threekingdoms-qa-sentences",
description="",
data_type="kv"
)
In [ ]:
Copied!
@traceable
def label_text(text, model="gpt-4o-mini"):
messages = [
{
"role": "system",
"content": "Please read the user query below and answer the question in 1 sentence.",
},
{"role": "user", "content": text},
]
result = openai.chat.completions.create(
messages=messages, model=model, temperature=0
)
return result.choices[0].message.content
results = evaluate(
lambda inputs: label_text(inputs["Input"], "gpt-4o-mini"),
data=dataset_name,
evaluators=[correct_label, qa_evaluator, context_qa_evaluator, cot_qa_evaluator],
experiment_prefix="threekingdoms-qa-sentences",
description="Testing the system.", # optional
)
@traceable
def label_text(text, model="gpt-4o-mini"):
messages = [
{
"role": "system",
"content": "Please read the user query below and answer the question in 1 sentence.",
},
{"role": "user", "content": text},
]
result = openai.chat.completions.create(
messages=messages, model=model, temperature=0
)
return result.choices[0].message.content
results = evaluate(
lambda inputs: label_text(inputs["Input"], "gpt-4o-mini"),
data=dataset_name,
evaluators=[correct_label, qa_evaluator, context_qa_evaluator, cot_qa_evaluator],
experiment_prefix="threekingdoms-qa-sentences",
description="Testing the system.", # optional
)
In [ ]:
Copied!
vLLM OpenAI Compatible API 로 모델 교체하기¶
오픈 웨이트 모델을 vLLM 으로 서빙한 후, 모델을 교체해서 사용해봅시다.
앞서 파인튜닝한 모델을 서빙한 후, 교체해서 채점해 봅시다.
참조 - https://jonhpark7966.github.io/vLLM_Course/QuickStartonRunPod/#_1
In [ ]:
Copied!
export HF_TOKEN=HF-TOKEN
vllm serve meta-llama/Llama-3.1-8B-Instruct
export HF_TOKEN=HF-TOKEN
vllm serve meta-llama/Llama-3.1-8B-Instruct
In [ ]:
Copied!
from langsmith import traceable, wrappers
from openai import OpenAI
# Define your custom endpoint
custom_api_endpoint = "http://localhost:8000/v1" # Replace with your actual endpoint
# Initialize OpenAI client with the custom endpoint
openai = wrappers.wrap_openai(OpenAI(
api_key="API_KEY",
base_url=custom_api_endpoint))
@traceable
def label_text(text, model="gpt-4o-mini"):
messages = [
{
"role": "system",
"content": "Please read the user query below and answer the question in 1 word.",
},
{"role": "user", "content": text},
]
result = openai.chat.completions.create(
messages=messages, model=model, temperature=0
)
return result.choices[0].message.content
from langsmith import traceable, wrappers
from openai import OpenAI
# Define your custom endpoint
custom_api_endpoint = "http://localhost:8000/v1" # Replace with your actual endpoint
# Initialize OpenAI client with the custom endpoint
openai = wrappers.wrap_openai(OpenAI(
api_key="API_KEY",
base_url=custom_api_endpoint))
@traceable
def label_text(text, model="gpt-4o-mini"):
messages = [
{
"role": "system",
"content": "Please read the user query below and answer the question in 1 word.",
},
{"role": "user", "content": text},
]
result = openai.chat.completions.create(
messages=messages, model=model, temperature=0
)
return result.choices[0].message.content
In [ ]:
Copied!
In [ ]:
Copied!
label_text("지구를 광범위하게 설명해봐", model="/workspace/Llama-3.1-8B-kowiki-...")
label_text("지구를 광범위하게 설명해봐", model="/workspace/Llama-3.1-8B-kowiki-...")
In [ ]:
Copied!
from langsmith.evaluation import LangChainStringEvaluator, evaluate
from langchain_openai import ChatOpenAI
eval_llm = ChatOpenAI(temperature=0.0, model="gpt-4o-mini")
qa_evaluator = LangChainStringEvaluator("qa", config={"llm": eval_llm})
context_qa_evaluator = LangChainStringEvaluator("context_qa", config={"llm": eval_llm})
cot_qa_evaluator = LangChainStringEvaluator("cot_qa", config={"llm": eval_llm})
results = evaluate(
lambda inputs: label_text(inputs["Input"], "MODEL_WE_MADE"),
data=dataset_name,
evaluators=[correct_label, qa_evaluator, context_qa_evaluator, cot_qa_evaluator],
experiment_prefix="threekingdoms-qa-words",
description="Testing the system.", # optional
)
from langsmith.evaluation import LangChainStringEvaluator, evaluate
from langchain_openai import ChatOpenAI
eval_llm = ChatOpenAI(temperature=0.0, model="gpt-4o-mini")
qa_evaluator = LangChainStringEvaluator("qa", config={"llm": eval_llm})
context_qa_evaluator = LangChainStringEvaluator("context_qa", config={"llm": eval_llm})
cot_qa_evaluator = LangChainStringEvaluator("cot_qa", config={"llm": eval_llm})
results = evaluate(
lambda inputs: label_text(inputs["Input"], "MODEL_WE_MADE"),
data=dataset_name,
evaluators=[correct_label, qa_evaluator, context_qa_evaluator, cot_qa_evaluator],
experiment_prefix="threekingdoms-qa-words",
description="Testing the system.", # optional
)