大模型火起来已经一年多,大家应该已经见过很多prompt提示工程和SFT微调训练的文章,但讲预训练的少之又少。原因也简单:没这么多显卡和数据。
作为 AI 信徒,不亲自跑一把体验一次,总觉得自己信仰不纯。也一度想试一试 NanoGPT 项目,直到我突然发现:百度智能云千帆平台上,提供了全套的 post-pretrain、sft 和 rlhf 功能可供使用——其他云厂只有 prompt api 或者最多有 sft 功能——这太让人惊喜了!接下来几个月,我算扎扎实实把增量预训练和微调训练跑了一遍,花了 3000 元。期间给百度提了两位数的工单,今天记录一下,供大家参考。
首先,训练模型肯定要有数据集。甚至可以说数据集才是大模型训练过程中最重要的工作。
平台在创建数据集的时候,对不同的训练阶段,有不同的数据类型要求。
数据导入时,你可能会碰上各种各样的局部数据导入失败。最常见的包括:
此外,你还会很郁闷的看到数据量和本地都对上了,但就说有非utf8编码的导入失败,其实可能是因为内容是全英文代码程序,被认为是 ascii 编码了。导入其实成功了,就是平台 bug 而已。
导入数据以后,可以进行数据清洗、数据分析、数据增强。
数据增强就是著名的 self_instruct。在一年前大家基本都通过这个方案来调 openai 接口生成大量微调数据。但现在很多结论证明微调其实不带来多少新知识,只是对齐和规范输出格式。那么少量微调数据就足够了。我这次也没尝试做数据增强。
数据分析会自动给你的数据分类,你可以根据结果来判断自己准备的语料是不是偏了要不要补充一些针对性的内容。但我个人体会:分类太细了,基本无意义,执行还特别慢。这步大家跳过算了。
数据清洗按说应该是很重要的一步,开源大模型的技术报告中,都会专门讲解数据清洗步骤。百度云在这块也提供了很多功能,包括:
\s
空格和\n
换行这种都算。开启以后你的数据看起来就跟文言文一样总结一下:百度云平台提供的流程很全,但是用起来很难,建议大家这部分还是本地写 python 跑吧。这类数据清洗工作逻辑简单,AI 都能帮你写好,我全程是让智谱 4.0 帮我生成的。
把长文档拆分成短文档时,有一个需要额外注意的地方:尽量保证段落完整。这块我采用的方案是,原始的adoc/docx/pdf/html文档尽量转换为 markdown 格式(pandoc 命令和 pdfplumber 库, tabulate 库),然后配合使用 markdown 库切分 section 和 tiktoken 库计算 token 数,尽量接近 4096 上限的划分 sections 到不同文件里。
百度 ernie 的 token 计算和 tiktoken 有些差异,百度云平台有计算器可以手工验证,但这个无伤大雅,不用太在意。
大模型预训练需要较多的语料。平台上明确提示说最好 10 亿 token,至少要 1000 万 token。平台之前会大概按照你的数据量字节数估算一下,不到 1GB 的明显不够,直接就不让提交预训练任务——但是刚才我打开发现提示文案还在,但约束被取消了??
所以重点就是怎么获取本领域足够的语料,尤其是高质量语料。依然以开源的 SecGPT 为例,数据很大一部分是论文、书籍、CVE 漏洞库。不过我和作者沟通,作者表示实际训练时按比例缩减了论文的部分:
类似的,我们如果要训练一个运维领域大模型,论文、书籍,也会是一个重点来源。
很可惜,这部分目前没有看到比较公开的语料库,从科研角度,比较现实的办法可能是下载一些影印图片的 PDF,然后通过 OCR 方式转换成 txt 纯文本——好在 OCR 已经是一个很成熟的领域,我个人经验,百度飞桨的 PaddleOCR 在中文识别上的效果非常 OK,比传统的pytesseract库高不知道多少~强力推荐!
至于 ocr 程序,照样还是让智谱 4.0 来生成。国产 LLM 生成国产库的代码,基本靠谱……反而让 GPT/claude/Bard 生成 paddleocr 的代码效果都不太行。
一般来说,PDF 文件经过 OCR 变成 txt 以后,大小会缩水 20-100 倍,取决于图片是否高清。大家可以根据这个来估算自己要下载多少 PDF~
到这步,终于可以开始大模型预训练了。
最终的数据集版本点击“发布”后,进入 post-pretrain 页面创建预训练任务:
选择你发布的纯文本数据集,然后开启混合训练,按照推荐的选择 5:1。千万注意,这里又是百度云的一个坑。因为通常大家都说领域数据和通用数据混合比例1:5,但百度的页面上偏偏是反过来说通用数据和领域数据5:1——事实上他们连自己产研都坑了,页面上的提示文案之前也推荐用户选1:5,是我报 bug 后刚改的。
表单底部可以看到估算的费用。必须预先充值到大于这个估算范围的最大值,否则无法继续。甚至即使这样,我依然在第三天收到一条短信,告诉我要超额,任务要停。但最后又正常运行结束了。我也不知道这个计费系统到底颗粒度是怎么回事……
总之,训练完成后,你可以看到预训练过程的困惑度和训练损失曲线:
可以看到,loss%一开始就挺低的,后续也没下降多少。某种程度上说明,我准备的运维领域语料,其实大多在 ernie 的原始语料中,已经覆盖到了——事实上在 openaiops 社区的运维大模型评测中,我司贡献的日志运维题库,ERNIE-Bot 4.0 的得分就高达 79 分,遥遥领先。
拿到一个经过 post-pretrain 的基座大模型,下一步就是“去 SFT”。
创建 SFT 任务的表单多数内容差不多,需要注意调整是“迭代轮次”超参。表单默认是 1,但是要根据实际数据情况来增加。另外,增加迭代轮次,其实就是重复训练,所以花的钱也是等比例变多的。
有趣的是:百度平台上对 post-pretrain 后“去 SFT”的任务,建议不仅仅是混合数据训练,而是先用平台预置的通用数据做一次 SFT,获取通用对话能力,然后再用自己的领域问答数据,做第二次 SFT,加强领域问答能力(https://cloud.baidu.com/doc/WENXINWORKSHOP/s/5lptj85pi)。但同时,SFT 任务的增量训练,又有一个要求,就是上一次的 SFT 必须是全量更新,不能是 Lora——所以大家开通计费时,同一个基座模型的三种训练方式的计费都得开通。
SFT 训练同样有 loss%曲线可看,还有 BLEU 等评估指标。评估指标应该是越高越好。显然下图显示效果非常烂,本次 SFT 的钱就是买个教训了:
和百度工程师的沟通,对方认为:我的微调数据集构成有较大问题。其中一些选择题,prompt 一大段文本,response 就一个字母。而这些评估都是基于 response 内容来计算。所以,要获取更好的结果,还是应该多构建一些工程化的 prompt 和 response。
这也让我想到从 GPT4 以来,大模型的输出普遍更加“啰嗦”的现状——看来大模型训练数据,就是要多解释逻辑细节。然后使用时有需要了再通过 prompt 去限定简短格式。如果训练数据就简短,就训练不到逻辑了。
基于百度智能云千帆大模型平台的大模型训练经验/教训分享就到这里了。边写文章边发现百度云今天半价了!我这文章也不是软文,SFT 效果又不理想,亏了亏了。口口口,口口!