如何对大模型进行评估下

2023-12-19

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

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

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

def load_models_tokenizer(args):
    #调用AutoTokenizer从预训练模型加载tokenizer,这里的checkpoint_path就是大模型名称或者存储的path
    tokenizer = 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)
    # 使用模型进行推断,获取模型的输出 logits
    outputs = 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的数据集格式即可。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何对大模型进行评估下 的相关文章

随机推荐

  • 渗透测试与安全测试主要区别是什么?

    在网络安全体系中 有很多专业术语 而且部分专业术语在名字上有很大的相似之处 因此很多小伙伴将它们混淆在一起 比如渗透测试和安全测试 这两个概念就经常被混淆在一起 那么什么是渗透测试和安全测试 有何区别 渗透测试是通过模拟恶意黑客的攻击方法
  • 转移mysql中的数据

    目录 1 mysqldump 2 将数据库中的数据转换为一个sql文件 3 执行sql文件 1 mysqldump 转移数据需要用到mysqldump 默认情况下mysqldump会自动被安装上 如果没有用不了 建议重新安装一下 参考 my
  • 4.docker镜像及相关命令

    目录 1 查看所有镜像 docker images 1 1 基本用法 1 2 docker images q 只显示所有镜像ID 1 3 docker images f 筛选条件 q 只显示符合条件的所有镜像ID 1 4 docker im
  • 在Springboot项目中使用Quartz执行定时任务

    所使用的jar包
  • C语言,scanf出错时,重新输入

    问题的关键在于 把stdin中剩余的字符 吃掉 才能正常地进行下次输入 scanf出错后重新输入 使用 n 清空错误的字符 include
  • 将yolo格式转化为voc格式:txt转xml(亲测有效)

    1 文件目录如下所示 对以上目录的解释 1 dataset下面的image文件夹 里面装的是数据集的原图片 2 dataset下面的label文件夹 里面装的是图片对应得yolo格式标签 3 dataset下面的Annotations文件夹
  • 集成测试:确保软件系统无缝协同的关键

    摘要 本文将详细介绍集成测试的概念 目的 方法和实践 通过深入探讨集成测试的重要性 以及如何有效地进行集成测试 帮助读者更好地理解和应用集成测试技术 提高软件系统的质量和稳定性 一 引言 随着软件开发过程的不断演进 软件系统变得越来越复杂
  • 各种免费的格式转换工具

    PDF转CAD或其它 Zamzar video converter audio converter image converter eBook converter
  • Arraylist与LinkedList有什么区别?

    Arraylist与LinkedList有什么区别 一个工作4年的程序员去某互联网公司面试 被问到了这个问题 如果大家不知道这个问题该怎么回答 可以在文章尾端扫码二维码领取我整理的50W字的大厂面试指南 问题分析 ArrayList和Lin
  • 模块测试:确保软件质量的关键步骤

    引言 在软件开发过程中 模块测试是确保软件质量的关键环节 通过模块化的设计和测试方法 可以提高开发效率 降低错误率 并最终提供稳定可靠的软件产品 本文将介绍模块测试的概念 重要性以及实施步骤 帮助读者了解如何有效地进行模块测试 一 什么是模
  • 5.docker容器及相关命令

    docker中的容器实际上就是宿主机中的一个进程 目录 1 创建并启动容器 docker run 1 1 如果没有指定的镜像的话 docker会尝试从源拉取 1 2 给容器起名字 name 1 3 交互方式启动 i 与弹出客户端 t 1 4
  • 软件测试之威胁分析:保护您的应用程序免受潜在风险的侵害

    引言 在当今数字化时代 软件已经成为我们日常生活和工作中不可或缺的一部分 然而 随着软件的复杂性和规模不断增加 软件测试的重要性也日益凸显 本文将重点介绍软件测试中的威胁分析 帮助您了解并应对潜在的风险 确保您的应用程序的安全性和稳定性 一
  • MCU平台下确定栈空间大小的方法

    本文介绍MCU平台下确定栈空间大小的方法 通常使用IDE开发MCU程序在生成Image文件时 Image文件被划分为代码区 数据区 BSS区 堆区 栈区 其中 代码区 数据区 BSS区空间大小由编译器最终决定 对于MCU 堆区一般设置为0
  • leetcode 560. 和为 K 的子数组(优质解法)

    代码 class Solution public int subarraySum int nums int k int length nums length key 表示前缀和 value 表示个数 HashMap
  • AI创艺术之美:摄影绘画的未来已来

    前言 AI 与摄影绘画 在这个数字化时代的浪潮中 人工智能技术以其惊人的创造力和创新性席卷全球 从智能助手到自动驾驶 从自然语言处理到机器学习 AI正日益成为我们日常生活和各个领域不可或缺的一部分 摄影和绘画领域也不例外 AI技术为我们提供
  • 股指期权开通要什么条件?

    股指期权是一种金融衍生工具 它赋予持有者在未来某一特定日期按照约定的价格买入或卖出标的资产的权利 对于投资者来说 开通股指期权账户需要满足一定的条件 那么股指期权开通要什么条件 本文来自 财顺期权 开通股指期权账户需要的条件是 申请前20个
  • 一网打尽目前常用的聚类方法,详细介绍了每一种聚类方法的基本概念、优点、缺点!!

    目前常用的聚类方法 1 K 均值聚类 K Means Clustering 2 层次聚类 Hierarchical Clustering 3 DBSCAN聚类 DBSCAN Clustering 4 谱聚类 Spectral Cluster
  • 小程序项目基于微信点单小程序系统

    前言 本微信点单小程序是根据当前的实际情况开发的 在系统语言选择上我们使用的Java语言 数据库是小巧灵活的MySQL数据库 框架方便使用的是当前最主流的SPRING BOOT框架 本系统的开发可以极大的满足了人们在线点单的需求 微信点单小
  • 期权有杠杆吗?在哪里看期权有多少倍杠杠?

    期权有杠杆吗 在哪里看期权有多少倍杠杠 期权本身没有杠杆 期权合约自带杠杆 期权买方只需要缴纳较少的权利金就可以获得更高价值的标的资产波动所带来的收益 但是期权卖方不需要缴纳保证金 期权卖方需要付出保证金才可以建仓 这是因为期权卖方需要履行
  • 如何对大模型进行评估下

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