# 训如何训练精通特定领域的大语言模型

By [Yooma](https://paragraph.com/@yooma) · 2023-05-16

---

前言
--

2022年11月ChatGPT发布了3.5版本，迅速成为了炙手可热的大语言模型。短时间内，网络上涌现出了许多基于ChatGPT的想法和应用。

ChatGPT展现了其毋庸置疑的强大能力，同时我们发现它在特定领域的能力依然不够突出。因此我们在思考：能否基于 ChatGPT 训练出一个专精于特定领域大语言模型，使之在该领域的认知更深入、更精准。

以 Metaverse 领域为例，在[MetaCat](https://www.metacat.world/learn?type=articles)官网中有大量 Metaverse 领域研究的重要文章，因此，我们在寻找一种方法能够将这些文章所传达观点、思维方式赋予类似 ChatGPT 的大语言模型，使之成为一个像 MetaCat 一样具备 Metaverse 领域深度见解的大语言模型，以下是探索过程。

调研：寻找训练出专属数据的“ChatGPT”的方式
-------------------------

我们开始时寻找是否已经有一个模型或者通过对现有模型的训练可以满足需求。通过查阅文档和进行初步的调研，预选了三种方式：

*   [LlamaIndex](https://gpt-index.readthedocs.io/en/latest/)（原GPT-Index）
    
*   [GPT微调](https://platform.openai.com/docs/guides/fine-tuning)（Fine-tuning）
    
*   BERT微调
    

### LlamaIndex：

简单了解了一下它的作用和工作原理

LlamaIndex是一种面向大规模文本数据集的索引技术，可为结构化和非结构化数据提供索引支持。它将庞大的文本数据集划分为多个小块，并通过索引表快速定位目标文档，以加快检索和处理速度。

在进一步调研之后，我们决定放弃采用LlamaIndex方案。最初我们的期望是让一个模型学习所有的文章，并且在提问时能够对这些知识进行总结和归纳。由于文章的连贯性，这可能需要对整篇文章进行一次性的学习，而LlamaIndex则是通过对内容进行分块索引的方式来工作的，不符合我们的需求。它适用于基于**文档内容**的对话场景。

接下来，我们将继续探索GPT微调和BERT这两种方式，以找到最适合我们目标的训练方法。

**GPT微调：**

GPT微调（Fine-tuning）是指在GPT模型的基础上，利用特定的数据集对其进行进一步的训练和调整，以适应特定的任务和应用场景。微调的目标是在已经训练好的模型上进行少量的调整，从而使模型在特定任务上表现更出色。

在微调过程中，我们使用 prompt 和 completion 文本对的格式作为输入数据。例如：

    {"prompt":"元宇宙和互联网有什么区别？","completion":" 元宇宙和互联网不同，互联网是一个“二维”的网络世界，而元宇宙则是一个“三维”的虚拟世界。"}
    

因此，我们需要将文章的内容进行拆分和总结，生成多个文本对，然后使用这些文本对进行微调。值得注意的是，**文本对中的信息质量将直接影响微调后模型的质量**。

通过利用GPT模型获取每个部分的文本对，并对其进行总结，我们可以基于这些文本对对模型进行微调，这样的微调过程将使模型对特定领域的理解和生成能力得到显著提升。

### BERT微调

Google的BERT（Bidirectional Encoder Representations from Transformers），它与GPT都是基于Transformer网络架构。但与GPT不同的是BERT 是一个双向的预训练模型，它通过在大规模无标签数据上进行预训练，学习到句子中各个位置的上下文表示。

BERT主要用于自然语言理解任务，如文本分类、情感分析、命名实体识别等。 它可以理解文本中的语义和关系，并能够找出语句之间的联系

相比之下GPT 则通常用于生成式任务，如文本生成、对话生成等。

**这样看下来，通过GPT微调可能会实现我们最初的需求，接着让我们来实现并总结评估一下该过程中遇到的问题。**

_注：什么是单向预训练模型和双向预训练模型？_

_单向预训练模型：单向模型只能按照给定的顺序阅读文本，类似于我们在阅读时从左到右的方式。这意味着模型只能看到当前单词之前的上下文信息，而无法预测后面的单词。_

_双向预训练模型：双向模型可以同时考虑当前单词之前和之后的上下文信息，类似于我们在阅读时可以回头查看前面的内容，然后再继续往后读。这样的模型可以更好地理解整个句子的语义和上下文关系。_

实现
--

[https://github.com/themetacat/ChatGPT\_Fine\_Tuning](https://github.com/themetacat/ChatGPT_Fine_Tuning)

_注：由于“gpt-3.5-turbo”模型不支持微调，GPT-4 api并未直接开放使用，需要_[_申请加入候补名单_](https://openai.com/waitlist/gpt-4-api)_所以我们选用GPT-3模型，_

1.  **首先获取到文章的内容，然后对其结构，内容进行处理**
    
2.  **通过 “gpt-3.5-turbo”获得问答对数据**
    
3.  **将数据整合上传**
    
4.  **根据上传的数据创建微调模型**
    
5.  **对模型进行质量评估**
    

我们可以通过GitHub获取到文章[content.txt](https://github.com/themetacat/ChatGPT_Fine_Tuning/blob/main/content.txt)，已经对其进行简单的结构化和内容处理。

（_处理原因：原始文章的段落结构可能不代表一个完整的内容段落。例如，第一段可能是提问问题，而第二段则是对问题的解答，这些应该放在同一个段落中。此外，如果文章是由某个组织撰写的，并且内容中出现了大量的"我们"等词语，需要将这些词替换为该组织的名称，以使GPT生成更准确的问题和答案。_）

    content.txt:
    似乎有许多新组织出现，在大型行业参与者的支持下，联合构建元宇宙。然后是 M3，一个由艺术家和开源黑客组成的草根社区，他们也想要参与构建开放元宇宙，并且在同一个章程的指导下已经运营了将近 4 年。
    
    M3代表 Metaverse Makers。我们无法决定第三个 M 是什么，所以发挥你的想象力吧。它是 JanusXR、AnarchyArcade、Webaverse 和 Hyperfy 等创新项目背后思想的家园。自 2019 年以来，我们一直致力于构建一个可互操作和去中心化的元宇宙的共同目标，我们的 GitHub 证明了这一点：github.com/m3-org
    
    ......
    

然后通过[“gpt-3.5-turbo”](https://github.com/themetacat/ChatGPT_Fine_Tuning/blob/a7e9ed1dea9d70b5fc406a7a5190807288ea0078/openai_test.py#LL9C1-L9C1)获取对每段内容获取不定量的问答对数据

获取到问答对数据后，我们可以使用官方提供的工具将数据格式转换为JSONL，并将其上传，获取文件的唯一标识符（ID）。

    # 由于上传文件的格式要是JSONL的，使用官方 CLI 工具做一下转化，输入以下内容
    # openai tools fine_tunes.prepare_data -f qa_pairs.json
    

    # 上传文件
    # https://platform.openai.com/docs/api-reference/files/upload
    def create_file():
        res = openai.File.create(
          file=open("qa_pairs_prepared.jsonl", "rb"),
          purpose='fine-tune'
        )
        print(res)
        return res
    

接着，我们可以基于上传的数据文件[创建微调模型](https://github.com/themetacat/ChatGPT_Fine_Tuning/blob/a7e9ed1dea9d70b5fc406a7a5190807288ea0078/openai_test.py#L100)，以便让模型能够更好地理解和回答特定领域的问题。

    def create_fine_tune():
        # file-xxx在上传文件后返回的结果中
        res = openai.FineTune.create(training_file="file-xxx")
        # res = openai.FineTune.retrieve(id="ft-AF1WoRqd3aJAHsqc9NY7iL8F")
    
        print(res)
    

最后，我们应对模型进行质量评估。（由于整体需求的性质，每个问题的答案可能是不确定的，类似于语文中的阅读理解。因此，直接进行人工评估可能是最准确的方法。通过评估模型在特定问题集上的回答质量，我们可以进一步优化微调过程，并确保生成的答案的准确性和一致性。）

关键步骤与成本评估
---------

在上述操作中提到，**文本对的内容质量会直接影响到微调模型的质量，而处理后的文章内容又会影响到文本对的内容质量**。因此，在初期的文章内容和文本对内容处理过程中，我们需要特别注意，因为它们会直接或间接地影响到最终模型的质量。

以此为前提，在初步测试和评估后得到以下问题

1.  在“实现”过程中的第一步是获取所有的文章。这可以通过脚本来实现，但是获取到的文章内容格式可能各不相同，因此需要进行预处理。在此过程中，需要处理的问题是：原始文章中的每个段落不一定代表一个完整的部分。有时，在第n-1段是问题，第n段是答案，或者第n段是问题，第n+1段是答案。因此，这部分预计需要进行人工处理
    
    ””” 例如： 我们是谁 我们是一群致力于具体化实用“Metaverse”的创客。 我们通过开发产品、内容制作、布道和筹款来做到这一点。 “““
    
2.  在分段处理完成后，类似于"我们"这样的内容需要明确指出是指文章的作者还是其他人，这样为了获得更准确的文本对，这也需要进行**人工处理**
    
3.  处理完内容后，我们可以使用"gpt-3.5-turbo"模型来获取文本对的内容。由于速率限制，每分钟只能调用3次，并且根据token数计费（成本为💲0.002/1k tokens）。对于文章的长度约为1600字，分为15段，获取到了53条文本对，总共花费了💲0.011
    
4.  对于获取到的文本对的内容，也需要通过**人工检查**和调整，以使其更加准确。
    
5.  最后，对于通过微调得到的模型质量，我们需要进行评估。由于每个问题的答案可能不是确定型的，如之前提到的，最好的评估方法是通过**人工实际测试**。这样可以确保模型在特定领域的问题回答能力的准确性。
    
6.  在所有的这些步骤处理好了之后，因为文章是频繁更新的，需要更新微调模型，而我在OpenAI文档中并未找到如何对微调模型进行更新操作
    

总结
--

在探索“训练一个精通于特定领域的GPT模型”解决方案的过程中，最初，我们希望将所有原始文章的内容输入到一个模型中，以获得专属数据的GPT。然而，我们最终发现这种方法不可行，大多数情况下需要通过微调的方式来实现。因此，我们对微调进行了测试和评估。

经过测试和评估后总结了上述“**关键步骤与成本评估**”内容，我们也可以看到，需要对所有的文章进行分段、内容处理，并检查获取到的文本对的质量（需要对每篇文章有一定的理解）。此外，我们还需要评估模型的质量（评估者需要具备对文章和MetaVerse领域的一定认知）。所有这些步骤都需要**人工进行处理**，而且后两步的检查还需要一定的**专业能力**。综合而言，这会导致成本很高。如果使用一些自动化的方法，很可能会对某些步骤的结果质量产生影响，从而影响微调模型的质量。

目前暂未找到其他方法可以更好的实现我们这个想法，如果读者有更好的期待交流。微调的实现过程所需的内容和代码已经上传到[GitHub](https://github.com/themetacat/ChatGPT_Fine_Tuning/tree/main)，供大家参考。如果您在使用过程中发现有任何不清楚或问题，欢迎随时交流。

_注：参考资料_

_OpenAI文档：_[_https://platform.openai.com/docs/introduction_](https://platform.openai.com/docs/introduction) _LlamaIndex文档：_[_https://gpt-index.readthedocs.io/en/latest/_](https://gpt-index.readthedocs.io/en/latest/) [_https://blog.frankzhao.cn/build\_gpt\_bot\_for\_doc/_](https://blog.frankzhao.cn/build_gpt_bot_for_doc/)

---

*Originally published on [Yooma](https://paragraph.com/@yooma/wilk7HHefqBKDB6y0bRP)*
