【OpenAI】私有框架代码生成实践

作者:京东零售 牛晓光

根据现有调研和实践,由OpenAI提供的ChatGPT/GPT-4模型和CodeX模型能够很好的理解和生成业界大多数编程语言的逻辑和代码,其中尤其擅长Python、JavaScript、TypeScript、Ruby、Go、C# 和 C++等语言。

然而在实际应用中,我们经常会在编码时使用到一些私有框架、包、协议和DSL等。由于相关模型没有学习最新网络数据,且这些私有数据通常也没有发布在公开网络上,OpenAI无法根据这些私有信息生成对应代码。

一、OpenAI知识学习方式

OpenAI提供了几种方式,让OpenAI模型学习私有知识:

1. 微调模型

OpenAI支持基于现有的基础模型,通过提供“prompt - completion”训练数据生成私有的自定义模型。

使用方法

在执行微调工作时,需要执行下列步骤:

1. 准备训练数据:数据需包含prompt/completion,格式支持CSV, TSV, XLSX, JSON等。

  • 格式化训练集:openai tools fine_tunes.prepare_data -f <LOCAL_FILE>
  • LOCAL_FILE:上一步中准备好的训练数据。

2. 训练模型微调:openai api fine_tunes.create -t <LOCAL_FILE> -m <BASE_MODULE> --suffix "<MODEL_SUFFIX>"

  • LOCAL_FILE:上一步中准备好的训练集。
  • BASE_MODULE:基础模型的名称,可选的模型包括adababbagecuriedavinci等。
  • MODEL_SUFFIX:模型名称后缀。

3. 使用自定义模型

使用成本

在微调模型方式中,除了使用自定义模型进行推理时所需支付的费用外,训练模型时所消耗的Tokens也会对应收取费用。根据不同的基础模型,费用如下:

【OpenAI】私有框架代码生成实践

结论

使用微调模型进行私有知识学习,依赖于大量的训练数据,训练数据越多,微调效果越好。
此方法适用于拥有大量数据积累的场景。

2. 聊天补全

GPT模型接收对话形式的输入,而对话按照角色进行整理。对话数据的开始包含系统角色,该消息提供模型的初始说明。可以在系统角色中提供各种信息,如:

  • 助手的简要说明

  • 助手的个性特征

  • 助手需要遵循的指令或规则

  • 模型所需的数据或信息

我们可以在聊天中,通过自定义系统角色为模型提供执行用户指令所必要的私有信息。

使用方法

可以在用户提交的数据前,追加对私有知识的说明内容。

openai.createChatCompletion({
  model: "gpt-3.5-turbo",
  messages: [
    { role: "system", content: "你是一款智能聊天机器人,帮助用户回答有关内容管理系统低代码引擎CCMS的技术问题。智能根据下面的上下文回答问题,如果不确定答案,可以说“我不知道”。\n\n" +
      "上下文:\n" + 
      "- CCMS通过可视化配置方式生成中后台管理系统页面,其通过JSON数据格式描述页面信息,并在运行时渲染页面。\n" + 
      "- CCMS支持普通列表、筛选列表、新增表单、编辑表单、详情展示等多种页面类型。\n" + 
      "- CCMS可以配置页面信息、接口定义、逻辑判断、数据绑定和页面跳转等交互逻辑。"
    },
    { role: "user", content: "CCMS是什么?" }
  ]
}).then((response) => response.data.choices[0].message.content);


使用成本

除了用户所提交的内容外,系统角色所提交的关于私有知识的说明内容,也会按照Tokens消耗量进行计费。

【OpenAI】私有框架代码生成实践

结论

使用聊天补全进行私有知识学习,依赖于系统角色的信息输入,且此部分数据的Tokens消耗会随每次用户请求而重复计算。

此方法适用于私有知识清晰准确,且内容量较少的场景。

二、私有知识学习实践

对于私有框架、包、协议、DSL等,通常具备比较完善的使用文档,而较少拥有海量的用户使用数据,所以在当前场景下,倾向于使用聊天补全的方式让GPT学习私有知识。

而在此基础上,如何为系统角色提供少量而精确的知识信息,则是在保障用户使用情况下,节省使用成本的重要方式。

3. 检索-提问解决方案

我们可以在调用OpenAI提供的Chat服务前,使用用户所提交的信息对私有知识进行检索,筛选出最相关的信息,再进行Chat请求,检索Tokens消耗。

而OpenAI所提供的嵌入(Embedding)服务则可以解决检索阶段的工作。

使用方法

1. 准备搜索数据(一次性)

  • 收集:准备完善的使用文档。如:https://jd-orion.github.io/docs

  • 分块:将文档拆分为简短的、大部分是独立的部分,这通常是文档中的页面或章节。

  • 嵌入:为每一个分块分别调用OpenAI API生成Embedding。

await openai.createEmbedding({
  model: "text-embedding-ada-002",
  input: fs.readFileSync('./document.md', 'utf-8').toString(),
}).then((response) => response.data.data[0].embedding);


  • 存储:保存Embedding数据。(对于大型数据集,可以使用矢量数据库)

2. 检索(每次查询一次)

  • 为用户的提问,调用OpenAI API生成Embedding。(同1.3步骤)

  • 使用提问Embedding,根据与提问的相关性对私有知识的分块Embedding进行排名。

const fs = require('fs');
const { parse } = require('csv-parse/sync');
const distance = require( 'compute-cosine-distance' );

function (input: string, topN: number) {
  const knowledge: { text: string, embedding: string, d?: number }[] = parse(fs.readFileSync('./knowledge.csv').toString());

  for (const row of knowledge) {
    row.d = distance(JSON.parse(row.embedding), input)
  }

  knowledge.sort((a, b) => a.d - b.d);

  return knowledge.slice(0, topN).map((row) => row.text));
}


3. 提问(每次查询一次)

  • 给请求的系统角色插入与问题最相关的信息
async function (knowledge: string[], input: string) {
  const response = await openai.createChatCompletion({
    model: "gpt-3.5-turbo",
    messages: [
      {
        role: 'system',
        content: "你是一款智能聊天机器人,帮助用户回答有关内容管理系        统低代码引擎CCMS的技术问题。\n\n" + knowledge.join("\n")
      },
      {
        role: 'user',
        content: input
      }
    ]
  }).then((response) => response.data.choices[0].message.content);
  return response
}


  • 返回GPT的答案

使用成本

使用此方法,需要一次性的支付用于执行Embedding的费用。

【OpenAI】私有框架代码生成实践

三、低代码自然语言搭建案例

解决了让GPT学习私有知识的问题后,就可以开始使用GPT进行私有框架、库、协议和DSL相关代码的生成了。

本文以低代码自然语言搭建为例,帮助用户使用自然语言对所需搭建或修改的页面进行描述,进而使用GPT对描述页面的配置文件进行修改,并根据返回的内容为用户提供实时预览服务。

使用方法

OpenAI调用组件

const { Configuration, OpenAIApi } = require("openai");
const openai = new OpenAIApi(new Configuration({ /** OpenAI 配置 */ }));
const distance = require('compute-cosine-distance');
const knowledge: { text: string, embedding: string, d?: number }[] = require("./knowledge")

export default function OpenAI (input, schema) {
  return new Promise((resolve, reject) => {
    // 将用户提问信息转换为Embedding
    const embedding = await openai.createEmbedding({
      model: "text-embedding-ada-002",
      input,
    }).then((response) => response.data.data[0].embedding);
    
    // 获取用户提问与知识的相关性并排序
    for (const row of knowledge) {
      row.d = distance(JSON.parse(row.embedding), input)
    }
    knowledge.sort((a, b) => a.d - b.d);
    
    // 将相关性知识、原始代码和用户提问发送给GPT-3.5模型
    const message = await openai.createChatCompletion({
      model: "gpt-3.5-turbo",
      messages: [
        {
          role: 'system',
          content: "你是编程助手,需要阅读协议知识,并按照用户的要求修改代码。\n\n" + 
                  "协议知识:\n\n" +
                  knowledge.slice(0, 10).map((row) => row.text).join("\n\n") + "\n\n" + 
                  "原始代码:\n\n" +
                  "```\n" + schema + "\n```"
        },
        {
          role: 'user',
          content: input
        }
      ]
    }).then((response) => response.data.choices[0].message.content);

      // 检查返回消息中是否包含Markdown语法的代码块标识
    let startIndex = message.indexOf('```');
    if (message.substring(startIndex, startIndex + 4) === 'json') {
      startIndex += 4;
    }

    if (startIndex > -1) {
      // 返回消息为Markdown语法
      let endIndex = message.indexOf('```', startIndex + 3);
      let messageConfig;

      // 需要遍历所有代码块
      while (endIndex > -1) {
        try {
          messageConfig = message.substring(startIndex + 3, endIndex);

          if (
            /** messageConfig正确性校验 */
          ) {
            resolve(messageConfig);
            break;
          }
        } catch (e) {
          /* 本次失败 */
        }

        startIndex = message.indexOf('```', endIndex + 3);

        if (message.substring(startIndex, startIndex + 4) === 'json') {
          startIndex += 4;
        }

        if (startIndex === -1) {
          reject(['OpenAI返回的信息不可识别:', message]);
          break;
        }

        endIndex = message.indexOf('```', startIndex + 3);
      }
    } else {
      // 返回消息可能为代码本身
      try {
        const messageConfig = message;

        if (
          /** messageConfig正确性校验 */
        ) {
          resolve(messageConfig);
        } else {
          reject(['OpenAI返回的信息不可识别:', message]);
        }
      } catch (e) {
        reject(['OpenAI返回的信息不可识别:', message]);
      }
    }
  })
}


低代码渲染

import React, { useState, useEffect } from 'react'
import { CCMS } from 'ccms-antd'
import OpenAI from './OpenAI'

export default function App () {
  const [ ready, setReady ] = useState(true)
  const [ schema, setSchema ] = useState({})

  const handleOpenAI = (input) => {
    OpenAI(input, schema).then((nextSchema) => {
      setReady(false)
      setSchema(nextSchema)
    })
  }

  useEffect(() => {
    setReady(true)
  }, [schema])

  return (
    <div style={{ width: '100vw', height: '100vh' }}>
      {ready && (
        <CCMS
          config={pageSchema}
          /** ... */
        />
      )}
      <div style={{ position: 'fixed', right: 385, bottom: 20, zIndex: 9999 }}>
        <Popover
          placement="topRight"
          trigger="click"
          content={
            <Form.Item label="使用OpenAI助力搭建页面:" labelCol={{ span: 24 }}>
              <Input.TextArea
                placeholder="请在这里输入内容,按下Shift+回车确认。"
                defaultValue={defaultPrompt}
                onPressEnter={(e) => {
                  if (e.shiftKey) {
                    handleOpenAI(e.currentTarget.value)
                  }
                }}
              />
            </Form.Item>
          }
        >
          <Button shape="circle" type="primary" icon={ /** OpenAI icon */ } />
        </Popover>
      </div>
    </div>
  )
}


四、信息安全

根据OpenAI隐私政策说明,使用API方式进行数据访问时:

  1. 除非明确的授权,OpenAI不会使用用户发送的数据进行学习和改进模型。
  2. 用户发送的数据会被OpenAI保留30天,以用于监管和审查。(有限数量的授权OpenAI员工,以及负有保密和安全义务的专业第三方承包商,可以访问这些数据)
  3. 用户上传的文件(包括微调模型是提交的训练数据),除非用户删除,否则会一直保留。

另外,OpenAI不提供模型的私有化部署(包括上述微调模型方式所生成的自定义模型),但可以通过联系销售团队购买私有容器。

文中所使用的训练数据、私有框架知识以及低代码框架均源自本团队开发并已开源的内容。用户使用相关服务时也会进行数据安全提示。

原文链接:https://www.cnblogs.com/Jcloud/p/17370365.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:【OpenAI】私有框架代码生成实践 - Python技术站

(0)
上一篇 2023年5月4日
下一篇 2023年5月4日

相关文章

  • 登峰造极,师出造化,Pytorch人工智能AI图像增强框架ControlNet绘画实践,基于Python3.10

    人工智能太疯狂,传统劳动力和内容创作平台被AI枪毙,弃尸尘埃。并非空穴来风,也不是危言耸听,人工智能AI图像增强框架ControlNet正在疯狂地改写绘画艺术的发展进程,你问我绘画行业未来的样子?我只好指着ControlNet的方向。本次我们在M1/M2芯片的Mac系统下,体验人工智能登峰造极的绘画艺术。 人工智能太疯狂,传统劳动力和内容创作平台被AI枪毙,…

    2023年4月5日
    00
  • 循环神经网络(RNN)的基本原理及LSTM的基本结构

    来源于课上实验,结果清晰,遂上传于此 该课件仅用于教学,请勿用于其他用途。 详细参考 实验笔记 实验视频 一、实验目的 学习掌握循环神经网络(RNN)的基本原理及LSTM的基本结构; 掌握利用LSTM神经元构造循环神经网络进行训练和预测时间序列。 二、实验内容 通过PC上位机连接服务器,登陆SimpleAI平台,利用python语言搭建基于LSTM的RNN模…

    2023年4月8日
    00
  • keras模块学习之model层【重点学习】

        本笔记由博客园-圆柱模板 博主整理笔记发布,转载需注明,谢谢合作!   model层是keras模块最重要的一个层,所以单独做下笔记,这块比较难理解,本博主自己还在学习这块,还在迷糊中。    model的方法: model.summary() : 打印出模型概况 model.get_config() :返回包含模型配置信息的Python字典 mod…

    Keras 2023年4月5日
    00
  • 多维卷积与一维卷积的统一性(运算篇)

    转自 http://blog.sina.com.cn/s/blog_7445c2940102wmrp.html   本篇博文本来是想在下一篇博文中顺带提一句的,结果越写越多,那么索性就单独写一篇吧。在此要特别感谢实验室董师兄,正因为他的耐心讲解,才让我理解了卷积运算的统一性(果然学数学的都不是盖的)。 —————————-…

    2023年4月6日
    00
  • tensorflow roadshow 全球巡回演讲 会议总结

    非常荣幸有机会来到清华大学的李兆基楼,去参加 tensorflow的全球巡回。本次主要介绍tf2.0的新特性和新操作。 1. 首先,tensorflow的操作过程和机器学习的正常步骤一样,(speaker: google产品经理)如图:           2. 接下来是 google tf 研发工程师,对tf2.0的新特性进行了部分讲解。     (注:e…

    2023年4月8日
    00
  • 使用Tensorflow object detection API——训练模型(Window10系统)

      【数据标注处理】   1、先将下载好的图片训练数据放在models-master/research/images文件夹下,并分别为训练数据和测试数据创建train、test两个文件夹。文件夹目录如下      2、下载 LabelImg 这款小软件对图片进行标注   3、下载完成后解压,直接运行。(注:软件目录最好不要存在中文,否则可能会报错)   4、…

    2023年4月8日
    00
  • Python_sklearn机器学习库学习笔记(七)the perceptron(感知器)

      一、感知器   感知器是Frank Rosenblatt在1957年就职于Cornell航空实验室时发明的,其灵感来自于对人脑的仿真,大脑是处理信息的神经元(neurons)细胞和链接神经元细胞进行信息传递的突触(synapses)构成。      一个神经元可以看做将一个或者多个输入处理成一个输出的计算单元。一个感知器函数类似于一个神经元:它接受一个或…

    机器学习 2023年4月10日
    00
  • TensorFlow + Keras 实战 YOLO v3 目标检测图文并茂教程

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习、深度学习的知识! 运行步骤 1.从 YOLO 官网下载 YOLOv3 权重 wget https://pjreddie.com/media/files/yolov3.weights 下载过程如图: 2.转换 Darknet YOLO 模型为 K…

    2023年4月8日
    00
合作推广
合作推广
分享本页
返回顶部