【问题标题】:Customize OpenAI model: How to make sure answers are from customized data?自定义 OpenAI 模型:如何确保答案来自自定义数据?
【发布时间】:2023-02-04 17:18:38
【问题描述】:

我正在使用带有“提示”和“完成”的自定义文本来训练新模型。

这是我用来从我的数据创建自定义模型的教程:

beta.openai.com/docs/guides/fine-tuning/advanced-usage

然而,即使在训练模型并向模型发送提示文本之后,我仍然得到并不总是适合我的通用结果。

我如何确保提示的完成结果仅来自我用于模型的文本,而不是来自通用 OpenAI 模型?

我可以使用一些标志来消除通用模型的结果吗?

【问题讨论】:

    标签: nlp customization openai gpt-3


    【解决方案1】:

    错误的目标:如果提示与来自微调数据集的提示相似,OpenAI API 应该从微调数据集中回答

    这是完全错误的逻辑。忘记微调。如官方OpenAI website所述:

    微调可以让您从可用的模型中获得更多 API 通过提供:

    1. 比提示设计更高质量的结果
    2. 能够训练比提示中更多的示例
    3. 由于较短的提示节省了代币
    4. 低延迟请求

      微调不是要从微调数据集中回答问题。微调有助于模型获得更多知识,但与模型无关如何模型回答。为什么?您从微调模型中获得的答案基于全部知识(即fine-tuned model knowledge = default knowledge + fine-tuning knowledge)。

      虽然 GPT-3 模型有很多常识,但有时我们希望模型用特定的答案(即“事实”)来回答。


      正确目标:当被问及“事实”时用“事实”回答,否则用 OpenAI API 回答

      注意:为了更好的(视觉)理解,以下代码在Jupyter中运行和测试。

      第 1 步:使用“事实”创建一个 .csv 文件

      为了简单起见,让我们添加两家公司(即 ABC 和 XYZ)的内容。我们案例中的内容将是对公司的 1 句话描述。

      公司.csv

      运行print_dataframe.ipynb 打印数据帧。

      打印数据框.ipynb

      import pandas as pd
      
      df = pd.read_csv('companies.csv')
      df
      

      我们应该得到以下输出:


      第 2 步:为每个“事实”计算一个 embedding 向量

      嵌入是一个数字向量,可以帮助我们理解文本在语义上的相似或不同程度。两个嵌入越接近,它们的内容就越相似(source)。

      让我们先测试Embeddings endpoint。使用输入 This is a test 运行 get_embedding.ipynb

      注意:在 Embeddings 端点的情况下,参数 prompt 称为 input

      get_embedding.ipynb

      import openai
      
      openai.api_key = '<OPENAI_API_KEY>'
      
      def get_embedding(model: str, text: str) -> list[float]:
          result = openai.Embedding.create(
            model = model,
            input = text
          )
          return result['data'][0]['embedding']
      
      print(get_embedding('text-embedding-ada-002', 'This is a test'))
      

      我们应该得到以下输出:

      您在上面的屏幕截图中看到的是 This is a test 作为嵌入向量。更准确地说,我们得到了一个 1536 维的嵌入向量(即里面有 1536 个数字)。您可能熟悉 3 维空间(即 X、Y、Z)。那么,这是一个很难想象的1536维空间。

      在这一点上,我们需要了解两件事:

      • 为什么我们需要将文本转换为嵌入向量(即数字)?因为稍后,我们可以比较嵌入向量并计算出这两个文本的相似程度。我们不能这样比较文本。
      • 为什么嵌入向量中正好有 1536 个数字?因为text-embedding-ada-002模型的输出维度是1536。它是预先定义的。

      现在我们可以为每个“事实”创建一个嵌入向量。运行get_all_embeddings.ipynb

      get_all_embeddings.ipynb

      import openai
      from openai.embeddings_utils import get_embedding
      import pandas as pd
      
      openai.api_key = '<OPENAI_API_KEY>'
      
      df = pd.read_csv('companies.csv')
      
      df['embedding'] = df['content'].apply(lambda x: get_embedding(x, engine = 'text-embedding-ada-002'))
      df.to_csv('companies_embeddings.csv')
      

      上面的代码将获取第一家公司(即x),获取其'content'(即“事实”)并使用text-embedding-ada-002模型应用函数get_embedding。它将第一家公司的嵌入向量保存在名为'embedding' 的新列中。然后会取第二家公司、第三家公司、第四家公司等。最后,代码会自动生成一个新的.csv文件,命名为companies_embeddings.csv

      在本地保存嵌入向量(即在.csv 文件中)意味着我们不必在每次需要它们时都调用 OpenAI API。我们为给定的“事实”计算一次嵌入向量,仅此而已。

      运行print_dataframe_embeddings.ipynb 以使用名为'embedding' 的新列打印数据框。

      print_dataframe_embeddings.ipynb

      import pandas as pd
      import numpy as np
      
      df = pd.read_csv('companies_embeddings.csv')
      df['embedding'] = df['embedding'].apply(eval).apply(np.array)
      df
      

      我们应该得到以下输出:

      第 3 步:计算输入的嵌入向量,并将其与使用 cosine similaritycompanies_embeddings.csv 的嵌入向量进行比较

      我们需要为输入计算一个嵌入向量,这样我们就可以将输入与给定的“事实”进行比较,看看这两个文本有多相似。实际上,我们将输入的嵌入向量与“事实”的嵌入向量进行比较。然后我们将输入与第二个“事实”、第三个“事实”、第四个“事实”等进行比较。运行get_cosine_similarity.ipynb

      获取余弦相似度.ipynb

      import openai
      from openai.embeddings_utils import cosine_similarity
      import pandas as pd
      
      openai.api_key = '<OPENAI_API_KEY>'
      
      my_model = 'text-embedding-ada-002'
      my_input = '<INSERT_INPUT>'
      
      def get_embedding(model: str, text: str) -> list[float]:
          result = openai.Embedding.create(
            model = my_model,
            input = my_input
          )
          return result['data'][0]['embedding']
      
      input_embedding_vector = get_embedding(my_model, my_input)
      
      df = pd.read_csv('companies_embeddings.csv')
      df['embedding'] = df['embedding'].apply(eval).apply(np.array)
      df['similarity'] = df['embedding'].apply(lambda x: cosine_similarity(x, input_embedding_vector))
      df
      

      上面的代码将获取输入并将其与第一个事实进行比较。它将计算出的两者的相似度保存在名为'similarity' 的新列中。然后它将采用第二个事实、第三个事实、第四个事实等。

      如果my_input = 'Tell me something about company ABC'

      如果my_input = 'Tell me something about company XYZ'

      如果my_input = 'Tell me something about company Apple'

      我们可以看到,当我们将 Tell me something about company ABC 作为输入时,它与第一个“事实”最相似。当我们将 Tell me something about company XYZ 作为输入时,它与第二个“事实”最相似。然而,如果我们将 Tell me something about company Apple 作为输入,它与这两个“事实”中的任何一个最不相似。

      第 4 步:如果相似度高于我们的阈值,则用最相似的“事实”回答,否则用 OpenAI API 回答

      让我们将相似度阈值设置为&gt;= 0.9。如果相似性是&gt;= 0.9,下面的代码应该用最相似的“事实”来回答,否则用 OpenAI API 来回答。运行get_answer.ipynb

      获取答案.ipynb

      # Imports
      import openai
      from openai.embeddings_utils import cosine_similarity
      import pandas as pd
      import numpy as np
      
      # Insert your API key
      openai.api_key = '<OPENAI_API_KEY>'
      
      # Insert OpenAI text embedding model and input
      my_model = 'text-embedding-ada-002'
      my_input = '<INSERT_INPUT>'
      
      # Calculate embedding vector for the input using OpenAI Embeddings endpoint
      def get_embedding(model: str, text: str) -> list[float]:
          result = openai.Embedding.create(
            model = my_model,
            input = my_input
          )
          return result['data'][0]['embedding']
      
      # Save embedding vector of the input
      input_embedding_vector = get_embedding(my_model, my_input)
      
      # Calculate similarity between the input and "facts" from companies_embeddings.csv file which we created before
      df = pd.read_csv('companies_embeddings.csv')
      df['embedding'] = df['embedding'].apply(eval).apply(np.array)
      df['similarity'] = df['embedding'].apply(lambda x: cosine_similarity(x, input_embedding_vector))
      
      # Find the highest similarity value in the dataframe column 'similarity'
      highest_similarity = df['similarity'].max()
      
      # If the highest similarity value is equal or higher than 0.9 then print the 'content' with the highest similarity
      if highest_similarity >= 0.9:
          fact_with_highest_similarity = df.loc[df['similarity'] == highest_similarity, 'content']
          print(fact_with_highest_similarity)
      # Else pass input to the OpenAI Completions endpoint
      else:
          response = openai.Completion.create(
            model = 'text-davinci-003',
            prompt = my_input,
            max_tokens = 30,
            temperature = 0
          )
          content = response['choices'][0]['text'].replace('
      ', '')
          print(content)
      

      如果my_input = 'Tell me something about company ABC'并且阈值是&gt;= 0.9,我们应该从companies_embeddings.csv得到以下答案:

      如果my_input = 'Tell me something about company XYZ'并且阈值是&gt;= 0.9,我们应该从companies_embeddings.csv得到以下答案:

      如果my_input = 'Tell me something about company Apple'并且阈值为&gt;= 0.9,我们应该得到以下答案来自 OpenAI API:

    【讨论】:

    • 非常感谢鹿!这太有见地了。但是有一个快速的问题 mm 在你的例子中,数据集实际上是一个带有确定列的普通 .csv 文件,如果我的知识库是一个网站,如何获取网络内容(几乎是非结构化的)并将其转换为数据集?任何帮助表示赞赏!非常感谢
    • 看一下this 的例子。他们使用了维基百科关于 2020 年夏季奥运会的文章中的数据集。 here 解释了数据收集过程。我知道,这仅对维基百科页面有用,因为它们使用维基百科 API 来提取数据。如果您没有任何可用于执行类似操作的 API,则需要手动收集数据。
    【解决方案2】:

    为确保 OpenAI 模型生成的答案来自自定义数据,您可以按照以下步骤操作:

    收集您的定制数据:这可以是文本、图像、音频或视频的形式,并且应该代表您希望模型学习的信息。清理和预处理数据:这涉及删除任何不相关的信息并将数据转换为可用于训练模型的格式。训练 OpenAI 模型:使用您的预处理数据来训练 OpenAI model。您可以根据需要使用迁移学习、微调或从头开始。评估模型:通过将模型生成的答案与自定义数据中的答案进行比较来检查模型的准确性。如果精度不令人满意,您可能需要对模型进行调整并重新训练。部署模型:一旦模型表现良好,您就可以部署它以供使用。监控和维护模型:持续监控模型的性能并根据需要进行更新,以确保它继续从您的自定义数据中生成答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      • 2017-02-12
      • 2018-01-12
      • 2020-04-24
      • 1970-01-01
      相关资源
      最近更新 更多