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.mzph.cn/bicheng/48152.shtml

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

相关文章

【权威发布】2024年生物技术与医学国际会议(IACBM 2024)

2024年生物技术与医学国际会议 2024 International Conference on Biotechnology and Medicine 【1】会议简介 2024年生物技术与医学国际会议旨在为全球生物技术与医学领域的专家学者提供一个交流最新研究成果、分享技术进展和探讨未来发展方向的平台。会议旨在加强国际间的学术…

阿里云 https证书部署

一.申请证书 二.查看状态 查看状态,已签发是完成了申请证书 三.部署 我在nginx服务器上部署 具体操作链接:阿里云文档 修改前 修改后 四.重启ngnix 五.验证是否成功 在浏览器输入域名查看

【JavaScript 算法】最长公共子序列:字符串问题的经典解法

🔥 个人主页:空白诗 文章目录 一、算法原理状态转移方程初始条件 二、算法实现注释说明: 三、应用场景四、总结 最长公共子序列(Longest Common Subsequence,LCS)是字符串处理中的经典问题。给定两个字符串…

ETL电商项目总结

ETL电商项目总结 ETL电商业务简介及各数据表关系 业务背景 ​ 本案例围绕某个互联网小型电商的订单业务来开发。某电商公司,每天都有一些的用户会在线上采购商品,该电商公司想通过数据分析,查看每一天的电商经营情况。例如:电商…

通信协议_C#实现CAN通信

CAN协议 CAN(Controller Area Network)即控制器局域网络。特点: 多主网络:网络上的任何节点都可以主动发送数据,不需要一个固定的主节点。双绞线:使用双绞线作为通信介质,支持较远的通信距离。…

时序数据库如何选型?详细指标总结!

工业物联网场景,如何判断什么才是好的时序数据库? 工业物联网将机器设备、控制系统与信息系统、业务过程连接起来,利用海量数据进行分析决策,是智能制造的基础设施,并影响整个工业价值链。工业物联网机器设备感知形成了…

C++那些事之依赖注入

C那些事之依赖注入 最近星球里面有个小伙伴让更新一下依赖注入,于是写出了这篇文章,来从实际的例子讲解,本文会讲解一些原理与实现,完整的实现代码懒人版放在星球中,我们开始正文。 大纲: 直接依赖接口依赖…

vue 腾讯云 javascript sdk + 简单富文本组件设计+实战

<template><div><quill-editor v-model"content" ref"myQuillEditor" :options"editorOption" change"onEditorChange"input"handleInput"></quill-editor><!-- 链接添加对话框 --><el-di…

【论文阅读笔记】In Search of an Understandable Consensus Algorithm (Extended Version)

1 介绍 分布式一致性共识算法指的是在分布式系统中&#xff0c;使得所有节点对同一份数据的认知能够达成共识的算法。且算法允许所有节点像一个整体一样工作&#xff0c;即使其中一些节点出现故障也能够继续工作。之前的大部分一致性算法实现都是基于Paxos&#xff0c;但Paxos…

前端Vue项目中腾讯地图SDK集成:经纬度与地址信息解析的实践

在前端开发中&#xff0c;我们经常需要将经纬度信息转化为具体的地址信息&#xff0c;这对于定位、地图展示等功能至关重要。Vue作为现代前端框架的代表&#xff0c;其组件化开发的特性使得我们能够更高效地实现这一功能。本文将介绍如何在Vue项目中集成腾讯地图SDK&#xff0c…

一个 基于nuxt3 + vite + ts 搭建的 网盘服务 (附带部署教程)

目录 介绍技术选型功能介绍代码地址部署安装 node 环境打包代码安装 pm2 去 后台运行代码安装一个nginx 介绍 最近 有个卖课的朋友 谈到 网盘没有目录分享的功能&#xff0c;我之前嫖了他太多课了&#xff0c;出于感激给他写个小服务。 在线地址&#xff1a; http://godboxs.c…

SpringMVC源码深度解析(上)

今天&#xff0c;聊聊SpringMVC框架的原理。SpringMVC属于Web框架&#xff0c;它不能单独存在&#xff0c;需要依赖Servlet容器&#xff0c;常用的Servlet容器有Tomcat、Jetty等&#xff0c;这里以Tomcat为例进行讲解。老规矩&#xff0c;先看看本项目的层级结构&#xff1a; 需…

【入门基础】java泛型和通配符详解

【入门基础】java泛型和通配符详解 文章目录 前言泛型类泛型方法泛型接口通配符&#xff08;Wildcards&#xff09;使用场景非主流用法 总结 前言 Java泛型&#xff08;Generics&#xff09;是JDK 5中引入的一个新特性&#xff0c;它提供了编译时类型安全检测机制&#xff0c;…

socket 收发TCP/UDP

一、c 个人测试记录&#xff0c;有问题还请指出&#xff0c;谢谢 参考&#xff1a;C开发基础之网络编程WinSock库使用详解TCP/UDP Socket开发_c udp使用什么库-CSDN博客 代码中Logger测试见文章&#xff1a; c中spdlog的使用/python中logger的使用-CSDN博客 1、main.cpp 收…

【体外诊断】ARM/X86+FPGA嵌入式计算机在医疗CT机中的应用

体外诊断 信迈科技提供基于Intel平台、AMD平台、NXP平台的核心板、2.5寸主板、Mini-ITX主板、4寸主板、PICO-ITX主板&#xff0c;以及嵌入式准系统等计算机硬件。产品支持GAHDMI等独立双显&#xff0c;提供丰富串口、USB、GPIO、PCIe扩展接口等I/O接口&#xff0c;扩展性强&…

前端组件化开发:以Vue自定义底部操作栏组件为例

摘要 随着前端技术的不断演进&#xff0c;组件化开发逐渐成为提升前端开发效率和代码可维护性的关键手段。本文将通过介绍一款Vue自定义的底部操作栏组件&#xff0c;探讨前端组件化开发的重要性、实践过程及其带来的优势。 一、引言 随着Web应用的日益复杂&#xff0c;传统的…

通义千问AI模型对接飞书机器人-模型配置(2-1)

一 背景 根据业务或者使用场景搭建自定义的智能ai模型机器人&#xff0c;可以较少我们人工回答的沟通成本&#xff0c;而且可以更加便捷的了解业务需求给出大家设定的业务范围的回答&#xff0c;目前基于阿里云的通义千问模型研究。 二 模型研究 参考阿里云帮助文档&#xf…

CSRF+XSS组合攻击实战

目录 0x01安装靶场 0x02分析功能点的请求接口&#xff0c;构造恶意请求 0x03寻找xss漏洞 0x01安装靶场 下载源码&#xff0c;解压到网站根目录 1.修改数据库配置文件 打开源码&#xff0c;进入到include目录下&#xff0c;打开数据库配置文件database.inc.php 将数据库的…

组内第一次会议

会议内容 1、科研平台使用 增删改查对文件 cp -r /root/mmdetection/dataset/ /root/user/wbzExperiment/mmdetection/ rm -r /root/user/yolov5-master tar -czvf test03.tar.gz test03/ unzip abc.zip 上传文件、解压文件&#xff1a;要在自己的目录中&#xff0c;进入…

Python函数基础:构建代码逻辑的基石(补全篇)

在前面我已经编写过一篇&#xff0c;python函数基础的博文&#xff0c;相信有基础的同学应该看得出来&#xff0c;那一篇的基础内容也是不全的&#xff0c;于是就有了这个补全篇。补全篇&#xff0c;补充了变量的作用与&#xff08;global与nonlocal&#xff09;、递归函数、闭…