一、方案简介:本方案以检索增强上下文学习(RAG-ICL)为核心,以Qwen14B-Finance(后文简称为Qwen大模型)为主要工具,进行问题分类与回答。
二、技术路线:
1.数据预处理
1.1. Text 文件:使用正则表达式抽取公司名称。将举办方提供的每个text格式招股书文件分为1000字每段,相邻两段具有200字重叠的片段,使用Qwen大模型的tokenizer进行词频统计备用。
1.2. PDF文件:使用pdfplumber 包进行表格抽取,主要补充了举办方提供的text文件中缺失的表格信息。
1.3. Questions:将1000个Questions中不含有公司名称的问题(即潜在的使用SQL查询进行回答
的问题)使用tokenizer统计词频,两两计算余弦相似度后进行谱聚类,类别个数75,可以看到每类问题基本具有相同格式。从每类问题中随机选择2个,构成RAG-ICL的样本库,编写并校对
SQL语句和回答。
2.工作流
2.1. 新问题进入,通过20个示例问题-分类结果构成的prompt,利用Qwen大模型分为SQL查询和文本理解两类。
对于SQL查询问题,新问题使用Qwen大模型的tokenizer统计词频,与RAG-ICL样本库中的问题比较,选取最相似的2-4个问题-SQL语句对加入prompt,利用Qwen大模型做“填空与替换”,生成高可解释性与可靠性的SQL查询。运行查询,利用Qwen大模型将查询结果和问题生成为答案。对于文本理解问题,新问题使用Qwen大模型的tokenizer统计词频,与分段的Text+表格文件计算
总词频加权的余弦相似度,选出与问题最相关的20个文本片段,利用他们生成答案。
三、项目亮点:
1.充分利用了Qwen大模型的tokenizer部分包含的金融语境信息,在外来embedding检索效果较差的情况下,不训练新的embedding,达到了较好的检索效果。
- RAG-ICL为核心的方法使得我们可以在仅标注较少数据集(不到200条),不精调模型的情况下快速得到一个效果较好的问答系统,同时本方案具有较高的可解释性(只需修改RAG-ICL样本库中的例子就可以修改生成效果),对于可见的新问题类型也无需调整模型,只需补充RAG-ICL 样本即可。
三、项目亮点:
Intel 技术架构使用:
1. 概述
本技术方案旨在通过集成Intel® Extension for Transformers优化库,部署一个高效的金融大模型。该模型将用于处理金融领域的复杂数据分析,包括风险管理、投资决策支持和客户服务等。
2. 目标
- 提高数据处理能力:利用Transformer架构的优势,提高金融数据的处理速度和准确性。
- 增强风险管理:通过模型的预测能力,提前识别和评估潜在的金融风险。
- 优化投资决策:提供基于数据驱动的投资建议,辅助投资决策过程。
- 提升客户服务体验:通过自然语言处理技术,改善客户服务的响应速度和质量。
3. 技术架构
3.1 系统组件
- 数据采集层:负责收集金融市场数据、交易数据和客户数据。
- 模型层:集成Intel® Extension for Transformers,部署金融大模型。
- 应用层:提供风险管理、投资分析和客户服务等应用。
- 用户界面:为用户提供交互界面,包括风险评估工具、投资建议和客户支持。
3.2 技术栈
- 编程语言:Python
- 框架:TensorFlow/PyTorch
- 优化库:Intel® Extension for Transformers
- 数据库:Oracle/SQL Server
4. 部署步骤
4.1 环境准备
- 安装Python环境和必要的库。
- 配置数据库和后端服务器。
4.2 模型集成
- 模型训练:使用金融数据集训练金融大模型。
- 模型优化:集成Intel® Extension for Transformers,针对Transformer架构进行特定优化。
- 模型部署:将训练好的模型部署到服务器上。
4.3 性能测试
- 进行压力测试和性能测试,确保系统在高并发情况下的稳定性和响应速度。
- 根据测试结果调整系统配置和模型参数。
4.4 用户界面开发
- 设计用户友好的前端界面,确保用户能够轻松地与系统交互。
- 实现前端与后端的无缝对接。
4.5 系统上线
- 完成所有测试后,将系统部署到生产环境。
- 监控系统运行状态,确保系统的稳定性和性能。
5. 维护与优化
- 定期更新:定期更新模型和系统,以适应新的数据和用户需求。
- 性能监控:持续监控系统性能,及时发现并解决性能瓶颈。
- 用户反馈:收集用户反馈,不断优化用户体验。
6. 风险评估
- 数据安全:确保用户数据的安全和隐私。
- 系统稳定性:确保系统在高负载下的稳定性。
7. 结论
通过集成Intel® Extension for Transformers,我们的金融大模型将能够更高效地处理金融数据,提供准确的风险评估和投资建议,从而提升金融决策的质量和客户服务的效率。
G8i 阿里云实例使用配置:
实现细节:
import csv
import pandas as pd
import numpy as np
import sqlite3
import re
import copy
from langchain.utilities import SQLDatabase
from modelscope import AutoModelForCausalLM, AutoTokenizer, snapshot_download
from modelscope import GenerationConfig
db0 = SQLDatabase.from_uri("sqlite:////tcdata/bs_challenge_financial_14b_dataset/dataset/博金杯比赛数据.db", sample_rows_in_table_info=0)
dbd0 = db0.table_info
db2 = SQLDatabase.from_uri("sqlite:////tcdata/bs_challenge_financial_14b_dataset/dataset/博金杯比赛数据.db", sample_rows_in_table_info=2)
dbd2 = db2.table_info
list1 = dbd2.split('CREATE TABLE')
for cyc_piece in range(len(list1)):
list1[cyc_piece] = 'CREATE TABLE' + list1[cyc_piece]
for piece in list1:
for word in table_name_list:
if word in piece:
table_info_dict[word] = piece
question_csv_file_dir = "/app/intermediate/A01_question_classify.csv"
question_csv_file = pd.read_csv(question_csv_file_dir,delimiter = ",",header = 0)
model_dir = '/tcdata/models/Tongyi-Finance-14B-Chat'
# Note: The default behavior now has injection attack prevention off.
tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="cuda:0", trust_remote_code=True, bf16=True).eval()
model.generation_config = GenerationConfig.from_pretrained(model_dir,
trust_remote_code=True,
temperature = 0.0001,
top_p = 1,
do_sample = False,
seed = 1234)
print('B01_model_loaded')
deny_token_list = list()
for word in deny_list:
temp_tokens = tokenizer(word)
temp_tokens = temp_tokens['input_ids']
deny_token_list = deny_token_list + temp_tokens
def get_prompt_v33(question,index_list):
Examples = '以下是一些例子:'
for index in index_list:
Examples = Examples + "问题:" + example_question_list[index] + '\n'
Examples = Examples + "SQL:" + example_sql_list[index] + '\n'
impt2 = """
你是一个精通SQL语句的程序员。
我会给你一个问题,请按照问题描述,仿照以下例子写出正确的SQL代码。
"""
impt2 = impt2 + Examples
impt2 = impt2 + "问题:" + question + '\n'
impt2 = impt2 + "SQL:"
return impt2
SQL_examples_file_dir = "/app/data/files/ICL_EXP.csv"
SQL_examples_file = pd.read_csv(SQL_examples_file_dir,delimiter = ",",header = 0)
example_employ_list = list()
for cyc in range(len(SQL_examples_file)):
example_employ_list.append(0)
example_question_list = list()
example_table_list = list()
example_sql_list = list()
example_token_list = list()
for cyc in range(len(SQL_examples_file)):
example_question_list.append(SQL_examples_file[cyc:cyc+1]['问题'][cyc])
example_sql_list.append(SQL_examples_file[cyc:cyc+1]['SQL'][cyc])
temp_tokens = tokenizer(SQL_examples_file[cyc:cyc+1]['问题'][cyc])
temp_tokens = temp_tokens['input_ids']
temp_tokens2 = [x for x in temp_tokens if x not in deny_token_list]
example_token_list.append(temp_tokens2)
g = open('/app/intermediate/question_SQL_V6.csv', 'w', newline='', encoding = 'utf-8-sig')
csvwriter = csv.writer(g)
csvwriter.writerow(['问题id','问题','SQL语句','prompt'])
pattern1 = r'\d{8}'
for cyc in range(len(question_csv_file)):
if cyc % 50 == 0:
print(cyc)
response2 = 'N_A'
prompt2 = 'N_A'
if question_csv_file['分类'][cyc] == 'SQL' and cyc not in [174]:
temp_question = question_csv_file[cyc:cyc+1]['问题'][cyc]
date_list = re.findall(pattern1,temp_question)
temp_question2_for_search = temp_question
for t_date in date_list:
temp_question2_for_search.replace(t_date,' ')
temp_tokens = tokenizer(temp_question2_for_search)
temp_tokens = temp_tokens['input_ids']
temp_tokens2 = [x for x in temp_tokens if x not in deny_token_list]
temp_tokens = temp_tokens2
#计算与已有问题的相似度
similarity_list = list()
for cyc2 in range(len(SQL_examples_file)):
similarity_list.append(len(set(temp_tokens) &set(example_token_list[cyc2]))/ (len(set(temp_tokens))+len(set(example_token_list[cyc2])) ))
#求与第X个问题相似的问题
t = copy.deepcopy(similarity_list)
# 求m个最大的数值及其索引
max_number = []
max_index = []
for _ in range(n):
number = max(t)
index = t.index(number)
t[index] = 0
max_number.append(number)
max_index.append(index)
t = []
temp_length_test = ""
short_index_list = list()
for index in max_index:
temp_length_test_1 = temp_length_test
temp_length_test = temp_length_test + example_question_list[index]
temp_length_test = temp_length_test + example_sql_list[index]
if len(temp_length_test) > 2300:
break
short_index_list.append(index)
prompt2 = get_prompt_v33(question_csv_file['问题'][cyc],short_index_list)
response2, history = model.chat(tokenizer, prompt2, history=None)
else:
pass
csvwriter.writerow([str(question_csv_file[cyc:(cyc+1)]['问题id'][cyc]),
str(question_csv_file[cyc:(cyc+1)]['问题'][cyc]),
response2,prompt2])