这是我用来创建自定义模型的教程:
beta.openai.com/docs/guides/fine-tuning/advanced-usage
然而,即使在对模型进行训练并向模型发送提示文本之后,我仍然得到了一些通用的结果,这些结果并不总是适合我的需求。我该如何确保完成的结果只来自于我用于模型的文本,而不是来自于通用的OpenAI模型?
我能否使用一些标志来排除通用模型的结果?
beta.openai.com/docs/guides/fine-tuning/advanced-usage
然而,即使在对模型进行训练并向模型发送提示文本之后,我仍然得到了一些通用的结果,这些结果并不总是适合我的需求。以下是基于OpenAI API使用嵌入的语义搜索示例。
这是完全错误的逻辑。忘掉微调吧。正如官方OpenAI文档所述:
微调并不是指从微调数据集中回答特定问题的特定答案。换句话说,微调模型不知道对于给定的问题应该给出什么答案。它无法读取你的思想。你将得到一个基于微调模型所具有的所有知识的答案,其中:微调模型的知识=默认知识(即微调之前模型已经具备的知识)+微调知识(即你通过微调添加到模型中的知识)。通过提供以下内容,微调使您能够更好地利用API可用的模型:
- 比提示设计更高质量的结果
- 能够训练更多无法适应提示的示例
- 由于提示较短而节省令牌
- 请求延迟较低
微调通过在许多无法适应提示的示例上进行训练,改进了少样本学习,使您能够在广泛的任务上取得更好的结果。
companies.csv
运行print_dataframe.ipynb
来打印数据框。
print_dataframe.ipynb
import pandas as pd
df = pd.read_csv('companies.csv')
df
嵌入是一组数字向量,帮助我们理解文本在语义上相似或不同。两个嵌入向量越接近,它们的内容就越相似(来源)。
让我们先测试嵌入终端点。使用输入This is a test
运行get_embedding.ipynb
。
注意:在嵌入终端点的情况下,参数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'))
在上面的屏幕截图中,我们看到的是这是一个测试
作为嵌入向量。更准确地说,我们得到了一个1536维的嵌入向量(即内部有1536个数字)。你可能熟悉三维空间(即X、Y、Z)。嗯,这是一个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'
(即"fact"),并使用text-embedding-ada-002
模型应用函数get_embedding
。它将把第一个公司的嵌入向量保存在名为'embedding'
的新列中。然后,它将获取第二个公司、第三个公司、第四个公司等等。最后,该代码将自动生成一个名为companies_embeddings.csv
的新的.csv
文件。.csv
文件中)意味着我们不必每次需要它们时都调用OpenAI API。我们只需为给定的"fact"计算一次嵌入向量,就可以了。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
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
my_input = '告诉我关于ABC公司的一些信息'
:
如果我的输入是 '告诉我一些关于XYZ公司的信息':
如果my_input = '告诉我一些关于苹果公司的信息'
:
我们可以看到,当我们将“Tell me something about company ABC”作为输入时,它与第一个“fact”最相似。当我们将“Tell me something about company XYZ”作为输入时,它与第二个“fact”最相似。然而,如果我们将“Tell me something about company Apple”作为输入,它与这两个“facts”中的任何一个都最不相似。get_answer.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 = '告诉我一些关于ABC公司的信息'
,并且阈值为>= 0.9
,我们应该从companies_embeddings.csv
中得到以下答案:
如果我的输入是'Tell me something about company XYZ',并且阈值为>= 0.9,我们应该从companies_embeddings.csv中得到以下答案:
如果my_input = '告诉我一些关于苹果公司的信息'
,并且阈值为>= 0.9
,我们应该从OpenAI API中得到以下答案:。
你可以使用Pinecone来存储嵌入向量,正如官方Pinecone文章所述:
嵌入向量是由人工智能模型(如大型语言模型)生成的,具有大量属性或特征,使得它们的表示方式具有挑战性。在人工智能和机器学习的背景下,这些特征代表了数据的不同维度,对于理解模式、关系和潜在结构至关重要。
这就是为什么我们需要一个专门设计用于处理这种类型数据的数据库。像Pinecone这样的向量数据库通过提供针对嵌入向量的优化存储和查询功能来满足这一需求。向量数据库具备传统数据库的功能,而独立的向量索引则缺乏这些功能,并且专门处理向量嵌入,这是传统基于标量的数据库所缺乏的。
davinci
、curie
、babbage
和ada
。您不能微调GPT-4模型。即使您可以,我仍然认为使用嵌入是获取个性化响应的最佳(如果不是唯一)方法。 - Rok Benko