隨著风波的平息,深视科技进入了一段难得的平稳期。
    公司的api调用量每天都在刷新纪录,现金流像涓涓细流匯成江河般涌入公司帐户。
    一切看起来都在轨道上高速运转。
    华清嘉园工作室,
    陈阳把自己关了起来。
    他正在进行一项实验,那就是训练超越这个时代的大语言模型。
    陈阳给这场行动取了一个代號:巴別塔。
    深夜,客厅。
    空调开到18度,陈阳坐在三台並联的显示器前,屏幕上密密麻麻的代码与日誌在流动。
    桌上散落著七八个空咖啡杯、三盒吃空的外卖、一堆揉皱的草稿纸。
    他已经在这把椅子上坐了十四个小时,眼睛布满血丝,下巴冒出了青色的胡茬。
    旁边的写字板上画了一张架构图,密密麻麻的线条和方块,像一张蜘蛛网。
    程序早就写好了。
    那套他高中暑假就开始设计出来的架构,代码已经调试完毕,理论上完全可行。
    但理论与实际能跑之间,隔著一道天堑。
    就像你设计了一张火箭的图纸,画得再漂亮,也得真正发射一次才知道能不能上天。
    这几天经过实际运行,这是陈阳优化后的第七版了!
    “不对,还是不对。“
    陈阳揉了揉发酸的眼睛,把第七版也刪掉了。
    他靠在椅背上,盯著天花板发呆。
    陈阳闭上眼睛,脑子里不断闪过各种画面。
    突然,一个念头击中了他。
    陈阳猛地坐直了身子。
    抓起笔,在一张白纸上疯狂画起来。
    “就是这个。“
    他转向电脑,开始敲代码。
    手指飞快地在键盘上跳动,屏幕上的字符像瀑布一样往下滚。
    大模型预训练,说白了就是三个字:餵数据。
    要把海量的文字塞进模型里,让它自己去学习语言的规律。
    看得越多,学得越好,最后就能像人一样理解和生成文字。
    听起来简单?
    一点都不简单。
    首先,数据从哪来?
    陈阳花了快一年时间,让星城那边的团队爬取了整个维基百科、几百万篇新闻报导、上千万条论坛帖子、小说的片段,清洗、去重、格式化,最后整理出三套数据:
    第一套,训练集,12.4gb。
    这是餵给模型的课本,让它自己从海量文字里自学语言规律。
    对,没错就是自己学习,模型一开始是一个什么都不知道的孩子。
    然后通过海量数据以及算法反馈。逐渐从数据里面学习规律,最终找到答案。
    第二套,验证集。
    这是提前准备好的隨堂测验,题目和標准答案都是现成的。
    比如给模型一句话:“珠穆朗玛峰多高“,標准答案是:“8848米“。
    模型回答完,跟答案一对,就知道它学得怎么样。
    验证集有两个用处。
    第一,防止死记硬背。
    如果模型在课本上的题越做越好,但隨堂测验的分数不涨反降,那就说明它只是在背课本原文,换道新题就懵了。这叫过擬合,得赶紧调整。
    第二,判断什么时候该停。
    模型不可能无限进步。
    学到一定程度,该会的都会了,再学也没什么提升了。
    怎么判断到没到这个点?
    就看验证集的分数。
    一开始,分数会蹭蹭往上涨。
    然后涨得越来越慢。最后,曲线变平了,连著好几轮分数都不动了。
    这就说明模型训练完成,可以停了。
    再往下硬学,就是浪费时间。
    第三套,测试集。
    这是最后的期末考试。
    同样是题目和標准答案,但模型在训练过程中从来没见过这套题。
    等训练结束、验证集曲线平稳之后,才拿出这套卷子做最终检验。
    为什么要单独留一套?
    因为验证集虽然没直接餵给模型,但你一直拿它来调整训练策略,模型多少会间接学到一些规律。就像老师反覆用同一套题摸底,学生慢慢就摸到套路了。
    测试集不一样,它从头到尾没告诉过模型。
    只有这套全新的题也能考高分,才能证明模型是真的学会了。
    三套数据,各司其职。
    课本、隨堂测、期末考,缺一不可。
    其次,算力够不够?
    这一块因为有超算中心,所以已经能吊打99%的ai实验室。
    但陈阳知道,还是不够。
    远远不够。
    他现在训练的是一个一亿参数的模型。
    就需要差不多十分之一算力,如果后续训练更大参数的模型,这点算力远远不够。
    模型的训练参数越多,就越聪明,但需要的算力也越恐怖。
    按他的估算,这次动用的十几台伺服器全力运转,至少要跑三天三夜才能完成一轮训练。
    中间任何一个环节出问题:loss不收敛、显卡过热、內存溢出、代码bug。
    那么一切就得从头再来。
    最后也是最关键的:流程能不能跑通?
    预训练不是按一下回车就完事了。
    数据要分批加载,模型要分布式並行,梯度要跨机器同步,检查点要定时保存,任何一个环节卡住,整个流程就会崩盘。
    这套流程,陈阳写了三万多行代码,调试了整整一周,依然不敢保证万无一失。
    今晚,就是最后的验证。
    凌晨5点38分,代码写完。
    陈阳深吸一口气,手指悬在回车键上方。
    这一刻,他突然有点紧张。
    说实话,他也不知道这玩意儿能不能跑通。
    理论上是对的,逻辑上是通的。
    但理论和现实之间,往往隔著一道叫做玄学的鸿沟。
    多少看起来完美的设计,一跑起来就原地爆炸。
    “开始吧。“
    没有继续犹豫,陈阳敲下回车。
    屏幕上,程序开始运行:
    [系统]正在初始化模型……
    [系统]参数量:1亿
    [系统]开始训练……
    陈阳盯著屏幕,大气都不敢出。
    前三十分钟是最危险的。
    数据加载、模型初始化、第一次前向传播、第一次反向传播,任何一步出错,程序就会直接崩掉。
    陈阳的目光像钉子一样钉在屏幕上,手心全是汗。
    十分钟。
    二十分钟。
    三十分钟。
    没有报错。
    他长出一口气,但还不敢放鬆。
    接下来要看的是loss值。
    loss,翻译过来是损失,可以理解成错误率。
    数字越高,说明ai越蠢,答案错得越离谱。
    数字越低,说明它越聪明,离正確答案越近。
    第一个数字跳了出来。
    10.87,很高,但这是正常的。
    刚开始嘛,模型什么都不懂,纯粹在瞎矇。
    关键是接下来能不能降。
    陈阳盯著屏幕,等待下一轮结束。
    一亿参数的模型,跑完一轮需要差不多三十分钟。
    而要让模型真正学会东西,至少需要跑一百多轮。
    也就是说,整个训练至少要三天三夜。
    这是一场漫长的煎熬。
    第一天。
    [epoch 5] loss: 8.34
    [epoch 12] loss: 6.71
    [epoch 20] loss: 5.43
    loss在稳步下降。
    陈阳每隔半小时就看一眼屏幕,確认曲线还在往下走。
    困了就灌咖啡,饿了就啃麵包,眼睛始终没离开过那串跳动的数字。
    到了深夜,loss降到了5以下。
    陈阳有点撑不住了,回臥室眯了几个小时。
    第二天。
    下降速度开始变慢了,但还在降。
    这是正常的。
    就像爬山,越接近山顶,坡度越陡,每走一步都越来越难。
    陈阳盯著那条曲线,心里默默计算。按这个速度,最终应该能收敛到2点几。
    然后,问题出现了。
    下午三点,loss卡在了2.41,死活不动。
    连续十几轮,纹丝不动,曲线变成了一条水平线。
    陈阳的眉头皱了起来。
    显存没爆,梯度没消失,数据也在正常加载,到底卡在哪了?
    他排查了两个小时,终於找到原因:学习率太大了。
    就像下山找最低点,步子迈太大,直接跨过了山谷,跳到对面去了。
    他把学习率调小,从断点继续跑。
    二十分钟后,loss开始鬆动:2.38。
    2.31。
    2.24。
    陈阳长出一口气。
    第三天凌晨。
    窗外的天色从漆黑变成深蓝,又从深蓝变成鱼肚白。
    陈阳这几天都呆在这里,胡茬冒了一脸,但此刻眼睛却亮得嚇人。
    因为模型的曲线开始收敛。
    他死死盯著屏幕,看著最后几轮训练完成。
    loss: 2.03。
    数据曲线平稳了下来,训练完成了。
    此时窗外,天已经亮了,第一缕阳光穿透云层,照进实验室。
    陈阳长长鬆了一口气,身体瘫软在椅子上。
    成了。
    架构跑通了,理论被验证了。
    在椅子上休息了一阵。
    陈阳站起身,走到窗边,窗外是渐渐甦醒的城市。
    楼下有人在遛狗,早餐店冒出白色的蒸汽,计程车载著乘客驶向远方。
    没有人知道,在这间不起眼的房间里,一扇通往新世界的大门,刚刚被推开了一条缝。
    他低头看了眼手机,屏幕上显示著日期:2013年4月28日。