AIGC(3)FinGPT:开源金融LLM模型

AIGC(3)FinGPT:开源金融LLM模型

一、背景

大型语言模型(LLM)已经显示出彻底改变不同领域自然语言处理任务的潜力,激发了人们对金融的极大兴趣。访问高质量的金融数据是金融LLM(FinLLM)面临的第一个挑战。虽然像BloombergGPT这样的专有模型利用了它们独特的数据积累,但这种特权访问需要一种开源替代方案来使互联网规模的金融数据民主化。 在本文中,我们提出了一个面向金融领域的开源大型语言模型FinGPT。与专有模型不同,FinGPT采用以数据为中心的方法,为研究人员和从业者提供可访问和透明的资源来开发他们的FinLLM。我们强调了自动数据管理管道和轻量级低秩适配技术在构建FinGPT中的重要性。此外,我们展示了几个潜在的应用程序作为用户的垫脚石,例如机器人咨询、算法交易和低代码开发。通过开源AI4Finance社区内的合作努力,FinGPT旨在刺激创新,使FinLLM民主化,并释放开放金融的新机遇。

论文地址:

Github地址:

二、 为什么需要FinGPT

1、金融是高度动态的。BloombergGPT使用金融和通用数据源的混合数据集重新训练LLM,这太昂贵了(1.3MGPU小时,成本约为500万美元)。每月或每周重新训练LLM模型成本很高,因此轻量级适应在金融领域非常有利。FinGPT可以快速微调以与新数据保持一致,而不是随着金融环境的每一次重大变化从头开始重新训练模型,这是一个昂贵而耗时的过程(适应成本大幅下降,估计每次训练不到300美元)。

2、互联网规模的财务数据民主化至关重要,这应该允许使用自动数据管理管道进行及时更新(每月或每周更新)。但是,BloombergGPT拥有特权数据访问和API。FinGPT提供了一个更容易获得的替代方案。它优先考虑轻量级适应,利用一些最好的开源LLM的优势,然后将财务数据输入这些LLM并为财务语言建模进行微调。

3、关键技术是BloombergGPT中缺少的“RLHF(从人类反馈中强化学习)”。RLHF使LLM模型能够学习个人偏好(风险厌恶水平、投资习惯、个性化机器人顾问等),这是ChatGPT和GPT4的“秘密”。

三、FinGPT 架构

FinNLP为所有对金融领域的LLM和NLP感兴趣的人提供了一个框架。在这里,我们为金融领域的LLM培训和微调提供了完整的管道。完整的架构如下图所示。详细代码和介绍可以在这里找到。

3.1架构

整个架构由4个部分组成:

  • 第一部分是 数据源 ,在这里,我们从互联网上收集历史和流媒体数据。
  • 第二部分是 数据工程 ,在这里我们会对数据进行清洗,标记化处理和提示工程。
  • 第三部分是 大语言模型(LLMs) 。在这里,我们可以以不同的方式使用LLMs。我们不仅可以使用收集到的数据来训练我们自己的 轻量级微调模型 ,还可以使用这些数据和 训练好的模型 LLM API 来支持我们的应用程序。
  • 最后一部分是 应用程序 部分,我们可以使用数据和LLMs来制作许多有趣的应用程序

3.2数据源

1. 新闻

平台 数据类型 相关市场 指定公司 时间范围 数据源类型 限制条件 文档数量(万) 支持情况
雅虎 金融新闻 美国股票 时间范围 官方 N/A 1,500+
路透社 金融新闻 美国股票 × 时间范围 官方 N/A 1,500+
新浪 金融新闻 中国股票 × 时间范围 官方 N/A 2,000+
东方财富 金融新闻 中国股票 时间范围 官方 N/A 1,000+
第一财经 金融新闻 中国股票 时间范围 官方 N/A 500+ 即将
央视 政府新闻 中国股票 × 时间范围 第三方 N/A 4
美国主流媒体 金融新闻 美国股票 时间范围 第三方 账户 (免费) 3,200+
中国主流媒体 金融新闻 中国股票 × 时间范围 第三方 ¥500/年 3000+
  • FinGPT可能比Bloomberg的文档数目更少,但我们是在同一个数量级上。

2. 社交媒体

平台 数据类型 相关市场 指定公司 范围类型 来源类型 限制 文档 (1e4) 支持
Twitter 推文 美国股票 时间范围 官方 N/A 18,000+
StockTwits 推文 美国股票 最新 官方 N/A 160,000+
Reddit (wallstreetbets) 帖子 美国股票 × 最新 官方 N/A 9+
微博 推文 中国股票 时间范围 官方 Cookies 1,400,000+
微博 推文 中国股票 最新 官方 N/A 1,400,000+
  • BloomberGPT 中,他们 不收集社交媒体数据 ,但我们认为 公众舆论是干扰股票市场的最重要因素之一

3. 公司公告

平台 数据类型 相关市场 指定公司 范围类型 数据来源 限制 文档数 (1e4) 支持情况
巨潮网 (官方) 文本 中国股票 时间范围 官方 N/A 2,790+
美国证监会 (官方) 文本 美国股票 时间范围 官方 N/A 1,440+
  • 由于我们从不同的股票市场收集数据,因此我们比Bloomberg GPT有更多的申报文档。

4. 趋势

平台 数据类型 相关市场 数据源 指定公司 范围类型 源类型 限制
谷歌趋势 指数 美国股票 Google Trends 日期范围 官方 N/A
百度指数 指数 中国股票 即将推出 - - - -


5. 数据集

数据源 类型 股票 日期 可用性
AShare 新闻 3680 2018-07-01 到 2021-11-30
stocknet-dataset 推文 87 2014-01-02 到 2015-12-30
CHRNN 推文 38 2017-01-03 到 2017-12-28


3.3模型

在数据中心的自然语言处理领域,我们不需要从头开始训练模型。我们只需要调用API和进行轻量级的微调。左边是一些可能会用到的LLM APIs,中间是我们可能用来进行微调的模型,右边是一些微调方法。

1. 微调:Tensor Layers (LoRA)

  • 在FinGPT中,我们使用新的金融数据集对预训练的LLM进行微调。高质量的标记数据是许多成功的LLM(包括ChatGPT)的最重要的关键之一。
  • 然而,这些高质量的标记数据通常非常昂贵和耗时,并且我们可能需要金融专家的帮助。
  • 如果我们的目标是使用LLM分析与金融相关的文本数据并帮助量化交易,为什么不让市场为我们做标记呢?
  • 因此,在这里,我们使用每个新闻相关的股票价格变化百分比作为输出标签,我们使用阈值将标签分成三组(积极的,消极的和中立的),并使用它们和新闻情感的标签。
  • 相应地,在提示工程师部分,我们还要求模型选择其中一个正面的,负面的和中性的作为输出,以便我们充分利用预训练信息。
  • 通过使用LoRA,我们可以将可训练参数减少从6.17B到3.67M。
  • 如表格所示,与chatGLM相比,FinGPT可以在多个指标上实现大幅改善。然而,直接将我们的模型用于量化交易可能是不合适的。由于大多数新闻标题都是中性的,LLMs的大多数原始输出都是中性的,因此LLMs在积极和消极的标签上表现不佳,而这些标签可能对于量化交易是有用的。
  • 然而,在微调之后,我们已经见证了在预测积极和消极标签方面的巨大改进。
  • 这也是为什么该模型可以实现积极的交易结果的原因。

2. 微调:强化学习在股价上的应用 (RLSP)

同样地,我们可以使用股价上的强化学习(RLSP)来替换ChatGPT中使用的人类反馈上的强化学习。

3.4应用

1. 智能投资顾问

  • ChatGPT可以像专业人士一样进行投资建议。
  • 在这个例子中,苹果的 股价上涨 与ChatGPT分析新闻的 预测相符


2. 量化交易

  • 我们还可以使用新闻、社交媒体推文或者公司公告来 构建情感因子 ,右侧的部分是由Twitter推文和ChatGPT信号产生的交易结果,数据来自于一个称为 stocknet-dataset 的数据集。
  • 正如您从图片中所看到的,由ChatGPT生成的交易信号 非常出色 ,我们甚至可以 仅通过根据Twitter情感因子交易而获得良好的结果
  • 因此,我们可以通过 结合价格因素 来获得更好的结果。

3. 低代码开发

  • 我们可以使用LLMs的帮助来编写代码。
  • 右侧显示了我们如何 快速高效地 开发我们的因子和其他代码。


四、FinGPT Demos

  • FinGPT V1
    • Let's train our own FinGPT in Chinese Financial Market with ChatGLM and LoRA (Low-Rank Adaptation)
  • FinGPT V2
    • Let's train our own FinGPT in American Financial Market with LLaMA and LoRA (Low-Rank Adaptation)

这里以 FinGPT V1 中国财经分析的.ipynb为例:

对中国财经的新闻做Embedding文本分析(积极或消极):

程序利用此模型一个运行得到特斯拉最近股票数据效果:

import gradio as gr
import pandas as pd
from pandas_datareader import data as pdr
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import yfinance as yfin
import openai
yfin.pdr_override()
# Set your API key
openai.api_key = "set your key here"
preset = "You now act as an agent to help me transform user's input to a formatted dictionary. The user should only request for financial stock market data. If it is not the case, you return a message 'ERROR'. If the user indeed ask for financial data, for example, give me the stock of apple in recent 60 days. Then you return a dictionary {'stock': 'AAPL', time: 60}.\n If no date information is found, then you set it by default to 60\n"
def generate_response(prompt, model="text-davinci-003", max_tokens=100):
    response = openai.Completion.create(
        engine=model,
        prompt=prompt,
        max_tokens=max_tokens,
        n=1,
        stop=None,
        temperature=0.5,
    message = response.choices[0].text.strip()
    return message
def plot_stock_gpt(prompt):
    prompt_to_gpt = preset + prompt
    response = generate_response(prompt_to_gpt)
    # try:
    input_dict = eval(response)
    #     if (type(input_dict) != dict):
    #         gr.Error("invalid input! Try it again!")
    # except:
    #     gr.Error("invalid input!")
    return plot_stock(input_dict['stock'], input_dict['time'])
def plot_stock(stock_name, time_period):
    # Fetch stock data
    end_date = pd.to_datetime('today')
    start_date = end_date - pd.to_timedelta(time_period, unit='D')
    stock_data = pdr.get_data_yahoo(stock_name, start_date.strftime('%Y-%m-%d'), end_date.strftime('%Y-%m-%d'))
    # Plot stock data
    fig, ax = plt.subplots()
    ax.plot(stock_data['Close'])
    ax.set_xlabel('Date')
    ax.set_ylabel('Close Price')
    ax.set_title(f'{stock_name} Stock Prices for the Last {time_period} Days')
    ax.grid()
    # Save plot as an image
    fig.savefig('stock_plot.png', bbox_inches='tight')
    return 'stock_plot.png'
# Define Gradio input and output components
# inputs = [
#     gr.Textbox(label="Stock Name (e.g. AAPL)"),
#     gr.Slider(minimum=1, maximum=365, label="Time Period (Days)")
inputs = [gr.Textbox(label="input your requirements!")]
output = gr.Image(label="Stock Price Plot")
# Create the Gradio interface
iface = gr.Interface(
    fn=plot_stock_gpt,
    inputs=inputs,
    outputs=output,
    title="Stock Price Plotter",