

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# `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_uri` と `dataset_name` を指定する必要があります。組み込みデータセットを使用する場合、`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` インターフェイスには、次のとおり 1 つの抽象メソッドがあります。

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

このメソッドは、プロンプトを文字列入力として取り込み、モデルテキスト応答と入力の対数確率を含むタプルを返します。すべての `predict` では、`ModelRunner` メソッドを実装する必要があります。

**カスタム `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` モデル設定を使用してテキスト生成戦略を設定するオプションの 1 つです。その他のモデルタイプについては、「[AutoConfig](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html)」を参照してください。
   + パラメータ `remove_prompt_from_generated_text` が `True` に設定されている場合、生成された応答には、リクエストで送信された元のプロンプトは含まれません。

   その他のテキスト生成パラメータについては、「[Hugging Face GenerationConfig のドキュメント](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\_runner](https://github.com/aws/fmeval/tree/main/src/fmeval/model_runners)」セクションを参照してください。

   `HuggingFaceCausalLLMModelRunner` コンストラクタには、以下の定義が含まれています。
   + この設定は、このセクションの冒頭で定義されている `HFModelConfig` に設定されています。
   + モデルは、インスタンス化時に model\_name パラメータを使用して指定された 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 は、PyTorch が指定したとおり、`return_tensors="pt"` テンソルオブジェクトとして返されます。その他のタイプの戻りテンソルタイプについては、「[apply\_chat\_template](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` メソッドからの出力には、応答で返されたトークン ID を人間が読み取れるテキストに変換する、`batch_decode` メソッドが返す文字列が含まれています。`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\_config としてインスタンス化され、`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()
   ```