评估 LLM

LM-Eval 提供了一个统一的框架,用于在各种评估任务上测试 LLM。该服务基于 EleutherAI 的 lm-evaluation-harnessUnitxt 构建。TrustyAI Operator 通过 LMEvalJob CRD 实现,使得评估作业可以在集群中创建和管理。

本文档介绍如何针对作为 Kubernetes InferenceService(兼容 OpenAI API)提供的 LLM 运行评估作业。

前提条件

  • 已安装 TrustyAI Operator(参见 安装 TrustyAI)。
  • 在目标命名空间中部署了作为 InferenceService 的 LLM(例如 vLLM 或 Hugging Face 运行时)。
  • 对于需要从互联网下载的任务或分词器(例如 Hugging Face):必须在 LMEvalJob 上启用 allowOnline,且集群必须允许(例如 DataScienceCluster TrustyAI 评估配置中的 permitOnline: allow)。启用在线访问存在安全隐患,详见 Red Hat 文档。

运行评估作业

创建一个指向 InferenceService 并指定评估任务的 LMEvalJob 自定义资源。Operator 会在 Pod 中运行该作业;作业完成后,结果写入 status.results

示例:使用 arc_easy 任务(lm-evaluation-harness 任务名)评估集群内的 LLM。模型通过 predictor 服务 URL 访问;分词器从 Hugging Face 加载(需要 allowOnline: true 和集群权限)。

apiVersion: trustyai.opendatahub.io/v1alpha1
kind: LMEvalJob
metadata:
  name: evaljob-sample
  namespace: <your-namespace>
spec:
  model: local-completions
  modelArgs:
    - name: model
      value: <inference-service-name>
    - name: base_url
      value: http://<inference-service-name>-predictor.<your-namespace>.svc/v1/completions
    - name: num_concurrent
      value: "1"
    - name: max_retries
      value: "3"
    - name: tokenized_requests
      value: "True"
    - name: tokenizer
      value: <huggingface-model-repo>             # 例如 Qwen/Qwen3.5-4B
  taskList:
    taskNames:
      - arc_easy
  allowOnline: true
  allowCodeExecution: false
  batchSize: "1"
  limit: "2"
  logSamples: true
  chatTemplate:
    enabled: false
  outputs:
    pvcManaged:
      size: 10Mi
  pod:
    container:
      env:
        # 可选:仅当您的组织提供可信镜像时设置 HF_ENDPOINT。
        # - name: HF_ENDPOINT
        #  value: https://<your-approved-hf-mirror>
  • 模型类型(model

    • local-completionslocal-chat-completions,用于兼容 OpenAI API 的服务器(例如 InferenceService predictor)。
    • 它们映射到 OpenAI 端点:
      • local-completions 对应 /v1/completions
      • local-chat-completions 对应 /v1/chat/completions
    • modelArgs.base_url 必须使用相同路径(例如 xxx/v1/completionsxxx/v1/chat/completions)。
  • 模型参数(modelArgs

    • base_url:包含路径的 predictor URL
      • local-completions 使用 /v1/completions
      • local-chat-completions 使用 /v1/chat/completions
    • model:通常与 InferenceService 名称匹配。
    • tokenizer:当 tokenized_requests 为 true 时,用于分词的 Hugging Face 模型 ID。
    • 其他参数(如 num_concurrentmax_retriesbatch_size)遵循 lm-evaluation-harness 文档
  • 任务(taskList.taskNames

    • lm-evaluation-harness 任务名称列表(例如 arc_easymmlu)。
    • 支持的完整任务集和通配符由 lm-evaluation-harness 定义(任务指南 / 可用任务)。
    • 或者,使用 Unitxt 卡片/模板的 taskRecipes 自定义任务。
  • 在线模式和代码执行

    • allowOnline:为 true 时,作业可从互联网下载数据集和分词器(例如 Hugging Face);需集群级权限。
    • allowCodeExecution:为 true 时,作业可运行下载资源中的代码;默认 false,仅在需要且允许时启用。
  • 输出和限制

    • outputs.pvcManaged:创建 Operator 管理的 PVC 用于存储作业结果(大小,例如 100Mi)。若只设置了 size,PVC 使用集群默认的 StorageClass;若无默认 StorageClass,PVC 会处于 Pending 状态且不会分配存储。也可使用 outputs.pvcName 绑定已有 PVC。
    • limit:可选的样本数量上限(例如快速运行时设置为 "2")。
    • logSamples:为 true 时,保存每个提示的模型输入和输出以供检查。

资源状态

LMEvalJob 的 status 子资源报告作业状态,完成后包含评估结果。

  • status.state:作业当前状态:NewScheduledRunningCompleteCancelledSuspended。读取结果前请等待 Complete
  • status.reason:作业结束时设置(例如 SucceededFailed)。
  • status.results:当状态为 Complete 时,包含评估结果的 JSON 字符串(每个任务/配方的指标)。
  • status.message:人类可读消息;status.podName 是作业 Pod 名称。

流量或结果读取应基于 status.state == Complete(且如适用,status.reason == Succeeded)。

获取结果

status.stateComplete 时,结果可在 status.results(JSON 字符串)中获取。示例:

kubectl get lmevaljob evaljob-sample -n <your-namespace> -o jsonpath='{.status.results}' | jq '.'

arc_easy 任务的示例结果结构(关键字段;完整输出包含 configsconfign-shotn-samples 和环境信息):

示例结果(arc_easy)
{
  "results": {
    "arc_easy": {
      "alias": "arc_easy",
      "acc,none": 0.5,
      "acc_stderr,none": 0.5,
      "acc_norm,none": 0.5,
      "acc_norm_stderr,none": 0.5
    }
  },
  "group_subtasks": {
    "arc_easy": []
  },
  "configs": {
    "arc_easy": {
      "task": "arc_easy",
      "tag": ["ai2_arc"],
      "dataset_path": "allenai/ai2_arc",
      "dataset_name": "ARC-Easy",
      "training_split": "train",
      "validation_split": "validation",
      "test_split": "test",
      "doc_to_text": "Question: {{question}}\nAnswer:",
      "doc_to_target": "{{choices.label.index(answerKey)}}",
      "unsafe_code": false,
      "doc_to_choice": "{{choices.text}}",
      "description": "",
      "target_delimiter": " ",
      "fewshot_delimiter": "\n\n",
      "num_fewshot": 0,
      "metric_list": [
        { "metric": "acc", "aggregation": "mean", "higher_is_better": true },
        { "metric": "acc_norm", "aggregation": "mean", "higher_is_better": true }
      ],
      "output_type": "multiple_choice",
      "repeats": 1,
      "should_decontaminate": true,
      "doc_to_decontamination_query": "Question: {{question}}\nAnswer:",
      "metadata": { "version": 1.0 }
    }
  },
  "versions": { "arc_easy": 1.0 },
  "n-shot": { "arc_easy": 0 },
  "higher_is_better": { "arc_easy": { "acc": true, "acc_norm": true } },
  "n-samples": {
    "arc_easy": { "original": 2376, "effective": 2 }
  },
  "config": {
    "model": "local-completions",
    "model_args": "model=<inference-service-name>,base_url=http://<inference-service-name>.trustyai-e2e-test.svc/v1/completions,num_concurrent=1,max_retries=3,tokenized_requests=True,tokenizer=......",
    "batch_size": "1",
    "device": "cpu",
    "limit": 2.0,
    "bootstrap_iters": 100000,
    "random_seed": 0,
    "numpy_seed": 1234,
    "torch_seed": 1234,
    "fewshot_seed": 1234
  },
  "model_source": "local-completions",
  "model_name": "<inference-service-name>",
  "start_time": 185129.71525112,
  "end_time": 185190.022770961,
  "total_evaluation_time_seconds": "60.307519840978784"
}

可选:离线存储和 PVC

离线 模式下,评估作业不访问互联网;模型和数据集必须从 PVC(或镜像)读取。适用于集群禁止在线访问或隔离环境。

离线模式的 Spec 设置

  • 作业字段

    • allowOnline: false:作业不从互联网下载。
    • offline.storage.pvcName:已有 PVC 名称。Operator 将该 PVC 挂载到作业 Pod,作业从挂载路径加载模型和数据集。
  • Spec 中的路径

    • 模型/数据集加载器必须指向挂载的 PVC。
    • 对于 Hugging Face 模型,配置 modelArgs 使模型路径位于 PVC 挂载下(例如 /opt/app-root/src/hf_home/<model-dir>)。
    • 对于从磁盘加载的 taskRecipes 或自定义 Unitxt 卡片,设置加载器路径在同一挂载下。

离线缓存的环境变量

spec.pod.container.env 中设置环境变量,使加载器使用 PVC 作为缓存/存储。为保证可靠性,以下变量均设置为 PVC 挂载下的同一目录(例如 /opt/app-root/src/hf_home):

  • HF_DATASETS_CACHE:Hugging Face datasets 的缓存目录。
  • HF_HOME:Hugging Face 主页,用于分词器和其他资源。
  • TRANSFORMERS_CACHEtransformers 模型和分词器的缓存目录。

离线模式示例片段:

spec:
  allowOnline: false
  offline:
    storage:
      pvcName: my-offline-pvc
  pod:
    container:
      env:
        - name: HF_DATASETS_CACHE
          value: /opt/app-root/src/hf_home
        - name: HF_HOME
          value: /opt/app-root/src/hf_home
        - name: TRANSFORMERS_CACHE
          value: /opt/app-root/src/hf_home

仅在存储 评估结果 时使用 outputs.pvcNameoutputs.pvcManagedoffline.storage.pvcName 用于 输入(模型和数据集)。

离线运行的 PVC 数据集准备

离线模式下,数据集(以及使用 HF 时的分词器/模型文件)必须已存在于 PVC 下。作业不会从网络获取。

准备 PVC 的一种实用方法:

  1. 在线预热作业

    • 创建一个 allowOnline: true 的 LMEvalJob。
    • 挂载目标 PVC(即后续离线模式使用的 PVC),例如通过 offline.storage.pvcName 或额外卷。
    • 让该作业下载所需的数据集/分词器/模型,存储在 HF_DATASETS_CACHEHF_HOMETRANSFORMERS_CACHE 以及配置的 modelArgs / 任务加载器所用的 PVC 路径下。
  2. 离线评估作业

    • 创建实际评估作业,设置 allowOnline: false,并将 offline.storage.pvcName 指向同一 PVC。
    • 作业将从 PVC 读取所有模型和数据集,无需外部网络访问。