文本生成模型
OpenAI的文本生成模型(也叫做生成预训练的转换器(Generative pre-trained transformers)或大语言模型)已经被训练成可以理解自然语言、代码和图片的模型。模型提供文本的输出作为输入的响应。对这些模型的输入内容也被称作“提示词”。设计提示词的本质是你如何对大语言模型进行开发,通常是提供指令和任务案例来使工作得以成功完成。
使用OpenAI的文本生成模型,你可以创建以下应用:
- 草拟文档
- 生成编程代码
- 回答常识问题
- 分析文本
- 为软件提供一个自然语言接口
- 输导课程
- 翻译
- 人物模拟
使用GPT-4-vision-preview,你可以构建处理和理解图片的系统
通过OpenAI API调用下面其中的一个模型,可以发送一个包含输入和API key的请求,并接收模型的响应输出。最新发布的模型GPT-4和GPT-3.5-turbo,可以通过聊天补全API端点(API的一个具体访问点)进行调用。
模型家族 | API 端点 | |
---|---|---|
新模型(2023 - ) | gpt-4, gpt-4-turbo-preview, gpt-3.5-turbo | https://api.openai.com/v1/chat/completions |
更新历史模型(2023) | gpt-3.5-turbo-instruct, babbage-002, davinci-002 | https://api.openai.com/v1/completions |
可以使用聊天后台测试各种模型,如果你不确定使用哪一个,推荐你使用gpt-3.5-turbo 或 gpt-4-turbo-preview
1. 聊天补全API
聊天模型采用一个消息列表作为输入,模型处理后再生成消息进行输出。聊天格式被设计成多轮会话小短文的形式,但也可设计成单轮会话的形式。
下面是聊天补全API(Chat Completions API)的一个例子:
# @Time : 2024/1/23 21:42
# @Author : NaiveFrank
# @Version : 1.0
# @Project : python_tutorial
from openai import OpenAI
# 加载 .env 文件到环境变量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
# 初始化 OpenAI 服务。会自动从环境变量加载 OPENAI_API_KEY 和 OPENAI_BASE_URL
client = OpenAI()
# 消息
messages=[
{"role": "system", "content": "你是一个超级助理"},
{"role": "user", "content": "OpenAI 是什么?"},
{"role": "assistant", "content": "OpenAI是一家位于美国旧金山的人工智能研究公司."},
{"role": "user", "content": "这是一家怎样的公司?"}
]
# 调用 GPT-3.5
chat_completion = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages
)
# 输出回复
print(chat_completion.choices[0].message.content)
OpenAI是一家非营利性的人工智能研究组织,致力于推动人工智能技术的发展和应用,以及确保这些技术对人类的利益具有正向影响。
OpenAI的目标是让人工智能对所有人具有广泛的益处,而不仅仅是少数特权阶层。该公司的使命是确保人工智能的发展是安全和有利于所有人类。
OpenAI的研究涵盖了各个领域,包括自然语言处理、计算机视觉、强化学习等。同时,OpenAI还发布了一些开源工具和数据集,
鼓励并促进全球范围内的合作和创新。
Process finished with exit code 0
消息参数作为主要输入。所有的消息必须是一个数组对象,为JSON格式,每一个消息元素必须有一个角色(可以是:system, user, assistant)和内容。消息可以短到一条,也可以是多条。
通常,首先使用系统消息格式化对话,接下来是用户和助理消息进行交替输入。
系统消息会协助助理的行为。例如,可以修改成为一个个性化的助理,或提供特定的指令,让它在聊天中如何表现。但请注意,系统消息是可选的,模型也可没有一个系统消息,只使用一个普通消息,例如:“你是一个超级助理”等。
用户消息为助手提供请求或评论,然后获得响应。助手消息会存储之前助手的响应,也可以给出你希望模型做什么的案例。
当用户给出指令时,参考之前的历史消息非常重要。在上面的例子中,用户最终发出“这是一家怎样的公司?”的请求,这个问题只有通过上下文的理解才有意义。因为模型不会记忆历史请求,每一个请求,都作为对话历史的一部分,所有相关信息都必须提供。如果会话长度超过模型token的限制,应采取一些办法缩短token长度。
1.1. 聊天补全响应内容格式
Chat Completions API 响应内容格式:
{
"id": "chatcmpl-8qzwxDRlj4oxE7YAujhchZ38vo4gI",
"choices": [
{
"finish_reason": "stop",
"index": 0,
"logprobs": null,
"message": {
"content": "OpenAI是一家致力于推动人工智能技术发展的研究公司。公司的目标是确保人工智能的益处能够普惠全人类,并且避免其造成潜在的危害。\n\nOpenAI的研究范围涵盖了人工智能的各个领域,包括机器学习、自然语言处理、计算机视觉等。他们不仅致力于开展基础研究,也关注将人工智能技术应用于解决现实世界的问题。\n\n此外,OpenAI还以开放合作的方式进行研究,积极与其他研究机构、学术界、开发者社区进行合作,共同推动人工智能技术的进步。他们也致力于开源一些自己的研究成果和工具,以促进人工智能技术的普及和发展。",
"role": "assistant",
"function_call": null,
"tool_calls": null
}
}
],
"created": 1707641883,
"model": "gpt-3.5-turbo-0613",
"object": "chat.completion",
"system_fingerprint": null,
"usage": {
"completion_tokens": 285,
"prompt_tokens": 70,
"total_tokens": 355
}
}
助理回复消息的提取:
chat_completion.choices[0].message.content
每个响应都要包含一个finish_reason,值可能如下:
- stop: API返回完整消息,或由stop参数提供的停止序列之一终止的消息
- length: 由于设置max_tokens参数或默认限制,返回未完成模型输出的长度
- function_call:模型要调用的函数
- content_filter:因内容过滤的标记而省略的内容
- null:API 响应仍然在处理或未完成
模型响应输出依赖输入的参数,参数不同,输出也会不同。
2. JSON模式输出
使用聊天补全一个常用的方法是:在系统消息里具体指定让模型一直返回JSON对象,这样做对项目更有意义。当我们做一些项目时,一些模型产生的输出偶尔不是有效的JSON对象。
为了防止这些错误和提升模型的表现,当调用GPT-4-turbo-preview或GPT-3.5-turbo-0125时,可以设置response_format参数为:{“type”:“json_object”}以开启JSON输出模式。当开启JSON输出模式时,模型将被强迫输出,能被解析成JSON对象字符串。
重要提示:
- 当使用JSON格式输出模式时,需要在对话消息中一直指示模型进行JSON格式输出,例如:系统消息。如果没有明确指示输出为JSON格式,模型可能会输出无穷的空白流,也可能请求持续运行一直到token的上限。如果漏设"JSON"格式输出,API会抛出例外。
- 如果返回的finish_reason值是length,模型返回的JSON信息可能被截断,代表信息超过了max_tokens参数或会话token的限制。为了防止这种情况发生,解析返回的响应信息时应检查finish_reason参数
- 在JSON模式下不能保证输出匹配任何特定格式,仅保证格式有效和解析没有错误。
响应输出的JSON对象可以如下:
{
"education": "硕士",
"experience": "6年",
"ability": "8个项目",
"attitude": "非常好",
"total": 32,
"result": true
}
请注意:当模型生成参数作为函数调用(function calling)的一部分时,JSON模式输出一直开启
3. 可重现输出
聊天补全默认具有不确定性(不同的请求之间模型的输出可能不同),为了保持稳定的输出,我们提供一些控制,可以设置seed参数和system_fingerpint响应字段
通过API调用获得确定性(大部分)输出,可以进行以下设置:
- 设置seed参数可以为任何整型,为了确保整个请求过程输出都是确定的都要使用同一个值
- 确保其它参数(如:prompt 或 temperature)在整个请求过程中也要相同
有时会对OpenAI模型配置做必要的更改,确定性可能会受到影响。为了帮助你一直保持对这些改变的追踪,我们暴露了system_fingerprint字段参数。如果这个参数值发生改变,得到不同的输出结果,是因为我们的系统发生了改变。
4. 管理令牌
语言模型的读和写的文本块称作tokens。在英文中,一个token可能短到一个字符也可能长到一个词(例如:a or apple),其它语言可能比一个字符更短,也可能比一个词更长。
例如,字符串"ChatGPT is great!“,编码为6个tokens:[“Chat”, “G”, “PT”, " is”, " great", “!”].
tokens的总数在调用API中的影响:
- API调用的费用,因为每一个token都要支付费用
- API调用的耗时,因为越多的tokens耗费的时间越长
- API调用是否有效,因为总令牌必须低于模型的最大限制(gpt-3.5-turbo的4097令牌)
输入和输出的tokens都是计数的。例如,你调用API输入的tokens是10,接收输出的tokens是20,那你要支付30个tokens的费用。但注意:对于某些模型,每个token的费用在输入和输出中也是不同的。
想看API的调用使用了多少tokens,可以查看API响应中的usage字段参数(例如:response[‘usage’][‘total_tokens’])
GPT-3.5-turbo 和 GPT-4-turbo-preview都是聊天补全API,使用tokens的方式是一样,因为它们都是基于消息的格式,但在一个会话中计算使用了多少tokens是一件很难的事情。
想看一个文本字符串有多少tokens没有被API调用消耗,可以使用OpenAI的 tiktoken Python 库进行统计
传给AIP的每一个参数都要消耗一定数量的tokens,包括:内容、角色和其它一些字段,外加一些额外的格式。这些在将来也许会有稍许变动。
如果一个会话包含太多的tokens,以至超出模型的最大限制(例如:GPT-3.5-turbo 超过4097),必须截断、省略或压缩文本直至在允许限制内。注意如果一个消息在输入时被删除,模型将什么都不懂了
值得注意:过长的对话很可能收到一个不完整的响应。例如:在模型GPT-3.5-turbo中,一个长度为4090 tokens的对话,它的回复在6个tokens后就会被截断。
5. 参数细节
5.1 频率和展现惩罚
在聊天补全API(Chat Completions API)和历史完成API(Legacy Completions API)中拥有频率和展现惩罚可以被用来减少重复令牌序列被采样的可能性。如果目标只是在一定程度上减少重复样本,惩罚系数的合理值应该在0.1到1之间。如果目标是强烈的抑制重复,可以将系统增加到2,但这可能会显著的降低样本的质量。负数可能会增加样本重复的可能性。
5.2 令牌日志概率
Chat Completions API和Legacy Completions API都存在logprobs参数,当请求时,提供每个输出token的日志概率;以及每个标记位置上有限数量的,最有可能的标记以及它们的对数概率。在某些情况下,这对于评估模型在其输出中的置信度或检查模型可能给出的替代响应是有用的。
6. 补全API(衍生)
聊天补全端点2023.7进行了最后的更新,它有一个新的聊天接口。用输入一个被称作prompt自由格式文本,代替消息列表。历史的聊天补全API的调用例子如下:
from openai import OpenAI
client = OpenAI()
response = client.completions.create(
model="gpt-3.5-turbo-instruct",
prompt="OpenAI是一家怎样的公司?"
)
6.1 插入文本
除了作为前缀处理的标准提示词之外,补全端点还支持通过后缀来插入文本。
在编写长篇文本时,段落之间的过渡或遵循一个大纲,指导模型该怎么结束。这个技巧也适用于代码的输入,在函数或文件的中间插入以上优化。
偿试给出更多的示例。
在某些情况下,为了更好地帮助模型的训练生成,可以通过提供一些模型可以遵循的模式示例,来确定一个自然的停止位置。
例如:
如何制作美味的热巧克力:
-
煮水
-
把热巧克力放进杯子里
-
往杯子里加入开水
-
享受热巧克力吧
-
狗是忠诚的动物。
-
狮子是凶猛的动物。
-
海豚是顽皮的动物。
-
马是威严的动物。
6.2 补全的响应格式
{
id='cmpl-8rbdsd9I3ORYB4iZmkfkE0VNpi7KW',
choices=[
{
finish_reason='length',
index=0,
logprobs=None,
text='\n\nOpenAI (Open Artificial Intelligence)是一家非营利性'
}
],
created=1707786772,
model='gpt-3.5-turbo-instruct',
object='text_completion',
system_fingerprint=None,
usage={
completion_tokens=16,
prompt_tokens=11,
total_tokens=27
}
}
用Python可以使用response[‘choices’][0][‘text’]提取输出。响应格式同聊天补全API类似。
6.3 聊天补全 对比 非聊天补全
聊天补全可以创建出一个同非聊天补全相似的一个请求只用一个单独的用户消息。例如:把下面的汉语翻译成英语的提示词:
非聊天补全:
把下面的汉语翻译成英语:"{text}"
聊天补全:
[
{
"role": "user",
"content": '把下面的汉语翻译成英语:"{text}"'
}
]
同样道理,非聊天补全也可以模拟聊天补全,使用"user"和"assistant"格式化后作为相应的输入
两者的不同之处在于底层所使用的模型不同。聊天补全API接口拥有最具能力(GPT-4-turbo-preview)和最有性价比(GPT-3.5-turbo)模型
7. 模型使用推荐
一般情况下推荐使用模型(GPT-4-turbo-preview)或(GPT-3.5-turbo)。使用的模型也依赖项目的复杂度。GPT-4-turbo-preview在更广范围中评估表现会更好一些,特别是在处理复杂指令的细节能力上表现的更强。相比之下,GPT-3.5-turbo擅长处理复杂任务的一部分。GPT-4-turbo-preview很少像GPT-3.5-turbo会编造一些信息,这种行为被称作:“幻觉”,GPT-4-turbo-preview有128,000 tokens的窗口大小,GPT-3.5-turbo只有4,096 tokens的窗口大小。但GPT-3.5-turbo模型输出具有低延时和每个token成本低的特点。
推荐在后台进行相应的测试,以权衡哪种模型能为您的应用提供最佳的性价比。一种常见的设计模式是,使用几个不同的查询类型,每个查询类型都分配给适当的模型来处理它们。
8. FAQ
-
怎样设置temperature参数?
temperature值越低输出的结果越稳定(如:0.2), 反之越高输出的结果越具有多样性和创造性(如:1.0)。根据你的特定应用场景,对一致性和创造性进行权衡,选择一个适合的temperature值。temperature值范围(0~2)之间 -
最新的模型可以用fine-tuning吗?
部分可以。当前仅能对gpt-3.5-turbo 和 基座模型(babbage-002 and davinci-002)进行fine-tuning -
会存储传入API的参数数据吗?
截止到2023.3.1,保留API参数数据30天,并不会使用这些数据来训练改善模型。 -
怎样使我的模型更安全?
你可以加一个审核层作为聊天补全API的输出。 -
我应该使用ChatGPT还是调用API?
ChatGPT为我们的模型提供一个聊天的入口,并且内置很多功能,像整合浏览、代码执行、插件等等。相比较,OpenAI API 提供更加灵活的特性,但需要写代码发送请求到模型中。