.. | ||
fin_qa | ||
test_data | ||
.gitignore | ||
build_db.py | ||
configuration.json | ||
predict_v1.py | ||
predict.py | ||
README.md | ||
README.pdf | ||
requirements.txt | ||
run.sh |
SMP 2023 ChatGLM金融大模型挑战赛参赛代码-结婚买房代代韭菜队
1. 简介
代码仓库
描述约定
为了后续沟通方便,对赛题进行重新定义
- type1
- type11,问一个单项存在于数据库内容的题目
- type12,统计题目
- type11-2,法定代表人是否相同的题目,赛方定义为type2,本方案定义为11。
- type2
- type21,特定型公式,如速动比率这样的公式
- type22,增长率,其实就是type11的一个组合
- type31
- 同赛方
- type32
- 同赛方
2. 总体思路
思路简介
本次的赛题按照赛方的划分主要分为三类
- type1代表可以单次完成的客观基础查询
- type2代表使用type1结果进行组合后的客观高阶查询
- type3代表需要模型使用(type31)/不使用相关资料(type32)进行主观总结的查询
本方案根据解题所需输入数据的不同,将问题重新分成三类
- 数据库精准查询题目,无论是单次还是多次后进行组合,即type1和type2一起
- 文档内容总结题目,即type31
- 模型金融知识题目,即type32
直到比赛结束,type32类型大家的分数都保持在90分左右,没有差距,90分已经是一个比较高的水平,去做应该是后面的事情,在比赛期间做的收益比较低;对于type31,大家的分数也有一些参差,但是不是影响排名的最重要因素;对于本次比赛,重心主要在type1以及type2
对于type1以及type2问题,查询数据是必要的步骤。由于是对于客观数据的基础查询,且在复赛加入了统计问题,本方案采用数据库来作为数据结构。type1和type2类型的题目主要有以下难点:
- 数据查询的精准度,与数据库落表时的干净程度相关。
- 理解问题意图,大多数问题的意图时找某个具体公司在某个或者多个具体年份的某项指标,这里面包括了三项要素,分别是公司,年份以及指标。
如何解决type1, type2
以下三个大步骤均训练了一个ptuningv2 prefix_encoder。
-
路由 - 分发问题
- 数据:
- B榜2k条query通过关键词解析,三元分析得到的数据集。具体可以看一下query_analyze.py中的query_type_router,自动构建完后人工扫了一遍,主要扫的比较容易搞混的type1和type31
- 将B榜和初赛的query集通过解析增强得到的数据集。具体是对于type1、type2提取中间的关键词,随机替换为词表中其他词来获得
- 测评效果
- 在训练集上应该已经过拟合了,B榜2k条相对于label有2条估错
- 数据:
-
nl2sql - 将精准查询转化为sql语句
- 数据:
- type11部分的nl2sql主要来自完全解析后的自动构建,为了让该模型能学到如负债合计->总负债这样的不在词库里的映射,在训练集中也进行了加强处理,通过alias表替换来进行训练
- type12部分主要来chatgpt生成,需要的话我可以把相关prompt和截图发出来(api由于没开外卡限速太严重,用的web批处理的),不过chatgpt仍然会有10%~20%的错误表现,需要人工扫过来进行纠正
- type11-2,这部分解析也能完成很多,人工也标了一部分
- nl2sql的数据列\公式召回
- 目前使用的方案是对query分词后去停词,对于每个剩下的关键词向量召回词表内的词,最后再进行编辑距离硬卡,这里虽然加入了解析结果的数据列,但是会对数据列进行shuffle来进行训练,所以应该没有泄露
- 测评效果
- type11基本cover,从来没有扫到相关badcase
- type12,偶尔出错,有可能是和type11混的太严重以及数据比例不协调的问题导致注册地址偶尔用in,不过整体效果也还是很不错的
- type11-2,基本都是对的
- 数据:
-
normalizer - 将sql查询结果和问题整理成符合问题格式的输出
- 数据:
- 首先用少量数据通过chatgpt训练了一个v1版的normalizer,然后通过它生成的答案进一步纠错数据再次训练得到新的normalizer,type2和type11-2的答案是固定的格式可以直接当label
- 测评效果
- 其实还不错。在正确工作的时候可以很完美的生成答案,但是会有5%左右的概率type1漏词比如少公司名或者少答案;type12表现得不够好,常常漏金额,可能还是数据质量不够高得原因,中间审得时候很多错误没审过来,type11-2回答也可能会少某一年得法定代表人或者少最终答案,可能可以达到90%得效果,但是对于本次评测来说可能不如规则生成答案
- 数据:
如何解决type31
因为数据结构早期构建得问题,这类问题本方案比较方便。通过txt构建得第一层数据结构是一棵文档树,每一级标题作为一个中间节点往下继续挂节点,所以通过向量搜索直接搜索中间得标题节点比较方便,然后把标题节点得子节点join一下喂给chatglm2,这个type因为时间精力问题没有深入探究。
如何解决type32
直接喂query
注
type1得整体流程都经历过三大步骤,对于type12由于训练得不够好得问题会对答案作一些adjust type2,法定代表人题目最后一步是规则生成得(规则生成和模型生成差八分,没办法),其他得只有router是过得模型,后面是规则生成,不过子项也可以直接走type1得流程 type31,查找知识直接喂 type32,直接喂
为什么type2得多数问题不走模型:因为模型效果不够好,为了提分没法子。其实感觉模型对于pattern太重得数据集确实没有规则好,模型得主要优势还是在泛化性能和更加复杂pattern得数据集上
附录 - 数据流程示例
- query 哪家上市公司,在北京注册,2020年总负债最高?金额为?
- router to type12
- prompt
哪家上市公司,在北京注册,2020年总负债最高?金额为?
- response
type12
- prompt
- nl2sql
- prompt
你的任务是将问题转化为SQL。 1. SQL语句查询的表名为: big 2. 涉及到的列名有: 注册地址,负债合计,预计负债,股票简称,公司名称,股票代码,年份 【问题】哪家上市公司,在北京注册,2020年总负债最高?金额为? 【SQL】
- response
select 公司名称, 负债合计 from big where 注册地址 like '%北京%' and 年份 = '2020年' order by 负债合计 desc limit 1
- prompt
- normalize
- prompt
根据查询结果回答问题。【查询结果】{'公司名称': ['华能国际电力股份有限公司'], '负债合计': ['296730398479']}【问题】哪家上市公司,在北京注册,2020年总负债最高?金额为?【回答】
- response
华能国际电力股份有限公司在2020年总负债最高,金额为296730398479元。
- prompt