

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# `fmeval` 라이브러리를 사용하여 워크플로 사용자 지정
<a name="clarify-foundation-model-evaluate-auto-lib-custom"></a>

JumpStart 또는 Amazon Bedrock 모델이 아닌 모델을 허용하도록 모델 평가를 사용자 지정하거나 평가에 사용자 지정 워크플로를 사용할 수 있습니다. 자체 모델을 사용하는 경우 사용자 지정 `ModelRunner`를 만들어야 합니다. 자체 데이터세트를 평가에 사용하는 경우 `DataConfig` 객체를 구성해야 합니다. 다음 섹션에서는 입력 데이터세트의 형식을 지정하고, 사용자 지정 데이터세트를 사용하도록 `DataConfig` 객체를 사용자 지정하고, 사용자 지정 `ModelRunner`를 만드는 방법을 보여줍니다.

## 사용자 지정 입력 데이터세트 사용
<a name="clarify-foundation-model-evaluate-auto-lib-custom-input"></a>

자체 데이터세트를 사용하여 모델을 평가하려면 `DataConfig` 객체를 사용하여 평가하려는 데이터세트의 `dataset_name` 및 `dataset_uri`를 지정해야 합니다. 기본 제공 데이터세트를 사용하는 경우 `DataConfig` 객체는 평가 알고리즘의 기본값으로 이미 구성되어 있습니다.

`evaluate` 함수를 사용할 때마다 하나의 사용자 지정 데이터세트를 사용할 수 있습니다. 원하는 개수의 데이터세트를 사용하기 위해 원하는 횟수만큼 `evaluate`를 간접 호출할 수 있습니다.

다음과 같이 질문 열에 모델 요청을 지정하고 열 응답에 대상 응답을 지정하여 사용자 지정 데이터세트를 구성합니다.

```
from fmeval.data_loaders.data_config import DataConfig
from fmeval.constants import MIME_TYPE_JSONLINES

config = DataConfig(
dataset_name="tiny_dataset",
dataset_uri="tiny_dataset.jsonl",
dataset_mime_type=MIME_TYPE_JSONLINES,
model_input_location="question",
target_output_location="answer",
)
```

`DataConfig` 클래스에는 다음 파라미터가 포함됩니다.
+ `dataset_name` - LLM을 평가하는 데 사용할 데이터세트의 이름입니다.

  `dataset_uri` – 데이터세트의 S3 위치에 대한 로컬 경로 또는 Uniform Resource Identifier(URI)입니다.
+ `dataset_mime_type` - LLM을 평가하는 데 사용할 입력 데이터의 형식입니다. FMEval 라이브러리는 `MIME_TYPE_JSON` 및 `MIME_TYPE_JSONLINES`을 모두 지원할 수 있습니다.
+ `model_input_location` – (선택 사항) 평가하려는 모델 입력 또는 프롬프트가 포함된 데이터세트의 열 이름입니다.

  열의 이름을 지정하는 `model_input_location`을 사용합니다. 열에는 다음과 같은 관련 작업에 해당하는 다음 값이 포함되어야 합니다.
  + **개방형 생성**, **유해성** 및 **정확도** 평가의 경우 모델이 응답해야 하는 **프롬프트**가 포함된 열을 지정합니다.
  + **질문 답변** 작업의 경우 모델이 응답을 생성해야 하는 **질문**이 포함된 열을 지정합니다.
  + **텍스트 요약 작업**의 경우 모델이 요약할 **텍스트**가 포함된 열의 이름을 지정합니다.
  + **분류 작업**의 경우 모델이 분류할 **텍스트**가 포함된 열의 이름을 지정합니다.
  + **사실적 지식** 평가의 경우 모델이 답변을 예측할 **질문**이 포함된 열의 이름을 지정합니다.
  + **의미 체계 견고성** 평가의 경우 모델이 교란할 **입력**이 포함된 열의 이름을 지정합니다.
  + **프롬프트 고정 관념화** 평가의 경우 다음 파라미터와 같이 `model_input_location` 대신 `sent_more_input_location` 및 ` sent_less_input_location`을 사용합니다.
+ `model_output_location` – (선택 사항) `target_output_location`에 포함된 참조 출력과 비교하려는 예측 출력이 포함된 데이터세트의 열 이름입니다. `model_output_location`을 제공하면 FMEval은 추론을 위해 모델에 요청을 보내지 않습니다. 대신 지정된 열에 포함된 출력을 사용하여 모델을 평가합니다.
+ `target_output_location` - `model_output_location`에 포함된 예측 값과 비교할 참 값을 포함하는 참조 데이터세트의 열 이름입니다. 사실적 지식, 정확도 및 의미 체계 견고성에만 필요합니다. 사실적 지식의 경우 이 열의 각 행에는 가능한 모든 답변을 구분 기호로 구분하여 포함해야 합니다. 예를 들어 질문에 대한 답변이 ['UK', 'England']인 경우 열에 'UK<OR>England'를 포함해야 합니다. 구분 기호로 구분된 답변 중 하나가 포함된 경우 모델 예측이 올바른 것으로 간주됩니다.
+ `category_location` - 범주의 이름이 포함된 열의 이름입니다. `category_location`에 값을 제공하면 점수가 집계되고 각 범주에 대해 보고됩니다.
+ `sent_more_input_location` - 편향이 더 많은 프롬프트가 포함된 열의 이름입니다. 프롬프트 고정 관념화에만 필요합니다. 무의식적 편향을 피하세요. 편향 예시는 [CrowS-Pairs dataset](https://paperswithcode.com/dataset/crows-pairs)를 참조하세요.
+ `sent_less_input_location` - 편향이 더 적은 프롬프트가 포함된 열의 이름입니다. 프롬프트 고정 관념화에만 필요합니다. 무의식적 편향을 피하세요. 편향 예시는 [CrowS-Pairs dataset](https://paperswithcode.com/dataset/crows-pairs)를 참조하세요.
+ `sent_more_output_location` – (선택 사항) 모델이 생성한 응답에 더 많은 편향이 포함될 예측 확률이 포함된 열의 이름입니다. 이 파라미터는 프롬프트 고정 관념화 작업에만 사용됩니다.
+ `sent_less_output_location` – (선택 사항) 모델이 생성한 응답에 더 적은 편향이 포함될 예측 확률이 포함된 열의 이름입니다. 이 파라미터는 프롬프트 고정 관념화 작업에만 사용됩니다.

`DataConfig` 클래스에 데이터세트 열에 해당하는 새 속성을 추가하려면 속성 이름 끝에 `suffix _location`을 추가해야 합니다.

## 사용자 지정 `ModelRunner` 사용
<a name="clarify-foundation-model-evaluate-auto-lib-custom-mr"></a>

사용자 지정 모델을 평가하려면 기본 데이터 클래스를 사용하여 모델을 구성하고 사용자 지정 `ModelRunner`를 만듭니다. 그런 다음 이 `ModelRunner`를 사용하여 원하는 언어 모델을 평가할 수 있습니다. 다음 단계를 사용하여 모델 구성을 정의하고, 사용자 지정 `ModelRunner`를 만들고, 테스트합니다.

`ModelRunner` 인터페이스에는 다음과 같은 하나의 추상적 메서드가 있습니다.

```
def predict(self, prompt: str) → Tuple[Optional[str], Optional[float]]
```

이 메서드는 프롬프트를 문자열 입력으로 가져와 모델 텍스트 응답과 입력 로그 확률이 포함된 튜플을 반환합니다. 모든 `ModelRunner`는 `predict` 메서드를 구현해야 합니다.

**사용자 지정 `ModelRunner` 만들기**

1. 모델 구성을 정의합니다.

   다음 코드 예시에서는 **Hugging Face** 모델에 대한 모델 구성을 정의할 수 있도록 `dataclass` 데코레이터를 사용자 지정 `HFModelConfig` 클래스에 적용하는 방법을 보여줍니다.

   ```
   from dataclasses import dataclass
   
   @dataclass
   class HFModelConfig:
   model_name: str
   max_new_tokens: int
   seed: int = 0
   remove_prompt_from_generated_text: bool = True
   ```

   이전 코드 예시에서는 다음이 적용됩니다.
   + `max_new_tokens` 파라미터는 LLM에서 반환하는 토큰 수를 제한하여 응답의 길이를 제한하는 데 사용됩니다. 모델 유형은 클래스가 인스턴스화될 때 `model_name`에 대한 값을 전달하여 설정됩니다. 이 예시에서는 이 섹션의 끝에 표시된 것처럼 모델 이름이 `gpt2`로 설정됩니다. `max_new_tokens` 파라미터는 사전 훈련된 OpenAI GPT 모델의 `gpt2` 모델 구성을 사용하여 텍스트 생성 전략을 구성하는 하나의 옵션입니다. 다른 모델 유형은 [AutoConfig](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html)를 참조하세요.
   + `remove_prompt_from_generated_text` 파라미터가 `True`로 설정된 경우 생성된 응답에는 요청에 전송된 원래 프롬프트가 포함되지 않습니다.

   다른 텍스트 생성 파라미터는 [GenerationConfig에 대한 Hugging Face 설명서](https://huggingface.co/docs/transformers/v4.34.1/en/main_classes/text_generation#transformers.GenerationConfig)를 참조하세요.

1. 사용자 지정 `ModelRunner`를 만들고 예측 방법을 구현합니다. 다음 코드 예시는 이전 코드 예시에서 만든 `HFModelConfig` 클래스를 사용하여 Hugging Face 모델에 대한 사용자 지정 `ModelRunner`를 만드는 방법을 보여줍니다.

   ```
   from typing import Tuple, Optional
   import torch
   from transformers import AutoModelForCausalLM, AutoTokenizer
   from fmeval.model_runners.model_runner import ModelRunner
   
   class HuggingFaceCausalLLMModelRunner(ModelRunner):
   def __init__(self, model_config: HFModelConfig):
       self.config = model_config
       self.model = AutoModelForCausalLM.from_pretrained(self.config.model_name)
       self.tokenizer = AutoTokenizer.from_pretrained(self.config.model_name)
   
   def predict(self, prompt: str) -> Tuple[Optional[str], Optional[float]]:
       input_ids = self.tokenizer(prompt, return_tensors="pt").to(self.model.device)
       generations = self.model.generate(
           **input_ids,
           max_new_tokens=self.config.max_new_tokens,
           pad_token_id=self.tokenizer.eos_token_id,
       )
       generation_contains_input = (
           input_ids["input_ids"][0] == generations[0][: input_ids["input_ids"].shape[1]]
       ).all()
       if self.config.remove_prompt_from_generated_text and not generation_contains_input:
           warnings.warn(
               "Your model does not return the prompt as part of its generations. "
               "`remove_prompt_from_generated_text` does nothing."
           )
       if self.config.remove_prompt_from_generated_text and generation_contains_input:
           output = self.tokenizer.batch_decode(generations[:, input_ids["input_ids"].shape[1] :])[0]
       else:
           output = self.tokenizer.batch_decode(generations, skip_special_tokens=True)[0]
   
       with torch.inference_mode():
           input_ids = self.tokenizer(self.tokenizer.bos_token + prompt, return_tensors="pt")["input_ids"]
           model_output = self.model(input_ids, labels=input_ids)
           probability = -model_output[0].item()
   
       return output, probability
   ```

   이전 코드는 FMEval `HuggingFaceCausalLLMModelRunner` 클래스에서 속성을 상속하는 사용자 지정 `ModelRunner` 클래스를 사용합니다. 사용자 지정 클래스에는 구성기와 예측 함수에 대한 정의가 포함되어 있으며, 이는 `Tuple`을 반환합니다.

   자세한 `ModelRunner` 예시는 `fmeval` 라이브러리의 [model\$1runner](https://github.com/aws/fmeval/tree/main/src/fmeval/model_runners) 섹션을 참조하세요.

   `HuggingFaceCausalLLMModelRunner` 구성기에 포함된 정의는 다음과 같습니다.
   + 구성은 이 섹션의 시작 부분에 정의된 `HFModelConfig`로 설정됩니다.
   + 모델은 인스턴스화 시 model\$1name 파라미터를 사용하여 지정된 Hugging Face [Auto Class](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html)의 사전 훈련된 모델로 설정됩니다.
   + 토큰화기는 `model_name`에서 지정한 사전 훈련된 모델과 일치하는 [Hugging Face 토큰화기 라이브러리](https://huggingface.co/docs/transformers/model_doc/auto#transformers.AutoTokenizer)의 클래스로 설정됩니다.

   `HuggingFaceCausalLLMModelRunner` 클래스의 `predict` 메서드는 다음 정의를 사용합니다.
   + `input_ids` - 모델의 입력을 포함하는 변수입니다. 모델은 다음과 같이 입력을 생성합니다.
     + `tokenizer`는 `prompt`에 포함된 요청을 토큰 식별자(ID)로 변환합니다. 특정 토큰(단어, 하위 단어 또는 문자)을 나타내는 숫자 값인 이러한 토큰 ID는 모델에서 직접 입력으로 사용할 수 있습니다. 토큰 ID는 `return_tensors="pt"`에 지정된 대로 PyTorch 텐서 객체로 반환됩니다. 다른 유형의 반환 텐서 유형은 [apply\$1chat\$1template](https://huggingface.co/docs/transformers/main_classes/tokenizer#transformers.PreTrainedTokenizer.apply_chat_template)에 대한 Hugging Face 설명서를 참조하세요.
     + 토큰 ID는 모델이 사용할 수 있도록 모델이 위치한 디바이스로 전송됩니다.
   + `generations` - LLM에서 생성된 응답을 포함하는 변수입니다. 모델의 생성 함수는 다음 입력을 사용하여 응답을 생성합니다.
     + 이전 단계의 `input_ids`입니다.
     + `HFModelConfig`에 지정된 `max_new_tokens` 파라미터입니다.
     + `pad_token_id`는 응답에 문장 끝(eos) 토큰을 추가합니다. 사용할 수 있는 다른 토큰은 [PreTrainedTokenizer](https://huggingface.co/docs/transformers/main_classes/tokenizer#transformers.PreTrainedTokenizer)에 대한 Hugging Face 설명서를 참조하세요.
   + `generation_contains_input` - 생성된 응답에 입력 프롬프트가 포함될 때는 `True`를, 포함되지 않을 때는 `False`를 반환하는 부울 변수입니다. 반환 값은 다음의 요소별 비교를 사용하여 계산됩니다.
     + `input_ids["input_ids"][0]`에 포함된 입력 프롬프트의 모든 토큰 ID입니다.
     + `generations[0][: input_ids["input_ids"].shape[1]]`에 포함된 생성된 콘텐츠의 시작입니다.

     구성에서 LLM을 `remove_prompt_from_generated_text`로 지시했지만 생성된 응답에 입력 프롬프트가 포함되지 않은 경우 `predict` 메서드는 경고를 반환합니다.

     `predict` 메서드의 출력에는 `batch_decode` 메서드에서 반환한 문자열이 포함되어 응답에서 반환된 토큰 ID를 사람이 읽을 수 있는 텍스트로 변환합니다. `remove_prompt_from_generated_text`를 `True`로 지정하면 생성된 텍스트에서 입력 프롬프트가 제거됩니다. `remove_prompt_from_generated_text`를 `False`로 지정하면 `skip_special_tokens=True`에 지정된 대로 `special_token_dict` 딕셔너리에 포함된 특수 토큰 없이 생성된 텍스트가 반환됩니다.

1. `ModelRunner`를 테스트합니다. 모델로 샘플 요청을 보냅니다.

   다음 예시에서는 Hugging Face `AutoConfig` 클래스의 `gpt2` 사전 훈련된 모델을 사용하여 모델을 테스트하는 방법을 보여줍니다.

   ```
   hf_config = HFModelConfig(model_name="gpt2", max_new_tokens=32)
   model = HuggingFaceCausalLLMModelRunner(model_config=hf_config)
   ```

   이전 코드 예시에서 `model_name`은 사전 훈련된 모델의 이름을 지정합니다. `HFModelConfig` 클래스는 파라미터 `max_new_tokens`에 대한 값이 있는 hf\$1config로 인스턴스화되며 `ModelRunner`를 초기화하는 데 사용됩니다.

   Hugging Face에서 사전 훈련된 다른 모델을 사용하려면 [AutoClass](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html)의 `from_pretrained`에서 `pretrained_model_name_or_path`를 선택합니다.

   마지막으로 `ModelRunner`를 테스트합니다. 다음 코드 예시와 같이 샘플 요청을 모델에 전송합니다.

   ```
   model_output = model.predict("London is the capital of?")[0]
   print(model_output)
   eval_algo.evaluate_sample()
   ```