オープンソースの MLflowを用いて大規模言語モデルを評価する

この記事では、オープンソースの MLflow LLM 評価機能 mlflow.evaluate() の使用方法について説明します。 LLMこの記事では、オープンソース を使用してMLflow を評価するために必要なことと、サポートされている評価メトリクスについても説明します。

MLflow LLM Evaluationとは何ですか?

LLMのパフォーマンスの評価は、比較する単一のグラウンドトゥルースが存在しないことが多いため、従来の機械学習モデルとは少し異なります。 MLflow には、LLM の評価に役立つ API mlflow.evaluate() が用意されています。

MLflow の LLM 評価機能は、次の 3 つの主要コンポーネントで構成されています。

  • 評価するモデル: MLflow pyfunc モデル、予測列を含む DataFrame、登録済みの 1 つの MLflow モデルを指す URI、またはモデルを表す任意の Python 呼び出し可能オブジェクト (HuggingFace テキスト要約パイプラインなど) を指定できます。

  • メトリクス:メトリクスをコンピュートし、LLM評価はLLMメトリクスを使用します。

  • 評価データ: モデルが評価されるデータで、Pandas DataFrame、Python リスト、 numpy 配列、 mlflow.data.dataset.Dataset インスタンスのいずれかです。

要件

  • MLflow 2.8 以降。

  • mlflow.evaluate()で LLM を評価するには、LLM が次のいずれかである必要があります。

    • 記録されたmlflow.pyfunc.PyFuncModelモデルを指すmlflow.pyfunc.PyFuncModelインスタンスまたは URI。

    • 文字列の入力を受け取り、1 つの文字列を出力するカスタム Python 関数。 呼び出し可能オブジェクトは、params引数なしでmlflow.pyfunc.PyFuncModel.predictのシグネチャと一致する必要があります。この関数は、次のことを行う必要があります。

      • dataを唯一の引数とし、pandas.Dataframenumpy.ndarray、Pythonリスト、辞書、またはscipy行列にすることができます。

      • pandas.DataFramepandas.Seriesnumpy.ndarray、またはリストのいずれかを返します。

    • 静的データセット。

MLflow モデルを使用して評価する

LLM を MLflow モデルとして評価できます。 モデルを mlflow.pyfunc.PyFuncModel インスタンスに変換する方法の詳細については、「 カスタム pyfunc モデルを作成する方法」を参照してください。

モデルを MLflow モデルとして評価するには、Databricksでは次の手順に従うことをお勧めします。

注:

Azure OpenAI サービスを対象とするモデルを正常にログに記録するには、認証と機能のために次の環境変数を指定する必要があります。 詳細については、 OpenAI と MLflow のドキュメント を参照してください。

os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["OPENAI_API_VERSION"] = "2023-05-15"
os.environ["OPENAI_API_BASE"] = "https://<>.<>.<>.com/"
os.environ["OPENAI_DEPLOYMENT_NAME"] = "deployment-name"
  1. LLM を MLflow モデルとしてパッケージ化し、 log_modelを使用して MLflow サーバーに記録します。 各フレーバー (opeanaipytorch、 ...) には、mlflow.openai.log_model()次のような独自の log_model API があります。

    with mlflow.start_run():
        system_prompt = "Answer the following question in two sentences"
        # Wrap "gpt-3.5-turbo" as an MLflow model.
        logged_model_info = mlflow.openai.log_model(
            model="gpt-3.5-turbo",
            task=openai.ChatCompletion,
            artifact_path="model",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": "{question}"},
            ],
        )
    
  2. mlflow.evaluate()では、記録済みモデルのURIをモデルインスタンスとして使用します。

    results = mlflow.evaluate(
        logged_model_info.model_uri,
        eval_data,
        targets="ground_truth",
        model_type="question-answering",
    )
    

カスタム関数で評価する

MLflow 2.8.0 以降では、モデルを MLflow に記録しなくても、 mlflow.evaluate() Python 関数の評価がサポートされています。 これは、モデルをログに記録せず、評価するだけの場合に便利です。 次の例では、 mlflow.evaluate() を使用して関数を評価します。

また、次のコードを実行するには、OpenAI 認証を設定する必要があります。

eval_data = pd.DataFrame(
    {
        "inputs": [
            "What is MLflow?",
            "What is Spark?",
        ],
        "ground_truth": [
            "MLflow is an open-source platform for managing the end-to-end machine learning (ML) lifecycle. It was developed by Databricks, a company that specializes in big data and machine learning solutions. MLflow is designed to address the challenges that data scientists and machine learning engineers face when developing, training, and deploying machine learning models.",
            "Apache Spark is an open-source, distributed computing system designed for big data processing and analytics. It was developed in response to limitations of the Hadoop MapReduce computing model, offering improvements in speed and ease of use. Spark provides libraries for various tasks such as data ingestion, processing, and analysis through its components like Spark SQL for structured data, Spark Streaming for real-time data processing, and MLlib for machine learning tasks",
        ],
    }
)


def openai_qa(inputs):
    answers = []
    system_prompt = "Please answer the following question in formal language."
    for index, row in inputs.iterrows():
        completion = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": "{row}"},
            ],
        )
        answers.append(completion.choices[0].message.content)

    return answers


with mlflow.start_run() as run:
    results = mlflow.evaluate(
        openai_qa,
        eval_data,
        model_type="question-answering",
    )

静的データセットで評価する

MLflow 2.8.0 以降では、 mlflow.evaluate() モデルを指定せずに静的データセットを評価できます。 これは、モデル出力を Pandas DataFrame または MLflow PandasDataset の列に保存し、モデルを再実行せずに静的データセットを評価する場合に便利です。

model=Noneを設定し、モデル出力を引数 data に入れます。この構成は、データが Pandas DataFrame の場合にのみ適用できます。

Pandas DataFrame を使用している場合は、mlflow.evaluate()の最上位の predictions パラメーターを使用して、モデル出力を含む列名を指定する必要があります。

import mlflow
import pandas as pd

eval_data = pd.DataFrame(
    {
        "inputs": [
            "What is MLflow?",
            "What is Spark?",
        ],
        "ground_truth": [
            "MLflow is an open-source platform for managing the end-to-end machine learning (ML) lifecycle. "
            "It was developed by Databricks, a company that specializes in big data and machine learning solutions. "
            "MLflow is designed to address the challenges that data scientists and machine learning engineers "
            "face when developing, training, and deploying machine learning models.",
            "Apache Spark is an open-source, distributed computing system designed for big data processing and "
            "analytics. It was developed in response to limitations of the Hadoop MapReduce computing model, "
            "offering improvements in speed and ease of use. Spark provides libraries for various tasks such as "
            "data ingestion, processing, and analysis through its components like Spark SQL for structured data, "
            "Spark Streaming for real-time data processing, and MLlib for machine learning tasks",
        ],
        "predictions": [
            "MLflow is an open-source platform that provides handy tools to manage Machine Learning workflow "
            "lifecycle in a simple way",
            "Spark is a popular open-source distributed computing system designed for big data processing and analytics.",
        ],
    }
)

with mlflow.start_run() as run:
    results = mlflow.evaluate(
        data=eval_data,
        targets="ground_truth",
        predictions="predictions",
        extra_metrics=[mlflow.metrics.genai.answer_similarity()],
        evaluators="default",
    )
    print(f"See aggregated evaluation results below: \n{results.metrics}")

    eval_table = results.tables["eval_results_table"]
    print(f"See evaluation table below: \n{eval_table}")

LLM評価メトリクスの種類

MLflow には 2 種類の LLM 評価メトリクスがあります。

  • OpenAI などの SaaS モデルに依存してスコアリングを行うメトリクス mlflow.metrics.genai.answer_relevance。 これらのメトリクスは、 mlflow.metrics.genai.make_genai_metric()を使用して作成されます。 これらのメトリクスは、データレコードごとに、次の情報で構成される 1 つのプロンプトを SaaS モデルに送信し、モデルの応答からスコアを抽出します。

    • メトリクスの定義。

    • メトリクスの採点基準。

    • 参考例を挙げます。

    • 入力データまたはコンテキスト。

    • モデル出力。

    • [オプション]グラウンドトゥルース。

  • 関数ベースの行ごとのメトリクス。 これらのメトリクスは、 Rouge、 mlflow.metrics.rougeL、 Flesch Kincaid などの特定の関数に基づいて、各データレコード (Pandas または Spark DataFrame に関する行) のスコアを計算しmlflow.metrics.flesch_kincaid_grade_level。 これらのメトリクスは、従来のメトリクスに似ています。

メトリクスを選択して LLMを評価します

モデルを評価するメトリクスを選択できます。 サポートされている評価メトリクスの完全なリファレンスについては、 MLflow 評価のドキュメントを参照してください。

次のいずれかを実行できます。

  • モデルタイプに事前定義された デフォルト メトリクスを使用します。

  • メトリクスの カスタム リストを使用します。

事前に選択されたタスクにデフォルトのメトリクスを使用するには、次の例に示すように、mlflow.evaluatemodel_type 引数を指定します。

results = mlflow.evaluate(
    model,
    eval_data,
    targets="ground_truth",
    model_type="question-answering",
)

次の表は、サポートされている LLM モデル タイプと関連する既定のメトリクスをまとめたものです。

question-answering

text-summarization

text

exact-match

ROUGE

toxicity*

toxicity*

toxicity*

ari_grade_level**

ari_grade_level**

ari_grade_level**

flesch_kincaid_grade_level**

flesch_kincaid_grade_level**

flesch_kincaid_grade_level**

* evaluatetorchtransformersの各パッケージが必要です。

** パッケージ textstat が必要です。

evaluatenltkrouge-score のパッケージが必要です。

メトリクスのカスタムリストを使用する

mlflow.evaluateextra_metrics 引数にメトリクスのカスタムリストを指定できます。

事前定義されたモデルタイプのデフォルトのメトリクスリストにメトリクスを追加するには、 model_type パラメーターを保持し、メトリクスを extra_metricsに追加します。 以下では、 question-answering モデルと mlflow.metrics.latency()のすべてのメトリクスを使用してモデルを評価します。

results = mlflow.evaluate(
    model,
    eval_data,
    targets="ground_truth",
    model_type="question-answering",
    extra_metrics=[mlflow.metrics.latency()],
)

デフォルトのメトリクス計算を無効にし、選択したメトリクスのみを計算するには、 model_type 引数を削除し、目的のメトリクスを定義します。

results = mlflow.evaluate(model,
                          eval_data,
                          targets="ground_truth",
                          extra_metrics=[mlflow.metrics.toxicity(), mlflow.metrics.latency()],
                        )

LLMジャッジによるメトリクス

また、LLM をジャッジとして使用する既定のメトリクスを mlflow.evaluate()extra_metrics 引数に追加することもできます。これらの LLM をジャッジとするメトリクスのリストについては、 LLM をジャッジとするメトリクスを参照してください。

from  mlflow.metrics.genai import answer_relevance

answer_relevance_metric = answer_relevance(model="openai:/gpt-4")

eval_df = pd.DataFrame() # Index(['inputs', 'predictions', 'context'], dtype='object')

eval_results = mlflow.evaluate(
    data = eval_df, # evaluation data
    model_type="question-answering",
    predictions="predictions", # prediction column_name from eval_df
    extra_metrics=[answer_relevance_metric]
)

評価結果の表示

mlflow.evaluate() 評価結果を mlflow.models.EvaluationResult インスタンスとして返します。

選択したメトリクスのスコアを確認するには、評価結果の次の属性を確認します。

  • metrics: 評価データセット全体の平均や分散などの集計結果を格納します。 次の例では、上記のコード例の 2 番目のパスを使用して、集計結果を出力することに重点を置いています。

    with mlflow.start_run() as run:
        results = mlflow.evaluate(
            data=eval_data,
            targets="ground_truth",
            predictions="predictions",
            extra_metrics=[mlflow.metrics.genai.answer_similarity()],
            evaluators="default",
        )
        print(f"See aggregated evaluation results below: \n{results.metrics}")
    
  • tables['eval_results_table']: 行ごとの評価結果を格納します。

    with mlflow.start_run() as run:
        results = mlflow.evaluate(
            data=eval_data,
            targets="ground_truth",
            predictions="predictions",
            extra_metrics=[mlflow.metrics.genai.answer_similarity()],
            evaluators="default",
        )
        print(
            f"See per-data evaluation results below: \n{results.tables['eval_results_table']}"
        )
    

MLflowを用いたLLM評価サンプル ノートブック

MLflow を使用した次の LLM 評価のサンプル ノートブックは、ユース ケース指向の例です。

MLflowを用いたLLM評価サンプル ノートブック

ノートブックを新しいタブで開く