Index
引言
3月份AI应用大爆发催生了国内大量需求。
然而,所有的需求都不可避免得遇到很多非技术性的问题:
部署开源模型的成本巨大,且效果成谜,65B的模型推理应用最少需要130G显存,而微调训练则需要额外添加8倍的资源。
ChatGPT官方API不对中国用户开放,且续费无法使用国内信用卡。强行使用存在法律隐患。
企业用户对安全隐私存在更高的要求。
要解决上面问题,允许私有部署的云服务厂商无疑是最佳选择。
微软作为OpenAI的主要投资者之一,早在2021年11月就推出了Azure OpenAI 服务,支持模型的私有部署,并由Azure来提供安全保证。
在定价方面,Azure OpenAI和OpenAI官方一致,且不限制使用中国信用卡付费。
在网络访问层面,Azure的服务并没有被限制。
注意
1.本文仅提供技术指导,不提供任何商业服务。
2.Azure国际版是否存在其他法律风险,请咨询专业法务人士。
3.截止2023年7月24日,有消息称美国政府准备限制中国公司使用美国云计算服务。到时候Azure OpenAI是否会受到影响,尚未可知。
申请
声明
本文省略申请Azure国际版账号和绑定信用卡的步骤。如若尚未申请,请参照此网页进行。这里将不再赘述。
再次强调:提供OpenAI服务的是国际版Azure,而不是国内版。
申请步骤
截止2023年7月24日,Azure OpenAI服务仅开放企业用户申请,需要在此处进行填表。
所有的信息请以英文如实填写。
需要特别注意的事项如下:
1.目前只支持企业邮箱,当前Azure对于企业邮箱的认定规则为:邮箱的域名必须和第12条的Company Website域名一致。
比如,如果你所在公司的网页为xxx.abc.com,那么你的企业邮箱必须为yy@abc.com。
2.第22条的OpenAI service feature请只选择Text and code models,这个是大语言模型。
DALL-E 2是OpenAI画图模型。一旦勾选会增加额外的审核流程。
3.第23条的Select your use case(s),需要覆盖你的AI模型的应用场景,请按需选择。
4.提交申请后,你会在10个工作日内收到核审通过的邮件。
而审核失败的话,则会列出失败原因。
可选操作:
通过审核后,你可以再申请GPT4模型的部署权限。
部署
搜索OpenAI,点击创建->Azure OpenAI。
在自己的订阅下新建一个资源组,区域选择离我们最近的地域,名称随意,定价层选标准的即可。
一直点击下一步。
作为演示,我们使用默认配置,有其他需求的,请按照自己的需求进行定制。
点击服务名称进入详细画面。
点击模型部署,前往部署画面。
点击管理部署,进入Azure OpenAI Studio。
点击新建部署,按需选择gpt模型,添加部署名,按需更改默认值,最后创建。
部署成功后,勾选部署模型,点击在操场中打开。
进入调试画面后,点击查看代码。
复制终结点和键,这些信息会在我们接下来的应用实例中用到。
应用
部署
接下来我们将演示一个实际的案例,将ChatGPT服务整合进kintone。
以同比环比数据可视化这个Demo为基础,我们为其添加AI分析功能。
将之前复制的终结点和键的值,粘贴到src目录下的index.js中
在项目根目录下运行以下指令:
npm i && npm run build
将dist目录下的成果物上传到kintone。
我们能看到如下效果:
原理
本质上,目前所有的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`