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

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-4zpa = zhipu_ai(configuration)m['zhipu_ai'] = zpareturn 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_workbookclass chat_interface(ABC):@abstractmethoddef request_chat(self, query: str, config: json) -> Union[dict, json]:pass# 针对4选1的xlsxdef deal_one_out_of_four_xlsx(self, path: str, config: json) -> List[dict]:wb = load_workbook(filename=path)shs = wb.sheetnamesres = []for sh in shs:ws = wb[sh]try:index = 1for 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 += 1except Exception as e:print(f'迭代处理excel表格时发生异常:{e}')return resreturn 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 responsereturn {"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.ppmy.cn/news/1465119.html

相关文章

HTML动态响应2-Servlet+Ajax实现HTTP前后台交互方式

作者:私语茶馆 前言 其他涉及到的参考章节: HTML动态响应1—Ajax动态处理服务端响应-CSDN博客 Web应用JSON解析—FastJson1.2.83/Tomcat/IDEA解析案例-CSDN博客 HTML拆分与共享方式——多HTML组合技术-CSDN博客 1.场景: WEb项目经常需要前后端交互数据,并动态修改HTML页…

Facebook代运营 | Facebook广告投放步骤及要点

Facebook体量大,素材的更新频率快,通过Facebook进行广告投放的用户也越来越多,Facebook坐拥大量用户,同时有着非常科学的用户画像构建系统和推送机制,对于很多广告涉足的伙伴来说,更加的友好。 1. 创建广告…

Linux tar 命令

解压.tar.xz文件 tar -xf qt-everywhere-src-6.7.1.tar.xz

第三部分:领域驱动设计之通过重构得到更深层的理解

通过重构得到更深层的理解 通过重构得到更深层的理解是一个涉及很多方面的过程。有三件事情是必须要关注的: 以领域为本;用一种不同的方式来看待事物;始终坚持与领域专家对话。 开始重构 获得深层理解的重构可能出现在很多方面。一开始有可能是为了解决代码中的问题——一段…

区块链技术和应用二

前言 学习长安链的一些基本原理 官网:长安链开源文档 b站课程:区块链基础与应用 一、共识算法 1.1 POW工作量证明 最长链共识,没听明白 1.2 51%攻击 二、区块链的发展 2.1 区块链1.0到3.0 2.2 共有链、联盟链、私有链 2.3 发展趋势 2.4 扩…

WebGIS 智慧城市三维可视化综合管控

智慧城市可视化建设不仅提升了城市管理的科技含量和效率,还促进了城市可持续发展,提升了居民的生活质量。随着技术的不断发展和应用,智慧城市可视化建设将会更加丰富和完善,为城市发展带来更加广阔的前景。 图扑应用自研 HT for W…

C. Swap Adjacent Elements 题解

C. Swap Adjacent Elements 题解 S A E 题目大意思路代码题目大意 输入格式: 第一行一个整数 n n n ( 2 ≤ (2≤ (2≤ n n n ≤ 200000 ) ≤200000) ≤200000) 第二行 n个整数 a 1 a_1 a1​, a 2 a_2 a2​

【npm】创建和发布无作用域的公共包

目录 1、创建包项目 2、进入目录 3、初始化项目 4、查看当前npm镜像源 5、切换镜像源 6、查看当前登录用户 7、登录 npm 用户 8、发布 9、查看公共包页面 10、删除已发布的npm包 11、📚总结 1、创建包项目 # 在命令行上,为包创建目录 mkdir…

为啥装了erlang,还报错erl: command not found?

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 问题背景: 在一台不通外网的服务器上装rabbitmq,然后在启动的时候,遇到了报错 “/usr/lib/…

【源码】2024完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城

后台可以自由拖曳修改前端UI页面 还支持虚拟商品自动发货等功能 前端UNIAPP 后端PHP 一键部署版本 获取方式: 微:uucodes

MySQL事务与并发控制案例

1. MySQL在事务与并发控制情况下加锁案例实现 第一步:开启一个事务并发锁 第二步:对加X锁(排他锁)的数据进行操作 可以看到锁被阻塞了; 2. 锁超时或死锁怎么办? Deadlock found when trying to get lock…

资深开发推荐的IDEA 插件

开发如虎添翼 工欲善其事,必先利其器。想要提升编程开发效率,必须选择一款顺手的开发工具,插件不在多,而在精,作为从业10年的程序员,我目前用到这十几个插件,在平时开发,代码review…

深入理解 Go 语言中的字符串不可变性与底层实现

文章目录 前言1 字符串类型的数据结构组成2 为什么要这么设计数据结构?3 为什么说字符串类型不可修改?4 如何实现字符串的修改?5 为什么字符串修改的字面量用单引号?6 如何判断字符串的修改新建了一个字符串?7 字符串的…

Spring MVC 运行流程?

1.spring mvc 将所有的请求都提交给 DispatcherServlet,它会委托应用系统的其他模块负责对请求 进行真正的处理工作。 2.DispatcherServlet 查询一个或多个 HandlerMapping,找到处理请求的 Controller。 3.DispatcherServlet 请请求提交到目标 Controller。 4.Controller 进行…

堆栈的简单应用

实验目的 (1) 掌握堆栈的定义及基本操作的实现 (2) 掌握顺序栈与链栈的区别与特点 (3) 掌握堆栈的应用场景与实际编程 实验内容 编写算法,借助堆栈将一个单链表置逆。 【提示】利用栈后进先出的特点,将单链表中的结点从链表头开始依次压栈&#xff0c…

【深度学习基础】使用Pytorch搭建DNN深度神经网络与手写数字识别

目录 写在开头 一、DNN的搭建 问题描述与数据集 神经网络搭建 模型训练 模型评估 模型复用 二、手写数字识别 任务描述 数据集 神经网络搭建 模型训练 模型评估 写在最后 写在开头 本文将介绍如何使用PyTorch框架搭建深度神经网络模型。实现模型的搭建、模…

释放视频潜力:Topaz Video AI for mac/win 一款全新的视频增强与修复利器

在数字时代,视频已经成为我们记录生活、分享经历的重要方式。然而,有时候我们所拍摄的视频可能并不完美,可能存在模糊、噪点、抖动等问题。这时候,就需要一款强大的视频增强和修复工具来帮助我们提升视频质量,让它们更…

标题:Go语言中的YAML魔法:轻松配置你的环境

摘要: 本文将介绍如何在Go语言项目中使用YAML文件来管理配置,包括如何读取YAML文件以及如何在代码中解析和使用这些配置。 正文: 在编程世界中,配置管理是每个项目都必须面对的问题。对于Go语言项目来说,YAML文件是一…

前端 CSS 经典:多行文本擦除效果

前言:使用动画实现更改变量 --p,实现多行文本擦除效果,css 动画逻辑,什么样的动画是生效的,一定是一个数值类的 CSS 属性。--p 只是个变量,不是 CSS 属性,通过 Houdini API 使它变成一个属性。 …

c++车票管理系统

这里写自定义目录标题 c车票管理系统vx:sredxc车票管理系统初始页面,需要源码vx:sredxc新增车票信息查询车票信息代码包含完整的发布车票信息,购票,退票,票数检测,余票检测,车票查询等功能 c车票管理系统vx:sredxc 这段代码实现了一个简单的高铁票务管理系统,具有以…