他们两目前的每天提交记录非常活跃。
岑言刚刚吃饭的时候就已经看过了。
利昂目前的办公地点在东京,东京比京海晚一小时,现在这时间,估计在睡觉。
他锁定的那根刺,是利昂处理的动态长度句子输入的问题。
在自然语言处理任务里,句子的长度总是不一样的。
机器需要把这些句子放进矩阵里计算。目前的做法非常笨拙,他们预先设定好几个固定长度的桶,也就是容器。
如果句子长度不够,就往里面强行填塞无用的字符来凑数。
如果句子太长,就直接截断。
这种思路虽然又笨又呆板,但也确实是现在大部分人能想到最好的逻辑思路。
岑言看着利昂写的那些繁琐的判断逻辑和补齐代码,忍不住在心里吐槽。
这代码写得又长又臭,为了迁就这种落后的机制,利昂甚至写了一大堆重复的静态计算图。
每次训练都得重新构建,算力简直全拿去打水漂了。
岑言新建了一个Issue。
在GitHub上,Issue通常是用来给作者提建议或者报告漏洞的。
但岑言不是来提建议的。
他是来直接打脸的。
《关于序列模型中动态长度处理的算力浪费与优化重构》
来人,开始钓鱼,上饵料!
既然要是饵料,那就要来点尖锐的。
岑言一点客套话都没说,直奔主题。
他先截取了利昂代码里的三段核心逻辑,直接指出这种桶排序机制导致的显存占用冗余率高达百分之三十以上。
bro,你是怎么进谷歌的?卖钩子吗?
bro,静态图,你简直是在作茧自缚。
bro,你的身份很亮眼,你的代码像消遣。
bro,......
岑言其实从小到大就没怎么喷过人。
他觉得自己是一个很有涵养的人。
但是今天,他觉得自己喷爽了。
大抵那个温文尔雅的他,还是被后世那些二极管网络环境给影响到了吧,绝对不是他想这么喷的。
只不过他现在这种喷法还是有些新颖。
来吧,让现在的纯良程序员感受一下来自后世的网络攻击吧!
一顿猛喷之后,岑言开始给糖吃。
他直接写了一段优化的伪代码。
这段代码抛弃了固定的桶,引入了一种全新的动态遮罩机制。
配合动态批处理的思想,在数据输入层直接计算实际长度,把那些无用的补齐部分在注意力计算时直接屏蔽掉。
他甚至附带了一张简单的文字版流程图,把数据流转的过程画得清清楚楚。
写完这部分,岑言点击了提交。
看到这里,可能会有人问了。
你岑言计算机实力什么时候这么屌了?还能这样根据别人的问题实时给出答案。
岑言的回答是。
我确实没那么屌,但这玩意在我的记忆数据中心里有,就是利昂哥自己在明年才会给出的全新方案。
我用你的成果来征服你。
你可以不认可我,但你不可能不认可未来的自己。
除非你现在就在巅峰期。
心满意足地摧毁利昂哥的信心,岑言又转头去寻找卢卡斯的踪迹。
卢卡斯的工作偏向算法的工业化转化,他最近一直在死磕循环神经网络的长序列并行计算问题。
岑言找到卢卡斯几天前在一个开源社区发起的讨论帖。
帖中,卢卡斯和几位同行探讨如何解决长文本训练时梯度消失和无法并行的问题。
他提出通过改进门控单元来缓解,但这属于治标不治本。
岑言毫不客气地在回复框里敲下极具攻击性的话。
bro,循环结构,死路一条。
只要你还需要依赖上一个时间步的输出作为下一个时间步的输入,那你们的模型就是纯废物,堆再多的显卡也没用。
别写代码了,回去你的波兰农场种玉米和棉花去吧。
还好。
开的是匿名。
为了防止被当成只会喷人的喷子,岑言紧接着给出了干货。
当然了,他给的干货也是卢卡斯自己的成果。
针对自注意力机制替代循环结构的核心推导。
完全抛弃序列时序计算,只利用全局注意力矩阵来进行位置编码和特征提取,不仅能够捕捉到更长距离的依赖关系,还能让模型在矩阵运算层面实现完美的全并行计算。
简单的方法,足以把卢卡斯现在的研究方向推翻。
忙完这些,已经过了零点。
岑言伸了个懒腰,关掉电脑屏幕,去洗漱睡觉。
鱼饵已经撒下去了,就看这两条大鱼什么时候咬钩。
时间来到十几个小时后。
东京涩谷区,谷歌办公楼。
难得来一次公司。
现在他们工作基本上是可以自宅工作。
但来都来了,还是装装样子好。
利昂端着一杯美式咖啡走到工位坐下。
他昨晚在家里自闭干活到很晚,一直在调优那个该死的句子补齐代码。
测试结果依然不理想,显存占用居高不下,训练速度慢得比奥尼尔的奶奶过马路一样慢。
oh,man,自己前阵子不该熬夜看nba五大囧的。
利昂有些懊恼地挠乱了自己的头发。
他习惯性打开电脑,登录GitHub,查看自己维护的仓库。
后台提示有个新的Issue,标签被系统自动标记为高优先级建议。
利昂点开这个由一个黑猫头像用户提交的Issue。
看到标题的那一刻,他挑了挑眉。
这个用户什么履历和工程都没有,纯纯的空白小号一个。
哪来的路边?
跑来指点我的算力优化?
他喝了口咖啡,带着审视又有些许不屑的目光往下看。
当看到岑言指出显存冗余率的数据时,利昂的动作停住了。
嗯?
holly shit,bro?
这个数据和他昨晚跑出来的测试结果惊人地一致。
他放下咖啡杯,身体前倾,凑近屏幕仔细阅读后续的内容。
随着视线扫过岑言给出的那段伪代码和动态遮罩机制的思路,利昂整个人都不好了。
这段逻辑太清晰了。
抛弃固定的桶,在计算环节直接通过掩码屏蔽无效数据。
这不仅仅是代码层面的优化,这完全是一种降维打击的工程思维。
他之前隐隐约约有这个方向的想法,但是一直没有很好的执行方案。
利昂快速尝试这段伪代码的运行结果。
几分钟后。
“砰!”
他一巴掌拍在办公桌上,把旁边工位的同事吓了一跳。
玛德,这个逼!
高级工程师不得了是吧?平时见不到人,来了就搁这吓人?!
无视了同事的蛐蛐,利昂双眼放光。
绝妙的思路!
这种动态Batch的处理方式,至少能把现在的训练效率提升百分之四十以上。
利昂立刻想要回复这个黑猫用户。
他敲了几行感谢的话,但觉得不够,又删掉。
他迫切地想知道这个人是谁,想和他探讨这种机制在分布式训练下的具体实现细节。
哪怕对方在Issue里狠狠的喷了他,那些垃圾话比他看NBA的时候,那些球员喷的垃圾话狠多了。
可利昂怀疑自己有抖M倾向。
不然怎么被他那么骂,自己不仅不会不高兴,还很想要再被他骂几句呢?
利昂百思不得其解。
他在回复框里写下长长的一段话。