乐趣区

关于人工智能:使用GPT4生成训练数据微调GPT35-RAG管道

OpenAI 在 2023 年 8 月 22 日发表,当初能够对 GPT-3.5 Turbo 进行微调了。也就是说,咱们能够自定义本人的模型了。而后 LlamaIndex 就公布了 0.8.7 版本,集成了微调 OpenAI gpt-3.5 turbo 的性能

也就是说,咱们当初能够应用 GPT- 4 生成训练数据,而后用更便宜的 API(gpt-3.5 turbo)来进行微调,从而取得更精确的模型,并且更便宜。所以在本文中,咱们将应用 NVIDIA 的 2022 年 SEC 10- K 文件来认真钻研 LlamaIndex 中的这个新性能。并且将比拟 gpt-3.5 turbo 和其余模型的性能。

RAG vs 微调

微调到底是什么? 它和 RAG 有什么不同? 什么时候应该应用 RAG 和微调? 以下两张总结图:

这两个图像总结了它们根本的差异,为咱们抉择正确的工具提供了很好的领导。

然而,RAG 和微调并不互相排挤。将两者以混合形式利用到同一个应用程序中是齐全可行的。

RAG/ 微调混合办法

LlamaIndex 提供了在 RAG 管道中微调 OpenAI gpt-3.5 turbo 的具体指南。从较高的档次来看,微调能够实现下图中形容的要害工作:

  1. 应用 DatasetGenerator 实现评估数据集和训练数据集的数据生成自动化。
  2. 在微调之前,应用第 1 步生成的 Eval 数据集对根本模型 gpt-3.5-turbo 进行 Eval。
  3. 构建向量索引查问引擎,调用 gpt- 4 依据训练数据集生成新的训练数据。
  4. 回调处理程序 OpenAIFineTuningHandler 收集发送到 gpt- 4 的所有音讯及其响应,并将这些音讯保留为.jsonl (jsonline)格局,OpenAI API 端点能够应用该格局进行微调。
  5. OpenAIFinetuneEngine 是通过传入 gpt-3.5-turbo 和第 4 步生成的 json 文件来结构的,它向 OpenAI 发送一个微调调用,向 OpenAI 发动一个微调作业申请。
  6. OpenAI 依据您的要求创立微调的 gpt-3.5-turbo 模型。
  7. 通过应用从第 1 步生成的 Eval 数据集来对模型进行微调。

简略的总结来说就是,这种集成使 gpt-3.5 turbo 可能对 gpt- 4 训练的数据进行微调,并输入更好的响应。

步骤 2 和 7 是可选的,因为它们仅仅是评估根本模型与微调模型的性能。

咱们上面将演示这个过程,在演示时,应用 NVIDIA 2022 年的 SEC 10- K 文件。

次要性能点

1、OpenAIFineTuningHandler

这是 OpenAI 微调的回调处理程序,用于收集发送到 gpt- 4 的所有训练数据,以及它们的响应。将这些音讯保留为.jsonl (jsonline)格局,OpenAI 的 API 端点能够应用该格局进行微调。

2、OpenAIFinetuneEngine

微调集成的外围是 OpenAIFinetuneEngine,它负责启动微调作业并取得一个微调模型,能够间接将其插件到 LlamaIndex 工作流程的其余部分。

应用 OpenAIFinetuneEngine, LlamaIndex 形象了 OpenAI api 进行微调的所有实现细节。包含:

  • 筹备微调数据并将其转换为 json 格局。
  • 应用 OpenAI 的文件上传微调数据。创立端点并从响应中获取文件 id。
  • 通过调用 OpenAI 的 FineTuningJob 创立一个新的微调作业。创立端点。
  • 期待创立新的微调模型,而后应用新的微调模型。

咱们能够应用 OpenAIFinetuneEngine 的 gpt- 4 和 OpenAIFineTuningHandler 来收集咱们想要训练的数据,也就是说咱们应用 gpt- 4 的输入来训练咱们的自定义的 gpt-3.5 turbo 模型

 from llama_index import ServiceContext
 from llama_index.llms import OpenAI
 from llama_index.callbacks import OpenAIFineTuningHandler
 from llama_index.callbacks import CallbackManager
 
 # use GPT-4 and the OpenAIFineTuningHandler to collect data that we want to train on.
 finetuning_handler = OpenAIFineTuningHandler()
 callback_manager = CallbackManager([finetuning_handler])
 
 gpt_4_context = ServiceContext.from_defaults(llm=OpenAI(model="gpt-4", temperature=0.3),
     context_window=2048,  # limit the context window artifically to test refine process
     callback_manager=callback_manager,
 )
 
 # load the training questions, auto generated by DatasetGenerator
 questions = []
 with open("train_questions.txt", "r") as f:
     for line in f:
         questions.append(line.strip())
 
 from llama_index import VectorStoreIndex
 
 # create index, query engine, and run query for all questions
 index = VectorStoreIndex.from_documents(documents, service_context=gpt_4_context)
 query_engine = index.as_query_engine(similarity_top_k=2)
 
 for question in questions:
     response = query_engine.query(question)
 
 # save fine-tuning events to jsonl file
 finetuning_handler.save_finetuning_events("finetuning_events.jsonl")
 
 from llama_index.finetuning import OpenAIFinetuneEngine
 
 # construct OpenAIFinetuneEngine 
 finetune_engine = OpenAIFinetuneEngine(
     "gpt-3.5-turbo",
     "finetuning_events.jsonl"
 )
 
 # call finetune, which calls OpenAI API to fine-tune gpt-3.5-turbo based on training data in jsonl file.
 finetune_engine.finetune()
 
 # check current job status
 finetune_engine.get_current_job()
 
 # get fine-tuned model
 ft_llm = finetune_engine.get_finetuned_model(temperature=0.3)

须要留神的是,微调函数须要工夫,对于我测试的 169 页 PDF 文档,从在 finetune_engine 上启动 finetune 到收到 OpenAI 的电子邮件告诉我新的微调工作曾经实现,这段时间大概花了 10 分钟。上面的电子邮件如下。

在收到该电子邮件之前,如果在 finetune_engine 上运行 get_finetuned_model,会失去一个谬误,提醒微调作业还没有筹备好。

3、ragas 框架

ragas 是 RAG Assessment 的缩写,它提供了基于最新钻研的工具,使咱们可能深刻理解 RAG 管道。

ragas 依据不同的维度来掂量管道的体现: 忠实度、答案相关性、上下文相关性、上下文召回等。对于这个演示应用程序,咱们将专一于掂量忠实度和答案相关性。

忠实度: 掂量给定上下文下生成的答案的信息一致性。如果答案中有任何不能从上下文推断进去的主张,则会被扣分。

答案相关性: 指答复间接针对给定问题或上下文的水平。这并不思考答案的真实性,而是惩办给出问题的冗余信息或不残缺答案。

在 RAG 管道中利用 ragas 的具体步骤如下:

  • 收集一组 eval 问题 (起码 20 个,在咱们的例子中是 40 个) 来造成咱们的测试数据集。
  • 在微调之前和之后应用测试数据集运行管道。每次应用上下文和生成的输入记录提醒。
  • 对它们中的每一个运行 ragas 评估以生成评估分数。
  • 比拟分数就能够晓得微调对性能的影响有多大。

代码如下:

 contexts = []
 answers = []
 
 # loop through the questions, run query for each question
 for question in questions:
     response = query_engine.query(question)
     contexts.append([x.node.get_content() for x in response.source_nodes])
     answers.append(str(response))
 
 from datasets import Dataset
 from ragas import evaluate
 from ragas.metrics import answer_relevancy, faithfulness
 
 ds = Dataset.from_dict(
     {
         "question": questions,
         "answer": answers,
         "contexts": contexts,
     }
 )
 
 # call ragas evaluate by passing in dataset, and eval categories
 result = evaluate(ds, [answer_relevancy, faithfulness])
 print(result)
 
 import pandas as pd
 
 # print result in pandas dataframe so we can examine the question, answer, context, and ragas metrics
 pd.set_option('display.max_colwidth', 200)
 result.to_pandas()

评估后果

最初咱们能够比拟一下微调前后的 eval 后果。

根本 gpt-3.5-turbo 的评估请看上面的截图。answer_relevance 的评分不错,但忠实度有点低。

通过微调,模型的性能在答案相关性中略有进步,从 0.7475 进步到 0.7846,进步了 4.96%。

应用 gpt- 4 生成训练数据对 gpt-3.5 turbo 进行微调的确看到了改善。

一些乏味的发现

1、对小文档进行微调会导致性能降落

最后用一个小的 10 页 PDF 文件进行了试验,我发现 eval 后果与根本模型相比性能有所降落。而后又持续测试了两轮,后果如下:

第一轮根本模型:Ragas_score: 0.9122, answer_relevance: 0.9601, faithfulness: 0.8688

第一轮微调模型:Ragas_score: 0.8611, answer_relevance: 0.9380, faithfulness: 0.7958

第二轮根本模型:Ragas_score: 0.9170, answer_relevance: 0.9614, faithfulness: 0.8765

第二轮微调模型:Ragas_score: 0.8891, answer_relevance: 0.9557, faithfulness: 0.8313

所以换衣小文件可能是微调模型比根本模型体现更差的起因。所以应用了 NVIDIA 长达 169 页的 SEC 10- K 文件。对下面的后果做了一个很好的试验——通过微调的模型体现得更好,忠实度减少了 4.96%。

2、微调模型的后果不统一

起因可能是数据的大小和评估问题的品质

只管 169 页文档的微调模型取得了预期的评估后果,但我对雷同的评估问题和雷同的文档运行了第二轮测试,后果如下:

第二轮根本模型:Ragas_score: 0.8874, answer_relevance: 0.9623, faithfulness: 0.8233

第二轮微调模型:Ragas_score: 0.8218, answer_relevance: 0.9498, faithfulness: 0.7242

是什么导致了 eval 后果的不统一?

数据大小很可能是导致不统一的微调计算结果的根本原因之一。“至多须要 1000 个微调数据集的样本。”这个演示利用显然没有那么多的微调数据集。

另一个根本原因很可能在于数据品质,也就是 eval 问题的品质。我将 eval 后果打印到一个 df 中,列出了每个问题的问题、答案、上下文、answer_relevance 和忠实度。

通过目测,有四个问题在忠实度中得分为 0。而这些答案在文件中没有提供上下文。这四个问题品质很差,所以我从 eval_questions.txt 中删除了它们,从新运行了评估,失去了更好的后果:

根本模型 eval:Ragas_score: 0.8947, answer_relevance: 0.9627, faithfulness: 0.8356

微调模型 eval:Ragas_score: 0.9207, answer_relevance: 0.9596, faithfulness: 0.8847

能够看到在解决了这四个品质差的问题后,微调版的回升了 5.9%。所以评估问题和训练数据须要更多的调整,以确保良好的数据品质。这的确是一个十分乏味的摸索畛域。

3、微调的老本

通过微调的 gpt-3.5-turbo 的价格高于根本模型的。咱们来看看根本模型、微调模型和 gpt- 4 之间的老本差别:

比拟 gpt-3.5-turbo (4K 环境)、微调 gpt-3.5-turbo 和 gpt-4 (8K 环境),能够看到:

  • 通过微调的 gpt-3.5 turbo 在输出和输入应用方面的老本是根本模型的 8 倍。
  • 对于输出应用,Gpt- 4 的老本是微调模型的 2.5 倍,对于输入应用则是 3.75 倍。
  • 对于输出应用,Gpt- 4 的老本是根本模型的 20 倍,对于输入应用状况是 30 倍。
  • 另外应用微调模型会产生 $0.008/1K 令牌的额定老本。

总结

本文摸索了 LlamaIndex 对 OpenAI gpt-3.5 turbo 微调的新集成。咱们通过 NVIDIA SEC 10- K 归档剖析的 RAG 管道,测试根本模型性能,而后应用 gpt- 4 收集训练数据,创立 OpenAIFinetuneEngine,创立了一个新的微调模型,测试了它的性能,并将其与根本模型进行了比拟。

能够看到,因为 GPT4 和 gpt-3.5 turbo 的微小老本差别(20 倍),在应用微调后,咱们能够失去近似的成果,并且还能节俭不少老本(2.5 倍)

如果你对这个办法感兴趣,源代码在这里:

https://avoid.overfit.cn/post/0a4ae4d87e69457dbd899d7a9af07237

作者:Wenqi Glantz

退出移动版