自己搓一个编码大模型,凑齐语料就OK

文摘   科技   2023-09-16 11:20   江苏  


背景

    chatGPT火了之后,各行各业都得到了广泛应用,特别是软件开发领域其编码能力也很受广大程序猿们推崇,使用chatGPT进行代码补全、代码生成、UT生成,特别是遗留代码中补充新功能、增加用例等方面更是大显身手,降低了广大程序猿们的基础编程门槛,有chatGPT协助,使很多熟练使用chatGPT程序猿一个人就像带了一个小团队,切实提升了工作效率。

   另一方面,chatGPT自身编程能力也在快速演进中,以chatGPT3.5为例,其4月份humaleval pass@1的评分还只有47(该分数100为满分,某个大模型超过20分就具备辅助编程能力了),到了8月底该分数就提升到了68.9,chatGPT4更是超过了80分,远远甩开其他编码大模型,可谓进步神速。广大程序猿们也是越用越熟悉,越来越喜欢。

    但是chatGPT在可用性上也碰到不少局限,以下因素比较常见:

    1、网络原因

    有些同学受网络限制访问不了chatGPT。

    2、安全限制

    很多行业代码都不能上传外网,防止泄密。

    3、私域知识含量考虑

    a、编码阶段

    要开发的代码越是通用知识多,chatGPT越是好用,原因很简单,chatGPT本身就是通用语料训练出来的。表现出来就是prompt简单,理解能力超强,程序员上手容易,生成的代码采纳率高;

    与之相反,越是私有领域知识占比高,prompt越是复杂,chatGPT生成代码越是不靠谱,程序猿用得不顺手,很多时候仅作为一个查阅资料的工具。

    b、测试阶段

    对于FT、ST测试用例来说,也是贯穿业务流较长,私域知识含量高,chatGPT生成用例就有些不靠谱,也不好用。

    4、特有编程语言

    比如一些小众设计或编程语言,比如verilog、tla+等,由于预训练语料中占比不高,也会出现效果不明显的情况。

解决思路

    能否自研一个私域编码大模型,把私有业务知识灌入,然后内网部署推理,既可以解决网络和安全问题,也可以解决chatGPT私域知识不足的问题,岂不美哉?

    说干就干,其实自研编码大模型,只要解决算力、算法、语料三个问题就可以了。

    算力方面,采购GPU和服务器或租用环境GPU就可以了;

   算法则一般从开源编码大模型(比如llama2、starcode、mpd、codellama等)入手,进行增量预训练和精调即可,精调接口有很多开源的;

    最核心的是准备语料,它是真正私域知识的载体,成本和价值都最高,也是我们应该花大力气投入的地方。绝大多数开源大模型,都不会把它的精调语料开放出来,可见精调语料的重要性。

    大模型研发的方式一般为预训练和精调,预训练一般6b模型需要64-128张A800(GPU数量随着模型规模变化),而增量精调仅需要2-8张A800,成本相对可控,所有自研模型一般都从精调开始。

    与之相对应语料分为精调语料和预训练语料,其中精调语料更为重要,即使预训练后也必须精调才能使大模型正确输出内容。

    我们以代码语料来分析语料准备的全程。

一、精调语料

1、精调语料作用

    我们希望模型输出的形式和内容都符合我们的要求,其中,精调主要是用来控制模型输出的形式,预训练主要是用来控制模型输出的内容。我们的基础编程大模型使用了海量代码进行预训练,具备通用编程的能力,但模型输出的形式可能不满足项目的需求。在这种情况下,就需要对模型进行精调。

2、精调语料的格式

    精调数据本质上就是你给模型展示的一个个例子,每一条精调数据就是一个具体例子,模型看到足够多的例子之后,就能够学会你想要的输出形式。需要说明的是,如果输出的形式是正确的,但内容是错误的,这说明精调已经起作用了,但是基础数据不足,模型不具备足够的知识,这时候少量精调就没用了,而要用大量的代码对模型进行精调或预训练。

    单条精调数据都是一个json对象,只有两个字段:instruction和output。其中:

    instruction是你要发给模型的指示;

    output是你期望模型返回的内容。其中output的格式建议为:

    - text:首先根据instruntion的问题直接回答一段文字来引出代码

   - code:建议使用markdown格式,例如python是'''python开头, java是'''java开头,然后换行后生成代码,最后再以'''结束。

    - explanation:一般包含代码的功能,用法以及代码的思路。往往会对代码中的关键函数或者组件进行解释。

例如:

{"instruction": "使用python语言编写一个函数add,返回两个数字相加之后的和""output": "好的,使用python生成代码如下:```pythondef add (i, j):\n    return i+j```函数add输入两个数字,数字加分计算和"}

    将多条类似json串数据保存在一个文本文件中即可用于模型精调训练。

    生成精调语料的过程就是标注过程。

3、精调语料要素

a、多样性

i、instruction的提问方式也有很多种,尽量能使用各种各样的祈使句、疑问句等多种表达形式

ii、语料整体也要具备很强的多样性,有数学,有字符转换,有算法、有流程等。

iii、相同的语料也用不同形式的prompt多问几遍,效果更佳。

2、output代码长度

语料中代码50行以上效果较佳(经验数据),不能太短。

3、数量

一般至少(1-10)k条才能有效果。

二、预训练语料

    预训练语料预训练代码语料需要经过以下步骤预处理

1、清洗

    消除代码中格式、文档性注释、json和sql(仅需要结构)等数据

2、抽样

    建议20%有代表性文件全量抽取,其余80%文件在第一行和最后一行中随机抽取0-32行,少于32行取全量,抽取总量25-30%的文件。

3、去重

    一般使用局部敏感哈希(LSH)将相似的代码文件映射到同一个桶中。推荐Jaccard相似性为0.7(经验值)。相似度高的代码必须进行去重,防止对重复部分造成过拟合。

4、脱敏

    a、去重PII

    b、去除项目信息(项目名称、简称、版本号等)

    c、去除客户信息、密码、IP地址、密钥

5、权重

    各种编程语言的占比要均衡,要和团队中各种语言使用的比例相对应,这一步非常关键。

6、净化

    评测集数据和方案删除(比如HumanEval和MBPP字符串或解决方案)

    一般来说,对于13b的大模型,预训练语料要大于10G才有一定效果。

可以通过脚本来处理预训练语料。

    无论是精调语料还是预训练语料,训练时长都需要估算,使用我们经验公式推算:对于7b大模型,20b token语料,使用A800 80g单卡训练,预计时长为80-90天左右(以考虑GPU并行效率损失),其他模型、语料、GPU数量不同,可以以此类推。

小结

    自研大模型的关键是语料收集、预处理和标注,只有具备高质量的语料,才能自研出高质量的代码大模型。防止garbage in,garbage out出现。

    高质量的足量的语料才是项目真正的资产,后续尽管基座模型会持续演进,但语料可以重复使用,仅需要更基座大模型,并重新预训练、精调和评估即可,所以高质量语料是关键。


丁辉的软件架构说
代码匠艺,软件系统架构,AI平台和应用,生活趣事。
 最新文章