很快AI智能体开始自己分解任务、解决任务,最后汇总。
三分钟后,第一版结果出来了。性能接近 68%,但精度偏差太大了。
一个大大的红色FAIL显示在屏幕上。
赵文渊在旁边松了一口气。
这才正常嘛。
他对韩路一说:“韩总你看,这就是我说的难点,做不过来”
韩路一没有回应赵文渊。
他重新打开CUDA的源代码,开了视界。
普通人看代码,看到的是字符。赵文渊看代码,看到的是逻辑。
但视界让韩路一看到的是另一层东西,不只是代码在做什么,还有代码为什么这样做。
每一个设计选择背后的权衡,都像批注一样浮现在代码旁边。
为什么softmax没有用最直觉的实现方式,而是拆成了三个阶段?因为直觉实现在长序列上会有数值溢出。
为什么矩阵乘的分块是这个尺寸,不大也不小?因为再大shared memory放不下,再小会产生内存冲突。
这些东西没有写在任何文档里。它们是英伟达的工程师经过无数次实验之后沉淀下来的经验,藏在代码的结构里,只有真正理解硬件的人才能读出来。
赵文渊不是读不懂代码,他只是没办法在几天之内,就把别人几年的工程经验全部提炼出来。
但是视界可以,韩路一可以。
韩路一关掉第一版的提示词,重新输入。
这一次,他没有让智能体自由发挥。
而是把视界看到的东西直接输入进去。
“softmax必须使用 online algorithm三阶段,不要使用 naive softmax。当前精度问题出在第二阶段 reduce,局部最大值和指数和更新顺序要保持一致。”
“矩阵乘 tile使用64x64,tile过大 shared memory不够,过小会增加 bank conflict。”
“reduce时按4-stride展开,避免 bank conflict。”
“K/V矩阵按 row-major缓存在 shared memory,避免跨 bank连续冲突。”
“先保证精度,再做性能优化。”
回车。
智能体又开始勤勤恳恳的劳动了。
五分钟后,一个大大的绿色PASS出现在屏幕上。
赵文渊在旁边眼珠子都快要瞪出来了。
“不是……这怎么回事?”
他不顾韩路一还坐在电脑前,把头凑到屏幕前面,把测试报告从头到尾看了一遍。
精度误差:2.3e-6,远低于1e-5的要求。
性能:N卡实现的83%。
不是70%,是83%。
赵文渊又把生成的代码拉出来,逐行看了一遍。
他越看越沉默。
这段代码根本不是那种“能跑就行”的粗糙实现:softmax用的是三阶段online algorithm,reduce的展开策略干净利落,shared memory的使用几乎没有浪费。
这是一个对底层硬件有深刻理解的人才能写出来的东西。
不,准确地说,是一个对底层硬件有深刻理解的人,才能指导AI写出来的东西。
赵文渊转过头,看着韩路一。
“韩总,你第二次输入的那些提示词softmax三阶段、tile 64x64、4-stride展开你怎么知道的?”
韩路一靠在椅背上:“我看了文档。”
“我去,原来你看了文档啊,不早说。”赵文渊先开了个玩笑,然后声音突然拔高了,“我也看了两天文档,跑了十几个测试,我都没找到这个tile尺寸,你看了几分钟就看出来了?”
韩路一没有回答,只是笑了笑。
赵文渊盯着他看了好一会儿,最后像是泄了气一样靠回椅子上。
“行吧。”他说,“我不问了。”
他之前不是没想过用AI来做这些工作,但是AI根本做不了。每次跑出来的结果,不是卡死,就是偏差太大。
怎么韩路一一上手就好用了?
赵文渊现在只想火速删掉发给韩路一的那个共享文档的标题。
韩路一在他眼前,把他觉得不可能的事情做出来了。
如果这个不是偶然呢?
如果scaled_dot_product_attention可以这样做,那其他算子呢?
什么暂无可行性啊?
什么叫“别想了,没戏”啊?
这不是有戏了吗?
他现在非常想让那个前同事过来现场看看。
第一百八十四章 处理过了,干净
周一上午十点,鼎盛大厦三十二层。
张弛的办公室朝南,晴天的时候能看到陆家嘴的轮廓。今天有雾,窗外是一片均匀的灰白。
刘亚光进来的时候,张弛正在看一份周报,头没抬:“说。”
“源码那边对接上了。”刘亚光在沙发上坐下来,声音压得很低,“他们往算力集群里送的数据,我们这边实时能拿到副本。”
张弛放下手机,看了他一眼:“现在进来的是什么?”
“预训练的数据。”刘亚光说,“就是洗过的语料。”
张弛皱了一下眉:“洗过的语料是什么意思?他们模型意图理解很强,是用的这个数据吗?”
刘亚光正了正身子,同时摇摇头:“训练大模型不是一步到位的。”
他停顿了一下,思考该怎么说:“我给您解释一下,这分几个阶段。第一步叫预训练。这个阶段喂给模型的是海量的原始文本网页、书籍、论文、论坛帖子,来源越杂越好,量越大越好,好一点的模型这个阶段要喂几万亿个词。模型在这个阶段做的事很简单,就是反复猜下一个词是什么。给它看「今天天气」,它猜「很好」;给它看「深度学习的本质是」,它猜「优化」。猜对了往前走,猜错了调参数,反复几千亿次,模型就慢慢学会了语言的规律,学会了世界上大量的知识和常识。”
张弛点点头。
刘亚光继续说道:“这个阶段的数据不需要人工标注,有什么文本就喂什么,但要先洗把乱码、重复内容、低质量的垃圾过滤掉,不然模型学了一堆噪声,反而有害。洗数据这个活听起来简单,但洗得好不好,直接影响预训练出来的模型底子有多扎实。”
“那第二步呢?”
“第二步才是让模型真正聪明起来。”刘亚光说,“要让它理解人的意图,知道同样一句话背后用户真正想要什么,这需要另一批数据,那些专门标注过的,一条一条告诉模型「这个场景下正确答案是这个」。这批数据量小很多,但每一条都要人工判断,很难批量生产。按照您之前告诉我的,源码的模型之所以意图理解强,核心就是这批标注数据。”
张弛听完总结道:“他们现在进来的是第一步的数据,但我们真正想要的是第二步的那批。”
“对。”刘亚光肯定道。
张弛看向窗外思考了几秒,又问:“技术上能确认,他们往云上送的数据,我们全都能拿到?”
“应该能的。”刘亚光说,“只要数据进了他们用的算力节点,我们这边就有完整副本,他们那边看不出来。”
张弛靠回椅背,语气平稳:“那先把这批预训练的语料导出来用。”
刘亚光有些惊讶:“这批数据没有标注,价值有限,我们自己也有语料”
“我知道。”张弛说,“我不是为了这批数据。主要是看看这条通道稳不稳,能不能安全导出。先跑一遍,如果他们那边没有动静,路径没问题,后面就好办了。”
他似笑非笑一下,补充道:“反正不用白不用,给坤元那边送过去,用不用看他们了。”
刘亚光点了点头,说:“明白了,张总。”
从张弛办公室出来,刘亚光一路出了鼎盛大厦,坐上了去鼎盛云园区的公交车。
刘亚光的工位在云园区,他今天是特意来给张弛当面汇报的。
下午两点,刘亚光在工位上给张弛发了条消息:“张总,数据弄好了。”
张弛过了几分钟才回复:“干净吗?”
刘亚光:“处理过了,干净。”
张弛:“给数据组发过去吧。”
刘亚光放下手机,在电脑上打开内部通讯,给吴英豪发了个消息:“在吗?”
然后他拿起手机,给吴英豪的微信发了一条:“有新数据。”
不一会,吴英豪发了个戴绿头盔的表情包回来。
刘亚光把一个加密压缩包的链接从内部通讯发了过去。
然后他在微信里给吴英豪有发了一句话:“密码老样子,走数据入库流程,来源写外部采购,批次号我生成好了,你们填进去就行。”
吴英豪的微信消息回复很快:“质量怎么样?”
“洗过的,能用。”
“好。”
吴英豪不是第一次从刘亚光这拿数据了,这事不干净,两人有固定的默契。
数据组每隔一段时间就会有这种批次进来,来源五花八门,有的是爬的,有的是买的,有的是“合作方共享”的。填外部采购是最干净的写法,因为采购来源很杂,审计不容易查到。
这种事不是第一次,也不会是最后一次。
三天后,坤元项目组。
刘大海盯着屏幕上的一条曲线,看了大概三分钟没动。
这是坤元这一轮预训练的Loss曲线。
Loss是损失值可以理解成模型犯错的程度,数字越低说明模型学得越好。训练的过程就是让这条曲线一路往下走。
这条曲线确实在往下走,但走得比他预期的快。
刘大海把时间轴拉长,把上一轮的曲线叠进来对比。差异很明显,不像是误差范围内的波动,应该是系统性的提升。
他在心里排除了几个可能的原因:学习率没改,模型架构没动,算力配置没变。难道这批数据有特殊?
刘大海立刻站起来,动身去了数据组。
数据组的负责人叫吴英豪,三十出头,戴眼镜。数据组主要的工作就是收集和清洗数据。
这是个脏活,累活,在大模型开发的产业链里比较底层。
刘大海过去的时候他正在核对一份入库日志。
“英豪,这轮训练咱用了什么新数据没有?”刘大海拍了下他的椅背。