메인 콘텐츠로 건너뛰기
_평가 기반 LLM 애플리케이션 개발(Evaluation-driven LLM application development)_은 일관되고 선별된 예시를 사용하여 LLM 애플리케이션의 동작을 체계적으로 측정하고 개선할 수 있도록 돕습니다.
Weave에서 워크플로우의 핵심은 _Evaluation 오브젝트_이며, 이는 다음을 정의합니다:Evaluation을 정의하고 나면, 이를 Model 오브젝트나 LLM 애플리케이션 로직을 포함하는 커스텀 함수에 대해 실행할 수 있습니다. .evaluate()를 호출할 때마다 _evaluation run_이 트리거됩니다. Evaluation 오브젝트를 청사진으로, 각 run을 해당 설정에서 애플리케이션이 어떻게 작동하는지 측정하는 것으로 생각하세요.
평가를 시작하려면 다음 단계를 완료하세요:
  1. Evaluation 오브젝트 생성
  2. 예시 데이터셋 정의
  3. 스코어링 함수 정의
  4. 평가할 모델 또는 함수 정의
  5. 평가 실행
전체 평가 코드 샘플은 여기에서 확인할 수 있습니다. 또한 저장된 뷰(Saved views)명령형 평가(Imperative evaluations)와 같은 고급 평가 기능에 대해서도 자세히 알아볼 수 있습니다.

1. Evaluation 오브젝트 생성

Evaluation 오브젝트를 생성하는 것은 평가 설정을 구성하는 첫 번째 단계입니다. Evaluation은 예시 데이터, 스코어링 로직 및 선택적 전처리로 구성됩니다. 나중에 이를 사용하여 하나 이상의 평가를 실행하게 됩니다. Weave는 각 예시를 가져와 애플리케이션을 통과시키고 여러 커스텀 스코어링 함수로 결과값을 스코어링합니다. 이를 통해 애플리케이션 성능에 대한 뷰를 확보하고, 개별 결과값과 점수를 상세히 분석할 수 있는 풍부한 UI를 활용할 수 있습니다.

(선택 사항) 커스텀 네이밍

평가 플로우에는 두 가지 유형의 사용자 정의 가능한 이름이 있습니다:

Evaluation 오브젝트 이름 지정

Evaluation 오브젝트 자체의 이름을 지정하려면 Evaluation 클래스에 evaluation_name 파라미터를 전달하세요. 이 이름은 코드 및 UI 목록에서 해당 평가를 식별하는 데 도움이 됩니다.
evaluation = Evaluation(
    dataset=examples, scorers=[match_score1], evaluation_name="My Evaluation"
)

개별 evaluation 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 키워드 인수를 가져야 하지만, 다른 인수는 사용자 정의이며 데이터셋 예시에서 가져옵니다. 인수 이름을 기반으로 사전 키를 사용하여 필요한 키만 가져옵니다.
스코어러가 output 인수를 예상하지만 받지 못하는 경우, 레거시 model_output 키를 사용 중인지 확인하세요. 이를 해결하려면 스코어러 함수가 output을 키워드 인수로 사용하도록 업데이트하세요.
다음 예시 스코어러 함수 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 클래스를 생성하고 싶을 수 있습니다. 예를 들어 특정 파라미터(예: 채팅 모델, 프롬프트), 각 행의 특정 스코어링, 특정 집계 점수 계산이 포함된 표준화된 LLMJudge 클래스를 생성해야 하는 경우입니다.자세한 내용은 RAG 애플리케이션의 모델 기반 평가에서 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 오브젝트가 있다고 가정할 때, 다음 코드는 평가 실행을 인스턴스화합니다.
asyncio.run(evaluation.evaluate(model))

(선택 사항) 여러 trials 실행

Evaluation 오브젝트에서 trials 파라미터를 설정하여 각 예시를 여러 번 실행할 수 있습니다.
evaluation = Evaluation(
    dataset=examples,
    scorers=[match_score],
    trials=3
)
실행 시 각 예시를 모델에 세 번씩 전달하며, 각 run은 독립적으로 스코어링되어 Weave에 표시됩니다.

전체 평가 코드 예시

다음 코드 샘플은 처음부터 끝까지 전체 평가 실행 과정을 보여줍니다. examples 사전은 MyModelprompt 값을 주었을 때의 성능과 커스텀 함수 function_to_evaluate를 평가하기 위해 match_score1match_score2 스코어링 함수에서 사용됩니다. 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 함수는 모델의 예측 함수로 전달되기 전의 입력에만 적용됩니다. 스코어러 함수는 항상 전처리가 적용되지 않은 원본 데이터셋 예시를 받습니다.
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 데이터셋 사용하기 쿡북을 참조하세요.

저장된 뷰 (Saved views)

평가 테이블 설정, 필터 및 정렬을 _저장된 뷰(saved views)_로 저장하여 선호하는 설정에 빠르게 액세스할 수 있습니다. UI와 Python SDK에서 저장된 뷰를 구성하고 액세스할 수 있습니다. 자세한 내용은 저장된 뷰를 참조하세요.

명령형 평가 (Imperative evaluations, EvaluationLogger)

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