OpenAI GPT-3 API:如何确保答案来自自定义(微调)数据集?

l5tcr1uw  于 2023-05-07  发布在  其他
关注(0)|答案(1)|浏览(241)

我使用自定义文本与'提示'和'完成'来训练新模型。
下面是我用来从我的数据创建自定义模型的教程:
beta.openai.com/docs/guides/fine-tuning/advanced-usage
然而,即使在训练模型并向模型发送提示文本之后,我仍然得到不总是适合我的通用结果。
如何确保提示的完成结果仅来自我用于模型的文本,而不是来自通用的OpenAI模型?
我可以使用一些标志来消除通用模型的结果吗?

wmtdaxz3

wmtdaxz31#

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

这是完全错误的逻辑。忘记微调。正如官方的OpenAI documentation所述:
通过提供以下功能,微调可让您从API提供的模型中获得更多信息:
1.比即时设计更高质量的结果
1.能够训练更多的例子比可以在提示
1.由于更短的提示而节省令牌
1.降低延迟请求

微调不是用微调数据集中的特定答案来回答特定问题。

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

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

  • 注意:为了更好地(直观)理解,以下代码在Jupyter中运行和测试。*

第一步:创建一个包含“facts”的.csv文件

为了保持简单,让我们添加两个公司(即ABC和XYZ)。在我们的案例中,内容将是对公司的一句话描述。

公司.csv

运行print_dataframe.ipynb打印 Dataframe 。

print_dataframe.ipynb

import pandas as pd

df = pd.read_csv('companies.csv')
df

我们应该得到以下输出:

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

嵌入是一个数字向量,可以帮助我们理解文本在语义上的相似或不同。两个嵌入彼此越接近,它们的内容就越相似(source)。
让我们先测试一下Embeddings endpoint。使用输入This is a test运行get_embedding.ipynb

  • 注意:对于Embeddings端点,参数prompt称为input。*
    get_embedding.ipynb
import openai
import os

openai.api_key = os.getenv('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个数字)。您可能熟悉三维空间(即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
import os

openai.api_key = os.getenv('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'的新列中。然后它将采取第二个公司,第三个公司,第四个公司等最后,代码将自动生成一个名为companies_embeddings.csv的新.csv文件。
将嵌入向量保存在本地(即保存在.csv文件中)意味着我们不必在每次需要时都调用OpenAI API。我们计算一次给定的“事实”的嵌入向量,就是这样。
运行print_dataframe_embeddings.ipynb打印新列为'embedding'的 Dataframe 。

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

我们应该得到以下输出:

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

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

get_cosine_similarity.ipynb

import openai
from openai.embeddings_utils import cosine_similarity
import pandas as pd
import os

openai.api_key = os.getenv('OPENAI_API_KEY')

my_model = 'text-embedding-ada-002'
my_input = '<INSERT_INPUT_HERE>'

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作为输入,它与这两个“事实”中的任何一个都最不相似。

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

让我们将相似度阈值设置为>= 0.9。如果相似度为>= 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
import os

# Use your API key
openai.api_key = os.getenv('OPENAI_API_KEY')

# Insert OpenAI text embedding model and input
my_model = 'text-embedding-ada-002'
my_input = '<INSERT_INPUT_HERE>'

# 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('\n', '')
    print(content)

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

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

如果my_input = 'Tell me something about company Apple',阈值为>= 0.9,我们应该从OpenAI API得到以下答案****:

相关问题