低延迟请求
微调不是要从微调数据集中回答问题。微调有助于模型获得更多知识,但与模型无关如何模型回答。为什么?您从微调模型中获得的答案基于全部知识(即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 similarity 的 companies_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 回答
让我们将相似度阈值设置为>= 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
# 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'并且阈值是>= 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: