메인 콘텐츠로 건너뛰기
_Evaluation 기반 LLM 애플리케이션 개발_은 일관되고 엄선된 예시를 사용해 동작을 체계적으로 측정함으로써 LLM 애플리케이션을 지속적으로 개선할 수 있도록 도와줍니다.
Weave에서 워크플로의 핵심은 _Evaluation 객체_이며, 다음을 정의합니다:Evaluation을 정의하고 나면, 이를 Model 객체나 LLM 애플리케이션 로직을 포함한 맞춤형 함수에 대해 실행할 수 있습니다. .evaluate()를 호출할 때마다 _평가 run_이 시작됩니다. Evaluation 객체를 설계도라고 생각하면, 각 run은 해당 설정에서 애플리케이션이 얼마나 잘 동작하는지를 측정한 결과라고 볼 수 있습니다.
평가를 시작하려면 다음 step을 완료하세요:
  1. Evaluation 객체 생성
  2. 예시 테스트 데이터셋 정의
  3. 채점 함수 정의
  4. 평가할 모델 또는 함수 정의
  5. 평가 실행
전체 평가 코드 샘플은 여기에서 확인할 수 있습니다. 저장된 뷰명령형 평가과 같은 고급 평가 기능에 대해서도 자세히 알아볼 수 있습니다.

1. Evaluation 객체 만들기

Evaluation 객체를 만드는 것은 평가 설정을 구성하는 첫 번째 step입니다. Evaluation은 예제 데이터, 점수 산정 로직, 그리고 선택적 전처리로 구성됩니다. 이후 이를 사용해 하나 이상의 평가를 실행합니다. Weave는 각 예제를 애플리케이션에 전달한 뒤 여러 맞춤형 점수 함수로 출력 결과를 평가합니다. 이렇게 하면 애플리케이션의 성능을 확인할 수 있는 뷰와, 개별 출력과 점수를 자세히 살펴볼 수 있는 풍부한 UI를 활용할 수 있습니다.

(선택) 맞춤형 이름 지정

평가 흐름에서는 맞춤 설정할 수 있는 이름이 두 가지 있습니다:

Evaluation 객체 이름 지정

Evaluation 객체 자체의 이름을 지정하려면 Evaluation 클래스에 evaluation_name 매개변수를 전달하세요. 이 이름은 코드와 UI 목록에서 Evaluation을 파악하는 데 도움이 됩니다.
evaluation = Evaluation(
    dataset=examples, scorers=[match_score1], evaluation_name="My Evaluation"
)

개별 평가 run 이름 지정

특정 평가 run(evaluate() 호출)의 이름을 지정하려면 display_name이 포함된 __weave 딕셔너리를 사용하세요. 그러면 해당 run에 대해 UI에 표시되는 이름이 달라집니다.
evaluation = Evaluation(
    dataset=examples, scorers=[match_score1]
)
evaluation.evaluate(model, __weave={"display_name": "My Evaluation Run"})

2. 테스트 예제용 데이터셋 정의

먼저, 평가할 예제 모음이 포함된 Dataset 객체 또는 예제 목록을 정의합니다. 이러한 예제는 보통 테스트하려는 실패 케이스이며, 테스트 주도 개발(TDD)의 단위 테스트와 비슷합니다.
다음 예제는 딕셔너리 목록으로 정의한 데이터셋을 보여줍니다:
examples = [
    {"question": "What is the capital of France?", "expected": "Paris"},
    {"question": "Who wrote 'To Kill a Mockingbird'?", "expected": "Harper Lee"},
    {"question": "What is the square root of 64?", "expected": "8"},
]

3. 채점 함수를 정의합니다

그런 다음 하나 이상의 채점 함수를 만듭니다. 이 함수들은 Dataset의 각 예제에 점수를 매기는 데 사용됩니다.
각 채점 함수에는 output 매개변수가 있어야 하며, 점수를 담은 딕셔너리를 반환해야 합니다. 필요하다면 예제의 다른 입력도 포함할 수 있습니다.채점 함수에는 output 키워드 인자가 필요하지만, 나머지 인자는 사용자가 정의하며 데이터셋 예제에서 가져옵니다. 인자 이름을 기준으로 딕셔너리 키를 매칭해 필요한 키만 사용합니다.
scorer가 output 인자를 기대하는데 전달받지 못한다면, 레거시 model_output 키를 사용하고 있는지 확인하세요. 이를 해결하려면 scorer 함수에서 output을 키워드 인수로 사용하도록 업데이트하세요.
다음 예제 scorer 함수 match_score1는 채점에 examples 딕셔너리의 expected 값을 사용합니다.
import weave

# 예제를 수집합니다
examples = [
    {"question": "What is the capital of France?", "expected": "Paris"},
    {"question": "Who wrote 'To Kill a Mockingbird'?", "expected": "Harper Lee"},
    {"question": "What is the square root of 64?", "expected": "8"},
]

# 맞춤형 채점 함수를 정의합니다
@weave.op()
def match_score1(expected: str, output: dict) -> dict:
    # 여기에서 모델 출력에 점수를 매기는 로직을 정의합니다
    return {'match': expected == output['generated_text']}

(선택) 맞춤형 Scorer 클래스를 정의합니다

일부 애플리케이션에서는 맞춤형 Scorer 클래스를 만들고 싶을 수 있습니다. 예를 들어 특정 매개변수(예: chat model, prompt), 각 행에 대한 특정 채점 방식, 그리고 집계 점수의 특정 계산 방식을 갖춘 표준화된 LLMJudge 클래스를 만들 수 있습니다.자세한 내용은 RAG 애플리케이션의 모델 기반 Evaluation에서 Scorer 클래스를 정의하는 튜토리얼을 참조하세요.

4. 평가할 모델 또는 함수 정의하기

Model을 평가하려면 Evaluation으로 .evaluate()를 호출하세요. Models는 실험해 보고 Weave에서 캡처하려는 매개변수가 있을 때 사용합니다.
from weave import Model, Evaluation
import asyncio

class MyModel(Model):
    prompt: str

    @weave.op()
    def predict(self, question: str):
        # 여기에 LLM 호출을 추가하고 출력을 반환합니다
        return {'generated_text': 'Hello, ' + self.prompt}

model = MyModel(prompt='World')

evaluation = Evaluation(
    dataset=examples, scorers=[match_score1]
)
weave.init('intro-example') # Weave로 결과 추적 시작
asyncio.run(evaluation.evaluate(model))
이 코드는 각 예제에 대해 predict를 실행하고, 각 채점 함수로 출력에 점수를 매깁니다.

(선택 사항) 평가할 함수 정의하기

또는 @weave.op()로 추적되는 맞춤형 함수를 평가할 수도 있습니다.
@weave.op
def function_to_evaluate(question: str):
    # 여기에 LLM 호출을 추가하고 출력을 반환합니다
    return  {'generated_text': 'some response'}

asyncio.run(evaluation.evaluate(function_to_evaluate))

5. 평가 실행

평가를 실행하려면 Evaluation 객체에서 .evaluate()를 호출합니다.
evaluation이라는 Evaluation 객체와 평가할 model이라는 Model 객체가 있다고 가정하면, 다음 코드는 평가 run을 생성합니다.
asyncio.run(evaluation.evaluate(model))

(선택) 여러 번 실행

각 예제를 여러 번 실행하려면 Evaluation 객체에서 trials 파라미터를 설정할 수 있습니다.
evaluation = Evaluation(
    dataset=examples,
    scorers=[match_score],
    trials=3
)
이 run에서는 각 예제가 모델에 세 번 전달되며, 각 run은 독립적으로 점수가 매겨지고 Weave에 개별적으로 표시됩니다.

전체 평가 코드 예시

다음 코드 샘플은 처음부터 끝까지 전체 평가 run 과정을 보여줍니다. examples 딕셔너리는 prompt 값이 주어졌을 때 MyModel을 평가하는 데 match_score1match_score2 Scorer 함수에서 사용되며, 맞춤형 함수 function_to_evaluate를 평가할 때도 사용됩니다. Model과 함수에 대한 평가는 모두 asyncio.run(evaluation.evaluate())로 호출합니다.
from weave import Evaluation, Model
import weave
import asyncio
weave.init('intro-example')
examples = [
    {"question": "What is the capital of France?", "expected": "Paris"},
    {"question": "Who wrote 'To Kill a Mockingbird'?", "expected": "Harper Lee"},
    {"question": "What is the square root of 64?", "expected": "8"},
]

@weave.op()
def match_score1(expected: str, output: dict) -> dict:
    return {'match': expected == output['generated_text']}

@weave.op()
def match_score2(expected: dict, output: dict) -> dict:
    return {'match': expected == output['generated_text']}

class MyModel(Model):
    prompt: str

    @weave.op()
    def predict(self, question: str):
        # 여기에서 LLM 호출을 추가하고 출력을 반환합니다
        return {'generated_text': 'Hello, ' + question + self.prompt}

model = MyModel(prompt='World')
evaluation = Evaluation(dataset=examples, scorers=[match_score1, match_score2])

asyncio.run(evaluation.evaluate(model))

@weave.op()
def function_to_evaluate(question: str):
    # 여기에서 LLM 호출을 추가하고 출력을 반환합니다
    return  {'generated_text': 'some response' + question}

asyncio.run(evaluation.evaluate(function_to_evaluate("What is the capitol of France?")))
Evals hero

평가 고급 사용법

평가 전에 데이터셋 행 형식 맞추기

preprocess_model_input 함수는 입력이 모델의 예측 함수에 전달되기 전에만 적용됩니다. scorer 함수는 전처리가 적용되지 않은 원본 데이터셋 예제를 항상 전달받습니다.
preprocess_model_input 매개변수를 사용하면 데이터셋 예제가 평가 함수에 전달되기 전에 변환할 수 있습니다. 다음과 같은 경우에 유용합니다.
  • 모델이 기대하는 입력에 맞게 필드 이름 바꾸기
  • 데이터를 올바른 형식으로 변환하기
  • 필드 추가 또는 제거하기
  • 각 예제에 대해 추가 데이터 불러오기
다음은 preprocess_model_input를 사용해 필드 이름을 바꾸는 방법을 보여주는 간단한 예제입니다.
import weave
from weave import Evaluation
import asyncio

# 데이터셋에는 "input_text"가 있지만 모델은 "question"을 기대합니다
examples = [
    {"input_text": "What is the capital of France?", "expected": "Paris"},
    {"input_text": "Who wrote 'To Kill a Mockingbird'?", "expected": "Harper Lee"},
    {"input_text": "What is the square root of 64?", "expected": "8"},
]

@weave.op()
def preprocess_example(example):
    # input_text를 question으로 이름 변경
    return {
        "question": example["input_text"]
    }

@weave.op()
def match_score(expected: str, output: dict) -> dict:
    return {'match': expected == output['generated_text']}

@weave.op()
def function_to_evaluate(question: str):
    return {'generated_text': f'Answer to: {question}'}

# 전처리를 포함한 평가 생성
evaluation = Evaluation(
    dataset=examples,
    scorers=[match_score],
    preprocess_model_input=preprocess_example
)

# 평가 실행
weave.init('preprocessing-example')
asyncio.run(evaluation.evaluate(function_to_evaluate))
이 예제에서는 데이터셋에 input_text 필드가 있는 예제가 들어 있지만, 평가 함수는 question 매개변수를 기대합니다. preprocess_example 함수는 필드 이름을 바꿔 각 예제를 변환하므로 평가가 올바르게 작동할 수 있습니다.전처리 함수는 다음과 같이 동작합니다.
  1. 데이터셋에서 원본 예제를 받습니다
  2. 모델이 기대하는 필드가 포함된 딕셔너리를 반환합니다
  3. 각 예제가 평가 함수에 전달되기 전에 적용됩니다
이는 모델이 기대하는 필드 이름이나 구조와 다른 외부 데이터셋으로 작업할 때 특히 유용합니다.

평가에서 HuggingFace 데이터셋 사용하기

서드파티 서비스 및 라이브러리와의 인테그레이션을 지속적으로 개선하고 있습니다.더 원활한 인테그레이션을 제공하기 위해 작업하는 동안, 현재는 Weave 평가에서 HuggingFace Datasets를 사용하기 위한 임시 우회 방법으로 preprocess_model_input을 사용할 수 있습니다.현재 방법은 평가에서 HuggingFace 데이터셋 사용 cookbook을 참조하세요.

저장된 뷰

Evals 테이블의 설정, 필터, 정렬을 _저장된 뷰_로 저장해 선호하는 설정에 빠르게 접근할 수 있습니다. 저장된 뷰는 UI와 Python SDK에서 설정하고 사용할 수 있습니다. 자세한 내용은 저장된 뷰를 참조하세요.

명령형 평가 (EvaluationLogger)

더 유연한 평가 프레임워크를 선호한다면 Weave의 EvaluationLogger를 확인해 보세요. EvaluationLogger는 Python과 TypeScript 모두에서 사용할 수 있으며, 복잡한 워크플로에 더 유연하게 대응할 수 있습니다. 반면 표준 평가 프레임워크는 더 체계적인 구조와 가이드를 제공합니다.