使用 MLflow 评估大型语言模型

本文介绍 MLflow LLM Evaluate,这是一项打包在 mlflow.evaluate 中的 MLflow 大型语言模型 (LLM) 评估功能。 本文还介绍评估 LLM 所需的条件,以及支持哪些评估指标。

什么是 MLflow LLM Evaluate?

评估 LLM 性能与传统 ML 模型略有不同,因为通常没有单一的基本事实可供比较。 MLflow 提供 API mlflow.evaluate() 来帮助评估 LLM。

MLflow 的 LLM 评估功能包含三个主要部分:

  • 要评估的模型:可以是 MLflow pyfunc 模型、具有预测列的数据帧、指向一个已注册的 MLflow 模型的 URI,或者代表模型的任意 Python 可调用对象(例如 HuggingFace 文本摘要管道)。
  • 指标:要计算的指标,LLM 评估使用 LLM 指标。
  • 评估数据:模型评估的数据,可以是 Pandas 数据帧、Python 列表、numpy 数组或 mlflow.data.dataset.Dataset 实例。

要求

  • MLflow 2.8 及更高版本。
  • 若要使用 mlflow.evaluate() 评估 LLM,LLM 必须是以下值之一:
    • 指向记录的 mlflow.pyfunc.PyFuncModel 模型的 mlflow.pyfunc.PyFuncModel 实例或 URI。
    • 接受字符串输入并输出单个字符串的自定义 Python 函数。 可调用对象必须与 mlflow.pyfunc.PyFuncModel.predict 的签名匹配,且不带 params 参数。 函数应:
      • data 作为唯一参数,可以是 pandas.Dataframenumpy.ndarray、Python 列表、字典或 scipy 矩阵。
      • 返回以下值之一:pandas.DataFramepandas.Seriesnumpy.ndarray 或列表。
    • 静态数据集。

使用 MLflow 模型进行评估

可以将 LLM 作为 MLflow 模型进行评估。 有关如何将模型转换为 mlflow.pyfunc.PyFuncModel 实例的详细说明,请参阅如何创建自定义 pyfunc 模型

若要将模型作为 MLflow 模型进行评估,Databricks 建议按照以下步骤操作:

注意

若要成功记录面向 Azure OpenAI 服务的模型,必须指定以下适用于身份验证和功能的环境变量。 有关更多详细信息,请参阅带有 MLflow 的 OpenAI 文档。

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…)都有自己的 log_model API,如 mlflow.openai.log_model()

    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. 使用记录的模型的 URI 作为 mlflow.evaluate() 中的模型实例:

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

使用自定义函数进行评估

在 MLflow 2.8.0 及更高版本中,mlflow.evaluate() 支持评估 Python 函数,无需将模型记录到 MLflow。 如果不希望记录模型而只希望评估模型,该方法非常有用。 以下示例使用 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 数据帧或 MLflow PandasDataset 中的列,并且希望在不重新运行模型的情况下评估静态数据集时,该方法非常有用。

设置 model=None,并将模型输出放入 data 参数中。 仅当数据是 Pandas 数据帧时,此配置才适用。

如果使用 Pandas 数据帧,则必须使用 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 中有两种类型的 LLM 评估指标:

  • 依赖 SaaS 模型(例如 OpenAI)进行评分的指标,例如 mlflow.metrics.genai.answer_relevance。 这些指标使用 mlflow.metrics.genai.make_genai_metric() 创建。 对于每个数据记录,这些指标都会向 SaaS 模型发送一个包含以下信息的提示,并从模型响应中提取分数。
    • 指标定义。
    • 指标评分标准。
    • 参考示例。
    • 输入数据或上下文。
    • 模型输出。
    • [可选] 基本事实。
  • 基于函数的每行指标。 这些指标根据某些函数(如 Rouge,mlflow.metrics.rougeL 或 Flesch Kincaid,mlflow.metrics.flesch_kincaid_grade_level)计算每个数据记录(Pandas 或 Spark 数据帧中的行)的分数。 这些指标类似于传统指标。

选择评估 LLM 的指标

可以选择用于评估模型的指标。 可以在 MLflow 评估文档中找到支持的评估指标的完整参考。

可以:

  • 使用为模型类型预定义的默认指标。
  • 使用自定义指标列表。

若要对预先选择的任务使用默认指标,请在 mlflow.evaluate 中指定 model_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:存储聚合结果,例如评估数据集中的平均值或方差。 以下部分再次执行上文的代码示例,重点介绍如何打印聚合结果。

    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 评估

获取笔记本