AB
AiBoss
チュートリアル

MMLU

チュートリアル

用 DeepEval 的 MMLU 基准评测自定义大模型的多学科选择题表现

MMLU 用 57 个学科的选择题考察大模型的知识广度。本文说明如何在 DeepEval 中构造 MMLU 基准、按学科挑选任务、设置 few-shot 数量、接入自定义模型并读取 overall_score,附完整可运行示例与常见限制。

MMLU(Massive Multitask Language Understanding)是一套用多项选择题考察大模型知识面的基准,题目覆盖数学、历史、法律、伦理等 57 个学科。它的价值在于覆盖面广、学科深度不一,因此比较容易暴露模型在某一类主题上的理解短板。在 DeepEval 中,MMLU 被封装成一个可以直接调用的基准类,你只需要指定要考哪些学科、用几个 few-shot 示例,再把模型对象传进去,就能拿到一个 0 到 1 之间的总分。这篇教程讲的就是这条链路怎么搭起来:从环境准备、构造基准、挑选任务、接入自定义模型,到读懂分数与避开常见坑。如果你还想看站内其他评测工具的用法,可以从 MMLU 这一条目入手对照。

适合读这篇的人大致有两类:一类是手里已经有一个自建或微调过的模型,想用公开基准给它做一次横向体检;另一类是团队在做模型选型,需要一个可复现、可脚本化的评测流程,而不是手工出题打分。MMLU 只考选择题,所以它衡量的是知识与推理的广度,不衡量长文本生成质量、指令遵循细节或多轮对话能力——这一点在解读分数时要一直记着。

准备工作

运行环境与依赖

MMLU 基准是 DeepEval 框架的一部分,因此第一步是把 DeepEval 装进你的 Python 环境。素材中出现的文档版本标识为 Python v4.3.3,这只是一个参考点,实际安装时请以官网当前发布的版本与安装说明为准。安装完成后,从 deepeval.benchmarks 导入 MMLU,从 deepeval.benchmarks.mmlu.task 导入 MMLUTask,这两个导入路径是后续所有代码的基础。

pip install deepeval

如果你的模型需要额外的推理依赖(例如本地加载权重所需的库),也要一并装好。DeepEval 本身是开源的评测框架,采用 Apache 2.0 许可,但具体版本的功能差异、依赖约束请以官网当前信息为准。

把模型包装成 DeepEval 可识别的对象

MMLU 的 evaluate 方法接收的是一个模型对象,而不是模型名称字符串。所以你需要先用 DeepEvalBaseLLM 把目标模型包一层,实现框架要求的接口,得到一个可以被基准调用的实例。素材示例里这个实例叫 mistral_7b,它代表任意一个自定义模型——你可以换成自己部署的模型、通过 API 访问的模型,或者本地加载的开源权重。

这一步是整个流程里最容易被低估的环节。基准会向模型批量发送选择题提示词,并期望模型返回一个选项字母。如果你的包装层在返回内容上做了额外处理(比如加了前缀、截断了输出、把结果包成 JSON),就可能影响精确匹配的判定。包装层应当尽量原样返回模型的文本输出,把格式适配留给基准去处理。

确认评测范围与成本

默认情况下,MMLU 会在全部 57 个学科上评测。这意味着调用次数与耗时都相当可观,尤其是本地推理的模型。在正式跑全量之前,建议先用一两个学科做小规模验证,确认包装层、返回格式、分数读取都正常,再放开到全量。另外,few-shot 数量会直接放大每次请求的提示词长度,进而影响 token 消耗与延迟,这一点在规划预算时要算进去。

操作步骤

第一步:构造 MMLU 基准对象

MMLU 类接受两个可选参数,除此之外没有别的开关:

  • tasks:一个 MMLUTask 枚举列表,用来指定要评测哪些学科。不传时默认评测全部 57 个学科。
  • n_shots:few-shot 学习的示例数量,默认值为 5,且不能超过 5。

构造方式很直接:

from deepeval.benchmarks import MMLU
from deepeval.benchmarks.mmlu.task import MMLUTask

benchmark = MMLU(
    tasks=[MMLUTask.HIGH_SCHOOL_COMPUTER_SCIENCE, MMLUTask.ASTRONOMY],
    n_shots=3,
)

上面这段代码创建了一个只考「高中计算机科学」和「天文学」两个学科、使用 3-shot 的基准。注意 tasks 传的是枚举成员而不是字符串,拼错枚举名会在导入或构造阶段直接报错,这其实是一件好事——它让你在跑评测之前就发现学科名写错了。

第二步:调用 evaluate 执行评测

基准对象构造好之后,把模型实例传进 evaluate:

benchmark.evaluate(model=mistral_7b)
print(benchmark.overall_score)

执行完成后,结果挂在 benchmark.overall_score 上。这个值的取值范围是 0 到 1,1 表示全部答对,0 表示一道都没答对。它是一个比例值,不是百分制,写报告时如果需要百分比,自行乘以 100。

第三步:理解打分机制

MMLU 的评分方式是精确匹配(exact matching)。具体来说,基准统计的是:模型给出的答案中,精确等于正确选项字母(例如 A)的题目数量,占题目总数的比例。这个定义有两个直接推论:

  • 模型必须输出正确的字母本身。如果它输出的是选项的完整文字内容、或者「答案是 A」这样的句子,是否被判对取决于基准的解析逻辑,而按精确匹配的定义,格式偏差会直接变成失分。
  • 分数对输出格式的敏感度很高,这也是为什么增加 few-shot 示例往往能显著提升分数——更多示例让模型更容易学会「只回一个字母」这种输出约定,从而减少格式性失分,而不是真的提升了学科知识。

解读分数时要把这两件事分开:分数上升可能来自知识能力提升,也可能只是格式遵从度变好了。做模型对比时,如果两个模型的输出风格差异很大,建议先统一提示与后处理方式,再比较分数。

第四步:按需挑选学科任务

MMLUTask 枚举把 57 个学科都做成了常量。你可以像下面这样单独取一个任务:

from deepeval.benchmarks.tasks import MMLUTask

mm_tasks = [MMLUTask.HIGH_SCHOOL_EUROPEAN_HISTORY]

完整可用的任务列表如下,可以按需组合成 tasks 参数:

学科任务学科任务学科任务
HIGH_SCHOOL_EUROPEAN_HISTORYBUSINESS_ETHICSCLINICAL_KNOWLEDGE
MEDICAL_GENETICSHIGH_SCHOOL_US_HISTORYHIGH_SCHOOL_PHYSICS
HIGH_SCHOOL_WORLD_HISTORYVIROLOGYHIGH_SCHOOL_MICROECONOMICS
ECONOMETRICSCOLLEGE_COMPUTER_SCIENCEHIGH_SCHOOL_BIOLOGY
ABSTRACT_ALGEBRAPROFESSIONAL_ACCOUNTINGPHILOSOPHY
PROFESSIONAL_MEDICINENUTRITIONGLOBAL_FACTS
MACHINE_LEARNINGSECURITY_STUDIESPUBLIC_RELATIONS
PROFESSIONAL_PSYCHOLOGYPREHISTORYANATOMY
HUMAN_SEXUALITYCOLLEGE_MEDICINEHIGH_SCHOOL_GOVERNMENT_AND_POLITICS
COLLEGE_CHEMISTRYLOGICAL_FALLACIESHIGH_SCHOOL_GEOGRAPHY
ELEMENTARY_MATHEMATICSHUMAN_AGINGCOLLEGE_MATHEMATICS
HIGH_SCHOOL_PSYCHOLOGYFORMAL_LOGICHIGH_SCHOOL_STATISTICS
INTERNATIONAL_LAWHIGH_SCHOOL_MATHEMATICSHIGH_SCHOOL_COMPUTER_SCIENCE
CONCEPTUAL_PHYSICSMISCELLANEOUSHIGH_SCHOOL_CHEMISTRY
MARKETINGPROFESSIONAL_LAWMANAGEMENT
COLLEGE_PHYSICSJURISPRUDENCEWORLD_RELIGIONS
SOCIOLOGYUS_FOREIGN_POLICYHIGH_SCHOOL_MACROECONOMICS
COMPUTER_SECURITYMORAL_SCENARIOSMORAL_DISPUTES
ELECTRICAL_ENGINEERINGASTRONOMYCOLLEGE_BIOLOGY

挑选学科时有几个实用思路。第一,按模型的训练数据侧重来选:如果模型大量训练过代码与理工内容,那么 HIGH_SCHOOL_COMPUTER_SCIENCE、COLLEGE_COMPUTER_SCIENCE、MACHINE_LEARNING、ABSTRACT_ALGEBRA 这类任务能验证强项是否真的强。第二,按业务场景来选:面向医疗场景的模型应重点看 CLINICAL_KNOWLEDGE、MEDICAL_GENETICS、PROFESSIONAL_MEDICINE、COLLEGE_MEDICINE、VIROLOGY、ANATOMY。第三,按「容易翻车」的方向来选:MORAL_SCENARIOS、MORAL_DISPUTES、JURISPRUDENCE、INTERNATIONAL_LAW 这类涉及价值判断与法律条文的题目,往往能暴露模型在细粒度区分上的弱点。

第五步:调整 n_shots

n_shots 控制 few-shot 示例的数量,默认 5,上限也是 5。也就是说你可以往下调到 0、1、2、3、4,但不能往上加。这个上限是硬约束,传 6 会失败。

选择 shot 数量时有一个权衡:shot 越多,模型越容易学会输出格式,分数通常越高,但每次请求的提示词越长,token 成本与延迟也越高;shot 越少,成本低,但格式性失分可能变多。做模型之间的公平对比时,所有模型必须使用相同的 n_shots,否则分数不可比。做历史趋势对比时,也要保证前后两次评测的 shot 设置一致。

第六步:读取并记录结果

评测结束后,benchmark.overall_score 就是你要的结果。建议在脚本里把它连同评测配置一起落盘,例如记录本次用了哪些 tasks、n_shots 是多少、模型标识是什么。因为 MMLU 的分数高度依赖这三项设置,脱离配置谈分数没有意义。如果一次评测只覆盖了两个学科,这个分数不能代表模型在全部 57 个学科上的水平,报告里要写清楚覆盖范围。

一个完整示例

下面是一个从头到尾可以跑通的最小例子。它评测一个自定义模型在两个学科上的表现,使用 3-shot,并打印总分。

from deepeval.benchmarks import MMLU
from deepeval.benchmarks.mmlu.task import MMLUTask

# 1. 构造基准:只考高中计算机科学与天文学,使用 3-shot
benchmark = MMLU(
    tasks=[MMLUTask.HIGH_SCHOOL_COMPUTER_SCIENCE, MMLUTask.ASTRONOMY],
    n_shots=3,
)

# 2. 执行评测:mistral_7b 是已经用 DeepEvalBaseLLM 包装好的模型实例
benchmark.evaluate(model=mistral_7b)

# 3. 读取结果:0 到 1 之间的比例值
print(benchmark.overall_score)

把这段代码拆开看,三个环节各自对应一个容易出错的点。构造环节要确认枚举名拼写正确、n_shots 不超过 5;执行环节要确认 mistral_7b 这个变量确实是一个可调用的模型包装对象,而不是字符串或未初始化的占位符;读取环节要记得 overall_score 是 0 到 1 的比例,不是百分数。

如果想把结果扩展成多学科对比,可以把 tasks 换成更长的列表,或者循环多次、每次只跑一个学科,分别记录分数。后一种做法能让你看清模型在哪个学科上掉分,代价是评测次数变多、总耗时变长。前一种做法只给一个汇总分,看不出学科间的差异。按你的报告需要选一种即可。

如果想把评测接进持续集成流程,思路是把上面的脚本做成一个可重复执行的命令,在模型或提示词发生变更时触发。由于 MMLU 全量评测耗时较长,CI 里通常只跑一个小子集作为冒烟检查,全量评测放在单独的流水线里跑。具体怎么编排取决于你的工程环境,这里不展开。

注意事项

MMLU 不支持思维链提示

这是一个明确的限制:MMLU 基准只暴露 tasks 和 n_shots 两个可选参数,没有提供开启思维链(chain-of-thought)的选项。如果你的模型依赖「先推理再作答」才能发挥水平,MMLU 这条路径不会给你打开这个开关。想评测思维链效果,需要换用其他基准或自行搭建评测流程。

n_shots 有硬上限

n_shots 默认 5,且不能超过 5。这不是建议值而是约束,传更大的数字不会生效或会直接报错。设计实验时把 5 当作天花板来规划。

分数对输出格式高度敏感

因为采用精确匹配,模型必须输出正确的选项字母才算对。任何格式偏差——多写了说明文字、把字母写成小写、返回了选项内容而非字母——都可能被判错。这既是 MMLU 的一个特性,也是它被诟病的地方:分数里混入了格式遵从能力的成分。做模型对比时,务必让所有模型在相同的提示与后处理条件下评测。

默认全量评测的规模

不传 tasks 时会在全部 57 个学科上评测。这个默认值对快速验证不友好,第一次跑建议显式指定一两个学科。等流程验证通过、预算确认之后,再放开到全量。

学科覆盖不等于能力全覆盖

MMLU 考的是选择题形式的知识与推理,覆盖 57 个学科。它不评估长文本生成、多轮对话、工具调用、代码执行等能力。用 MMLU 分数给模型下总体结论是不合适的,它只是众多评测维度中的一个。反过来,MMLU 在发现「模型在某个特定主题上理解不足」这件事上确实有效,这正是它的主要用途。

版本与许可信息以官网为准

DeepEval 的版本迭代、安装方式、依赖要求、许可条款都可能变化。本文提到的版本标识仅用于说明素材所处的时点,实际使用时请查阅官网当前信息。评测本身的题目集与学科划分也可能随基准维护而调整,跨时间对比分数时要注意这一点。