AFAC2024-基于保险条款的问答 比赛日记 llamafactory qwen npu 910B1

AFAC2024: 基于保险条款的问答挑战——我的实战日记

概述

在最近的AFAC2024竞赛中,我参与了基于保险条款的问答赛道。这是一次深度学习与自然语言处理的实战演练,旨在提升模型在复杂保险文本理解与问答生成方面的能力。本文将分享我的参赛过程,包括数据处理、模型选择、微调策略、实验观察及最终成果。
比赛报名链接 https://tianchi.aliyun.com/competition/entrance/532194/introduction

数据与挑战

竞赛提供的数据集包含约6000条基于保险条款的问答对。这些数据覆盖了多种保险类型,如人寿保险、财产保险和健康保险,涉及保险条款的解释、索赔流程、覆盖范围等问题。数据集的多样性和专业性构成了此次竞赛的主要挑战。

llama factory 数据预处理
import jsontrain = json.load(open("round1_training_data/train.json",'r'))
dev = json.load(open("round1_training_data/dev.json",'r'))
a = []
for train_one in train:a.append({"input":"""目前有产品名称、相关条款。如果问题与产品名称、相关条款有关系,那么就依照产品名称、相关条款回答问题,如果没有关系直接回答问题。根据"""+train_one['产品名']+""",相关条款"""+train_one['条款']+",问题:"+train_one['问题'],"output":train_one['答案']})
for train_one in dev:a.append({"input":"""目前有产品名称、相关条款。如果问题与产品名称、相关条款有关系,那么就依照产品名称、相关条款回答问题,如果没有关系直接回答问题。根据"""+train_one['产品名']+""",相关条款"""+train_one['条款']+",问题:"+train_one['问题'],"output":train_one['答案']})
json.dump(a,open('data/a.json','w'),ensure_ascii=False)

任务总共数据6000条。
最大长度超过10000。
修改llama factory data下的data_info.json 加入我们的数据集

 "a": {"file_name": "a.json","columns": {"prompt": "input","response": "output"}},

启动云脑任务的时候可以预先选择上我们要进行作业的模型。
在这里插入图片描述
配置好这个以后我们就可以启动任务了。在项目启动后我们需要把模型文件拉到本地。

from c2net.context import prepare#初始化导入数据集和预训练模型到容器内
c2net_context = prepare()#获取数据集路径
chat_json_path = c2net_context.dataset_path+"/"+"chat.json"#获取预训练模型路径
qwen1_5_14b_chat_path = c2net_context.pretrain_model_path+"/"+"Qwen1.5-14B-Chat"#输出结果必须保存在该目录
you_should_save_here = c2net_context.output_path

如果不选择会浪费更多的时间在下载数据集上。平台不支持访问transformers只能访问国内的modelscope。

模型选择与微调

为了应对挑战,我选择了Qwen的多个版本作为基础模型。具体来说,我尝试了两种策略:

  1. LoRA微调:首先,我使用了qwen2-7b-instruct和qwen1.5-14B-chat模型,通过LoRA(低秩适配)进行微调。LoRA允许在不修改原模型权重的情况下,仅优化少量新增参数,从而有效减少了计算资源需求。
    lora 微调 qwen2-7b-instruct 在比赛中拿到了489分
    lora 微调 qwen1.5-14B-chat
    超参数 qwen1.5-14B-chat
### model
model_name_or_path: pretrainmodel/Qwen1.5-14B-Chat### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: all
deepspeed: examples/deepspeed/ds_z2_config.json### dataset
dataset: a
template: qwen
cutoff_len: 2048
overwrite_cache: true
preprocessing_num_workers: 16### output
output_dir: saves/qwen1.5-14b/full/sft
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true### train
per_device_train_batch_size: 1
gradient_accumulation_steps: 2
learning_rate: 5.0e-5
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true
ddp_timeout: 180000000### eval
val_size: 0.1
per_device_eval_batch_size: 1
eval_strategy: steps
eval_steps: 500

这里我们选择了使用deepspeed zero2的方式进行微调工作。在910B1 npu上可以使用bf16精度进行模型训练。验证集设置的大小是百分之十的数据作为验证数据集规模。
第一个500步验证精度

{
'eval_loss': 0.2957316040992737, 
'eval_accuracy': 0.910640437309614, 
'eval_runtime': 156.6478, 
'eval_samples_per_second': 3.83, 
'eval_steps_per_second': 3.83, 
'epoch': 0.19
}

第二个500步验证精度

{'eval_loss': 0.27959996461868286, 'eval_accuracy': 0.9174682889249636, 'eval_runtime': 158.7283, 'eval_samples_per_second': 3.78, 'eval_steps_per_second': 3.78, 'epoch': 0.37}

第三个500步验证

{
'eval_loss': 0.25857865810394287, 
'eval_accuracy': 0.9208686929382228, 
'eval_runtime': 158.2571, 
'eval_samples_per_second': 3.791, 
'eval_steps_per_second': 3.791, 
'epoch': 0.56
}

llama factory只有在最后训练结束的时候才会把图生成出来,但是我们在openi平台上只有四个小时。所以我们可以在模型输出目录下找到train log文件自己绘图。

import pandas as pd
import matplotlib.pyplot as plt# 将日志数据转换为Pandas DataFrame
import json
log_data = []
trainer_log = open("sft/trainer_log.jsonl").readlines()
for trainer_log_one in trainer_log:trainer_log_data = json.loads(trainer_log_one)if "loss" in trainer_log_data:log_data.append(trainer_log_data)
df = pd.DataFrame(log_data)# 设置图表样式
plt.style.use('ggplot')# 绘制损失随训练步骤变化的图表
plt.figure(figsize=(12, 6))
plt.plot(df['current_steps'], df['loss'])
plt.title('Training Loss Over Steps')
plt.xlabel('Steps')
plt.ylabel('Loss')
plt.grid(True)
plt.savefig('Training Loss Over Steps')# 绘制学习率随训练步骤变化的图表
plt.figure(figsize=(12, 6))
plt.plot(df['current_steps'], df['learning_rate'])
plt.title('Learning Rate Over Steps')
plt.xlabel('Steps')
plt.ylabel('Learning Rate')
plt.grid(True)
plt.savefig('Learning Rate Over Steps')

在这里插入图片描述
在这里插入图片描述
验证集相关图表

import pandas as pd
import matplotlib.pyplot as plt# 将日志数据转换为Pandas DataFrame
import json
log_data = []
trainer_log = open("sft/trainer_log.jsonl").readlines()
for trainer_log_one in trainer_log:trainer_log_data = json.loads(trainer_log_one)if "eval_loss" in trainer_log_data:log_data.append(trainer_log_data)
df = pd.DataFrame(log_data)# 设置图表样式
plt.style.use('ggplot')# 绘制损失随训练步骤变化的图表
plt.figure(figsize=(12, 6))
plt.plot(df['current_steps'], df['eval_loss'])
plt.title('eval Loss Over Steps')
plt.xlabel('Steps')
plt.ylabel('Loss')
plt.grid(True)
plt.savefig('eval Loss Over Steps')

验证集损失

针对所出现的拟合过快的问题,我们提出以下的优化策略。

  1. 降低学习率(learning_rate
    学习率是影响模型训练速度和稳定性的重要因素。降低学习率可以让模型在训练过程中更加谨慎地更新权重,从而减慢拟合速度。
    learning_rate: 2.0e-5  # 从5.0e-5降低到2.0e-5
    
  2. 增加warmup步数或比例(warmup_ratio
    增加warmup的步数或比例可以让模型在前期以更慢的速度学习,这有助于模型在后期训练中更稳定。
    warmup_ratio: 0.2  # 从0.1增加到0.2
    
  3. 减少梯度累积步数(gradient_accumulation_steps
    减少梯度累积步数会增加每次更新权重的间隔,从而使模型的学习速度减慢。
    gradient_accumulation_steps: 1  # 从2减少到1
    
  4. 增加训练批次大小(per_device_train_batch_size
    增加批次大小可以提高训练的稳定性,但同时需要相应地调整学习率。
    per_device_train_batch_size: 2  # 从1增加到2,同时可能需要再次调整学习率
    
  5. 调整优化器的动量或重量衰减(如果使用的话)
    对于使用动量或重量衰减的优化器,调整这些参数可以影响模型的收敛速度。
    # 假设使用的是AdamW优化器
    optimizer:type: AdamWbetas: [0.8, 0.999]  # 降低动量参数weight_decay: 0.01  # 增加重力衰减
    
  6. 使用更保守的lr调度器(lr_scheduler_type
    选择一个更保守的调度器,如linearcosine的缓慢下降版本。
    lr_scheduler_type: linear  # 从cosine改为linear
    
  7. 增加正则化
    增加L1或L2正则化可以防止模型过拟合,从而减慢拟合速度。
    # 增加L2正则化
    optimizer:weight_decay: 0.01  # 增加这个值可以增加正则化
    

请记住,调整超参数是一个试验和错误的过程,可能需要多次尝试才能找到最佳的配置。每次调整后,都应该监控模型的性能,以确保它仍然在正确的方向上前进。

  1. 全参数量微调:其次,我利用qwen2-7B-instruct模型进行了全参数量微调,以探索模型在充分学习数据集方面的潜力。
    最开始我也想全参数量微调qwen1.5 14B chat模型。目前观察的情况是会爆显存。所以暂时搁浅。

合并模型部分
通过对训练过程的观察,发现在2.5k步的时候验证损失是最低的。所以采用2.5k步的模型作为此次验证最优模型。这里我在第一个4小时结束训练后启动第二次四小时训练的开始选择模型合并操作。模型合并操作执行了将近半个小时。

### Note: DO NOT use quantized model or quantization_bit when merging lora adapters### model
model_name_or_path: pretrainmodel/Qwen1.5-14B-Chat
adapter_name_or_path: saves/qwen1.5-14b/full/sft/checkpoint-2500
template: qwen
finetuning_type: lora### export
##export_dir: /home/songzhijun/work/Langchain-Chatchat/longbao1
export_dir: models/Qwen1.5-14B-match
export_size: 2
export_device: cpu
export_legacy_format: false

生成答案部分
因为在openi平台中启动api接口后无法本地调用。所以这里我选择了使用huggingface transformers原生的办法进行生成提交数据的操作。

from transformers import AutoModelForCausalLM, AutoTokenizermodel_name = "models/Qwen1.5-14B-match"
device = "npu" # the device to load the model ontomodel = AutoModelForCausalLM.from_pretrained(model_name,torch_dtype="auto",device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)data_test = json.load(open("round1_training_data/test.json",'r'))outfile = open("tianyan_result.jsonl",'w',encoding="utf-8")
for data_test_one in data_test:messages = [{"role": "user", "content": "根据条款"+data_test_one['条款']+"回答问题"+data_test_one['问题']}]text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True)model_inputs = tokenizer([text], return_tensors="pt").to(device)generated_ids = model.generate(**model_inputs,max_new_tokens=512)generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]# data = response.json()outfile.write(json.dumps({"ID": str(data_test_one['ID']), "question": data_test_one['问题'], "answer": response}, ensure_ascii=False) + "\n")
计算资源

实验是在华为910B1 GPU上进行的,配备了64GB显存。这一配置足以支持大型语言模型的高效训练和微调。
我做采用的资源来自openi平台。每天启动云脑任务会给10积分。相当于两个半小时的910B1 64GB版本计算资源。
您的好友正在邀请您加入OpenI启智AI协作平台,畅享充沛的普惠算力资源(GPU/NPU/GCU/GPGPU/DCU/MLU)。
注册地址:https://openi.pcl.ac.cn/user/sign_up?sharedUser=nlp_future_01
推荐人:nlp_future_01

实验观察

在初步实验中,我发现模型在较短时间内便达到了较高的训练集准确率,显示出了快速拟合的趋势。这可能是由于数据集的大小相对于模型容量而言较小,导致过拟合现象。
7b lora 微调后
score:489.9103
14B lora 微调后
score:592.4397

参数调节与时间限制

为解决过拟合问题,我开始调整学习率、批次大小和正则化参数。此外,我还增加了Dropout比例,以增强模型的泛化能力。然而,openi平台的时间限制(每轮实验仅限4小时)为模型训练和验证带来了额外的挑战。我不得不精心设计实验计划,确保在有限时间内完成尽可能多的有效迭代。

结论

尽管面临时间限制和技术难题,这次竞赛经历极大地丰富了我的知识库,特别是在处理特定领域文本和优化模型训练流程方面。未来,我计划继续探索更高级的微调技术和模型架构,以提高模型在保险条款问答任务上的表现。


通过本次竞赛,我深刻体会到理论与实践结合的重要性,以及在有限资源下优化模型性能的挑战。希望我的经验能为同样热衷于自然语言处理领域的研究者和工程师们提供有价值的参考。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

秒杀优化: 记录一次bug排查

现象 做一人一单的时候,为了提升性能,需要将原来的业务改造成Lua脚本加Stream流的方式实现异步秒杀。 代码改造完成,使用Jmeter进行并发测试,发现redis中的数据和预期相同,库存减1,该用户也成功添加了进去…

【Linux】Linux的基本使用

一.Linux的背景知识. 1.1什么是Linux Linux是一种开源的类Unix操作系统内核. 和Windows是" 并列 "的关系. 1.2Linux的发行版本. Linux 严格意义来说只是一个 “操作系统内核”.一个完整的操作系统 操作系统内核 配套的应用程序. 由于 Linux 是一个完全开源免费…

C++:格式化输入和输出、非格式化输入和输出(控制布尔值格式、整型值格式、浮点数格式;单字节操作put和get、多字节操作getline等)

1、格式化输入和输出 (1)What 标准库定义了一组操纵符&#xff08;本质是函数或对象&#xff09;来修改流的格式状态 当操作符改变流的格式状态时&#xff0c;通常改变后的状态对所有后续 IO 都生效 (2)Which A.控制布尔值的格式 bool bFlag true; std::cout<<std::b…

HTML+CSS3网页字符下雨特效

HTMLCSS3网页字符下雨特效https://www.bootstrapmb.com/item/14952 要在HTML和CSS3中创建一个字符下雨的特效&#xff0c;我们需要使用HTML来构建基本结构&#xff0c;然后使用CSS3的动画和关键帧&#xff08;keyframes&#xff09;来创建动画效果。但请注意&#xff0c;CSS3本…

pdf的下载,后端返回工作流,前端进行转换

前端将后端返回的工作流进行转换 项目中接触到了pdf的下载和预览的功能&#xff0c;记录一下~ 这里pdf的下载和预览的接口&#xff0c;后端返回的数据结构与其他的接口返回的数据结构有点不同&#xff0c;是直接返回的工作流&#xff0c;在控制台接口的响应预览内容大致是这样…

Aquila优化算法(基本原理+matlab源代码)—— 基于Aquila Optimizer原始论文分析

Matlab源代码位于&#xff1a; Aquila Optimizer: A meta-heuristic optimization algorithm - File Exchange - MATLAB Central (mathworks.cn) 1 Aquila优化算法 AO是一种基于种群优化方法&#xff0c;受启发于Aquila捕获猎物的方式。Aquila捕获猎物的方式主要有四种&#x…

JVM常用工具中jmap实现手动进行堆转储(heap dump文件)并使用MAT(Memory Analyzer Tool)进行堆分析-内存消耗分析

场景 JVM-常用工具(jps、jstat、jinfo、jmap、jhat、jstack、jconsole、jvisualvm)使用&#xff1a; JVM-常用工具(jps、jstat、jinfo、jmap、jhat、jstack、jconsole、jvisualvm)使用_jvm分析工具-CSDN博客 上面讲了jmap的简单使用。 下面记录其常用功能&#xff0c;实现堆…

【瑞芯微RV1126(板端摄像头图像数据采集)】②使用v4l2视频设备驱动框架采集图像数据

RV1126开发板&#xff1a;使用v4l2视频设备驱动框架采集图像数据 前言一、按键二、LCD显示三、V4L2 摄像头应用编程四、完整代码 前言 本系列的目的是&#xff0c;不仅仅将能够进行图片推理的模型部署于板端&#xff0c;还提供了两种摄像头数据采集的方法&#xff0c;集成到自…

国际化技术参考

一、概述 国际化就是用户可以选择对应的语言,页面展示成对应的语言; 一个系统的国际化按照信息的所在位置,可以分为三种国际化信息: 前端页面信息后端提示信息数据库的字典类信息二、前端页面国际化 使用i18n库实现国际化 i18n国际化库思路:通过jquery或者dom操作拿到需…

15现代循环神经网络—GRU与LSTM

目录 1.门控循环单元 GRU关注一个序列门候选隐状态(candidate hidden state)隐状态总结从零开始代码实现代码简洁实现2.长短期记忆网络 LSTM门候选记忆单元(candidate memory cell)记忆单元隐状态代码1.门控循环单元 GRU GRU 是最近几年提出来的,在 LSTM 之后,是一个稍微简…

Spring Boot + Spring Cloud 入门

运行配置 java -jar spring-boot-config-0.0.1-SNAPSHOT.jar --spring.profiles.activetest --my1.age32 --debugtrue "D:\Program Files\Redis\redis-server.exe" D:\Program Files\Redis\redis.windows.conf "D:\Program Files\Redis\redis-cli.exe" &q…

开源安全态势感知平台Security Onion

简介 Security Onion是一款由安全防御人员为安全防御人员构建的免费开放平台。它包括网络可见性、主机可见性、入侵检测蜜罐、日志管理和案例管理等功能。详细信息可以查看官网Security Onion Solutions 在网络可见性方面&#xff0c;Security Onion提供了基于签名的检测&…

一文了解LLM大模型会话 QA 增强

概述 在日常对话中&#xff0c;由于我们的大脑记录了对话的历史信息&#xff0c;为了减少冗余的内容&#xff0c;在进行回复时通常会存在指代和省略的情况。因为人脑具有记忆的能力&#xff0c;能够很好地重建对话历史的重要信息&#xff0c;自动补全或者替换对方当前轮的回复…

创建最佳实践创建 XML 站点地图--SEO

您是否正在努力让您的网站被搜索引擎索引&#xff1f;您想提高您网站的搜索引擎知名度吗&#xff1f;如果是&#xff0c;您可能会错过 XML 站点地图的重要性。XML 站点地图在改善您网站的 SEO 方面发挥着至关重要的作用。‍ XML 站点地图是您网站结构的蓝图&#xff0c;可帮助…

详解Stable Diffusion 原理图

参考英文文献&#xff1a;The Illustrated Stable Diffusion – Jay Alammar – Visualizing machine learning one concept at a time. 在这个Stable Diffusion模型的架构图中&#xff0c;VAE&#xff08;变分自编码器&#xff09;模型对应的是图中的 E 和 D 部分。 具体来说…

【深入理解SpringCloud微服务】深入理解Eureka核心原理

深入理解Eureka核心原理 Eureka整体设计Eureka服务端启动Eureka三级缓存Eureka客户端启动 Eureka整体设计 Eureka是一个经典的注册中心&#xff0c;通过http接收客户端的服务发现和服务注册请求&#xff0c;使用内存注册表保存客户端注册上来的实例信息。 Eureka服务端接收的…

JS 鼠标拖动实现移动滚动条的滚动效果

效果 现在很多场景都以移动端为基本开发&#xff0c;比如说需要隐藏滚动条&#xff0c;在pc上实现鼠标拖动和手机触摸拖动差不多的效果。 实现 以mdn的overflow属性中范例为基础&#xff0c;内容溢出时候可使用overflow: auto;和overflow: scroll;实现滚动效果。 要实现鼠标…

聚焦智慧出行,TDengine 与路特斯科技再度携手

在全球汽车行业向电动化和智能化转型的过程中&#xff0c;智能驾驶技术正迅速成为行业的焦点。随着消费者对出行效率、安全性和便利性的需求不断提升&#xff0c;汽车制造商们需要在全球范围内实现低延迟、高质量的数据传输和处理&#xff0c;以提升用户体验。在此背景下&#…

java用freemarker导出word

freemarker导出word 第一步、将word转换为xml格式第二步、将转换后的xml文件修改后缀为ftl后复制到项目 resources 目录下&#xff08;可以自己新建一个文件夹放在文件夹中&#xff09;第三步、格式化xml代码&#xff08;如果问价太大可能会无法格式化&#xff09;这时候需要在…

Windows上让Qt支持https请求

一.前言 Qt默认其实支持https的&#xff0c;但需要openssl的支持。所以有时候你代码中写了支持https的请求连接&#xff0c;发现程序可以运行&#xff0c;但到了https请求时会报错&#xff0c;如下&#xff1a; 这就是没有openssl的支持&#xff0c;导致QSslSocket无法进行ht…