LLM工程师手册——评估大语言模型

738 阅读39分钟

LLM 评估是评估大型语言模型性能和能力的关键过程。评估可以采取多种形式,例如选择题回答、开放式指令以及来自真实用户的反馈。目前,还没有统一的方法来衡量模型的表现,但我们可以根据特定的使用场景来调整已有的模式和方案。

虽然通用评估最为常见,像是大规模多任务语言理解 (MMLU) 或 LMSYS Chatbot Arena 等基准测试,但在处理特定领域和任务的模型时,更专注的评估方法更具优势。尤其是在评估整个 LLM 系统时(与单独的模型不同),通常围绕一个检索增强生成 (RAG) 管道展开。这种情况下,我们需要扩展评估框架,以涵盖整个系统,包括检索器和后处理器等新模块。

在本章中,我们将涵盖以下主题:

  • 模型评估
  • RAG 评估
  • TwinLlama-3.1-8B 的评估

通过本章的学习,您将了解最受欢迎的 LLM 评估方法,并掌握如何使用不同技术来评估模型和 RAG 系统。

模型评估

在模型评估中,目标是评估单个模型的能力,而不涉及提示工程、RAG(检索增强生成)管道等。这种评估对选择最合适的LLM或确保微调过程确实改进了模型至关重要。在本节中,我们将比较ML(机器学习)和LLM的评估,以理解这两个领域之间的主要区别。随后,我们将探索适用于通用、特定领域和任务的模型基准。

ML和LLM评估的比较

ML评估主要集中在评估用于预测、分类和回归等任务的模型性能。与之不同的是,LLM评估更关注模型对语言的理解和生成能力,而ML评估则更侧重于模型处理结构化数据的准确性和效率。这一差异来源于两者处理任务的性质不同。ML模型通常专为狭义定义的问题而设计,例如预测股票价格或检测异常值,这通常涉及数值或分类数据,使得评估过程更为直接。而LLM则需要解释和生成语言,为评估过程增加了一层主观性。在LLM评估中,往往需要更细致的方法,包括定性评估,以考察模型在自然语言中的连贯性、相关性和语境准确性。

特别地,我们可以看到这两种模型的工作方式存在三大关键区别,从而影响评估过程:

  1. 数值指标:ML模型评估通常涉及客观性能指标的测量,如准确率、精确率、召回率或均方误差,这取决于具体任务。LLM由于能处理多种任务(因此需要多种评估),很少能依赖同一数值指标。
  2. 特征工程:在传统ML中,手动选择和转换相关数据特征是关键环节,并且评估特征工程的成效往往是模型评估的一部分。而LLM设计旨在直接处理原始文本数据,从而减少了对手动特征工程的需求。
  3. 可解释性:ML模型的预测或分类通常更易于解释,且这种可解释性往往是评估的一部分。而在LLM中,直接解释模型的生成过程较难实现,但在生成过程中请求解释可以提供模型决策过程的洞察。

在接下来的部分中,我们将更细致地探讨不同类型的LLM。虽然通用模型的评估与ML评估相差较大,但任务专用的LLM与传统ML更为接近。

通用LLM评估

通用评估是针对基础和通用微调模型的指标,覆盖知识性和实用性广泛相关的能力,而不专注于特定任务或领域。这种评估帮助开发人员概览模型能力,进行竞品对比,并识别模型的优势与劣势。根据这些结果,可以调整数据集和超参数,甚至修改模型架构。

我们可以将通用评估大致分为三个阶段:预训练中、预训练后和微调后。

  • 预训练中,密切监控模型的学习进度。最直接的指标是低级的、与模型训练相关的指标:

    • 训练损失:基于交叉熵损失,测量模型预测的概率分布与真实分布之间的差异。
    • 验证损失:与训练损失相同,但在保留的验证集上计算,以评估泛化能力。
    • 困惑度:交叉熵损失的指数,表示模型对数据的“惊讶度”(越低越好)。
    • 梯度范数:监控训练期间梯度的幅度,以检测潜在的不稳定或梯度消失/爆炸问题。

    这一阶段也可以包括如HellaSwag(常识推理)等基准,但可能会有过拟合风险。

  • 预训练后,常使用评估套件来测试基础模型。这些套件可以包括内部和公共基准测试。以下是常见的公共预训练评估的非详尽列表:

    • MMLU(知识) :测试模型在57个科目上的多项选择题,涵盖从小学到专业级别。
    • HellaSwag(推理) :挑战模型在给定情境下选择最合理的结尾。
    • ARC-C(推理) :用小学级科学问题评估模型的因果推理能力。
    • Winogrande(推理) :通过代词解析评估常识推理。
    • PIQA(推理) :通过日常物理互动问题衡量物理常识理解。

    许多这些数据集也用于评估通用微调模型。在这种情况下,我们关注基准分数在基础模型与微调模型之间的差异。例如,不良微调可能降低模型的知识水平(以MMLU测量),而优良微调则可能增加知识,提高MMLU分数。这也可以帮助识别任何数据污染问题,如模型微调时的数据过于接近测试集,导致分数异常上升。

  • 微调后,微调模型也有其自身的基准测试。这里“微调模型”指的是经过监督微调(SFT)和偏好对齐训练的模型。这些基准测试针对微调模型理解和回答问题的能力,特别是指令遵循、多轮对话和自主技能:

    • IFEval(指令遵循) :评估模型在不输出任何逗号等约束下执行指令的能力。
    • Chatbot Arena(对话) :一个框架,人们在两模型头对头对话中投票选出最佳回答。
    • AlpacaEval(指令遵循) :自动评估微调模型,与Chatbot Arena高度相关。
    • MT-Bench(对话) :评估模型在多轮对话中的连贯性。
    • GAIA(自主) :测试多步操作下的工具使用和网页浏览等多种能力。

理解这些评估的设计和使用有助于选择最佳LLM。例如,如果你计划微调模型,理想情况下选择知识和推理能力最强的基础模型,即便不打算微调,Chatbot Arena或IFEval等基准也能帮助比较不同的指令模型。例如,若要构建聊天机器人,出色的对话能力必不可少。但如果最终目标是从非结构化文档中提取信息,则良好的指令遵循能力更为重要。

尽管这些基准流行且实用,但它们也有固有的缺陷。例如,公共基准可能因训练数据包含测试数据而被“作弊”。即使是人工评估也常偏向于长而自信的回答,尤其是格式美观的答案(如Markdown)。而私有测试集也未必完美,可能存在偏差。因此,基准不应被视为唯一的真理,而应作为参考信号。

特定领域LLM评估

特定领域的LLM不具备通用模型的广泛适用性,这有助于更深入地评估细化的能力,而不仅仅是通用基准。在这一类别中,基准的选择完全取决于具体领域。对于常见应用,如特定语言模型或代码模型,建议寻找相关评估方法,甚至成套的基准测试。这些套件涵盖不同的基准,旨在便于复现。通过针对领域的不同方面,通常可以更准确地捕捉到该领域的表现。

以下是带有 Hugging Face Hub 排行榜的几个特定领域评估示例:

  • Open Medical-LLM 排行榜:评估LLM在医学问答任务中的表现,涵盖9项指标,包含1,273道美国医学执照考试问题(MedQA)、500道PubMed文章问题(PubMedQA)、4,183道印度医学入学考试问题(MedMCQA)和来自MMLU六个子类别的1,089道问题(临床知识、医学遗传学、解剖学、专业医学、大学生物学和大学医学)。
  • BigCodeBench 排行榜:评估代码LLM的表现,分为两个主要类别:BigCodeBench-Complete(基于结构化文档字符串的代码补全)和BigCodeBench-Instruct(从自然语言指令生成代码)。模型根据贪婪解码的Pass@1分数排名,Complete类别还附加了Elo评分,覆盖了测试LLM组合推理和指令遵循能力的广泛编程场景。
  • Hallucinations 排行榜:评估LLM在16项任务中产生虚假或不实信息的倾向,这些任务分为5类,包括问答(NQ Open、TruthfulQA和SQuADv2数据集)、阅读理解(TriviaQA和RACE)、摘要(HaluEval Summ、XSum和CNN/DM)、对话(HaluEval Dial和FaithDial)以及事实核查(MemoTrap、SelfCheckGPT、FEVER和TrueFalse)。排行榜还评估模型使用IFEval的指令遵循能力。
  • 企业场景排行榜:评估LLM在六个真实企业用例中的表现,涵盖与业务应用相关的多种任务。基准包括FinanceBench(100个包含检索上下文的金融问题)、Legal Confidentiality(100个来自LegalBench的法律推理题)、写作提示(创意写作评估)、客户支持对话(客户服务互动的相关性)、有害内容生成的安全性(Toxic Prompts),以及企业PII(敏感信息保护的业务安全)。部分测试集为闭源以防止“作弊”。该评估关注如答案准确性、法律推理、创意写作、上下文相关性和安全措施等特定能力,为评估LLM在企业环境中的适用性提供了全面的考察。

排行榜根据领域有不同的方法。例如,BigCodeBench仅依赖于两个足以捕捉整个领域的指标,而Hallucinations排行榜则结合16项指标,包括许多通用评估。这表明除了定制基准,重复使用通用基准也可以完善评估套件。

特别地,特定语言的LLM通常会重复使用通用基准的翻译版本,并辅以该语言的原始评估。尽管有些基准使用机器翻译,但依赖人工翻译可以显著提高质量。我们选取以下三个任务特定排行榜及其相应的评估套件,以便为构建您自己的排行榜提供参考:

  • OpenKo-LLM 排行榜:通过九项指标评估韩国LLM的表现。这些指标包括翻译成韩语的通用基准(GPQA、Winogrande、GSM8K、EQ-Bench和IFEval)以及自定义评估(知识、社会价值、无害性和有用性)。
  • Open Portuguese LLM 排行榜:通过九项多样化的基准评估葡萄牙语LLM的表现。这些基准包括教育评估(1,430道ENEM题目和724道来自大学入学考试的BLUEX题)、职业考试(超过2,000道OAB考试题)、语言理解任务(ASSIN2 RTE和STS、FAQUAD NLI),以及社交媒体内容分析(包含7,000条Instagram评论的HateBR、5,668条推文的PT Hate Speech和tweetSentBR)。
  • Open Arabic LLM 排行榜:通过一组全面的基准评估阿拉伯语LLM的表现,包括阿拉伯语原生任务和翻译数据集。排行榜包含两个阿拉伯语原生基准:AlGhafa和Arabic-Culture-Value-Alignment,此外还加入了12个涵盖各种领域的翻译基准,如MMLU、ARC-Challenge、HellaSwag和PIQA。

通用和特定领域的评估设计基于三项主要原则。首先,评估应具有复杂性,能区分好坏输出。其次,应多样化,涵盖尽可能多的主题和场景;当一个基准不够时,额外的基准可以加强评估套件。最后,评估应实用、易于运行,这通常与评估库的复杂性相关。推荐使用Eleuther AI的lm-evaluation-harness和Hugging Face的lighteval来运行您的基准测试。

任务专用LLM评估

尽管通用和领域专用的评估可以表明基础或指令模型的强大之处,但它们无法揭示这些模型在特定任务中的表现。这需要专为此目的设计的基准,以衡量模型的下游性能。

由于任务专用LLM的目标较为狭窄,因此很少依赖现有的评估数据集。这反倒是一个优势,因为其输出往往更结构化,更便于使用传统ML指标进行评估。例如,总结任务可以使用ROUGE(Recall-Oriented Understudy for Gisting Evaluation)指标,该指标通过n元组(n-grams)衡量生成文本与参考文本之间的重叠度。

同样,分类任务也可受益于以下经典指标:

  • 准确率(Accuracy) :正确预测实例的比例,适用于类别输出明确或答案对错分明的任务,例如命名实体识别(NER)。
  • 精确率(Precision) :模型正确预测的正类实例占其所有预测正类的比例。
  • 召回率(Recall) :模型正确预测的正类实例占实际正类实例的比例。
  • F1值:精确率和召回率的调和平均数,用于平衡两者,特别适用于分类或实体提取任务。

当任务无法直接映射到传统的ML任务时,可以创建定制基准。这种基准可以借鉴通用和领域专用的评估数据集。多项选择问答是一种常见且成功的模式,问题由多个选项构成。以下是MMLU数据集中一道抽象代数题的示例:

指令

在Q(sqrt(2), sqrt(3))相对于Q的字段扩展中,找出度数。 A. 0
B. 4
C. 2
D. 6

输出
B

表7.1:来自MMLU数据集的示例

这种方案的模型评估主要有两种方式:文本生成评估和对数似然评估:

  1. 文本生成:让模型生成文本答案并与预设答案选择进行比较。例如,模型生成答案的字母(A, B, C, 或 D),然后检查其是否正确。此方法测试模型在实际应用场景中生成连贯且准确回答的能力。
  2. 概率评估:无需生成文本答案,而是查看模型对不同选项的预测概率。例如,lm-evaluation-harness通过比较MMLU数据集中每个选项文本的概率来评估模型的理解能力,这种方法可以捕捉模型对不同选项的相对信心。

为简单起见,建议采用模拟人类考试的文本生成版本的评估方法,易于实现且区分性更强,因为低质量模型在基于概率的评估中可能表现过于出色。可以将此技术用于特定任务的模型测试,甚至扩展至特定领域。

如果任务过于开放,传统ML指标和多项选择问答可能不适用。在此情境下,可以使用第5章中介绍的“LLM-作为-裁判”技术评估答案质量。如果有真实答案,作为额外上下文提供会提高评估准确性。否则,可定义不同维度(如相关性或有害性,视任务而定)以使评估在更易解释的类别上进行。

建议使用大型模型进行评估,并迭代完善提示。在此过程中,模型输出的解释对于理解其推理错误并通过提示工程加以修正至关重要。

为了便于解析答案,可以在指令中指定结构或使用某种结构化生成(如大纲或OpenAI的JSON模式)。以下是带有结构的指令示例:

你是一名评估员,负责评估答案对指令的完成质量。

目标是提供一个分数,代表答案在多大程度上满足指令要求。你将使用1到4的评分,其中每个数字表示:

  1. 答案与指令无关。
  2. 答案相关但无帮助。
  3. 答案相关且有帮助,但可更详细。
  4. 答案相关、有帮助且详细。

请按以下格式提供评估: ##评估##
解释:(分析答案的相关性、帮助性和复杂性)
总评分:(1到4之间的最终分数)

指令
{instruction}
答案
{answer}
##评估##
解释:

表7.2:通用LLM-作为-裁判的答案评估示例

当然,您可以调整评分标准,将真实答案添加到提示中,并根据自己的使用场景自定义。

然而,裁判型LLM可能会偏向肯定或冗长的回答,可能会高估显得自信却不准确的回答。此外,对于特定领域的专业知识不足,可能会导致误判。评分一致性也是一个问题,LLM可能对相似回答打出不同分数。此外,它们可能对某些写作风格有偏好,与实际答案质量无关。为减轻这些问题,可以将LLM评估与其他指标结合,使用多个裁判,并精心设计提示以解决偏差。

一旦模型被正确评估且运行正常,就可以将其纳入更广泛的系统。在下一节中,我们将探讨系统如何改变评估框架。

RAG评估

传统的LLM评估关注模型的固有能力,而RAG(检索增强生成)评估需要更综合的方法,既考察模型的生成能力,又考察其与外部信息源的交互能力。

RAG系统结合了LLM的优势和信息检索机制,使得生成的回答不仅连贯、符合上下文,而且基于最新、来自外部的信息来源。这使RAG在新闻报道、研究和客户支持等对最新和准确信息至关重要的领域具有特别重要的价值。

RAG系统的评估不仅仅是对独立LLM的评估,它需要考察整个系统的表现,包括以下方面:

  • 检索准确性:系统获取相关信息的准确性如何?
  • 集成质量:检索到的信息如何有效地融入生成的回答?
  • 真实性和相关性:最终输出是否正确回应了查询,同时无缝融合了检索和生成的内容?

RAG评估的关键指标包括检索的精确率和召回率,这些指标衡量检索信息的准确性和全面性。此外,检索数据和生成文本的集成质量、输出的整体真实性和连贯性也是关键指标。

为了说明这些指标如何应用于实际场景,考虑一个为电商场景设计的客户支持聊天机器人的RAG系统。在这种情况下,用户询问“假期促销期间购买的笔记本电脑的退货政策是什么?”RAG管道找到了关于电子产品退货政策和假期促销条款的相关文件。该上下文附加在问题末尾,模型基于这些信息进行回答:

在我们假期促销期间购买的笔记本电脑享有延长的退货期限,从购买日期起60天内可退货。这比我们针对电子产品的标准30天退货政策更长。请确保笔记本电脑保持原包装并附带所有配件,以获得全额退款。

表7.3:客户支持RAG管道的输出示例

在此管道中,我们可以评估检索的文档是否符合预期(检索准确性),还可以衡量有无附加上下文时回答的差异(集成质量)。最后,可以评估输出是否与文档提供的信息相关且真实(真实性和相关性)。

本节将介绍两种评估RAG模型如何将外部信息整合到回答中的方法。

Ragas

Retrieval-Augmented Generation Assessment(Ragas)是一个开源工具包,旨在为RAG评估和优化提供全面工具。它基于指标驱动开发(MDD)的理念,一种依赖数据作出明智决策的产品开发方法,涉及对关键指标的持续监控,以深入了解应用的性能。Ragas采用这一方法,使开发者可以客观地评估RAG系统,识别需要改进的领域,并跟踪变化随时间的影响。

Ragas的关键能力之一是生成多样化且复杂的合成测试数据集。此功能解决了RAG开发中的一个主要难点,因为手动创建数百个问题、答案和上下文既耗时又费力。相反,Ragas采用了一种进化式方法,灵感来源于如Evol-Instruct等工作,能够生成具有不同特性的复杂问题,如推理复杂度、条件要素和多重上下文需求。这种方法确保对RAG管道中不同组件的全面评估。

此外,Ragas可以生成模拟聊天的对话样本,以进行基于问题和后续互动的交互评估,使开发人员可以在更真实的场景中评估系统。

image.png

如图7.1所示,Ragas提供了一套由LLM辅助的评估指标,用于客观衡量RAG系统性能的不同方面。这些指标包括:

  • 忠实性(Faithfulness) :该指标衡量生成答案与给定上下文的一致性。其工作原理是将答案拆解成独立的陈述,并验证每一陈述是否可以从提供的上下文中推导出来。忠实性得分计算为可验证陈述与答案中总陈述数的比率。
  • 答案相关性(Answer relevancy) :该指标评估生成的答案与给定提示的相关性。它采用一种创新方法,通过让LLM基于答案生成多个问题,然后计算这些生成的问题与原始问题之间的平均余弦相似度。此方法有助于识别那些虽然事实正确但偏题或不完整的答案。
  • 上下文精确度(Context precision) :该指标评估上下文中所有真实相关项是否被恰当排序。它考虑相关信息在检索到的上下文中的位置,对将最相关信息置于前面的系统给予奖励。
  • 上下文召回率(Context recall) :该指标衡量检索到的上下文与标注答案(真实值)的对齐程度。它分析真实答案中的每个陈述,确定其是否可以归因于检索到的上下文,从而提供关于检索信息完整性的见解。

此外,Ragas还提供了用于生产环境中监控RAG质量的构建模块,便于持续改进RAG系统。通过利用测试数据集的评估结果和从生产监控中收集的见解,开发者可以迭代提升应用。这可能包括微调检索算法、调整提示工程策略,或优化检索上下文和LLM生成内容之间的平衡。

Ragas还可以结合另一种基于定制分类器的方法使用。

ARES

ARES(自动化RAG系统评估框架)是一款全面工具,专为评估RAG系统设计。它提供了一个自动化流程,将合成数据生成与微调分类器相结合,用于评估RAG性能的各个方面,包括上下文相关性、答案忠实性和答案相关性。

ARES框架分为三个主要阶段:合成数据生成、分类器训练和RAG评估。每个阶段都可以配置,允许用户根据具体需求和数据集定制评估流程。

在合成数据生成阶段,ARES创建了接近真实场景的数据集,以进行稳健的RAG测试。用户可以通过指定文档文件路径、少样本提示文件和合成查询的输出位置来配置此过程。框架支持多种预训练语言模型执行此任务,默认模型为google/flan-t5-xxl。用户可以控制采样的文档数量及其他参数,在全面覆盖与计算效率之间取得平衡。

image.png

分类器训练阶段涉及创建高精度的分类器,以确定RAG输出的相关性和忠实性。用户可以指定分类数据集(通常来自前一阶段生成的合成数据)、用于评估的测试集、标签列和模型选择。ARES默认使用microsoft/deberta-v3-large模型,但支持其他Hugging Face模型。用户还可以微调训练参数,例如训练轮数、早停的耐心值和学习率,以优化分类器性能。

最终阶段——RAG评估,利用训练好的分类器和合成数据评估RAG模型的性能。用户需提供评估数据集、用于指导评估的少样本示例、分类器检查点和真实标签路径。ARES支持多种评估指标,并可以为其评估生成置信区间。

ARES提供灵活的模型执行选项,通过vLLM集成支持云端和本地运行。框架还支持多种类型的输出(如代码片段、文档、HTML、图片等),从而可以全面评估不同的RAG系统输出。

总而言之,Ragas和ARES通过各自独特的评估和数据集生成方法相辅相成。Ragas在生产监控和LLM辅助指标方面的优势可以与ARES高度可配置的评估流程和基于分类器的评估相结合。Ragas依赖于LLM能力,可提供更细致的评估,而ARES一旦分类器训练完成,则能提供一致且更快速的评估。将两者结合可以构建一个全面的评估框架,从Ragas的快速迭代和ARES在关键阶段的深入、定制化评估中获益。

在下一节中,我们将创建自己的评估框架,以评估特定任务的TwinLlama-3.1-8B模型。

评估TwinLlama-3.1-8B

在前几章中,我们创建了两个微调模型,用于生成高质量的帖子和文章:TwinLlama-3.1-8B和TwinLlama-3.1-8B-DPO。基于此总结,我们希望评估它们写出准确且表达良好的文本的能力。相比之下,通用的微调模型虽然因其广泛的知识而准确,但通常使用过于正式且冗长的语言。通过此次微调,我们希望采用更自然的写作风格,基于训练集中的原始文章。

由于问题的开放性,我们将利用一个裁判型LLM来评估生成文本的质量。它将指令和答案都作为输入,并基于两个标准按1到3的评分尺度进行评分:

  • 准确性:答案中所提供信息的事实正确性和完整性
  • 风格:博客或社交媒体内容的语气和写作风格的适合度(无正式或学术表达)

在我们的评估框架中,将使用指令数据集的测试拆分来获取测试指令。我们会将这些指令输入我们的模型并生成答案。这些答案将由我们的裁判LLM(GPT-4o-mini)评估,评估提示会指定我们的评分标准。最后,我们将分析得分,并基于定性和定量评估得出结论。

生成答案

第一步是为测试集中的每条指令高效生成答案。除了我们的两个模型,我们还将使用meta-llama/Meta-Llama-3.1-8B-Instruct(Llama-3.1-8B的官方指令版本)作为参考点,以更好地了解我们所做的取舍。

开始实施的第一阶段:

我们导入相关库,包括用于快速生成的vLLM库。该库比transformers更适合批量生成本地模型:

from vllm import LLM, SamplingParams
from datasets import load_dataset
from tqdm.auto import tqdm
import gc

我们定义一个名为generate_answers的函数,用于处理数据集并生成指定模型的响应。它接收两个输入——我们希望使用的模型ID和测试数据集名称:

def generate_answers(model_id, dataset_name):
    dataset = load_dataset(dataset_name, split="test")

我们需要使用模型训练时的聊天模板格式化原始指令。请注意,Llama-3.1-8B-Instruct使用了不同的模板,但它可以遵循这种简单的格式。为了简化操作,我们为每个模型使用相同的聊天模板,并通过format()函数将整个测试集映射到此模板:

    def format(sample):
        return "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\n{}\n\n### Response:\n".format(sample["instruction"])
    dataset = dataset.map(lambda sample: {"prompt": format(sample)})

接着,我们初始化由vLLM使用的LLM对象,最大长度为4096个token。还可以指定采样参数,这些参数对应于解码策略中使用的变量。这里,我们使用参数鼓励多样性(高温度),同时去除最不可能的token(top_p和min_p)。最后,启动生成过程并提供数据集的prompt列表:

    llm = LLM(model=model_id, max_model_len=4096)
    sampling_params = SamplingParams(temperature=0.8, top_p=0.95, min_p=0.05, max_tokens=4096)
    outputs = llm.generate(dataset["prompt"], sampling_params)

此过程应在几分钟内完成(共有334条指令)。完成后,从vLLM输出的对象中提取答案,并将这些答案添加为数据集的新列,以便记录和后续查看:

    answers = [output.outputs[0].text for output in outputs]
    dataset = dataset.add_column("answers", answers)

我们将结果上传到Hugging Face Hub,以便稍后方便访问。然后,清理GPU内存,以避免在处理下一个模型时空间不足:

    print(f"Uploading results for {model_id}")
    dataset.push_to_hub(f"mlabonne/{model_id.split('/')[-1]}-results")
    gc.collect()
    return dataset

我们创建一个包含要测试的三个模型的列表。然后,为每个模型运行generate_answers()函数。这将为每个模型生成并上传一组独立的结果:

model_ids = [    'mlabonne/TwinLlama-3.1-8B',    'mlabonne/TwinLlama-3.1-8B-DPO',    'meta-llama/Meta-Llama-3.1-8B-Instruct']
for model_id in model_ids:
    generate_answers(model_id, "mlabonne/llmtwin")

现在我们已经完成答案生成,可以进入评估过程。

评估答案

为了评估生成的答案,我们将使用GPT-4o-mini作为裁判。这一策略类似于我们在数据生成过程中使用的方法,事实上,你可以在数据生成过程中应用此方法以筛除不良样本。在此处,我们将对每个模型生成的每个答案进行准确性和风格评分。平均分数将帮助我们了解微调后的模型质量与Llama-3.1-8B-Instruct的对比情况:

首先,我们导入所需的库,包括openai库:

import json
from typing import List
from datasets import Dataset, load_dataset
from openai import OpenAI
from tqdm.auto import tqdm
import concurrent.futures

然后定义evaluate_answer()函数。此函数包含我们的评估提示,提供基于准确性和风格评估答案的上下文:

def evaluate_answer(
    instruction: str, answer: str, client: OpenAI
) -> dict:
    prompt = f"""You are an expert judge. Please evaluate the quality of a given answer to an instruction based on two criteria:
1. Accuracy: How factually correct is the information presented in the answer? You are a technical expert in this topic.
2. Style: Is the tone and writing style appropriate for a blog post or social media content? It should use simple but technical words and avoid formal or academic language.

在同一提示中,我们定义了每个指标的评分标准。使用三点Likert量表,对每个分数进行了明确定义:

  • 准确性评分

    • 1(差):包含事实错误或误导性信息
    • 2(良好):大部分准确,仅有少量错误或遗漏
    • 3(优秀):高度准确且全面
  • 风格评分

    • 1(差):过于正式,使用了一些过于复杂的词汇
    • 2(良好):技术内容与易读性之间的平衡良好,但仍使用了正式词汇和表达
    • 3(优秀):完全适合博客/社交媒体,必要时使用简单但精确的技术术语

我们在提示中添加两个示例,说明“复杂词汇”和“正式或学术语言”的含义。提供对应的指令-答案对,并要求模型以JSON格式返回响应:

    Example of bad style: The Llama2 7B model constitutes a noteworthy progression in the field of artificial intelligence, serving as the successor to its predecessor, the original Llama architecture.
    Example of excellent style: Llama2 7B outperforms the original Llama model across multiple benchmarks.
    
    Instruction: {instruction}
    Answer: {answer}
    
    Provide your evaluation in JSON format with the following structure:
    {{
        "accuracy": {{
            "analysis": "...",
            "score": 0
        }},
        "style": {{
            "analysis": "...",
            "score": 0
        }}
    }}
    """

将此提示作为用户查询传递给GPT-4o-mini模型。系统提示强化了我们关注基于准确性和风格的答案评估:

    completion = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {
                "role": "system",
                "content": "You are a helpful assistant who evaluates answers based on accuracy and style. Provide your response in JSON format with a short analysis and score for each criterion.",
            },
            {"role": "user", "content": prompt},
        ],
        response_format={"type": "json_object"},
        max_tokens=1000,
        temperature=0.8,
    )

与前几章相同,我们将批量处理请求以加快处理速度。为此,我们创建了evaluate_batch()函数,该函数返回包含结构化输出和对应索引的列表。这些索引对于确保评估的正确顺序至关重要:

def evaluate_batch(batch, start_index):
    client = OpenAI(api_key=OPENAI_KEY)
    return [
        (i, evaluate_answer(instr, ans, client))
        for i, (instr, ans) in enumerate(batch, start=start_index)
    ]

现在可以在evaluate_answers()函数中协调前面的代码。该函数接收模型ID、线程数和批量大小作为输入。首先,加载包含我们之前保存的生成结果的数据集:

def evaluate_answers(model_id: str, num_threads: int = 10, batch_size: int = 5) -> Dataset:
    dataset = load_dataset(f"mlabonne/{model_id.split('/')[-1]}-results", split="all")

我们从数据集中创建指令-答案对的批次。每个批次包含batch_size个对:

    batches = [        (i, list(zip(dataset["instruction"][i:i+batch_size], dataset["answers"][i:i+batch_size])))
        for i in range(0, len(dataset), batch_size)
    ]

我们使用多线程对批次进行并行评估。通过并行处理,可以同时评估多个批次,从而加快整体评估过程。ThreadPoolExecutor提交每个批次到evaluate_batch()。评估结果存储在evaluations列表中:

    evaluations = [None] * len(dataset)
    with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor:
        futures = [executor.submit(evaluate_batch, batch, start_index) for start_index, batch in batches]
        for future in tqdm(concurrent.futures.as_completed(futures), total=len(futures)):
            for index, evaluation in future.result():
                evaluations[index] = evaluation

我们创建一个新列来存储评估过程的结果。此列将存储裁判模型的原始JSON输出,包括得分和解释:

    if 'evaluation' in dataset.column_names:
        dataset = dataset.remove_columns(['evaluation'])
    dataset = dataset.add_column("evaluation", evaluations)

可以直接用json.loads()解析此JSON对象,并尝试提取生成的准确性和风格分数。该过程尽量获取分数,如果解析出错,则使用None作为备选值:

    accuracy_scores = []
    style_scores = []
    for evaluation in dataset['evaluation']:
        try:
            eval_dict = json.loads(evaluation) if isinstance(evaluation, str) else evaluation
            accuracy_score = eval_dict['accuracy']['score']
            style_score = eval_dict['style']['score']
            accuracy_scores.append(accuracy_score)
            style_scores.append(style_score)
        except (json.JSONDecodeError, KeyError, TypeError):
            accuracy_scores.append(None)
            style_scores.append(None)

我们添加两个新列以存储准确性和风格分数,便于进一步分析:

    if 'accuracy' in dataset.column_names:
        dataset = dataset.remove_columns(['accuracy'])
    dataset = dataset.add_column('accuracy', accuracy_scores)
    if 'style' in dataset.column_names:
        dataset = dataset.remove_columns(['style'])
    dataset = dataset.add_column('style', style_scores)

将包含生成的答案、评估结果和评分的最终数据集推送到Hugging Face Hub:

    dataset.push_to_hub(f"mlabonne/{model_id.split('/')[-1]}-results")
    return dataset

现在可以使用我们选择的三个模型调用evaluate_answers()函数:

model_ids = [    'mlabonne/TwinLlama-3.1-8B',    'mlabonne/TwinLlama-3.1-8B-DPO',    'meta-llama/Meta-Llama-3.1-8B-Instruct']
for model_id in model_ids:
    evaluate_answers(model_id)

通过保存中间结果,我们的评估框架对故障更具鲁棒性。同时,它也易于扩展到其他模型、数据集和评估标准。

结果分析

在评估过程结束时,我们可以查看三个方面:模型生成的答案、评估中的解释以及评分。

尽管逐一查看答案并不具备可扩展性,但这是一个关键步骤,有助于识别很多常见错误,例如错误的聊天模板或不正确的模型。在这里,我们将重点关注一个指令,并查看两个模型和Llama-3.1-8B-Instruct提供的答案。

指令 讨论算法偏差的概念及其影响。

TwinLlama-3.1-8B

算法偏差是指算法由于潜在假设或编程偏差而导致结果偏颇或不公平的倾向。这会产生重要影响,特别是在依赖算法进行关键决策的机器学习和人工智能领域。如果算法未经过充分的偏差审核,可能会导致歧视性结果,例如贷款政策对特定人群的负面影响或招聘过程不公正。因此,确保算法在设计和实施时考虑公平性和准确性至关重要,以减少这些风险。

TwinLlama-3.1-8B-DPO

算法偏差是指算法由于潜在假设或编程偏差而导致结果偏颇或不公平的倾向。这在依赖算法进行决策的机器学习和AI等关键领域中尤为重要。如果算法没有经过适当的偏差检查,可能会导致歧视性结果,比如拒绝特定群体的贷款申请或强化刻板印象。因此,主动应对算法偏差至关重要,以确保我们开发的技术具有公平性和正义性。

Llama-3.1-8B-Instruct

算法偏差,也称为算法偏向,是指机器学习模型中可能影响其性能、准确性和公平性的非预期或固有偏差。这种偏差可能由多种因素引起,包括用于训练模型的数据、算法本身以及社会或文化中存在的偏见。算法偏差的一个重大影响是可能会加剧现有的社会不平等。例如,面部识别软件已被证明对有色人种的准确性较低,导致错误逮捕和歧视。同样,语言处理模型被发现倾向于主流群体的语言和方言,使得边缘化社区难以获取信息和服务。算法偏差在医疗、教育和就业等领域也可能产生严重后果。例如,偏向某些人群的医疗诊断算法可能会对其他群体误诊或漏诊,从而导致延迟或不充分的治疗。在教育中,偏向特定学习风格的算法可能会不公平地影响具有不同学习能力的学生,导致机会不平等。为了减轻算法偏差的影响,必须从根源上解决偏差问题,并实施确保机器学习模型公平性和透明度的措施。这可以通过数据清理、正则化和去偏等技术实现,并通过多样且具代表性的数据集来支持。此外,在算法的开发和测试中纳入边缘化社区的成员也至关重要,以确保其公平性和公正性。综上所述,算法偏差是一个重大问题,可能对个人和社会产生深远影响。识别机器学习模型中的潜在偏差并采取积极措施加以缓解至关重要。通过这样做,我们可以创造更公平和公正的系统,使所有人,无论其背景或人口特征如何,均能受益。

表7.4:针对指令生成的答案示例

可以看到,两个微调模型的答案非常接近。而Llama-3.1-8B-Instruct的答案则非常冗长,列举了许多例子。尽管内容正确,但由于其长度,读起来感觉人工化且不易接受。而DPO模型则稍微简化了SFT版本的语言,使其不那么学术化,这正是我们想要捕捉的行为:修改写作风格,而不改变答案的实际内容。

现在,让我们查看GPT-4o-mini对每个答案的评估。

TwinLlama-3.1-8B

  • 准确性

    答案准确地定义了算法偏差,并强调了其在机器学习和AI等领域的影响。它正确指出了由于偏差算法而导致的歧视性结果风险。没有明显的事实错误,提供了全面的回答。

    • 评分:3
  • 风格

    语气信息丰富且相对易懂,但在某些部分(如“潜在假设或编程偏差”)倾向于正式语调。虽然适当地使用了一些技术术语,但可以进一步简化,以吸引更广泛的受众,特别是博客或社交媒体内容。

    • 评分:2

TwinLlama-3.1-8B-DPO

  • 准确性

    答案准确地定义了算法偏差,并概述了其在机器学习和AI等关键领域的影响。它强调了可能导致歧视性结果,全面概述了主题且无事实错误。

    • 评分:3
  • 风格

    文风清晰易懂,有效传达了算法偏差的技术概念,而不过于正式。尽管使用了一些技术术语,但它们合适且易于普通受众理解。

    • 评分:3

Llama-3.1-8B-Instruct

  • 准确性

    答案准确地定义了算法偏差,并讨论了其在面部识别、医疗和教育等多个领域的原因和影响。它还正确识别了解决偏差的方法,如纳入多样化的利益相关者和去偏技术。总体上,信息准确且全面。

    • 评分:3
  • 风格

    语气信息丰富且易懂,技术术语解释清楚。但某些表达如“非预期或固有偏差”和“多样和代表性数据集的实施”可以简化,以吸引更广泛的受众。总体上适合博客或社交媒体内容,但可以更具对话性。

    • 评分:2

表7.5:GPT-4o-mini对每个答案的风格和准确性评估

根据我们的裁判LLM,答案的准确性没有问题,所有答案得分均为满分。然而,对于风格,TwinLlama-3.1-8B(SFT)和Llama-3.1-8B-Instruct被认为过于正式,得分为2。裁判LLM认同我们的分析,并为TwinLlama-3.1-8B-DPO的答案打了满分,认为其“有效传达了算法偏差的技术概念而不过于正式”。

平均分数进一步证实了这一趋势:

  • TwinLlama-3.1-8B - 准确性:2.45
  • TwinLlama-3.1-8B - 风格:2.04
  • TwinLlama-3.1-8B-DPO - 准确性:2.46
  • TwinLlama-3.1-8B-DPO - 风格:2.12
  • Llama-3.1-8B-Instruct - 准确性:2.62
  • Llama-3.1-8B-Instruct - 风格:1.86

在准确性方面,我们的两个微调模型获得了相近的分数,而Llama-3.1-8B-Instruct的准确性最高,达到了2.62。这表明该指令微调的Llama模型在提供事实正确信息方面略有优势,可能得益于其超过1000万样本的扩展训练(相比之下,我们使用了13000样本)。

但在风格方面,我们看到了不同的模式。TwinLlama-3.1-8B-DPO以2.12分领先,成功实现了更易读且较少正式的写作风格,同时不牺牲内容质量。TwinLlama-3.1-8B(SFT)以2.04分紧随其后,风格上有所改善但仍带有些许正式语气,而Llama-3.1-8B-Instruct则以1.86分垫底,倾向于冗长。

基于此反馈和对生成答案的手动审查,我们可以检测错误并识别改进区域。这对于通过额外的筛选或用缺失信息增强数据集来改进数据生成过程至关重要。虽然此版本已显示出良好的效果,但通过在不同数据集和模型上迭代,我们将能够显著超越基线,为我们的用例创建最佳模型。

总结

在本章中,我们探讨了LLM的评估方法,包括对模型和RAG系统的评估。我们了解了如何解读MMLU等经典基准,以选择适合的候选模型进行使用或微调。同时,我们详细介绍了领域专用和任务专用评估的工作原理,并基于公开的示例展示了如何创建自己的评估。

我们将多项选择问答和“LLM-作为-裁判”这两种技术作为自定义评估框架的核心。

然而,模型通常被集成到提供额外上下文的更广泛系统中。我们介绍了RAG系统的两种评估框架:Ragas和ARES。我们了解了它们在评估RAG系统时的相似性(如合成数据生成)和差异(基于上下文的指标与训练分类器)。最后,我们使用裁判LLM从相关性、连贯性和简洁性三个标准评估了TwinLlama-3.1-8B,获得了关于如何改进模型的见解。

在下一章中,我们将探索推理优化技术,以提高速度并减少内存使用,同时尽量不影响模型性能。此外,我们还将深入优化方法、模型并行技术,并研究不同的量化方法。

参考文献

  • Lianmin Zheng et al. “Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena.” arXiv preprint arXiv:2306.05685, June 2023.
  • Aymeric Roucher. “Using LLM-as-a-judge for an automated and versatile evaluation - Hugging Face Open-Source AI Cookbook.” huggingface.co, 无日期,huggingface.co/learn/cookb….
  • LangChain. “Aligning LLM-as-a-Judge with Human Preferences.” blog.langchain.dev, 2024年6月26日, blog.langchain.dev/aligning-ll….
  • Dan Hendrycks et al. “Measuring Massive Multitask Language Understanding.” arXiv preprint arXiv:2009.03300, September 2020.
  • Jeffrey Zhou et al. “Instruction-Following Evaluation for Large Language Models.” arXiv preprint arXiv:2311.07911, November 2023.
  • Yann Dubois et al. “Length-Controlled AlpacaEval: A Simple Way to Debias Automatic Evaluators.” arXiv preprint arXiv:2404.04475, April 2024.
  • Grégoire Mialon et al. “GAIA: a benchmark for General AI Assistants.” arXiv preprint arXiv:2311.12983, November 2023.
  • Giwon Hong et al. “The Hallucinations Leaderboard -- An Open Effort to Measure Hallucinations in Large Language Models.” arXiv preprint arXiv:2404.05904, April 2024.
  • Shahul Es et al. “RAGAS: Automated Evaluation of Retrieval Augmented Generation.” arXiv preprint arXiv:2309.15217, September 2023.
  • Jon Saad-Falcon et al. “ARES: An Automated Evaluation Framework for Retrieval-Augmented Generation Systems.” arXiv preprint arXiv:2311.09476, November 2023.