今天我们可以用自己的数据训练出一个模型,这样就可以回答相关内容的问题,我们可以用OpenAI提供的模型微调功能。
为什么要微调呢,就是在某些领域里一些数据比较丰富,会比基础模型的某些数据更丰富,所以就可以利用这些数据来“微调”一个特别擅长这个垂直领域的模型,这个模型微调完,我们就可以直接提问了。
OpenAI提供模型微调还是很简单的,只要遵守它的规则就可以,按照它的格式,每一行里都有prompt属性和completion内容,就像如下的格式:
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
...
模型微调的过程,就是根据输入的内容,在原来的基础模型上训练。所以我们需要提供一个基础模型,在它的基础上进行微调,可以是Ada、Babbage、Curie 和 Davinci等等等。。
因为你提供数据的不同,所以微调出来擅长的领域也不同,如你提供的是笑话类的数据,那么它就是笑话类的模型,那么我们接下来就微调一个擅长写“历史英雄人物和奥特曼一起打怪兽”的AI。对应的故事数据,也利用ChatGPT的模型来帮助我们生成,代码如下:
以下代码也是很简单,定义的gpt35()函数中,我们把prompt和其他的基础配置传入进去,让OpenAI给我们生成对应的故事就可以了。
在prepare_stories()函数里,我们则多层嵌套循环将对应列表的数据动态传入到prompt来告诉AI要生成什么样子的数据。
import os,openai,backoff
import pandas as pd
openai.api_key = os.getenv("OPENAI_API_KEY")
dynasties= ['唐', '宋', '元', '明', '清', '汉', '魏', '晋', '南北朝']
super_powers = ['隐形', '飞行', '读心术', '瞬间移动', '不死之身', '喷火']
story_types = ['轻松', '努力', '艰难']
@backoff.on_exception(backoff.expo, openai.error.RateLimitError)
def gpt35(prompt, max_tokens=2048, temperature=0.5, top_p=1, frequency_penalty=0, presence_penalty=0):
response = openai.Completion.create(
engine="text-davinci-003",
prompt=prompt,
max_tokens=max_tokens,
temperature=temperature,
top_p=top_p,
frequency_penalty=frequency_penalty,
presence_penalty=presence_penalty)
return response["choices"][0]["text"]
def prepare_stories(dynasties, super_powers, story_types, output_file="data/ultraman_stories.csv"):
df = pd.DataFrame()
repeat = 3
for dynasty in dynasties:
for super_power in super_powers:
for story_type in story_types:
for i in range(repeat):
prompt = f"""请你用中文写一段300字的故事,情节跌宕起伏,讲述一位{dynasty}朝时期的英雄人物,穿越到现代,拥有了{super_power}这样的超能力,通过{story_type}的战斗,帮助奥特曼一起打败了怪兽的故事。"""
story = gpt35(prompt)
row = {"dynasty": dynasty, "super_power": super_power, "story_type": story_type, "story": story}
row = pd.DataFrame([row])
df = pd.concat([df, row], axis=0, ignore_index=True)
df.to_csv("data/ultraman_stories.csv")
prepare_stories(dynasties, super_powers, story_types)
这里大家可以不用执行了,浪费token,可以直接用我给你的ultraman_stories.csv文件使用即可。(文件可以进入我的主页点击资源里可以看到)
拿到了原始数据,我们为了微调,需要先把内容转换为OpenAI需要的数据格式,代码如下:
# 读取数据
df=pd.read_csv("data/ultraman_stories.csv")
# 定义了prompt用dynasty+super_power+story_type内容形式
df["sub_prompt"]=df['dynasty']+","+df['supe