创新实训2024.05.29日志:评测数据集与baseline测试

news2025/1/20 3:45:17

1. 评测工作

在大模型微调和RAG工作都在进行的同时,我们搭建了一套评测数据集。这套数据集有山东大学周易研究中心背书。主要考察大模型对于易学基本概念与常识的理解与掌握能力。

1.1. 构建评测集

在周易研究中心的指导下,我们构建出了一套用以考察大模型对易学基本概念的掌握能力的数据集。

这套数据集是纯手工制作的,没有用之前之前的自动语料生成技术。因为我们要确保评测集100%的正确性和权威性。因此手写了170个四选一的单选题,配有分类与正确答案,让大模型进行回答。

怎么评估大模型在这个评测数据集上的性能?

我们对回答结果与正确结果进行比对,评估大模型的能力(准确来说,是Solve Rate,问题解决率)。其中,Solve Rate计算公式如下:

SR = \frac {Problem \hspace{1mm} Solved}{Total \hspace{1mm} Problem \hspace{1mm} numbers} \cdot {100\%}\cdot \cdot \cdot \cdot \cdot \cdot \cdot \cdot (1) 

这里,SR是Solve Rate,分子是解决的问题数(也即大模型给出的答案能和正确答案对的上的问题数),分母是问题总数。

评测数据集的结构

评测数据集的一行的结构如下所示:

其中:

  1. A列:一个有关周易(易学)的问题,有且仅有一个明确的答案。
  2. B~E列:这个问题的4个选项,分别对应A\B\C\D。其中有且仅有一个正确答案。
  3. F列:这个问题的正确答案。
  4. G列:该问题的分类

共170行,对应170个问题。

1.2. 构建测试过程

我们打算与目前现有的大模型对比,进行基准(baseline)测试。由于评测数据集和测试脚本完成编写后,我们微调的大模型还没有能够集成到服务器上。因此一开始我只跑了三个大模型:

  1. chatglm3-6b + 我们构建的易学知识库
  2. chatglm3-6b(不带知识库)
  3. 智谱AI chatglm-4(但是不带知识库)

在这个实验中,我们想探究知识库对于会给大模型的能力带来多少提升。我这里就以这个基准测试举例了,重点介绍这个Baseline Test的Working Pipeline。(后续,我们会加入经过结构化文本构成的数据集微调的大模型,并有带/不带知识库两种类型,另外还可以加入国内外已有通用大模型,例如文心一言、ChatGPT等)。

配置测试环境

这里我通过一个json文件对基线测试的环境进行配置。

{
  "sources": ["./source/test_data.xlsx"],
  "targets": ["./target/target1"],
  "prompt": {
    "one_out_of_four": "我现在有一个关于周易的问题,是一个四选一选择题,请你帮我回答。题目是:{question},选项是:{options},答案是:(请你回答)。请直接回答,不要解释。"
  },
  "test_args": {
    "origin_llm_kb": {
        "url": "http://zy.tessky.top/chat/knowledge_base_chat",
        "top_k": 20,
        "score_threshold": 1.00,
        "llm_models": ["chatglm3-6b", "zhipu-api", "openai-api"],
        "prompt_name": ["default","text","empty"],
        "knowledge_base_name": "faiss_zhouyi",
        "temperature": 0.7
    },
    "zhipu_ai": {
        "api_key": "you should never know this,my dear friends,use your own api keys",
        "model": "glm-4"
    }
  }
}
  1. sources:由于我们可能有多份评测数据集,所以是一个评测集文件的路径的数组
  2. targets:每个评测集文件基线测试的目标文件(保存每一个问题的评测结果的json文件)的路径数组
  3. prompt:不同评测集对应的prompt模板,比如我是四选一任务。
  4. test_args:不同大模型的参数,这个要根据具体情况配置了。

测试过程

我构建测试过程如下:

1. 首先,初始化所有将要进行基线测试的大模型的实例到一个dict中。(后面我会说这个实例如何构建)例如这里就是带知识库的chatglm3-6b和chatglm-4(zhipu_ai)。

def init_models(configuration: json) -> dict[str, chat_interface]:
    m = {}

    # ours:带知识库但是不带微调大模型的
    olk = origin_llm_kb()
    m['origin_llm_kb'] = olk
    # zhipuai:glm-4
    zpa = zhipu_ai(configuration)
    m['zhipu_ai'] = zpa

    return m

其中,其中key是在config/batch_evaluation.json中test_args中配置的key(我们要用这个key反解析配置文件中的大模型对话时的参数)。

2. 随后,遍历配置文件中的每一个评测集(当然我们这个例子中目前就还只有一个)。

    for i in range(len(srcs)):
        src = srcs[i]
        target = targets[i]

3. 再后,对之前初始化好的dict做kv对遍历,调用其中每个实例的处理评测数据集并进行大模型对话的方法,对当前评测集,返回一个List[dict],也即字典的数组:

 for chat, handler in chats.items():
                print(f"{chat} evaluating {src} ......")
                dicts = handler.deal_one_out_of_four_xlsx(src, config)

4. 最后将这个字典的数组转为json,保存到目标json文件中

                with open(os.path.join(target, f"{chat}.json"), 'w', encoding='utf-8') as tf:
                    json_str = json.dumps(dicts, ensure_ascii=False, indent=4)
                    tf.write(json_str)
                print(f"{chat} evaluated {src}")
                os.system('cls')

大模型对话实例构建

测试过程搭好了一个通用的框架,因为对于每一个大模型,他都要跑这套流程去做评测。但是剩下的部分就是每个大模型自己的工作了(请求大模型对话的接口往往不同)。不过其中还是有一些公共的部分的,也就是处理excel表格的部分。

抽象基类处理excel表格

因此我选择了建立一个抽象基类,把请求大模型进行对话的部分封装为一个抽象方法,让后面的子类去实现,而处理excel表格的公共部分,就在抽象基类中实现。形成代码的继承复用

import json
from abc import ABC, abstractmethod
from typing import List, Union
from openpyxl import load_workbook


class chat_interface(ABC):

    @abstractmethod
    def request_chat(self, query: str, config: json) -> Union[dict, json]:
        pass

    # 针对4选1的xlsx
    def deal_one_out_of_four_xlsx(self, path: str, config: json) -> List[dict]:
        wb = load_workbook(filename=path)

        shs = wb.sheetnames

        res = []
        for sh in shs:
            ws = wb[sh]

            try:
                index = 1
                for row in ws.iter_rows(min_row=1, values_only=True):
                    # row 是一个元组,包含了当前行的所有数据
                    question = row[0]
                    options = [f'A:{row[1]}', f'B:{row[2]}', f'C:{row[3]}', f'D:{row[4]}']
                    answer = row[5]
                    question_type = row[6]

                    query = config["prompt"]["one_out_of_four"].format(question=question, options=options)
                    response = self.request_chat(query=query, config=config)
                    print(f'{index}.{query}')
                    print(response)
                    res.append(
                        {
                            "question": question,
                            "options": options,
                            "correct_answer": answer,
                            "type": question_type,
                            "kb_answer": response["answer"],
                        }
                    )
                    index += 1
            except Exception as e:
                print(f'迭代处理excel表格时发生异常:{e}')
                return res

        return res
  1. 这里的request_chat就是交给后续继承这个抽象基类的子类实现的抽象方法,用来请求大模型对话。
  2. deal_one_out_of_four_xlsx是处理四选一excel表格的公共逻辑:
    1. 首先通过openpyxl库打开.xlsx文件
    2. 随后遍历每张worksheet
    3. 开启sheet的迭代器,遍历每一行,根据上述每行的结构,取出:
      1. 问题
      2. 选项数组
      3. 正确答案
      4. 类型
    4. 随后,构建prompt模板,调用request_chat进行询问。
    5. 将结果封装为dict,添加到字典的数组中
    6. 返回该数组
子类实现

之后,我们只需要为不同大模型编写一个request_chat的接口就可以。

1. 对于我们自己搭建的服务器上的chatglm3-6b的大模型,之前我写过请求的方式,详情请见于:创新实训2024.05.28日志:记忆化机制、基于MTPE与CoT技术的混合LLM对话机制-CSDN博客

这里我直接说request_chat方法的实现:

class origin_llm_kb(chat_interface):

    def request_chat(self, query: str, config: json) -> Union[dict, json]:
        args = config["test_args"]["origin_llm_kb"]

        request_body = {
            "query": query,
            "knowledge_base_name": args["knowledge_base_name"],
            "top_k": args["top_k"],
            "score_threshold": args["score_threshold"],
            "model_name": args["llm_models"][0],
            "temperature": args["temperature"],
            "prompt_name": args["prompt_name"][0],
        }

        try:
            response = requests.post(url=args["url"], headers={"Content-Type": "application/json"}, json=request_body)
        except Exception as e:
            response = '{\'answer\':\'发生异常' + str(e) + '\'}'

        return json.loads(response.text[response.text.find('{'):response.text.rfind('}') + 1])

这里的请求体的各个参数全部都是之前提到的配置文件中配置好的。

我们服务器的接口返回的大模型的回答是一个json格式的字符串,因此只需要找到最外围括号,然后把json字符串反解析成json对象即可返回。(在python中,dict和json对象是可以通用的,所以不用担心转不成dict)

2. 对于智谱清言的chatglm4,可以查阅它的官方文档,在之前的一篇博客中:创新实训2024.04.11日志:self-instruct生成指令_self instruct 中的seed是什么-CSDN博客

我已经提到过如何使用chatglm-4进行大模型对话请求,这里不再赘述:

class zhipu_ai(chat_interface):

    def __init__(self, config: json):
        args = config['test_args']['zhipu_ai']
        self.client = ZhipuAI(api_key=args['api_key'])
        self.model = args['model']

    def request_chat(self, query: str, config: json) -> Union[dict, json]:
        try:
            response = self.client.chat.completions.create(
                model=self.model,
                messages=[
                    {
                        "role": "user",
                        "content": query
                    }
                ]
            )
        except Exception as e:
            response = '{\'answer\':\'发生异常' + str(e) + '\'}'
            return response

        return {"answer": response.choices[0].message.content}

由于请求智谱AI需要一个客户端,因此在类实例创建时,我们先给他注入一个客户端,省的每次request_chat都得重新注入开销太大。

测试结果

可以看到,两个大模型分别将他们的回答写到了json文件中。

2. 性能评估

有了测试结果,我们就能根据之前的公式(1)进行性能评估了。首先我们要做一个统计,也就是json文件中每个json对象里的大模型的回答是否和正确答案一致。这一部分的实现由另一个队友完成,具体见于:

创新实训-结果统计-CSDN博客

实际结果如下:

其中,origin_llm和origin_llm_kb分别是不带知识库和带知识库的初始大模型chatglm3-6b的正确率,而zhipu_ai是智谱AI目前提供接口的chatglm4-14b的回答。

而带知识库的回答中,还有一个大模型没有明确说选项,但是回答对了的:

 因此实际上带知识库的glm3-6b的回答正确的个数是116个。

baseline测试结果
llm是否微调是否带知识库回答正确数量问题总数Solve Rate
glm3-6b××8017047.06%
glm3-6b×11617068.23%
glm4-14b××12117071.18%

可以看到,RAG技术为大模型的生成回答的准确性带来了巨大的提升。从80到116,共计提升了Δ(acc) = \frac {116-80}{80} \cdot {100\%} = 45\%

的准确性 。

后续,我们将继续将微调后的大模型部署到服务器,再跑一遍这个基线测试,生成更加完成的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1719589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【并查集】专题练习

题目列表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 模板 836. 合并集合 - AcWing题库 #include<bits/stdc.h> using lllong long; //#define int ll const int N1e510,mod1e97; int n,m; int p[N],sz[N]; int find(int a) {if(p[a]!a) p[a]find(p[a]);return p[a…

数据结构:希尔排序

文章目录 前言一、排序的概念及其运用二、常见排序算法的实现 1.插入排序2.希尔排序总结 前言 排序在生活中有许多实际的运用。以下是一些例子&#xff1a; 购物清单&#xff1a;当我们去超市购物时&#xff0c;通常会列出一份购物清单。将购物清单按照需要购买的顺序排序&…

【前端】Mac安装node14教程

在macOS上安装Node.js版本14.x的步骤如下&#xff1a; 打开终端。 使用Node Version Manager (nvm)安装Node.js。如果你还没有安装nvm&#xff0c;可以使用以下命令安装&#xff1a; curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash 然后关…

安通控股CRM数字化一阶段成功上线,重塑企业客户关系管理新格局

在数字化浪潮的席卷下&#xff0c;企业数字化转型已成为不可逆转的趋势&#xff0c;由于内循环增加、数字化转型、流量成本获客趋高等趋势作用力下&#xff0c;企业的精益化管理以围绕客户为中心构建市场竞争力的重要性日益凸显。 随着“客户为中心”理念的愈加深入&#xff0…

NFT Insider #132:Solana链上NFT销售总额达到55.49亿美元, The Sandbox成立DAO

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members&#xff08;https://twitter.com/WHALEMembers&#xff09;、BeepCrypto &#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、…

docker基本操作命令(3)

目录 1.Docker服务管理命令&#xff1a; 启动&#xff1a;systemctl start docker 停止&#xff1a;systemctl stop docker 重启&#xff1a;systemctl restart docker 开机自启&#xff1a;systemctl enable docker 查看docker版本&#xff1a; 2.镜像常用管理命令&…

k8s的ci/cd实践之旅

书接上回k8s集群搭建完毕&#xff0c;来使用它强大的扩缩容能力帮我们进行应用的持续集成和持续部署&#xff0c;整体的机器规划如下&#xff1a; 1.192.168.8.156 搭建gitlab私服 docker pull gitlab/gitlab-ce:latest docker run --detach --hostname 192.168.8.156 --publ…

数据挖掘 | 实验三 决策树分类算法

文章目录 一、目的与要求二、实验设备与环境、数据三、实验内容四、实验小结 一、目的与要求 1&#xff09;熟悉决策树的原理&#xff1b; 2&#xff09;熟练使用sklearn库中相关决策树分类算法、预测方法&#xff1b; 3&#xff09;熟悉pydotplus、 GraphViz等库中决策树模型…

【运维项目经历|026】Redis智能集群构建与性能优化工程

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

SpringBoot源码(自动装配、内嵌Tomcat)

文章目录 依赖管理pom依赖管理Web依赖自定义starter 一、WebMvcAutoConfiguration1.1 Filter1.2 Interceptor 二、源码解析2.1 SpringApplication2.1.1 构造方法1、填充webApplicationType2、自动装配Initializers3、自动装配Listeners 2.1.2 run(args) 2.2 SpringApplicationR…

buuctf的RSA(五)

[RoarCTF2019]RSA 一看到题目&#xff0c;我就有些蒙了&#xff0c;A是代表了什么&#xff0c; 先来分解n 接下来可以暴力破解e了&#xff0c;因为e没有给出来&#xff0c;应该不会太大&#xff0c;猜测是四位数字 import gmpy2 import libnum from Crypto.Util.number import…

2024就业寒潮下的挑战与机遇:能否守住饭碗,人工智能能否成为新春天?

前言 随着时代的飞速发展&#xff0c;2024年的就业市场迎来了前所未有的挑战。数以百万计的高校毕业生涌入市场&#xff0c;使得就业竞争愈发激烈。然而&#xff0c;在这股就业寒潮中&#xff0c;我们也看到了新的曙光——人工智能的崛起。这一新兴行业以其独特的魅力和巨大的…

【每日刷题】Day52

【每日刷题】Day52 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 2965. 找出缺失和重复的数字 - 力扣&#xff08;LeetCode&#xff09; 2. 350. 两个数组的交集 II …

【LeetCode】38.外观数列

外观数列 题目描述&#xff1a; 「外观数列」是一个数位字符串序列&#xff0c;由递归公式定义&#xff1a; countAndSay(1) "1"countAndSay(n) 是 countAndSay(n-1) 的行程长度编码。 行程长度编码&#xff08;RLE&#xff09;是一种字符串压缩方法&#xff0c…

【评价类模型】熵权法

1.客观赋权法&#xff1a; 熵权法是一种客观求权重的方法&#xff0c;所有客观求权重的模型中都要有以下几步&#xff1a; 1.正向化处理&#xff1a; 极小型指标&#xff1a;取值越小越好的指标&#xff0c;例如错误率、缺陷率等。 中间项指标&#xff1a;取值在某个范围内较…

【QEMU中文文档】1.关于QEMU

本文由 AI 翻译&#xff08;ChatGPT-4&#xff09;完成&#xff0c;并由作者进行人工校对。如有任何问题或建议&#xff0c;欢迎联系我。联系方式&#xff1a;jelin-shoutlook.com。 QEMU 是一款通用的开源机器仿真器和虚拟化器。 QEMU 可以通过几种不同的方式使用。最常见的用…

Linux上传文件

在finalshell中连接的Linux系统中&#xff0c;输入命令rz然后选择windows中的文件即可。

多维数组操作,不要再用遍历循环foreach了!来试试数组展平的小妙招!array.flat()用法与array.flatMap() 用法及二者差异详解

目录 一、array.flat&#xff08;&#xff09;方法 1.1、array.flat&#xff08;&#xff09;的语法及使用 ①语法 ②返回值 ③用途 二、array.flatMap() 方法 2.1、array.flatMap()的语法及作用 ①语法 ②返回值 ③用途 三、array.flat&#xff08;&#xff09;与a…

Nature 审稿人:值得关注的里程碑!段路明研究组首次实现基于数百离子量子比特的量子模拟计算

2024年5月30日&#xff0c;清华大学最新科研成果发表于Nature&#xff08;自然&#xff09;&#xff0c;这项成果被Nature审稿人称为“量子模拟领域的巨大进步”“值得关注的里程碑”&#xff01;究竟是什么样的成果值得这样的赞誉呢&#xff1f; 该成果就是中国科学院院士、清…

vue3 前端实现导出下载pdf文件

这样的数据实现导出 yourArrayBufferOrByteArray 就是后端返回数据 // 创建Blob对象const blob new Blob([new Uint8Array(res)], { type: application/pdf })// 创建一个表示该Blob的URLconst url URL.createObjectURL(blob);// 创建一个a标签用于下载const a document.cr…