(建议收藏深读)GPT 高阶玩法 - 万字 GPT 模型自动化应用指南( javaScript 示例)(上)

本文涉及的产品
交互式建模 PAI-DSW,5000CU*H 3个月
简介: (建议收藏深读)GPT 高阶玩法 - 万字 GPT 模型自动化应用指南( javaScript 示例)

image.png

当提到领先的人工智能研究机构,OpenAI 人工智能公司绝对是其中之一。作为全球最知名的 AI 研究机构之一,OpenAI 的成果和贡献不可谓不深远。它在自然语言处理和生成领域的 GPT 系列模型(GPT-1、GPT-2、GPT-3)尤为出色,引领了该领域的发展。

如果还不清楚怎么注册使用 GPT 的同学,不妨看看这篇《(建议收藏)ChatGPT 被锁中国区 ip ?别慌,看这篇ChatGPT & OpenAI 注册使用指北》

大家好,我是祯民。最近 ChatGPT 对各个领域都造成了不小的冲击,大家或多或少都已经和 ChatGPT 对话过,并且也得到了不少答案和结果,相信对它的能力也有了较为清晰的认知。

当然这篇文章的重点并不是怎么注册使用 ChatGPT 或是怎么搭建一个自己的 ChatGPT 服务,在很多同学的印象里,ChatGPT 是一个人工智能的模型,可以通过聊天的方式得到一些答案。这个并不是一个全面的认知,它能做到的事情也远不及此。

通过 GPT 模型 , 可以批量智能并且自动化地完成各行各业的工作。在这篇文章中,我们就将来学习 GPT 的高阶玩法 -- 基于GPT模型开发自动化应用, 通过这篇文章的学习,大家将对 GPT 模型产生一个初步的认知,并且具备使用 GPT 模型应用到自己需要的方向的基本开发能力,形成整个 AI 应用维度的架构思维。本文将从以下几个大方向展开这部分的学习:

  • GPT 模型篇:通过这部分的学习,大家将对 GPT 模型具备一个相对清晰的认知,并且了解怎么根据自己的应用场景灵活选用模型。实际上,我们使用的 ChatGPT 只是其中的一种模型,即 GPT-3.5-turbo 模型。
  • GPT 接入篇:这部分我们将结合实际的例子来介绍 GPT 模型的接入,涵盖流获取、流式接入等高阶玩法。
  • GPT 应用篇:这部分我会基于我最近开发 GPT 模型的 vscode 自动化测试插件 GPT Unit Test,来具体剖析整个方案是如何设计的,并延伸到其他方向应该如何展开具体的 AI 应用。

全文干货很多,建议收藏深读! 本文虽会以技术视角展开,但是并没有较深的技术门槛,非技术同学也可以关注,其中的 AI 应用思路相信会对优秀的你有不一样的启发,在这个领域,想法💡远比技术要更有价值

GPT 模型篇

初识 -- 什么是 GPT 模型?

GPT (Generative Pre-trained Transformer) 模型是一种基于 Transformer 结构的预训练语言模型,由 OpenAI 人工智能公司开发。它表现出色的原因是它能够在大规模文本数据上进行预训练,并根据任务进行微调,从而在多种自然语言处理任务上取得优异的结果。

GPT 模型是在大规模语料库上进行训练的。在预训练阶段,它会学习构建句子的基本结构、单词之间的关系、句子的文法和语法等等。在对其进行微调后,它可以实现诸如对话生成、文本摘要、机器翻译、命名实体识别等任务。

简单来说,GPT 是一种预训练算法模型,在它的基础上,存在一些变体,具备更大的预训练规模和数据集,使得它的自然语言能力更强,我们一直使用 ChatGPT 就是其中的一种变体。

因为这个性质,GPT 也可以被理解为是一系列预训练模型的统称,这些变体其实我们也可以称它们为 GPT 模型。经过这样的描述,相信大家也可以理解,GPT 模型的能力来自于大量数据集的反复预训练,不同的变体之间的差异也与训练的次数、规模和数据集息息相关

差异 -- GPT-3 , GPT-3.5, GPT-4 模型之间有什么区别?

InstructGPT(2022 年 1 月)是一系列 GPT-3 模型(包括 text-davinci-001、text-davinci-002 和 text-davinci-003)统称,于GPT-3相比,它的最大不同是针对人类指令(reinforcement learning with human feedback, RLHF)进行了微调 ; InstructGPT 产生的幻觉更少,更真实,但它在生成的多样性或者说创意上相对更差,因为它们试图在“对齐”的前提下,将人类偏好/价值观硬塞进原始数据模型中。

ChatGPT(2022 年 11 月)更进一步。 为了训练 ChatGPT,OpenAI 对 InstructGPT 对话模型进行了微调(马斯克在Twitter上指出openai 使用了Twitter 数据), 这种微调在一定程度上也是可以的, 区别在于使用的policy and reward model

在了解了什么是 GPT 模型后,我们来看一下它的变体。当然除了 GPT-3, GPT-3.5, GPT-4 以外还有 GPT-2,GPT-2的能力在各方面都比较差,也不适合微调,这里就不展示描述了。

image.png

首先大家需要了解 GPT-3, GPT-3.5, GPT-4 都是具备对人类指令做出基本有效反馈的模型:

  • GPT-3 模型也称 davinci 模型,它虽然具备基础的响应能力,但是创造性比较差,在逻辑构造方面也比较难形成有规律或者说逻辑紧密的回答,所以通常来说,项目的应用(即 GPT 模型 的接入)我们并不会直接选用 GPT-3 模型,更多是用于模型微调,来产生适合业务的变体。
  • GPT-3.5 模型是在 GPT-3 模型的基础上微调的产物,相比之下,它具备更强的语言逻辑组织能力和创造力,也是目前使用范围比较广的 GPT 模型。
  • GPT-4 模型在 GPT-3.5 模型上提供了更具有实效性的数据集来进行微调,在时效性、创造力上都有一定的提升,缺陷是还没有完全公开,需要体验名额,或者接入微软提供的 azure gpt 模型使用。

清晰认知 -- 最近大火的 ChatGPT 使用的是哪种模型?

那么我们平时常用 web ChatGPT 使用的是哪种模型呢?通常来说,使用的都是 GPT-3.5 模型,即 gpt-3.5-turbo 和 gpt-3.5-turbo-0301 这两种模型。

上文我们也提到 GPT-3 模型通常是不会直接用来应用的,而 GPT-3.5 模型是在 GPT-3 模型基础上做出的更具创造力的模型,也是最基本适合应用直接使用的模型。至于 GPT-4 模型目前还没有直接推广,需要和企业签订协议,或者拿到体验名额后才能尝试。(不过目前我实验下来的效果,个人感觉,GPT-4 和 GPT-3.5 并没有太大差异)

大家在看完 GPT 接入篇后也可以尝试接入一下 GPT-3 模型试试效果,相比目前的答案实体,GPT-3 的答案更像是信息的堆砌,所以这也是 GPT-3 模型通常是作为其他模型母体的原因。

思路确定 -- 应用阶段,我们应该选择哪种模型?

如果你的应用比较轻量,没有过多的业务背景或是技术壁垒(即没办法在外网查阅到),那么可以直接接入 GPT-3.5 及以上模型。

反之,如果你的应用需要了解业务背景,或者存在一些自研的能力,形成了技术壁垒,又或者是在时效性上有更高的要求,那么则需要以 GPT-3 模型为母体,进行微调。

微调的文档可以参考platform.openai.com/docs/api-re… ,这里不再赘述,需要注意的是,请提前准备好和你业务背景、技术能力相关的训练数据,微调的效果与数据集的完整度和逻辑可靠性强相关。

GPT 接入篇

迈出第一步 -- GPT 模型的接入 ?

相信大家在上面的学习中,应该已经对 GPT 模型有了一个较为清晰的认知,事实上,GPT 模型提供可以为应用接入的能力,我们可以按照自己想法为自己的业务接入 GPT,并基于它批量完成一些工程化的事情。

当然这里提到的自动化能力,绝不仅仅是 ChatGPT 这种 web 聊天这么简单, 通过对实际业务场景的通用性问题总结以及规律性结果处理,我们完全可以做到自动化完成一些工程化的事情,比如测试,代码优化等等,这个就是后话了,我们会在应用篇详细介绍。

GPT 模型提供了 fetch 和 npm 包两种方式接入,当然这两种接入方式底层都是相同的,npm 包可以理解为是基于 fetch 逻辑的 nodejs 包装。接下来,我会结合实际的例子来给大家详细讲解 GPT 模型的接入以及实际业务接入使用中必须解决的一系列问题。

GPT 模型接入 -- fetch

GPT 模型可以通过接口的方式来完成接入,上面我们提到 GPT-3 模型有很多变体,分别用于不同行业方向,比如 图片、聊天等,具体的文档大家可以参考 platform.openai.com/docs/api-re…

下面我们将以聊天模型的接入展开介绍,这个是我们应用中最常用的模型(即使不是用来做聊天室),它的结果更具备逻辑性,容易总结出通用性问题并集中处理, 我们来看下面的例子

const messages = "Once upon a time";
const apiKey = "<INSERT_YOUR_API_KEY_HERE>"; // OpenAI API 授权密钥
const apiUrl = "https://api.openai.com/v1/chat/completions";
const headers = {
  "Content-Type": "application/json",
  Authorization: `Bearer ${apiKey}`,
};
const data = {
  messages,
  max_tokens: 5,
};
const options = {
  method: "POST",
  headers,
  body: JSON.stringify(data),
};
fetch(apiUrl, options)
  .then((res) => res.json())
  .then((json) => console.log(json))
  .catch((err) => console.error(err));
复制代码

在上面的例子中,我们实现了一个简单的 fetch 方式的接入,其中 apiurl 即是 chatgpt 模型的接入地址,我们需要获取到 openAPI KEY 并作为鉴权传入 headers 中,其中 openAPI Key 可以从 openAI 账号中生成,是一个用户信息鉴权 key,使用过程将会消耗 openAI 的额度,大家可以到 platform.openai.com/account/api… 生成。

image.png

data 的部分是 openAI 提供给我们的参数,可以进行一些自定义的配置,大家需要关注的有下面这些参数:

  • model:文本生成器使用的模型,即 GPT-3.5及以上 模型
  • messages:文本生成器的输入,表示您要向 API 提出的问题或问题描述。
  • temperature:控制生成的文本的随机性。值越高,生成的文本越具有创造性和想象力。当然并不是越高越好,值越高,答案存在错误的可能性也越高,需要根据业务场景灵活调整,默认为 0.7。
  • max_tokens:生成文本的最大长度,以 token 数量为单位。默认为 150,最大为 2048。
  • top_p:控制模型多个单词的权重。取值范围从 0 到 1,默认为 1.0。
  • n:请求 API 生成的新文本的数量。默认为 1。
  • stop:如果生成的文本包含以下任意一个字符串,即停止文本生成过程。默认为一个空数组 []。
  • presence_penalty:生成文本时减少出现重复子串。若设置,则模型尝试消除两个已经重复出现的词语间的文本。默认为 0.0。
  • frequency_penalty:在生成文本时惩罚使用过于频繁的单词。较高的值有助于提高生成文本的多样性,但可能会导致生成文本的不连贯性等问题。默认为 0.0。

需要额外注意的是,该模型输入(即 messages)最大为 4096 token,这里 token 的单位指的是自然语言处理领域中的最小语言单位,可以理解成小于等于1个单词,而输出(即max_tokens)最大为 2048 token。

也就是说如果问题过大,或者说回答过大,都将会造成内容的截断,常规的调用并不能无限制地问答,当然这个也是有解法的,我们会在下文中流相关部分详细介绍。

GPT 模型接入 -- npm 包

除 fetch 调用外,我们还可以通过 npm 包的方式完成接入,当然底层都是用 fetch 链接,我们需要安装一下 npm 包的依赖。

npm install openai --save
复制代码

我们来结合例子看看具体应该怎么通过 npm 接入 GPT 模型

const openai = require("openai");
const prompt = "Once upon a time";
const apiKey = "<INSERT_YOUR_API_KEY_HERE>"; // OpenAI API 授权密钥
openai.api_key = apiKey;
const parameters = {
  model: 'text-davinci-003',
  prompt,
  max_tokens: 5,
};
openai.Completion.create(parameters)
  .then((response) => console.log(response))
  .catch((err) => console.error(err));
复制代码

不过需要注意的一点是,fetch 中我们举例调用的 chatgpt 模型,即 gpt-3.5-turbo 及以上模型,而 npm 包不需要填 fetch 链接,如果想调用了 davinci 模型(即 gpt-3),参数需要有一些调整,需要将 messages 换成 promt,因为 davinci 底层调用的链接其实是 api.openai.com/v1/completi…

如果用的是 gpt-3.5-turbo 及以上模型, 那么 parameters 中的问题描述参数请用 messages。

流获取 -- 如何解决 max_tokens 答案截断的问题?

在上文中,我们有提到 gpt 输出的结果长度由一个参数 max_tokens 限制,最大为 2048。但是在实际的业务场景中,我们不可能保证我们需要的答案一定只在 2048 内,一个可能截断的答案我们是没办法进行有效规律地提取我们需要的内容然后做一些事情的。

这个问题很头疼,但是是有解法的,我们来看下面这段示例

/**
 * 询问 openai 问题
 * @param question 
 * @returns 
 */
const openApiAsk = async (question: string) => {
  const openApiKey = 'test'; // your openApi key
  // 以流的方式接入
  const responseStream = await axios({
    method: 'POST',
    url: openAIURL,
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${openApiKey}`,
    },
    data: JSON.stringify({
      model: 'gpt-3.5-turbo',
      messages: [{ role: "user", content: question }],
      max_tokens: 2048,
      temperature: vscode.workspace.getConfiguration().get('chatgptUiUnitTest.temperature')
    }),
    responseType: 'stream'
  });
  return responseStream;
};
// 处理文件流
const question = "hello openai";
const resultStream = await openApiAsk(question);
const fileStream = fs.createWriteStream('test.txt');
resultStream.data.pipe(fileStream);
fileStream.on('close', () => {
  fs.readFile('test.txt', (err, data) => {
    fs.writeFile('test.txt', data.toString(), (err) => {
      // 二次处理, do something 
    });
  });
});
复制代码

在上面的例子中,我们在请求中补充了一个响应类型,即 responseType:stream,这将使得 openai 的响应将由一个固定的结果,调整为文件流。在后面的逻辑中,我们创建了一个可写流,接收这个可读流,并将内容完整写入到文件中。

流是一种处理读写文件、网络通信或任何端到端信息交换的有效方式。流的独特之处在于,它不像传统的程序那样一次将一个文件读入内存,而是逐块读取数据、处理其内容,而不是将其全部保存在内存中。这也是为什么通过这种方式可以突破 max_tokens 长度限制的原因,因为我们并不是一次性拿到全部的答案,而是逐步写入。


目录
相关文章
|
1天前
|
JavaScript 前端开发 数据可视化
Three.js第2篇,加载glb / gltf模型,Vue加载glb / gltf模型(如何在vue中使用three.js,vue使用threejs加载glb模型)
Three.js 是一个用于在 Web 上创建和显示 3D 图形的 JavaScript 库。它提供了丰富的功能和灵活的 API,使开发者可以轻松地在网页中创建各种 3D 场景、模型和动画效果。可以用来展示产品模型、建立交互式场景、游戏开发、数据可视化、教育和培训等等。这里记录一下如何在Vue项目中使用Three.js
30 4
Three.js第2篇,加载glb / gltf模型,Vue加载glb / gltf模型(如何在vue中使用three.js,vue使用threejs加载glb模型)
|
1天前
|
人工智能
苹果推出理解、转化模型ReALM,性能超GPT-4
【5月更文挑战第13天】苹果发布ReALM模型,将参考解析转化为语言建模,超越GPT-4。ReALM通过将非文本实体转为文本处理,解决了AI在处理特定问题时的局限。实验显示,ReALM在多种参考解析任务上优于GPT-3.5和GPT-4,尤其在屏幕实体参考解析上提升超5%。但模型可能因信息丢失和高计算需求带来挑战。[链接](https://arxiv.org/abs/2403.20329)
9 3
|
1天前
|
前端开发 JavaScript TensorFlow
如何将训练好的Python模型给JavaScript使用?
本文介绍了如何将TensorFlow模型转换为Web格式以实现浏览器中的实际应用。首先,简述了已有一个能够检测扑克牌的TensorFlow模型,目标是将其部署到Web上。接着,讲解了TensorFlow.js Converter的作用,它能将Python API创建的GraphDef模型转化为TensorFlow.js可读取的json格式,用于浏览器中的推理计算。然后,详细说明了Converter的安装、用法及不同输入输出格式,并提供了转换命令示例。最后,文中提到了模型转换后的实践步骤,包括找到导出的模型、执行转换命令以及在浏览器端部署模型的流程。
17 3
|
1天前
|
设计模式 JavaScript 算法
js设计模式-策略模式与代理模式的应用
策略模式和代理模式是JavaScript常用设计模式。策略模式通过封装一系列算法,使它们可互换,让算法独立于客户端,提供灵活的选择。例如,定义不同计算策略并用Context类执行。代理模式则为对象提供代理以控制访问,常用于延迟加载或权限控制。如创建RealSubject和Proxy类,Proxy在调用RealSubject方法前可执行额外操作。这两种模式在复杂业务逻辑中发挥重要作用,根据需求选择合适模式解决问题。
|
1天前
|
存储 监控 JavaScript
使用Node.js构建实时聊天应用的技术指南
【5月更文挑战第12天】本文指导使用Node.js、Express.js和Socket.IO构建实时聊天应用。技术栈包括Node.js作为服务器环境、WebSocket协议、Express.js作为Web框架和Socket.IO处理实时通信。步骤包括项目初始化、安装依赖、搭建服务器、实现实时聊天功能、运行应用以及后续的完善和部署建议。通过这个指南,读者可以学习到创建简单实时聊天应用的基本流程。
|
1天前
|
JavaScript 前端开发
JavaScript 提供了多种方法来操作 DOM(文档对象模型)
【5月更文挑战第11天】JavaScript 用于DOM操作的方法包括获取元素(getElementById, getElementsByClassName等)、修改内容(innerHTML, innerText, textContent)、改变属性、添加/删除元素(appendChild, removeChild)和调整样式。此外,addEventListener用于监听事件。注意要考虑兼容性和性能当使用这些技术。
7 2
|
1天前
|
前端开发 JavaScript UED
JavaScript 的事件循环机制是其非阻塞 I/O 模型的核心
【5月更文挑战第9天】JavaScript的事件循环机制是其非阻塞I/O的关键,通过单线程的调用栈和任务队列处理异步任务。当调用栈空时,事件循环从任务队列取出一个任务执行,形成循环。异步操作完成后,回调函数进入任务队列,等待被事件循环处理。微任务如Promise回调在每个宏任务结束后执行。此机制确保JavaScript能高效处理异步操作,不阻塞主线程,提供流畅的用户体验。
12 2
|
1天前
|
机器学习/深度学习 人工智能 自然语言处理
|
1天前
|
数据采集 JavaScript 数据可视化
Node.js爬虫在租房信息监测与分析中的应用
Node.js爬虫在租房信息监测与分析中的应用
|
1天前
|
机器学习/深度学习 运维 持续交付
构建高效自动化运维体系:Ansible与Docker的完美结合构建高效机器学习模型的五大技巧
【4月更文挑战第30天】 在当今快速发展的云计算和微服务架构时代,自动化运维已成为维持系统稳定性和提高效率的关键。本文将探讨如何通过结合Ansible和Docker技术构建一个高效的自动化运维体系。文章不仅介绍了Ansible与Docker的基本原理和优势,还详细阐述了如何整合这两种技术以简化部署流程、加强版本控制,并提高整体运维效率。通过案例分析,我们将展示这一组合在实际环境中的应用效果,以及它如何帮助企业实现持续集成和持续部署(CI/CD)的目标。 【4月更文挑战第30天】 在数据驱动的时代,构建一个高效的机器学习模型是获取洞察力和预测未来趋势的关键步骤。本文将分享五种实用的技巧,帮助数