部署企业级ChatGPT,将AI整合进工作

cybozu发表于:2023年07月24日 17:04:46更新于:2024年06月19日 13:13:35

Index

引言

3月份AI应用大爆发催生了国内大量需求。

然而,所有的需求都不可避免得遇到很多非技术性的问题:

  • 部署开源模型的成本巨大,且效果成谜,65B的模型推理应用最少需要130G显存,而微调训练则需要额外添加8倍的资源。

  • ChatGPT官方API不对中国用户开放,且续费无法使用国内信用卡。强行使用存在法律隐患。

  • 企业用户对安全隐私存在更高的要求。


要解决上面问题,允许私有部署的云服务厂商无疑是最佳选择。

微软作为OpenAI的主要投资者之一,早在2021年11月就推出了Azure OpenAI 服务,支持模型的私有部署,并由Azure来提供安全保证。

在定价方面,Azure OpenAI和OpenAI官方一致,且不限制使用中国信用卡付费。

在网络访问层面,Azure的服务并没有被限制。


  caution  注意

  1.本文仅提供技术指导,不提供任何商业服务。
  2.Azure国际版是否存在其他法律风险,请咨询专业法务人士。
  3.截止2023年7月24日,有消息称美国政府准备限制中国公司使用美国云计算服务。到时候Azure OpenAI是否会受到影响,尚未可知。


申请

声明

本文省略申请Azure国际版账号和绑定信用卡的步骤。如若尚未申请,请参照此网页进行。这里将不再赘述。

再次强调:提供OpenAI服务的是国际版Azure,而不是国内版。


申请步骤

截止2023年7月24日,Azure OpenAI服务仅开放企业用户申请,需要在此处进行填表。

所有的信息请以英文如实填写

需要特别注意的事项如下:

1.目前只支持企业邮箱,当前Azure对于企业邮箱的认定规则为:邮箱的域名必须和第12条的Company Website域名一致。

00164be48cfad3c3fd82c903d133971

00164be48f571de103636554e48e843

比如,如果你所在公司的网页为xxx.abc.com,那么你的企业邮箱必须为yy@abc.com。


2.第22条的OpenAI service feature请只选择Text and code models,这个是大语言模型。

00164be4981e2752b564dddc0a586ef

DALL-E 2是OpenAI画图模型。一旦勾选会增加额外的审核流程。


3.第23条的Select your use case(s),需要覆盖你的AI模型的应用场景,请按需选择。

00164be49ca0205addd6597f0d79096


4.提交申请后,你会在10个工作日内收到核审通过的邮件。

00164be4a3d21c33b5d0b32d77033b5

而审核失败的话,则会列出失败原因。

00164be4a6f9c759a15bebd3098311e

可选操作

通过审核后,你可以再申请GPT4模型的部署权限。


部署

获得权限后,我们进入Azure主页,点击创建资源

00164be4bb0682c68b73ff2d814387f

搜索OpenAI,点击创建->Azure OpenAI。

00164be4c12eb5c942dab6ace241796


在自己的订阅下新建一个资源组,区域选择离我们最近的地域,名称随意,定价层选标准的即可。

00164be4cbfbf2db85f45f2f2ce24ed


一直点击下一步。

作为演示,我们使用默认配置,有其他需求的,请按照自己的需求进行定制。


点击服务名称进入详细画面。

00164be4d70097adbc6f86b0eb09af1


点击模型部署,前往部署画面。

00164be4da8a38ce2c1f7eb9580b944


点击管理部署,进入Azure OpenAI Studio。

00164be4e3b53a4c1976c5c9e8901ed

点击新建部署,按需选择gpt模型,添加部署名,按需更改默认值,最后创建。

00164be4eb70c1b46c50698eb69c252

部署成功后,勾选部署模型,点击在操场中打开。

00164be4f07bbbe0e43db32f2cece55

进入调试画面后,点击查看代码。

00164c89e7aa2e0a5cc4745aa82ef71

复制终结点,这些信息会在我们接下来的应用实例中用到。

00164c89efc865088f4e95f72a8ede8

应用

部署

接下来我们将演示一个实际的案例,将ChatGPT服务整合进kintone。

同比环比数据可视化这个Demo为基础,我们为其添加AI分析功能。


将之前复制的终结点的值,粘贴到src目录下的index.js

00164c8b577246fccb71cb6642a8b5d

在项目根目录下运行以下指令:

npm i && npm run build


dist目录下的成果物上传到kintone。

我们能看到如下效果:

00164c8b79d0d5d60f35fa34a7ea52d

原理

本质上,目前所有的GPT应用,都是让ChatGPT担任翻译工作。

翻译并不单单是自然语言之间的互译,也包含自然语言到计算机程序、数字到自然语言的翻译。

在上面的案例中,我们利用Prompt Engineering,对GPT的输出内容进行控制

{role: 'system',content: `I want you to act as an ${role} and translator. I can communicate with you in any language you prefer. Based on the data my provide, You will respond to my questions in my chosen language.`,},
{role: 'user',content: `I need a concrete conceptual plan. Use the following data to provide an answer to the question: "${input}"         
//Today is ${new Date().toISOString().slice(0, 10)} and ${datas}`,},


由于Azure的Restful API本身默认是跨域的,我们不需要使用kintone.proxy中转,可以直接用使用fetch。

但是如果我们想做到1个个单词输出的效果,就必须在request中设定steam,也就是SSE。

{
method: 'POST',
mode: 'cors',
headers: { 'api-key': apikey, 'Content-Type': 'application/json' },
body: JSON.stringify({messages: [
      {role: 'system',content: `I want you to act as an ${role} and translator. I can communicate with you in any language you prefer. Based on the data my provide, You will respond to my questions in my chosen language.`,},
      {role: 'user',content: `I need a concrete conceptual plan. Use the following data to provide an answer to the question: "${input}"         //Today is ${new Date().toISOString().slice(0, 10)} and ${datas}         `,},],
max_tokens: 800,
temperature: 0.7,
frequency_penalty: 0,
presence_penalty: 0,
top_p: 0.95,
stream: true,
}

利用微软的@microsoft/fetch-event-source,我们可以简单的在画面上接受SSE的每个message。

onmessage(ev) {
const msg = JSON.parse(ev.data).choices[0]?.delta?.content
if (msg) {
if (!txtel) {
txtel = document.createElement('p')
txtel.className = 'anwser'
el.appendChild(txtel)
}
const word = document.createElement('span')
word.className = 'spantxt'
word.style.animationDelay = `${index * 0.01}s`
word.textContent = msg
txtel.appendChild(word)
index += 1
if (msg.includes('\n')) {
txtel = undefined
}
}
},

最后利用css的animationDelay,将每个单词延迟输出,实现逐字输出的视觉效果。

word.style.animationDelay = `${index * 0.01}s`