如何对大模型进行评估下

2023-12-19 07:52
文章标签 进行 模型 评估 对大

本文主要是介绍如何对大模型进行评估下,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  如果从实现评估的纬度来分,可以将不同类型的评估分为三类,具体如下所示。更多理论的详细信息可以参见博客《如何对大模型进行评估上》。接下来就从第一种类型出发,看看评估脚本是如何实现的。这里分析的源代码是Qwen的评估脚本。

如何使用选择题类型数据集进行评估

  下面的代码是Qwen大模型提供的evaluate_ceval.py评估脚本的部分代码,原始代码所有信息请查看官网。下面对脚本中部分重点代码进行了解释。以get_logits为例,输入的信息通过tokenizer进行编码处理后,输入大模型,得到原始输出outputs后,通过softmax函数,将得到的结果转换为概率分布数据,这样,在提取大模型的答案时,从4个选项中选取概率最大的作为选择题的答案,与真实答案进行对比即刻。

def load_models_tokenizer(args):#调用AutoTokenizer从预训练模型加载tokenizer,这里的checkpoint_path就是大模型名称或者存储的pathtokenizer = AutoTokenizer.from_pretrained(args.checkpoint_path,pad_token='<|extra_0|>',eos_token='<|endoftext|>',padding_side='left',trust_remote_code=True)#加载大模型model = AutoModelForCausalLM.from_pretrained(args.checkpoint_path,pad_token_id=tokenizer.pad_token_id,device_map="auto",trust_remote_code=True).eval()#主要用于设置生成文本的参数model.generation_config = GenerationConfig.from_pretrained(args.checkpoint_path,pad_token_id=tokenizer.pad_token_id,trust_remote_code=True)return model, tokenizer#从下载的csv文件原始数据中读取每一行的question,并进行文本的简要处理
def format_example(line, include_answer=True):example = "问题:" + line["question"]for choice in choices:example += f'\n{choice}. {line[f"{choice}"]}'if include_answer:example += "\n答案:" + line["answer"] + "\n\n"else:example += "\n答案:"return example#从下载的zip文件中,解压出dev,eval,test三个folder,dev中有5条数据作为shot,这里提取这5条数据作为few-shot
def generate_few_shot_prompt(k, subject, dev_df):prompt = ""if k == -1:k = dev_df.shape[0]for i in range(k):prompt += format_example(dev_df.iloc[i, :],include_answer=True,)return prompt#组装好的inputs就是问题+few_shot的prompt,传入后,调用模型,得到原始模型输出logits,然后将得到的答案转换为概率
def get_logits(tokenizer, model, inputs: List[str]):#inputs_ids的长度不等,这里按最大长度进行填充input_ids = tokenizer(inputs, padding='longest')["input_ids"]#将输入的信息转换为pytorch中的张量input_ids = torch.tensor(input_ids, device=model.device)tokens = {"input_ids": input_ids}# 创建 attention_mask,用于指示哪些位置是 padding 位置,以便在模型中进行注意力处理时排除这些位置attention_mask = input_ids.ne(tokenizer.pad_token_id)# 使用模型进行推断,获取模型的输出 logitsoutputs = model(input_ids, attention_mask=attention_mask)["logits"]logits = outputs[:, -1, :]#通过softmax函数,将原始的logits转换为概率分布数据log_probs = torch.nn.functional.softmax(logits, dim=-1)return log_probs, {"tokens": tokens}

  除了关键的get_logits方法外,还有format_example函数,该函数的作用就是从原始数据集中获取question,然后,对格式进行稍微的调整。调整后的结果如下图所示,这是数据中某一个问题

  获取question后,在输入给大模型前,还带了5-shot,结果如下图所示,在输入信息中提供shot,能最大程度的告知大模型如何回答后面的问题,保证能评估到大模型真正的能力。

  输入的文字信息通过tokenizer进行编码后,再通过pytorch提供的tensor方法,将信息转换为张量,即大模型认识的一种信息表达方式。具体如下所示

  输入信息转换成张量后,传递给大模型,得到原始的logis结果,结果信息如下图所示,也是张量信息。接着调用softmax函数,将结果信息转换成概率分布数据,即下图中的probs信息。

  在得到大模型对于每个答案的概率信息后,选取概率最大的答案作为大模型生成的答案,然后与数据集中真实的答案进行对比,计算正确的百分比作为最终的评估值。下图是调用整个评估脚本得到的Qwen-7B大模型的评估分数。可以看到,数据集中有很多subset的子集,不同的子集又被划分到不同类型中。例如某些题目属于Social Science类型,某些属于Humanities类型。这里计算的是不同类型的平均分值。

  执行脚本后,除了得到最终的评估值外,还会生成一份详细的评估数据信息,如下图所示。可以看到,该文件中记录了整个中间信息。包括id,提取的question,数据集中的可选答案:A、B、C、B,数据集中的标准答案answer,对四个选项,大模型的预估概率值:prob_A、prod_B、prob_C、prob_D,最有还有correctness值。如果与真实答案相同则值为1,如果不相同值为0.

  以上就是对于选择题类型的数据集,在编写脚本调用大模型获取评估值的过程,总结脚本中关键步骤,如下图所示:

如何使用代码生成类型数据集进行评估

  对于代码生成类型的数据集,openai已经提供了一套评估脚本。对于大模型本身,如果想估算pass@k的值,只需要生成数据集中每个任务的答案,并组装成jsonl文件即可,然后,调用openai提供的脚本就能得到pass@k的值。即执行下面的命令即可计算出pass@k值。

evaluate_functional_correctness xx.jsonl

传递给上述命令的jsonl文件的内容,如下所示:

  查看Qwen中evaluate_humanEval脚本,有核心方法generate_sample()方法,该方法中将输入的信息通过调用tokenizer.encode进行编码,然后调用torch.tensor()将输入信息转换为张量,接着调用model生成输出信息,对于输出信息,调用了decode方法进行解码,解码后就是最终的输出信息,即上面jsonl文件中的completion字段内容了。

下面是decode()方法的代码,除了调用tokenizer.decode()进行解码外,还通过split方法对生成的内容进行了提取。

通过split方法对生成的内容进行提取,下图是截取的数据集中某一个题目的生成中间信息,input text是从数据集中提取出来的需要完成的题目prompt,before sent是大模型生成的原始答案,可以看到不止生成了一个解决方案,总共生成了4个答案,后面三个答案的function名称是大模型自定义的。上面的decode方法中提取的就是第一个内容。after sent就是提取出来的内容。

  经过decode后,最终组装出来的jsonl文件如下图所示:

  生成了包含大模型结果的jsonl文件中,执行下面的命令,即调用openai官网提供的脚本即可计算出pass@k的值。

"""
git clone https://github.com/openai/human-eval
$ pip install -e human-eval
evaluate_functional_correctness sample-output-file
"""

  那么openai的脚本是如何check生成的代码是否能通过单元测试呢?这里主要使用了python中的exec方法。

  在 Python 中,exec() 是一个内置函数,用于执行存储在字符串中的 Python 代码,即通过调用exec(),可以执行jsonl文件中completion字符串中的代码。在执行的时候,脚本从数据集中提取出单元测试,从jsonl文件中提取出completion,组装在一起,调用exec()执行,执行通过,则说明生成的代码能让单元测试通过。执行过程中报错,则说明生成的代码有问题,无法让所有的单元测试通过。

如何使用数学类题目数据集进行评估

 对于数学类题目,如何进行验证呢?查看Qwen目录下的gsm8k的评估脚本。同理,核心方法也是generate_sample(),函数中的代码与上面的HumanEval脚本类似。

对于数学类题目,多加了一个步骤,就是对output_text进行extract_answer的处理,extrace_answer方法的作用是:从生成的答案中提取最后一个数字作为最终的题目答案。然后,与数据集中的正确答案进行对比,如果相等则认为题目回答正确。extract_answer方法的代码如下所示:

总结

通过分析Qwen中大模型评估脚本,大致理解了对于三种不同类型的数据集,如何通过python脚本实现对大模型能力的评估。汇总如下所示:

对于选择题类型的数据集,评估过程如下:

对于代码生成的数据集,评估过程如下:

备注:如果原始数据集与HumanEval数据集的prompt有差异的,需要先对数据集进行预处理,格式follow HumanEval的数据集格式即可。

对于数学运算类数据集,评估过程如下所示:

这篇关于如何对大模型进行评估下的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/511431

相关文章

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详

Python使用DrissionPage中ChromiumPage进行自动化网页操作

《Python使用DrissionPage中ChromiumPage进行自动化网页操作》DrissionPage作为一款轻量级且功能强大的浏览器自动化库,为开发者提供了丰富的功能支持,本文将使用Dri... 目录前言一、ChromiumPage基础操作1.初始化Drission 和 ChromiumPage

Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

《Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursion)的问题及解决方案》使用Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursi... 目录解决方案‌1. 使用 @jsonIgnore 忽略一个方向的引用2. 使用 @JsonManagedR