news 2026/1/25 2:37:21

大模型评估指南:从MMLU到LLM裁判,4种方法带你玩转AI性能测试,小白也能秒变评估大神!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大模型评估指南:从MMLU到LLM裁判,4种方法带你玩转AI性能测试,小白也能秒变评估大神!

我们究竟该如何评估大语言模型(LLMs)?

这是一个看似简单的问题,但往往会引出一场更为宏大的讨论。

在我为项目提供建议或参与协作时,被问到最多的问题之一就是:如何在不同模型之间做出选择,以及如何理解现有的各种评测结果。(当然,还包括在微调或开发我们自己的模型时,如何衡量进展。)

正因为这个问题被反复提及,我觉得分享一份关于人们用于比较大语言模型的主要评估方法的简要概览,或许会很有帮助。当然,LLM 评估是一个非常庞大的主题,不可能在单一资源中被全面覆盖,但我认为,拥有一张关于这些主要方法的清晰“心智地图”,会让我们更容易解读各种基准测试、排行榜和论文。

我最初计划将这些评估技术纳入我即将出版的书《从零构建推理模型》中,但它们最终有些超出了该书的主要范围。(这本书本身更侧重于基于验证器的评估。)因此,我想,把这些内容作为一篇更长的文章,并配以从零开始的代码示例来分享,会是一个不错的选择。

在《从零构建推理模型》中,我采取了一种动手实践的方法,从零开始构建一个推理型大语言模型。

如果你喜欢《从零构建大语言模型》,那么这本书在“从零开始、纯 PyTorch 构建”的写作风格上与之类似。

推理是近年来提升大语言模型能力中最令人兴奋、也最重要的进展之一,但如果你只是听到“推理”这个词,并在理论层面阅读相关内容,它同样也是最容易被误解的概念之一。因此,在这本书中,我采取了一种从零开始、动手实践的方式来构建一个推理型大语言模型

这本书目前处于早期访问阶段,已经有 100 多页内容上线。我刚刚完成了另外 30 页,目前正在由排版团队处理中。如果你加入了早期访问计划(非常感谢你的支持!),当这些内容上线时,你应该会收到一封邮件通知。

PS:最近 LLM 研究领域发生了很多事情。我仍在努力追赶不断增长的论文书签列表,并计划在下一篇文章中重点介绍其中一些最有趣的工作。

现在,让我们来讨论四种主要的 LLM 评估方法,并结合从零开始的代码实现,更好地理解它们的优缺点。

理解用于评估大语言模型的主要方法

在实践中,评估已训练的大语言模型通常有四种常见方式:多项选择、验证器、排行榜,以及 LLM 裁判,如下图所示。研究论文、市场材料、技术报告以及模型卡(这是针对 LLM 的一种技术报告形式)通常会包含来自其中两类或更多类别的评测结果。

此外,这里介绍的四个类别可以进一步归为两大类:基于基准的评估和基于判断的评估,如上图所示。

(此外,还有一些其他指标,例如训练损失、困惑度和奖励值,但它们通常用于模型开发过程中的内部评估。)

接下来的小节将对这四种方法分别进行简要概述和示例说明。

方法一:评估答案选择准确率

我们从一种基于基准的方法开始:多项选择问答。

从历史上看,最广泛使用的评估方法之一是多项选择基准测试,例如 MMLU(Massive Multitask Language Understanding 的缩写)。为了说明这种方法,图 2 展示了一个来自 MMLU 数据集的代表性任务。

图 2:通过将 LLM 的多项选择预测与数据集中给出的正确答案进行比较,对模型在 MMLU 上进行评估

图 2 只展示了 MMLU 数据集中的一个示例。完整的 MMLU 数据集包含 57 个学科(从高中数学到生物学),总计约 1.6 万道多项选择题,其性能通常以准确率来衡量,例如,如果 16,000 道题中有 14,000 道答对,则准确率为 87.5%。

像 MMLU 这样的多项选择基准测试,以一种直接、可量化的方式测试 LLM 的知识回忆能力,类似于标准化考试、学校考试或理论驾驶考试。

需要注意的是,图 2 展示的是一种简化版本的多项选择评估方法,即直接将模型预测的答案字母与正确答案进行比较。还有两种同样流行的方法,它们涉及对数概率评分。我已经在 GitHub 上实现了这些方法。(由于这些方法建立在本文解释的概念之上,我建议在读完本文后再查看。)

接下来的小节将展示如何在代码中实现图 2 所示的 MMLU 评分方法。

1.2 加载模型

首先,在我们能够在 MMLU 上评估模型之前,需要加载一个预训练模型。在这里,我们将使用一个纯 PyTorch 实现的、从零构建的 Qwen3 0.6B 模型,它只需要大约 1.5 GB 的内存。

请注意,Qwen3 模型的具体实现细节在这里并不重要;我们只是将它视为一个需要被评估的 LLM。不过,如果你感兴趣,可以在我之前的文章《从零理解与实现 Qwen3》中找到完整的从零实现讲解,其源代码也可以在 GitHub 上获取。

为了避免复制粘贴大量的 Qwen3 源代码,我们从我的 reasoning_from_scratch Python 库中直接导入它,该库可以通过以下方式安装:

pip install reasoning_from_scratch

或者

uv add reasoning_from_scratch

代码块 1:加载一个预训练模型

from pathlib import Pathimport torchfrom reasoning_from_scratch.ch02 import get_devicefrom reasoning_from_scratch.qwen3 import ( download_qwen3_small, Qwen3Tokenizer, Qwen3Model, QWEN_CONFIG_06_B)device = get_device()# Set matmul precision to "high" to # enable Tensor Cores on compatible GPUstorch.set_float32_matmul_precision("high")# Uncomment the following line # if you encounter device compatibility issues# device = "cpu"# Use the base model by defaultWHICH_MODEL = "base"if WHICH_MODEL == "base": download_qwen3_small( kind="base", tokenizer_only=False, out_dir="qwen3" ) tokenizer_path = Path("qwen3") / "tokenizer-base.json" model_path = Path("qwen3") / "qwen3-0.6B-base.pth" tokenizer = Qwen3Tokenizer(tokenizer_file_path=tokenizer_path)elif WHICH_MODEL == "reasoning": download_qwen3_small( kind="reasoning", tokenizer_only=False, out_dir="qwen3" ) tokenizer_path = Path("qwen3") / "tokenizer-reasoning.json" model_path = Path("qwen3") / "qwen3-0.6B-reasoning.pth" tokenizer = Qwen3Tokenizer( tokenizer_file_path=tokenizer_path, apply_chat_template=True, add_generation_prompt=True, add_thinking=True, )else: raise ValueError(f"Invalid choice: WHICH_MODEL={WHICH_MODEL}")model = Qwen3Model(QWEN_CONFIG_06_B)model.load_state_dict(torch.load(model_path))model.to(device)# Optionally enable model compilation for potential performance gainsUSE_COMPILE = Falseif USE_COMPILE: torch._dynamo.config.allow_unspec_int_on_nn_module = True model = torch.compile(model)

1.3 检查生成的答案字母

在这一节中,我们将实现最简单、也可能是最直观的一种 MMLU 评分方法,它依赖于检查模型生成的多项选择答案字母是否与正确答案一致。这与前面图 2 中所展示的过程是类似的,下面为了方便再次展示。

图 3:通过将 LLM 的多项选择预测与数据集中给出的正确答案进行比较,对模型在 MMLU 上进行评估

为此,我们将使用一个来自 MMLU 数据集的示例:

example = { "question": ( "How many ways are there to put 4 distinguishable" " balls into 2 indistinguishable boxes?" ), “choices”: ["7", "11", "16", "8"], “answer”: "D",}

接下来,我们定义一个函数,用于格式化 LLM 的提示词。

代码块 2:格式化提示词

def format_prompt(example): return ( f"{example['question']}\n" f"A. {example['choices'][0]}\n" f"B. {example['choices'][1]}\n" f"C. {example['choices'][2]}\n" f"D. {example['choices'][3]}\n" "Answer: " )# Trailing space in "Answer: " encourages a single-letter next token

让我们在这个 MMLU 示例上执行该函数,以直观了解格式化后的 LLM 输入是什么样子:

prompt = format_prompt(example)print(prompt)

输出结果是:

How many ways are there to put 4 distinguishable balls into 2indistinguishable boxes?A. 7B. 11C. 16D. 8Answer:

如上所示,该提示词向模型提供了一组不同的答案选项,并以“Answer: ”结尾,从而鼓励模型生成正确的答案。

虽然这并非严格必要,但有时在输入中额外提供一些示例问题及其正确答案,也会有所帮助,这样模型可以观察到期望的解题方式。(例如,提供 5 个示例的情况也被称为 5-shot MMLU。)不过,对于当前一代的 LLM 来说,即使是基础模型也已经相当强大,因此通常不需要这样做。

加载不同的 MMLU 样本

你可以通过 datasets 库直接加载 MMLU 数据集中的示例(可通过 pip install datasets 或 uv add datasets 安装):

from datasets import load_datasetconfigs = get_dataset_config_names("cais/mmlu")dataset = load_dataset("cais/mmlu", "high_school_mathematics")# Inspect the first example from the test set:example = dataset["test"][0]print(example)

在上面的示例中,我们使用了 “high_school_mathematics” 子集;如果想获取其他子集的列表,可以使用下面的代码:

from datasets import get_dataset_config_namessubsets = get_dataset_config_names("cais/mmlu")print(subsets)

接下来,我们对提示词进行分词(tokenize),并将其包装成一个 PyTorch 张量对象,作为 LLM 的输入:

prompt_ids = tokenizer.encode(prompt)prompt_fmt = torch.tensor(prompt_ids, device=device)# Add batch dimension:prompt_fmt = prompt_fmt.unsqueeze(0)

在完成上述准备工作之后,我们定义下面的主评分函数。该函数会生成少量 token(此处默认生成 8 个 token),并提取模型输出中首次出现的字母 A/B/C/D。

代码块 3:提取生成的答案字母

from reasoning_from_scratch.ch02_ex import ( generate_text_basic_stream_cache)def predict_choice( model, tokenizer, prompt_fmt, max_new_tokens=8): pred = None for t in generate_text_basic_stream_cache( model=model, token_ids=prompt_fmt, max_new_tokens=max_new_tokens, eos_token_id=tokenizer.eos_token_id, ): answer = tokenizer.decode(t.squeeze(0).tolist()) for letter in answer: letter = letter.upper() # stop as soon as a letter appears if letter in "ABCD": pred = letter break if pred: break return pred

接下来,我们可以使用上面代码块中的函数来检查生成的答案字母,方式如下:

pred1 = predict_choice(model, tokenizer, prompt_fmt)print( f"Generated letter: {pred1}\n" f"Correct? {pred1 == example['answer']}")

结果如下所示:

Generated letter: CCorrect? False

正如我们所看到的,在这个示例中,生成的答案是不正确的(False)。

这只是 MMLU 中 high_school_mathematics 子集的 270 个示例之一。下面的截图(图 4)展示了在整个子集上运行时,基础模型和推理模型的整体性能。相关代码可以在 GitHub 上找到。

图 4:基础模型与推理模型在 MMLU high_school_mathematics 子集上的表现

假设每个问题的答案概率是均匀分布的,那么一个随机猜测者(以相同概率选择 A、B、C 或 D)的期望准确率为 25%。因此,无论是基础模型还是推理模型,在这里的表现都并不算好。

多项选择答案格式

需要注意的是,本节为了说明问题,实现的是一种简化版本的多项选择评估方式,即直接将模型预测的答案字母与正确答案进行比较。在实际应用中,更常见的是一些变体方法,例如基于对数概率(log-probability)的评分方式,即衡量模型对每一个候选答案的偏好程度,而不仅仅是检查最终选择的字母。(我们将在第 4 章中讨论基于概率的评分方法。)对于推理模型而言,评估还可以包括在将正确答案作为输入提供时,模型生成该答案的可能性。

图 5:其他 MMLU 评分方法的说明与实现已在 GitHub 上分享

不过,无论我们使用哪一种 MMLU 评分变体,这类评估的本质仍然是检查模型是否从预定义的答案选项中做出了选择。

像 MMLU 这样的多项选择基准测试的一个局限性在于,它们只衡量 LLM 在预定义选项中进行选择的能力。因此,除了用来检查模型相较于基础模型遗忘了多少知识之外,它们并不太适合用于评估推理能力。同时,这类评估也无法反映模型在自由文本写作或真实世界任务中的实用性。

尽管如此,多项选择基准测试依然是简单且有用的诊断工具。例如,一个很高的 MMLU 分数并不一定意味着模型在实际应用中很强,但一个很低的分数往往可以揭示潜在的知识缺口。

方法二:使用验证器检查答案

与上一节讨论的多项选择问答相关,基于验证的评估方法同样通过准确率指标来量化 LLM 的能力。然而,与多项选择基准不同的是,验证方法允许 LLM 给出自由形式的答案。随后,我们会从模型输出中提取相关的答案部分,并使用所谓的验证器(verifier),将该答案部分与数据集中提供的正确答案进行比较,如下图所示。

图 6:在自由形式问答中,使用基于验证的方法评估 LLM。模型生成一个自由形式的答案(可能包含多个推理步骤)以及一个最终被框出的答案,该答案会被提取出来,并与数据集中给出的正确答案进行比较

当我们将提取出的答案与给定答案进行比较时,如上图所示,还可以借助外部工具,例如代码解释器或类似计算器的工具/软件。

这种方法的缺点在于,它只能应用于那些容易(且理想情况下是确定性地)验证的领域,例如数学和代码。此外,这种方法可能引入额外的复杂性和依赖关系,并且可能会将一部分评估负担从模型本身转移到外部工具上。

然而,由于它允许我们以编程方式生成无限数量的数学题变体,并且能够从逐步推理中获益,因此它已经成为推理模型评估与开发中的一个基石。

我在《从零构建推理模型》这本书中,用了整整 35 页系统性地介绍这一主题,因此这里我将跳过代码实现。(我上周已经提交了该章节。如果你拥有早期访问版本,当它上线时你会收到一封邮件并可以阅读。在此之前,你可以在 GitHub 上找到逐步讲解的代码【代码】。)

图 7:基于验证的评估方法示例,完整内容可在 GitHub 上查看【代码】

https://github.com/rasbt/reasoning-from-scratch/blob/main/ch03/01_main-chapter-code/ch03_main.ipynb

方法三:通过偏好与排行榜比较模型

到目前为止,我们介绍了两种可以提供易于量化指标(例如模型准确率)的评估方法。然而,上述方法都无法以更整体的方式评估 LLM,例如对回答风格的判断。本节将讨论一种基于判断的方法——LLM 排行榜,如下图所示。

图 8:本书所涵盖主题的心智模型,重点突出本附录中介绍的基于判断和基于基准的评估方法。在前一节已经介绍了基于基准的方法(多项选择、验证器)之后,这里我们引入基于判断的方法来衡量 LLM 的性能,本小节重点关注排行榜

这里描述的排行榜方法是一种基于判断的方式,模型并非依据准确率或其他固定基准分数进行排名,而是依据用户(或其他 LLM)对模型输出的偏好进行排序。

一个广受欢迎的排行榜是LM Arena(原 Chatbot Arena),用户会对两个由用户选择或匿名的模型生成的回答进行对比,并投票选择自己更偏好的一个,如下图所示。

图 9:一个基于判断的排行榜界面示例(LM Arena)。两个 LLM 接收相同的提示,其回答并排展示,用户为自己偏好的答案投票

这些偏好投票会被汇总,并形成一个排行榜,根据用户偏好对不同模型进行排序。下图展示的是截至 2025 年 10 月 3 日访问时的 LM Arena 排行榜快照。

图 10:LM Arena 排行榜截图,展示了基于用户在文本任务上的偏好而排名靠前的 LLM

在本节的其余部分,我们将实现一个简单的排行榜示例。

为了构造一个具体示例,假设用户在类似图 9 的设置中对不同 LLM 进行提问。下面的列表表示成对投票结果,其中第一个模型是胜者:

votes = [ ("GPT-5", "Claude-3"), ("GPT-5", "Llama-4"), ("Claude-3", "Llama-3"), ("Llama-4", "Llama-3"), ("Claude-3", "Llama-3"), ("GPT-5", "Llama-3"),]

在上面的列表中,每一个元组表示两个模型之间的一次偏好比较,格式为(胜者,败者)。因此,(“GPT-5”,“Claude-3”)表示用户更偏好 GPT-5 的回答,而不是 Claude-3。

接下来,我们将把这些投票结果转换成一个排行榜。为此,我们将使用著名的Elo 评分系统,该系统最初是为国际象棋选手排名而设计的。

在查看具体代码实现之前,先简要说明其工作原理:每个模型从一个基础分数开始。之后,每进行一次比较并产生一次偏好投票,模型的评分就会更新。(在 Elo 系统中,更新幅度取决于结果的“意外程度”。)

具体来说,如果用户偏好一个当前评分较低的模型而非一个高评分模型,那么该模型将获得较大的分数提升,从而在排行榜中上升。相反,如果它击败的是一个低评分对手,分数提升就会较小。(如果模型失败,则会以类似方式扣除分数。)

将成对投票转换为排行榜的代码如下所示。

代码块 4:构建排行榜

def elo_ratings(vote_pairs, k_factor=32, initial_rating=1000): # Initialize all models with the same base rating ratings = { model: initial_rating for pair in vote_pairs for model in pair } # Update ratings after each match for winner, loser in vote_pairs: # Expected score for the current winner expected_winner = 1.0 / ( 1.0 + 10 ** ( (ratings[loser] - ratings[winner]) / 400.0 ) ) # k_factor determines sensitivity of updates ratings[winner] = ( ratings[winner] + k_factor * (1 - expected_winner) ) ratings[loser] = ( ratings[loser] + k_factor * (0 - (1 - expected_winner)) ) return ratings

上述 elo_ratings 函数以投票列表作为输入,并生成一个排行榜,例如:

ratings = elo_ratings(votes, k_factor=32, initial_rating=1000)for model in sorted(ratings, key=ratings.get, reverse=True): print(f"{model:8s} : {ratings[model]:.1f}")

最终得到如下排行榜,其中分数越高表示模型表现越好:

GPT-5 : 1043.7Claude-3 : 1015.2Llama-4 : 1000.7Llama-3 : 940.4

那么,这一过程是如何运作的呢?对于每一对比较,我们都会使用下面的公式计算胜者的期望得分:

expected_winner = 1 / (1 + 10 ** ((rating_loser - rating_winner) / 400))

这个 expected_winner 表示在当前评分下,模型在无平局情形中获胜的预测概率。它决定了评分更新的幅度。

首先,所有模型的初始评分都是 initial_rating = 1000。如果两者评分相同,则 expected_winner = 0.5,表示势均力敌。在这种情况下,评分更新如下:

胜者评分 + k_factor × (1 − 0.5) = 胜者评分 + 16
败者评分 + k_factor × (0 − (1 − 0.5)) = 败者评分 − 16

如果一个明显的热门模型(评分很高)获胜,则 expected_winner ≈ 1。此时胜者只会获得很小的分数提升,败者也只会损失很少:

胜者评分 + 32 × (1 − 0.99) = 胜者评分 + 0.32
败者评分 + 32 × (0 − (1 − 0.99)) = 败者评分 − 0.32

而如果一个冷门模型(评分较低)获胜,则 expected_winner ≈ 0,胜者将获得几乎全部的 k_factor 分数,而败者将损失近似数量的分数:

胜者评分 + 32 × (1 − 0.01) = 胜者评分 + 31.68
败者评分 + 32 × (0 − (1 − 0.01)) = 败者评分 − 31.68

顺序的重要性

Elo 方法会在每一场对比之后立即更新评分,因此后续结果建立在已经更新过的评分之上。这意味着,即便结果集合相同,只要呈现顺序不同,最终分数也可能略有差异。这种影响通常较小,但在冷门结果出现在早期或晚期时尤其明显。

为了减弱顺序效应,可以对投票对进行随机打乱,多次运行 elo_ratings 函数,并对最终评分取平均值。

像上述这样的排行榜方法,相比静态基准分数,能够提供更动态的模型质量视角。然而,其结果也可能受到用户群体、提示词选择以及投票偏差的影响。基准和排行榜同样可能被“刷榜”,而用户也可能更多基于风格而非正确性来选择答案。此外,与自动化基准测试工具相比,排行榜无法为新模型变体提供即时反馈,因此在模型的主动开发过程中使用起来更为困难。

其他排序方法

LM Arena 最初使用的正是本节介绍的 Elo 方法,但最近已经转向基于Bradley–Terry 模型的统计方法。Bradley–Terry 模型的主要优势在于其统计学基础,使得我们可以构建置信区间来表达排名的不确定性。此外,与 Elo 不同,Bradley–Terry 模型会在整个数据集上进行联合估计,从而避免了顺序效应。

为了保持评分在一个熟悉的范围内,Bradley–Terry 模型通常会被拟合为生成与 Elo 可比的数值。尽管排行榜已不再官方使用 Elo 评分,但在 LLM 研究者和实践者中,“Elo”这一术语仍被广泛用来指代模型间的比较。相关代码示例可在 GitHub 上找到【代码】。

图 11:Elo 与 Bradley–Terry 排名的对比;源代码可在 GitHub 上获取【代码】

方法四:使用其他大语言模型对回答进行裁判式评估

在早期,大语言模型通常使用统计方法和基于启发式规则的方法进行评估,其中包括一种名为 BLEU 的指标,它是一种粗略衡量生成文本与参考文本匹配程度的方法。这类指标的问题在于,它们要求精确的词级匹配,无法考虑同义词、措辞变化等情况。

如果我们希望从整体上评判一段书面回答文本,一个解决方案是使用上一节讨论的相对排序排行榜方法。然而,排行榜的一个缺点在于其基于偏好的比较本身具有主观性,因为它依赖于人工反馈(以及收集这些反馈所面临的挑战)。

一种相关的方法是:使用另一个大语言模型,并结合一个预定义的评分量表(即评估准则),将待评估模型的回答与参考答案进行比较,并依据该量表对回答质量进行判断,如图 12 所示。

图 12:LLM 裁判式评估示例。被评估的模型生成一个答案,随后由另一个裁判 LLM 根据评分量表和给定的参考答案对其进行打分

在实践中,当裁判 LLM 足够强大时,这种基于裁判的方法通常效果很好。常见的设置是通过 API 使用领先的专有 LLM(例如 GPT-5 API),当然,也存在一些专门的裁判模型。(例如众多案例之一是 Phudge;但从本质上看,这些专用模型大多只是经过微调的小模型,使其评分行为接近专有 GPT 模型。)

裁判方法之所以效果显著,其中一个原因在于:评估一个答案通常比生成一个答案更容易

要在 Python 中以编程方式实现图 12 所示的裁判式模型评估,我们可以选择在 PyTorch 中加载一个更大的 Qwen3 模型,并使用评分量表以及我们希望评估的模型答案对其进行提示。

或者,我们也可以通过 API 使用其他 LLM,例如 ChatGPT API 或 Ollama API。

由于我们已经了解了如何在 PyTorch 中加载 Qwen3 模型,为了让示例更有意思,在本节剩余部分中,我们将使用Ollama API在 Python 中实现图 12 所示的裁判式评估。

具体来说,我们将使用 OpenAI 提供的、参数规模为 200 亿的开源权重模型gpt-oss,因为它在能力与效率之间提供了良好的平衡。关于 gpt-oss 的更多信息,可以参考我之前的文章《From GPT-2 to gpt-oss: Analyzing the Architectural Advances》。

https://magazine.sebastianraschka.com/p/from-gpt-2-to-gpt-oss-analyzing-the

4.1 使用 Ollama 实现 LLM-as-a-Judge 方法

Ollama 是一款高效的开源应用程序,用于在个人电脑上运行大语言模型。它本质上是对开源的 llama.cpp 库的一层封装,而 llama.cpp 使用纯 C/C++ 实现大语言模型,以最大化运行效率。需要注意的是,Ollama 仅用于使用 LLM 进行文本生成(推理),并不支持模型的训练或微调。

要运行下面的代码,请访问 Ollama 官方网站 https://ollama.com 并按照你所使用操作系统的说明完成安装:

  • • 对于 macOS 和 Windows 用户:打开下载好的 Ollama 应用。如果系统询问是否安装命令行工具,请选择“yes”。
  • • 对于 Linux 用户:请使用 Ollama 官网提供的安装命令。

在实现模型评估代码之前,我们首先需要下载 gpt-oss 模型,并通过命令行验证 Ollama 是否可以正常工作。

请在命令行终端(而不是 Python 会话中)执行以下命令,以尝试运行 200 亿参数规模的 gpt-oss 模型:

ollama run gpt-oss:20b

第一次执行该命令时,占用约 14 GB 存储空间的 gpt-oss 200 亿参数模型将被自动下载。输出结果如下所示:

$ ollama run gpt-oss:20bpulling manifest pulling b112e727c6f1: 100% ▕██████████████████████▏ 13 GB pulling fa6710a93d78: 100% ▕██████████████████████▏ 7.2 KB pulling f60356777647: 100% ▕██████████████████████▏ 11 KB pulling d8ba2f9a17b3: 100% ▕██████████████████████▏ 18 B pulling 55c108d8e936: 100% ▕██████████████████████▏ 489 B verifying sha256 digest writing manifest removing unused layers success

替代的 Ollama 模型

请注意,命令中的 gpt-oss:20b 指的是 200 亿参数规模的 gpt-oss 模型。使用该模型大约需要 13 GB 的内存。如果你的机器内存不足,可以尝试使用更小的模型,例如通过 ollama run qwen3:4b 运行 40 亿参数规模的 qwen3 模型,它只需要大约 4 GB 内存。

如果你的计算机性能更强,也可以使用更大的 1200 亿参数 gpt-oss 模型,只需将 gpt-oss:20b 替换为 gpt-oss:120b。不过需要注意,该模型对计算资源的要求要高得多。

当模型下载完成后,你将看到一个命令行界面,可以直接与模型进行交互。例如,尝试向模型提问:“What is 1+2?”:

>>> What is 1+2?Thinking...User asks: “What is 1+2?” This is simple: answer 3. Provide explanation? Possibly ask for simplearithmetic. Provide answer: 3....done thinking.1 + 2 = **3**

你可以通过输入 /bye 结束 ollama run gpt-oss:20b 会话。

在本节剩余部分中,我们将使用 Ollama API。该方式要求 Ollama 在后台运行。可以通过以下三种方式之一实现:

    1. 在终端中运行 ollama serve 命令(推荐)。这会将 Ollama 后端作为服务器运行,通常监听在 http://localhost:11434。需要注意的是,模型只有在通过 API 调用时才会被加载。
    1. 类似前面那样运行 ollama run gpt-oss:20b,但不要通过 /bye 退出会话。正如前文所述,这实际上是在本地 Ollama 服务器之上运行的一个最小封装。
    1. 使用 Ollama 桌面应用。打开桌面应用会自动运行同一个后端,并提供一个图形界面,如前面的图 12 所示。

图 13:两种保持 Ollama 服务器(或应用)运行的方法,以便我们可以在 Python 中通过 Ollama API 使用它

Ollama 服务器 IP 地址

Ollama 通过在本地启动一个类似服务器的进程来运行。如果你在终端中运行 ollama serve 时遇到错误提示:

Error: listen tcp 127.0.0.1:11434: bind: address already in use

请尝试使用以下命令:

OLLAMA_HOST=127.0.0.1:11435 ollama serve

如果该地址仍然被占用,可以继续递增端口号,直到找到一个可用的地址。

下面的代码用于在使用 Ollama 对上一节中生成的测试集回答进行评估之前,验证 Ollama 会话是否正在正常运行。

代码块 5:检查 Ollama 是否正在运行

import psutildef check_if_running(process_name): running = False for proc in psutil.process_iter(["name"]): if process_name in proc.info["name"]: running = True break return runningollama_running = check_if_running("ollama")if not ollama_running: raise RuntimeError( "Ollama not running. " "Launch ollama before proceeding." )print("Ollama running:", check_if_running("ollama"))

请确保执行上述代码后输出显示 Ollama running: True。如果显示为 False,请确认 ollama serve 命令或 Ollama 应用正在运行(参见图 13)。

在本文接下来的部分中,我们将通过 Python 使用 Ollama REST API,与本地运行的 gpt-oss 模型进行交互。下面的 query_model 函数演示了如何使用该 API。

代码块 6:查询本地 Ollama 模型

import jsonimport urllib.requestdef query_model( prompt, model="gpt-oss:20b", # If you used # OLLAMA_HOST=127.0.0.1:11435 ollama serve # update the address below url="http://localhost:11434/api/chat"): # Create the data payload as a dictionary: data = { "model": model, "messages": [ {"role": "user", "content": prompt} ], # Settings required for deterministic responses: "options": { "seed": 123, "temperature": 0, "num_ctx": 2048 } } # Convert the dictionary to JSON and encode it to bytes payload = json.dumps(data).encode("utf-8") # Create a POST request and add headers request = urllib.request.Request( url, data=payload, method="POST" ) request.add_header("Content-Type", "application/json") response_data = "" # Send the request and capture the streaming response with urllib.request.urlopen(request) as response: while True: line = response.readline().decode("utf-8") if not line: break # Parse each line into JSON response_json = json.loads(line) response_data += response_json["message"]["content"] return response_data

下面是一个使用刚刚实现的 query_model 函数的示例:

ollama_model = "gpt-oss:20b"result = query_model("What is 1+2?", ollama_model)print(result)

返回结果为 “3”。(由于默认设置不同,这一结果与直接使用 ollama run 或 Ollama 应用时的输出可能略有差异。)

借助 query_model 函数,我们可以使用包含评分量表的提示词,让 gpt-oss 模型作为裁判,根据参考答案,对目标模型的回答按 1 到 5 分进行评分。

我们使用的提示词如下所示:

代码块 7:包含评分量表的提示词模板

def rubric_prompt(instruction, reference_answer, model_answer): rubric = ( "You are a fair judge assistant. You will be " "given an instruction, a reference answer, and " "a candidate answer to evaluate, according to " "the following rubric:\n\n" "1: The response fails to address the " "instruction, providing irrelevant, incorrect, " "or excessively verbose content.\n" "2: The response partially addresses the " "instruction but contains major errors, " "omissions, or irrelevant details.\n" "3: The response addresses the instruction to " "some degree but is incomplete, partially " "correct, or unclear in places.\n" "4: The response mostly adheres to the " "instruction, with only minor errors, " "omissions, or lack of clarity.\n" "5: The response fully adheres to the " "instruction, providing a clear, accurate, and " "relevant answer in a concise and efficient " "manner.\n\n" "Now here is the instruction, the reference " "answer, and the response.\n" ) prompt = ( f"{rubric}\n" f"Instruction:\n{instruction}\n\n" f"Reference Answer:\n{reference_answer}\n\n" f"Answer:\n{model_answer}\n\n" f"Evaluation: " ) return prompt

其中,rubric_prompt 中的 model_answer 代表我们实际要评估的目标模型所生成的回答。为了便于演示,这里我们直接硬编码了一个合理的模型回答,而不是动态生成。(当然,你也可以使用本文开头加载的 Qwen3 模型来生成真实的 model_answer。)

接下来,我们生成传递给 Ollama 模型的完整提示词:

rendered_prompt = rubric_prompt( instruction=( "If all birds can fly, and a penguin is a bird, " "can a penguin fly?" ), reference_answer=( "Yes, according to the premise that all birds can fly, " "a penguin can fly." ), model_answer=( "Yes – under those premises a penguin would be able to fly." ))print(rendered_prompt)

其输出如下所示:

You are a fair judge assistant. You will be given an instruction, areference answer, and a candidate answer to evaluate, according to thefollowing rubric:1: The response fails to address the instruction, providing irrelevant,incorrect, or excessively verbose content.2: The response partially addresses the instruction but contains majorerrors, omissions, or irrelevant details.3: The response addresses the instruction to some degree but isincomplete, partially correct, or unclear in places.4: The response mostly adheres to the instruction, with only minorerrors, omissions, or lack of clarity.5: The response fully adheres to the instruction, providing a clear,accurate, and relevant answer in a concise and efficient manner.Now here is the instruction, the reference answer, and the response.Instruction:If all birds can fly, and a penguin is a bird, can a penguin fly?Reference Answer:Yes, according to the premise that all birds can fly, a penguin canfly.Answer:Yes – under those premises a penguin would be able to fly.Evaluation:

提示词以 “Evaluation: ” 结尾,会促使模型生成评估结果。下面我们来看 gpt-oss:20b 模型是如何对该回答进行裁判的:

result = query_model(rendered_prompt, ollama_model)print(result)

输出结果如下:

**Score: 5**The candidate answer directly addresses the question, correctly applies the given premises, and concisely states that a penguin would be able to fly. It is accurate, relevant, and clear.

正如我们所看到的,该回答获得了最高分,这是合理的,因为它确实是正确的。尽管这只是一个手动演示的简单示例,但我们可以将这一思路扩展,例如在一个 for 循环中迭代地用评估数据集中的问题去查询目标模型(例如前面加载的 Qwen3 模型),再通过 gpt-oss 进行评估,并计算平均得分。一个使用 gpt-oss 作为裁判、在 MATH-500 数据集上评估 Qwen3 模型的完整脚本,可以在 GitHub 上找到。

图 14:在 MATH-500 数据集前 10 个样本上,由 gpt-oss:20b 作为裁判,对 Qwen3 0.6 基础模型与推理模型进行评估的对比结果

https://github.com/rasbt/reasoning-from-scratch/tree/main/chF/04_llm-judge

使用过程奖励模型对中间推理步骤进行评分

与符号验证器和 LLM 裁判相关,还有一类被称为过程奖励模型(Process Reward Models,PRMs)的学习型模型。与裁判模型类似,PRM 不仅可以评估最终答案,还可以评估推理过程;但与通用裁判不同的是,它们专注于中间推理步骤。同时,与通常只在结果层面进行符号正确性检查的验证器不同,PRM 在强化学习训练过程中提供逐步的奖励信号。

我们可以将 PRM 视为“步骤级裁判”,它们主要用于训练,而非纯粹的评估。(在实践中,PRM 很难在大规模场景下稳定训练。例如,DeepSeek R1 并未采用 PRM,而是结合了验证器来进行推理训练。)

与基于偏好的排行榜相比,裁判式评估在可扩展性和一致性方面具有优势,因为它不依赖于大量人工投票者。(从技术上讲,也可以用 LLM 裁判来替代排行榜背后的人工偏好评分。)然而,LLM 裁判同样存在与人工评审类似的弱点:结果可能受到模型偏好、提示词设计以及回答风格的影响;此外,评估效果高度依赖于裁判模型和评分量表的选择,其可复现性也不如固定基准测试。

结论

在本文中,我们介绍了四种不同的评估方法:多项选择、验证器、排行榜,以及 LLM 裁判。

我知道这是一篇篇幅较长的文章,但希望它能帮助你全面了解当前 LLM 评估的主要方式。像这样从零开始的讲解虽然较为冗长,但它有助于我们理解这些方法在底层是如何运作的,从而更容易识别其弱点和改进空间。

那么,你可能会问:“评估一个 LLM 的最佳方式是什么?”遗憾的是,并不存在唯一的最佳方法。正如我们所看到的,每种方法都有不同的权衡取舍。简要总结如下:

多项选择

(+) 在大规模运行时相对快速、成本较低
(+) 标准化程度高,论文或模型卡之间具有良好的可复现性
(-) 主要衡量基础知识回忆能力
(-) 无法反映 LLM 在真实世界中的使用方式

验证器

(+) 在存在标准答案的领域中,提供标准化、客观的评分
(+) 允许自由形式的回答(对最终答案格式有一定约束)
(+) 若使用过程验证器或过程奖励模型,还可以对中间步骤进行评分
(-) 仅适用于可验证领域(如数学或代码),且构建高质量验证器并不容易
(-) 仅基于结果的验证器无法评估推理质量

竞技场式排行榜(人工成对偏好)

(+) 直接回答“人们更偏好哪个模型”这一问题
(+) 允许自由形式回答,并隐式考虑风格、帮助性与安全性
(-) 对人工而言成本高、耗时长
(-) 衡量的是偏好而非正确性
(-) 非平稳的人群分布会影响结果稳定性

LLM-as-a-Judge

(+) 可在多种任务上扩展
(+) 允许自由形式回答
(-) 依赖裁判模型自身的能力(可通过模型集成提高鲁棒性)
(-) 强依赖评分量表的设计

虽然我通常不太喜欢雷达图,但在这里,它确实有助于直观展示这些不同的评估维度,如下图所示。

图 15:雷达图示意,强调在评估 LLM 时需要关注多个维度,以识别模型的优势与不足

例如,一个在多项选择基准上表现强劲的模型,通常意味着它具备扎实的通用知识;如果同时在验证器评估中得分也很高,那么它很可能在技术问题上也能给出正确答案。然而,如果该模型在 LLM 裁判和排行榜评估中表现较差,那么它可能在写作或表达方面存在不足,并可能需要一定程度的 RLHF。

因此,最佳的评估方式往往是多种方法的组合,并且最好使用与你自身目标或业务问题直接相关的数据。例如,如果你正在构建一个用于法律相关任务的 LLM,那么运行 MMLU 等通用基准可以作为快速的合理性检查,但最终仍应针对法律领域定制评估。虽然可以从公开基准入手,但最终,你应当使用自己的专有数据进行测试,只有这样,才能较为确信模型在训练阶段没有见过这些测试数据。

无论如何,模型评估都是一个非常重要且庞大的主题。希望本文能够帮助你理解这些主要评估方法的运作方式,并在你下次查看或运行模型评估时,提供一些有价值的参考。

一如既往,

祝你折腾愉快!

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/23 1:18:58

如何快速掌握PvZ Toolkit:游戏修改的终极指南

如何快速掌握PvZ Toolkit:游戏修改的终极指南 【免费下载链接】pvztoolkit 植物大战僵尸 PC 版综合修改器 项目地址: https://gitcode.com/gh_mirrors/pv/pvztoolkit 还在为植物大战僵尸中的资源不足而烦恼吗?PvZ Toolkit作为植物大战僵尸PC版的终…

作者头像 李华
网站建设 2026/1/24 11:51:12

IPX协议重生记:让经典游戏在Windows 10/11重获网络对战能力

IPX协议重生记:让经典游戏在Windows 10/11重获网络对战能力 【免费下载链接】ipxwrapper 项目地址: https://gitcode.com/gh_mirrors/ip/ipxwrapper 还记得那些年与朋友在局域网里激烈对战的《红色警戒2》、《魔兽争霸II》吗?这些承载着青春记忆…

作者头像 李华
网站建设 2026/1/20 17:46:55

CentOS 7.9创建用户深度解析:底层原理、工程化实践与10大核心场景实例(SRE/DevOps扩容版)

文章目录 CentOS 7.9创建用户深度解析:底层原理、工程化实践与10大核心场景实例(SRE/DevOps扩容版) 前言 一、CentOS 7.9创建用户的底层深度拆解(扩容版) 1. UID/GID分配:基础规则与特殊场景 2. 核心身份文件:字段解析与安全机制 3. 家目录与环境初始化:细化配置与特殊…

作者头像 李华
网站建设 2026/1/20 17:46:53

Linux用户管理:从单机到全球规模的深度探索

文章目录 《Linux用户管理:从单机到全球规模的深度探索》 以CentOS 7.9为例,SRE/DevOps视角的全景式指南(五倍增强版) 第一部分:Linux用户创建的核心机制深度剖析 第1章:用户创建命令的多维度解析 1.1 useradd命令的100+参数深度解析 1.2 系统配置文件的深度交互机制 第2…

作者头像 李华
网站建设 2026/1/25 0:54:10

Android手机变身USB输入设备:USB HID Client实战指南

Android手机变身USB输入设备:USB HID Client实战指南 【免费下载链接】android-hid-client Android app that allows you to use your phone as a keyboard and mouse WITHOUT any software on the other end (Requires root) 项目地址: https://gitcode.com/gh_m…

作者头像 李华