大模型开发(六):OpenAI Completions模型详解并实现多轮对话机器人

全文共8500余字,预计阅读时间约17~30分钟 | 满满干货(附代码),建议收藏!

在这里插入图片描述
代码下载点这里

一、 Completions与Chat Completions基本概念

经过海量文本数据训练的大模型会在全量语义空间内学习语法关系和表达风格,并通过某些微调过程使得其能够更好的向人类意图对齐,模型在进行预测时,本质上是根据输入(也就是提示)来预测对应的文字输出,GPT模型作为以transformer为框架的生成式预训练大语言模型,这是它最基本的功能。

在大语言模型领域,这种根据提示来预测对应的文字输出的过程,被称为Completion,中文译为“补全”。能够完成Completion过程的模型,则被成为Completion模型,这也是OpenAI对于能够实现Completion功能的模型的命名。

比如text-davinci-003模型(在text-davinci-002模型基础上通过RLHF微调的模型),就是一个Completion模型。

对于大语言模型的应用而言,有一个非常重要的应用方向——对话机器人。尽管Completion模型也能很好的对文字进行补全,但这种补全有时很难准确理解人类意图,从而出现一些“幻觉”。例如下图为早期与text-davinci-002模型打招呼的对话,只输入了“你好”作为提示词,text-davinci-002自动补全了“您找谁”,并且返回了对应的英文翻译结果:

202306241244044

很明显,模型并没有很好的理解“意图”,当输入“你好”的时候,其实是想和模型打招呼,但模型只是根据已有知识,对“你好”之后可能出现的文字进行了补全。

基于此,为了更好的理解人类的对话意图,OpenAI在Completion模型模型基础上,进一步微调训练得到了对话类模型,也就是Chat Completion模型。相比Completion模型,Chat Completion模型在大量对话预料上进行了微调训练,并且在模型内部新增了system、user和assistant等参数,用于设置聊天语境及不同的聊天角色,从而使得模型能够更好的理解人类意图,从而更好的完成对话类任务。

例如gpt-3.5-turbo就是Chat Completion模型,同时也是ChatGPT普通版背后的大模型。这里我在gpt-3.5-turbo中输入你好,则返回结果如下:

02d4c18c14fa9a8b9befbe3c81bf1186_202306241504280

能够看出,模型返回的结果符合人类预期,说明模型能够较好的理解人类对话意图,并返回更加合适的结果。由此也能看得出Completions模型与Chat Completions模型之间性能区别。

总的来说:Completions 和 Chat Completions 都是 OpenAI 提供的 API,它们都可以用来生成文本。Completions API 主要用于补全问题,用户输入一段提示文字,模型按照文字的提示给出对应的输出。而 Chat Completions API 则专门用于处理聊天任务,它在接口上显示定义了 system、user 和 assistant 三个角色。system 可以理解为聊天的语境,可有可无;user 和 assistant 可以理解为聊天的两个角色

二、 Completions与Chat Completions模型类

点击进入官网

截至目前,OpenAI发布的Completions模型与Chat Completions模型如下:

image-20230717224140771

OpenAI发布的带有text标识的A、B、C、D四大类模型都是Completions模型(也就是gpt-3系列模型),而gpt-3.5和gpt4,则是Chat Completions模型。

从实际功能定位上来说,Completions模型是一类功能更加基础、同时配套功能更加齐全的模型(例如OpenAI只为Completions模型提供了微调的接口),而Chat Completions模型则是一类功能更加特异化、并且更加先进的一类模型。两类模型都有各自适用的场景

三、 Completion.create API

3.1 参数详解

在OpenAI提供的在线大模型中,所有的Completions模型都需要通过Completion.create进行调用,并在实际调用的过程中通过超参数设置对应的调用模型及模型相关参数。

看下官网的参数:

image-20230717224644862

各参数解释如下:

1

3.2 代码测试

先引入依赖包和OPENAI_API_KEY

import os
import openaiopenai.api_key = os.getenv("OPENAI_API_KEY")

所有的Completions模型都需要通过Completion.create进行调用,在实际调用的过程中通过超参数设置对应的调用模型及模型相关参数。

response = openai.Completion.create(model="text-davinci-003",prompt="Say this is a test")

输出结果如下:

image-20230718082318770

最简单的调用是:在函数中设置model和prompt参数,这两个是必填的参数。其中model表示调用的模型,而prompt则表示提示词。

返回结果response包含了text_completion id(completion任务编码),以及返回结果和模型参数。

response是一个OpenAIObject类型对象

image-20230718082627570

获取元素就是常规的Python操作了,如:

  • 提取response中具体返回的文本

image-20230718082759411

  • 提取text对象

image-20230718082851549

生成式大模型的结果往往是无法复现的。尽管从理论上来说,当temperature取值为0的时候,模型在每个步骤中总是选择最可能的下一个token,这会导致生成的文本变得确定和可预测,但在实践过程中,由于模型内部的计算精度和舍入误差等因素,也可能无法完全保证结果的完全一致性。

除了temperature外,目前OpenAI并没有提供任何额外的可以用于控制结果随机性的参数。top_p尽管可以影响输出结果,但并不能完全控制模型随机性。此外,目前OpenAI的在线大模型也并没有类似机器学习领域的随机数种子的参数设置。因此,就目前的情况而言,控制大语言输出结果使其能够复现,几乎是不可能做到的。

3.3 参数调参实践

大语言模型是非常复杂的黑箱模型,导致很多时候参数设置导致的结果并不能完全按照理论情况来进行推演。

因此需要通过大量的实践,来积累不同参数的使用经验——即掌握不同参数在实际Completion过程中对输出结果的影响。

先来试一下 尝试调整Completion.create的核心参数来观察模型输出结果变化情况

3.3.1 参数n

response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=3)response

此时的返回就有3个completion,如下:

image-20230718085111023

单独看某一个的话:

response["choices"][0]["text"].strip('?\n\n')

输出如下:

image-20230718085203488

封装成函数:

import openaidef generate_response(n):response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=n)for i in range(n):print(response["choices"][i]["text"].strip('?\n\n'))# 测试函数
generate_response(3)

3.3.2 参数temperature

temperature参数是非常核心的用于控制模型输出结果随机性的参数。其取值范围在0-2之间,默认值为1,数值越大模型随机性越大。

先尝试设置temperature=1.5并观察返回结果:

response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=3,temperature=1.5)

看下结果:

image-20230718085705866

对于“请问什么是机器学习”这一较为简单的提示(预训练文本中存在大量相关语料),返回的结果已经出现了非常严重的随机性,很多文本甚至不可读。这也说明temperature对文本输出结果的随机性影响非常大。

设置一个更小的temperature取值,并观察输出结果:

response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=3,temperature=0.8)

看下结果:

image-20230718085925440

从结果上就能看出,当temperature参数数值下降时,模型返回的多个结果会更加“趋同”,整体来看答案严谨但缺乏创造力,更像是教科书式的定义。

关于temperature参数的设置技巧:

  • 首先是关于参数推荐的取值范围,尽管temperature可以在[0,2]范围内进行调节,但temperature的数值对模型结果影响极大,往往小幅的数值调整就会导致非常大的影响,因此建议的调整范围在**[0.8,1.2]**之间;
  • 其次是参数不同取值的实际影响,伴随着temperature取值逐渐增加,返回的文本也将从严谨表述逐渐变为“胡言乱语”,但temperature在某些取值时,返回的结果会呈现出具备一定“启发性”的特性。具体temperature参数取值如何设置,还需要根据实际情况来判断

更新一下函数:

import openaidef generate_response(n, temperature):response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=n,temperature=temperature)for i in range(n):print(response["choices"][i]["text"].strip('?\n\n'))# 测试函数
generate_response(3, 0.8)

3.3.3 参数presence_penalty

对文本输出质量有重要影响的另一个参数,是presence_penalty。

不同于temperature是用于控制输出结果是“严谨表述”还是“胡言乱语”,presence_penalty更多的是控制返回语句的精炼程度。presence_penalty参数在[-2,2]中取值,数值越大,返回结果越精炼,数值越小,返回结果越啰嗦。

仍然还是以“请问什么是机器学习”作为提示,观察presence_penalty取值不同时的输出结果:

response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=3,presence_penalty=2)

看下结果:

image-20230718090453425

此时的输出结果是非常精炼的。而如果设置presence_penalty为-2:

response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=3,presence_penalty=-2)

结果如下:

image-20230718090606378

此时结果则显得“啰嗦”了不少。

看起来presence_penalty参数对模型结果的影响并不如temperature那么显著,但在实际调用大模型进行Completion时,presence_penalty参数和temperature参数搭配进行使用,往往能达到非常好的效果。一般来说,如果希望模型更加具有创造力,则会增加temperature取值,并且适当降低presence_penalty取值

response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=3,presence_penalty=-1,temperature=1.2)

结果如下:

image-20230718091043514

反之,如果希望结果更加精准,则会适当降低temperature,同时增加presence_penalty取值:

response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=3,presence_penalty=2,temperature=0.8)

结果如下:

image-20230718091204523

这也就是经常会看到一些大语言模型具备三种不同的模式,分别为精确模式、平衡模式和创造力模式(例如早期的Bing AI聊天),其功能的实现都是通过大模型的参数调整来完成的,而支持这些不同模式功能实现的最基础的两个参数就是presence_penalty参数和temperature参数。

更新一下函数:

import openaidef generate_response(n, temperature, presence_penalty):"""根据输入的n、temperature和presence_penalty生成相应的响应。n: 输出结果的数量。temperature: 控制输出的随机性。值越高,输出结果越随机;值越低,输出结果越确定。presence_penalty: 控制模型输出时对于当前已存在的内容的依赖程度。值越高,模型在生成文本时就越不会重复使用当前已有的内容;值越低,模型生成的文本就可能会有更多的重复。注意:如果希望模型更具有创造力,可以增加temperature的值,同时适当降低presence_penalty的值;如果希望结果更加精确,可以适当降低temperature的值,同时增加presence_penalty的值。"""response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=n,temperature=temperature,presence_penalty=presence_penalty)for i in range(n):print(response["choices"][i]["text"].strip('?\n\n'))# 测试函数
generate_response(3, 0.8, 2)

3.3 4 参数best_of

best_of能够让一个模型预测多组结果,并择优进行输出。

比如:如果设置best_of=5,则代表总共创建5个备选文本,再从中选取概率最大(得分最高)的一组进行输出:

response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,presence_penalty=-1,temperature=1.2,best_of=5)

结果如下:

image-20230718091754746

  • 在大多数情况下,随着best_of值增加,最终的输出结果质量也会随之提升;

  • best_of参数会消耗大量Token配额以及每分钟调用次数配额,同时也会消耗更多的资金;

best_of是自动筛选最优结果,参数n可以支持手动筛选最佳结果,有的时候可以同时使用这两个参数,以期获得更好的结果。如best_of=2、n=2时,总共发出四次请求,最终返回两个结果。

更新代码:

import openaidef generate_response(n, temperature, presence_penalty, best_of):"""根据输入的n、temperature、presence_penalty和best_of生成相应的响应。n: 输出结果的数量。temperature: 控制输出的随机性。值越高,输出结果越随机;值越低,输出结果越确定。presence_penalty: 控制模型输出时对于当前已存在的内容的依赖程度。值越高,模型在生成文本时就越不会重复使用当前已有的内容;值越低,模型生成的文本就可能会有更多的重复。best_of: 让模型预测多组结果,并择优进行输出。注意:如果希望模型更具有创造力,可以增加temperature的值,同时适当降低presence_penalty的值;如果希望结果更加精确,可以适当降低temperature的值,同时增加presence_penalty的值。"""response = openai.Completion.create(model="text-davinci-003",prompt="请问什么是机器学习",max_tokens=1000,n=n,temperature=temperature,presence_penalty=presence_penalty,best_of=best_of)for i in range(n):print(response["choices"][i]["text"].strip('?\n\n'))# 测试函数
generate_response(3, 1.2, -1, 5)

四、基于Completion.create函数的可调节对话风格的多轮对话机器人

在了解Completion.create函数功能之后,尝试编写一个基于Completion.create函数的可以在Jupyter内部实现多轮对话的聊天机器人,同时通过预设不同的参数,在函数内部预设精确模式、平衡模式和创造力模式,以满足不同使用场景。函数定义如下:

def chat_now(model='text-davinci-003',mode='balance'):"""基于Completion.create函数的多轮对话机器人:param model: 调用的大语言模型,默认为text-davinci-003:param mode: 聊天机器人预设模式,默认为平衡模式balance,可选precision(精确模式)和creativity(创造力模式)"""# 提示想终止聊天时输入"quit"print("if you want to stop the conversation, please input 'quit'") # 三种不同的模式及其对应的参数if mode == 'balance':temperature = 1presence_penalty = 0elif mode == 'precision':temperature = 0.8presence_penalty = 2elif mode == 'creativity':temperature = 1.2presence_penalty = -1     # 定义执行对话函数,方便后续反复调用def chat(prompt):try:# 不报错的情况下,返回Completion.create函数输出结果response = openai.Completion.create(model = model,prompt = prompt,max_tokens = 1000,temperature=temperature, presence_penalty=presence_penalty,stop = [" Human:", " AI:"])answer = response["choices"][0]["text"].strip()return answerexcept Exception as exc:# 报错时返回"broken"return "broken"# 对话执行函数,首先准备空容器text = "" turns = [] # 执行多轮对话,即多次调用chat函数while True: # 启动对话框question = input()# 首次开启对话框时提示请输入问题if len(question.strip()) == 0: print("please input your question")# 当输入为'quit'时,停止多轮对话,即停止while循环elif question == "quit":  print("\nAI: See You Next Time!")breakelse:# 多轮对话时,将问题和此前对话结果都作为prompt输入prompt = text + "\nHuman: " + questionresult = chat(prompt)# 当一次请求失败时,再次发起请求while result == "broken": print("please wait...")result = chat(prompt) else:# 保留本次对话结果turns += [question] + [result]print(result)# 最多保留十次对话结果,超出次数则最开始的对话会被删除if len(turns)<=10:  text = " ".join(turns)else:text = " ".join(turns[-10:])

测试一下,运行函数进行对话:

chat_now()

image-20230718092743153

五、总结

文章详细阐述了OpenAI的Completions与Chat Completions模型的基本概念与模型类。接着,对Completion.create API进行了深度解析,包括参数详解、代码测试以及参数调参实践,特别是对n、temperature、presence_penalty、best_of等参数的详细讲解。最后,以Completion.create函数为基础,实现了具有可调节对话风格的多轮对话机器人,展现了AI对话系统的灵活性。掌握这些知识,对优化AI对话系统具有重要的指导意义。

感谢您阅读这篇文章!如果您觉得有所收获,别忘了点赞、收藏并关注我,这是我持续创作的动力。您有任何问题或建议,都可以在评论区留言,我会尽力回答并接受您的反馈。如果您希望了解某个特定主题,也欢迎告诉我,我会乐于创作与之相关的文章。谢谢您的支持,期待与您共同成长!

最后,给大家送上干货!建议大家点赞&收藏,Mark住别丢了。有高质量资料免费送!

1. 关于魔法,你需要知道的

2. 超全流程!OpenAI账户注册看这里!

3. ChatGPT Plus 升级指南

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java学习路程之篇十、知识点、数组介绍、二维数组介绍、静态初始化、访问元素、遍历元素、动态初始化、内存图、数组常见问题

文章目录 01、数组介绍02、数组静态初始化03、数组元素访问04、数组遍历操作05、数组动态初始化06、数组内存图07、数组常见问题08、二维数组介绍09、二维数组静态初始化10、二维数组遍历11、二维数组动态初始化12、二维数组内存图 01、数组介绍 02、数组静态初始化 03、数组元…

Python爬虫学习笔记(一)————网页基础

目录 1.网页的组成 2.HTML &#xff08;1&#xff09;标签 &#xff08;2&#xff09;比较重要且常用的标签&#xff1a; ①列表标签 ②超链接标签 &#xff08;a标签&#xff09; ③img标签&#xff1a;用于渲染&#xff0c;图片资源的标签 ④div标签和span标签 &…

Dcat-admin使用 Alpine 双向数据绑定

介绍 Alpine.js 这东西真的轻量级&#xff0c;和vue相似&#xff0c;和 livewire 同一个作者&#xff0c;推荐大家使用&#xff0c;可以平替jquery 效果 实现 在 bootstrap.php 引入js Admin::headerJs([https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-y/alpinejs/3.9.0/…

在Windows下安装Anaconda平台

Anaconda介绍 安装Python的方法有很多&#xff0c;其中利用Anaconda来安装&#xff0c;是最为安全和便捷的方法之一。在Python中安装类库&#xff0c;各个类库之间可能存在相互依赖、版本冲突等问题。为了解决这个问题&#xff0c;Python社区提供了方便的软件包管理工具&#…

Swift 中的 Actors 使用以及如何防止数据竞争

文章目录 前言Actors 的基本原理Actor 是引用类型&#xff0c;但与类相比仍然有所不同 为什么会出现数据竞争如何防止数据竞争使用 async/await 访问数据防止不必要的暂停非隔离(nonisolated)访问为什么在使用 Actors 时仍会出现数据竞争&#xff1f;总结 前言 Actors 是 Swif…

mongodb,redis,mysql 区别

一、MySQL 关系型数据库。 在不同的引擎上有不同 的存储方式。 查询语句是使用传统的sql语句&#xff0c;拥有较为成熟的体系&#xff0c;成熟度很高。 开源数据库的份额在不断增加&#xff0c;mysql的份额页在持续增长。 缺点就是在海量数据处理的时候效率会显著变慢。 二、Mo…

CDA数据分析系01 anaconda

简介 数据处理集成包&#xff0c;不局限于python 创建一个新的environment conda create --name python34 python3.4 激活一个environment activate python34 # for windows conda的package管理 类似pip&#xff0c;conda install xxxx 查看已安装的python包 conda list…

如何用Three.js + Blender打造一个web 3D展览馆

作者&#xff1a;vivo 互联网前端团队- Wei Xing 运营活动新玩法层出不穷&#xff0c;web 3D炙手可热&#xff0c;本文将一步步带大家了解如何利用Three.js和Blender来打造一个沉浸式web 3D展览馆。 一、前言 3D展览馆是什么&#xff0c;先来预览下效果&#xff1a; 看起来像…

【电路原理学习笔记】第4章:能量与功率:4.5 稳压电源与电池

第4章&#xff1a;能量与功率 4.5 稳压电源与电池 电网采用交流电形式将电能从发电站传输给用户&#xff0c;这是因为交流电易于转换成适宜传输的高压和终端用户使用的低压。在远距离传输时&#xff0c;采用高电压传输的效率和效益要高得多。对于给定的功率&#xff0c;较高的…

蓝桥杯,我劝你不要参加的8个完美理由

蓝桥杯&#xff0c;是一个全国高校的IT技术比拼&#xff0c;如果你参加了&#xff0c;可能不止是刷题数量的剧增&#xff0c;还有你的软件人生 我劝你不要参加&#xff0c;因为如果你参加了&#xff0c;可能会有以下烦恼&#xff1a; 目录 1、会让你变得上进 2、会提前感受码…

http连接处理(中)(四)

2. 结合代码分析请求报文解析 上一节我们对http连接的基础知识、服务器接收请求的处理流程进行了介绍&#xff0c;接下来将结合流程图和代码分别对状态机和服务器解析请求报文进行详解。 流程图部分&#xff0c;描述主、从状态机调用关系与状态转移过程。 代码部分&#xff…

【云原生】k8s之Ingress

1.Ingress的相关知识 1.1 Ingress的简介 service的作用体现在两个方面&#xff0c;对集群内部&#xff0c;它不断跟踪pod的变化&#xff0c;更新endpoint中对应pod的对象&#xff0c;提供了ip不断变化的pod的服务发现机制&#xff1b;对集群外部&#xff0c;他类似负载均衡器…

HTML5学习简记(更新中~)

目录 HTML定义 标签 HTML基本骨架 常见标签 标题标签 段落标签 换行与水平线标签 文本格式化标签 图像标签 绝对路径与相对路径 超链接标签 音频与视频标签 列表标签 无序列表 有序列表 定义列表 表格标签 表格结构标签 合并单元格 表单标签 input标签 input标签占…

linux中的sendmail发送邮件

Linux/UNIX 下的老牌邮件服务器。 Sendmail 作为一种免费的邮件服务器软件&#xff0c;已被广泛的应用于各种服务器中&#xff0c;它在稳定性、可移植性、及确保没有 bug 等方面具有一定的特色&#xff0c;且可以在网络中搜索到大量的使用资料。 一、邮件发送原理图 MUA&#x…

腾讯云对象存储联合DataBend云数仓打通数据湖和数据仓库

随着数字化进程不断深入&#xff0c;数据呈大规模、多样性的爆发式增长。为满足更多样、更复杂的业务数据处理分析的诉求&#xff0c;湖仓一体应运而生。在Gartner发布的《Hype Cycle for Data Management 2021》中&#xff0c;湖仓一体&#xff08;Lake house&#xff09;首次…

性能测试学习阶段性总结

目录 1.前言 2.概念部分 2.1不同角度看软件性能 2.2关键词 2.3测试的方法 2.4应用领域 3.性能测试过程模型&#xff08;PTGM&#xff09; 2.1测试前期准备 2.2测试工具引入 2.3测试计划 2.4测试设计与开发 2.5测试执行和管理 2.6测试分析 总结&#xff1a; 1.前言…

Django admin管理工具TabularInline表格内联

详解 TabularInline 是 Django Admin 中的一个内联模型选项&#xff0c;用于在父模型的编辑页面中以表格形式显示关联的子模型对象。下面是对 TabularInline 的一些详解&#xff1a; 显示方式&#xff1a;TabularInline 以表格的形式显示子模型对象。每个子模型对象将以一行的…

vue实现左右布局(右侧超出的时候换行展示)

目录 vue实现左右布局(右侧超出的时候换行展示)code效果 vue实现左右布局(右侧超出的时候换行展示) code <ul class"body-detail"><li><div class"li-label">姓名</div><div class"li-value">XXXXXXXXXXXXXXXXXX…

SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)

文章目录 1. 环境准备1. 查询全部2. 根据 name 查询 match 分词查询3. 根据 name 和 品牌查询 multiMatch 分词查询4. 根据 brand 查询 match 分词查询5. 按照价格 范围查询6. 精确查询7. boolQuery8. 分页9. 高亮查询9. 公共解析 上一节讲述了 SpringBoot 实现 elasticsearch …

Sentinel整合OpenFegin

之前学习了openFeign的使用&#xff0c;我是超链接 现在学习通过Sentinel来进行整合OpenFegin。 引入OpenFegin 我们需要在当前的8084项目中引入对应的依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sta…