零点五
项目评审会的会议室在二十一楼,落地窗外是整片灰蒙蒙的天空。五台笔记本电脑排成一排,五位评审的表情像是提前商量好了似的,统一得令人心寒。
我站在投影幕布旁边,手里的激光笔还亮着,红色的光点在幕布上微微颤抖。幕布上的PPT停在最后一页,那是一行我用了一个月打磨的slogan——“让每一个声音都被听见。”
评审组长叫程志宏,四十六岁,方脸,金丝眼镜,说话的时候习惯性地用手指敲桌面。他敲了三下,然后开口了。
“沈言,你这个项目——”他顿了顿,像是在斟酌措辞,又像是在积蓄某种力量,“我们五个人讨论过了,一致意见是……不太行。”
他把打分表推过来。我低头看了一眼,那张A4纸上印着五个评分框,每个框里都写着一个数字。
零。
五个零。
我以为自己看错了,眨了眨眼睛,再看一遍。还是五个零。
会议室里安静了大概有五秒钟,安静到我能听见隔壁房间复印机运转的嗡鸣声。窗外的云压得更低了,像是要下雨。我的手掌心开始出汗,激光笔的金属外壳变得滑腻腻的。
“程老师,”我开口,声音还算稳,“零分的意思是——”
“意思是从商业价值、技术可行性、市场前景、团队能力、创新性这五个维度来看,你这个项目都不具备立项条件。”坐在程志宏左边的女人接过话头。她叫邱敏,是公司从外面请来的行业顾问,据说在互联网圈混了十五年,说话从来不看人脸色,“说得直白一点,沈言,你这个东西没有人会用的。语音社交?市面上已经有七八个成熟产品了,你凭什么觉得自己能切进去?”
“我的算法不一样。”我说。
“算法?”邱敏嘴角浮起一个极淡的笑,那种笑容我在职场里见过很多次,它不表达善意,表达的是一种居高临下的怜悯,“你所谓的核心算法,我刚才听你讲了四十分钟,本质上就是一个语音匹配的推荐模型。类似的模型,市面上开源的有十几个。你花了两年时间就做了这个?”
我的喉咙发紧。两年。她说得对,我花了整整两年。七百多个日夜,我一个人写了六万行代码,搭建了整套语音识别加情感分析加智能匹配的底层架构。为了让模型在嘈杂环境下的识别准确率提高零点三个百分点,我曾经连续调试了三天三夜没合眼。
但在她嘴里,这些东西只是“类似的模型市面上有十几个”。
“而且你刚才的演示出了故障。”坐在最右边的一个秃顶男人补充道。他叫赵建国,是公司技术部的总监,平时跟我抬头不见低头见,偶尔在茶水间遇到还会聊两句球赛。此刻他说话的语气公事公办,像是在汇报一个跟自己毫无关系的系统bug,“语音交互卡顿了两次,有一次直接没响应。评审会之前你没测试过吗?”
“测试过,”我说,“可能是会议室的网络不太稳定——”
“不要说网络的问题。”赵建国摆了摆手,“一个语音社交产品,在演示环节都搞不定语音交互,你让评审怎么相信你的技术是成熟的?”
我没有再辩解。因为我知道辩解没有用。一个项目被打五个零分,说明评审们不是来挑毛病的,他们是来判死刑的。在死刑面前,任何辩护都是多余的。
程志宏合上了面前的笔记本电脑,这个动作意味着今天的评审正式结束了。他把打分表往我这边又推了推,推到了桌沿。
“沈言,我是看着你进公司的。三年前你校招进来的时候,是我面的你。”他的语气变得柔和了一些,但这种柔和比刚才的严厉更让我难受,因为它代表着一种盖棺定论的惋惜,“你有才华,你的代码能力在你们那一届里是拔尖的。但这个项目……你投入太多了,有时候人要学会及时止损。”
“程老师,我——”
“行了,今天就这样吧。打分表你留着,想申诉的话走公司流程,一周之内提交材料到项目管理办公室。”他站起来,把椅子往桌下推了推,“不过我劝你别浪费时间,五个零分的评审意见,从我进这家公司到现在,没见过。”
他说完就走了。邱敏跟在后面,高跟鞋敲在地板上的声音又脆又急。赵建国走的时候看了我一眼,嘴唇动了动,像是想说什么,但最终什么都没说,拎着电脑包出去了。另外两位评审——一个财务的副总,一个运营的总监——从头到尾没有说过一句话,默默地收拾东西离开了会议室。
门关上了。
我一个人站在会议室里,面前是空荡荡的五把椅子,桌上是那张印着五个零分的A4纸。激光笔还亮着,红色的光点打在幕布上那句“让每一个声音都被听见”上面,像一个无声的讽刺。
让每一个声音都被听见。
但今天,没有一个人愿意听我的声音。
我在会议室里站了大概十分钟。窗外的天终于绷不住了,雨点噼里啪啦地砸在落地窗上,整个城市的高楼大厦在雨幕中变得模糊不清。我把激光笔关掉,把那张打分表折好放进兜里,然后拿起笔记本电脑走出了会议室。
走廊很长,天花板上的灯管坏了一根,明一暗地闪着。我走得很慢,步子沉得像脚上绑了沙袋。路过茶水间的时候,我看到赵建国在里面接水,他也看到了我,眼神接触了不到半秒就移开了。他端着杯子快步走出了茶水间,往跟我相反的方向去了。
我回到工位的时候,整个办公区的人都在假装很忙。没有人抬头看我,但我知道他们都在用余光扫我。五个零分的消息在评审会结束的瞬间就已经传遍了整个公司,比任何内部邮件都快。这就是职场,好消息没人关心,坏消息长着翅膀。
我的工位在大开间最角落的位置,旁边是服务器机房的通风口,一年四季都嗡嗡嗡地响。三年前我进公司的时候就被安排在这里,三年后我还是坐在这里。我带的项目叫“回声”——一个基于语音情感分析的社交匹配平台,用户通过语音交流,系统会根据声纹特征和情绪波动来推荐真正合拍的人。这个想法是我大四的时候想出来的,那时候我喜欢在深夜听广播,听那些素不相识的人打电话进直播间,跟主持人聊自己的烦恼和孤独。我发现很多时候,人们打电话不是为了寻求答案,只是想让自己的声音被听见。
“回声”这个名字,就是从那个时候定下来的。
但我花了两年时间,写了六万行代码,换来的结果是五个零分。
我坐在工位上,屏幕亮着,桌面是“回声”的项目文件——核心算法、前端界面、后台管理、用户数据库,一个又一个文件夹排得整整齐齐。我盯着这行字看了大概有十分钟,然后打开了核心算法的文件夹。
六万行代码,其中核心算法大概有一万两千行,是整个系统的心脏。语音识别模块、情感分析引擎、声纹匹配算法、动态学习层……我一行一行地往下翻,屏幕上密密麻麻的代码像一条一条的血管,每一行都是我一个字母一个字母敲出来的。
我的光标停在了主程序的第一行。
那句话是我两年前写的注释,绿色的,在两个斜杠后面:“//一切从这里开始,让每一个声音都被听见。”
我盯着那行注释看了很久,久到屏幕自动进入了屏保模式,黑底上飘着一个彩色的气泡。气泡在屏幕上游来游去,碰到边缘就弹回来,永不停歇。
然后我打开了终端。
输入了删除命令。
我的手指悬在回车键上方,只悬了一秒,然后按了下去。
删除进度条从零跳到百分之一,跳到百分之十,跳到百分之五十。硬盘灯开始疯狂地闪,风扇呜呜地转了起来。六万行代码在固态硬盘上被逐段抹除,物理地址上的数据变成了无法恢复的随机字节。
百分之百。
核心算法文件夹变成了空的。
然后我删了前端界面库。删了用户数据库的建表脚本。删了后台管理系统的全部模块。一个文件夹接一个文件夹,我的手指机械地敲着键盘,像是着了魔一样。
全删完了。
回收站被我清空。我又打开了一键还原的确认界面,把三年来的所有代码提交记录、版本迭代日志、测试用例数据,一条一条地勾选,然后点了“永久删除”。
电脑弹出一个确认框:“此操作不可撤销,确定要继续吗?”
我点了确定。
硬盘发出了最后一声尖锐的读写声,然后安静了下来。整个系统变得干干净净,三年来所有跟“回声”有关的一切,全部消失了。电脑像是被洗过了一遍脑,什么都不记得了。
我靠在椅背上,长长地呼了一口气。胸口没有想象中那么痛,反而有一种奇怪的轻松感,像是压在身上的某座大山突然被搬走了。两年,六万行代码,无数个不眠的夜晚,全部归零。也许程志宏说得对,人要学会及时止损。五个零分已经说明了一切,我做的这个东西从根本上就是一个错误。
手机在兜里震了。
我掏出来看了一眼,是苏敏——我前女友。我们已经三个月没联系了,她在这个时候发消息来,要么是巧合,要么是有人告诉了她评审会的结果。我猜是后者,因为公司里她的眼线不止一个。
“听说项目被毙了?”她的消息简短得像一封电报。
我不想回。但手指还是不受控制地打了几个字:“五个零分。”
“我早就说过,你不适合做产品。你太理想化了,总觉得技术能解决一切问题。但商业逻辑不是这样的。你那个项目,我从第一天就没看好过。”
我看着这段话,忽然觉得很有意思。苏敏当初跟我在一起的时候,说过完全相反的话。那时候她说,沈言你是我见过最有想法的人,你那个语音社交的点子一定会火的。她甚至在一次朋友聚会上帮我拉过投资,虽然最后没谈成。如今分手了,她说的是“我从第一天就没看好过。”
我没再回她的消息,把手机屏幕朝下扣在了桌上。但手机马上又震了,这次不是微信,是电话。屏幕上显示的是一个没存名字的号码,尾号四个八。
我接起来,声音疲得像用旧了的抹布:“喂。”
“沈言。”电话那头是一个中年男人的声音,浑厚、沉稳,带着一种常年发号施令养成的笃定感。这个声音我太熟悉了,全公司没有人不熟悉。
是赵鹤鸣。
公司的CEO,创始人,持股百分之三十七的实际控制人。他平时在顶楼办公,跟基层员工之间隔着至少三层管理层级。我在公司三年,跟他面对面说过的话加起来不超过十句。他从来没有直接给我打过电话。
而现在,距离我删完代码大概过了十分钟,他的电话来了。
“赵总。”我下意识坐直了身体。
“你在工位上?”他问。
“在。”
“你刚才对‘回声’项目的代码做了什么?”
我愣住了。他怎么知道的?我删代码这件事,从我坐到工位上到现在不过十来分钟,全程没有任何人过来看我的屏幕。除非——除非服务器机房里的监控系统捕捉到了什么异常。核心算法的备份文件存在公司的云端服务器上,我本地的删除操作触发了云端的同步删除协议,服务器那边可能弹出了安全警告。如果刚好有人看到了那个警告,再结合评审会的结果,不难猜出发生了什么。
“赵总,评审会给出了五个零分,”我深吸一口气,“项目没有继续推进的必要了,我清理了一下本地文件。”
电话那头沉默了大概三秒钟。这三秒钟安静得像一个黑洞,把我整个人往里吸。
“清理。”赵鹤鸣重复了这个词,语气很平,听不出喜怒,“你把六万行代码、两年的核心数据、十五份专利交底书,全部清理了?”
他连我写了多少行代码都知道。
“沈言,我现在跟你说两件事。”赵鹤鸣的声音依然平稳,但那种平稳里带着一种山雨欲来的压迫感,“第一,今天评审会的五个零分,不作数。评审委员会给出的结论没有经过我的确认,按照公司项目管理条例第七条第三款,CEO对评审结果有最终裁决权。”
我的呼吸停了一拍。
“第二,”他继续说,语速比刚才稍微快了一些,“你现在立刻停下手里的一切操作。你的电脑不要关机,不要断网,不要做任何操作。云端的备份需要时间恢复,你本地删除的东西,技术部的人会想办法给你找回——”
“找不回来了。”我打断了他,声音干涩得像砂纸,“我用的是底层擦除命令,数据在物理层面上已经没了。云端备份我刚才也同步清理了,回收周期是四十八小时,现在还没触发自动备份。”
电话那头又沉默了。这次的沉默比刚才更长,长到我能听见听筒里微弱的电流声。
“你确定?”赵鹤鸣的声音终于有了一丝波动,那种波动很细微,像是平静水面下涌过了一道暗流。
“确定。”
“你在工位上等着。”
电话挂断了。听筒里传来忙音,嘟嘟嘟地响了三声,然后归于寂静。
我拿着手机坐在工位上,脑子里的思绪像是被搅成了一锅粥。赵鹤鸣说五个零分不作数。赵鹤鸣说评审结论没有经过他的确认。赵鹤鸣——这家公司最大的老板——在电话里用一种明显在压着情绪的语气跟我说,你删掉的那些代码,是公司花了两年时间和大量资源堆出来的东西。
但我还是没想明白,一个被五位评审一致判了死刑的项目,为什么会让CEO亲自打来电话?
答案在七分钟之后揭晓了。
赵鹤鸣没有让我在工位上等,他直接下来的。电梯叮的一声响,他从走廊那头大步走过来,身后跟着三个人——一个是技术总监赵建国,表情慌乱,领带歪到了一边;一个是总裁办主任,手里拿着一个文件夹,踩着高跟鞋一路小跑;还有一个我不认识,西装革履,戴着蓝牙耳机,看起来像是法务或者投资方面的人。
整个办公区的人都愣住了。CEO下到基层员工的工位,这种场面在公司历史上从未发生过。坐在我旁边的同事们纷纷站起来,不知道该回避还是该留在原地,一个个脸上的表情像是被按了暂停键。
赵鹤鸣走到我工位前停下来。他五十三岁,头发花白,但腰板挺得笔直,一双眼睛极为锐利。他低头看了一眼我的屏幕——桌面上空空荡荡的,所有的项目文件夹都不见了。
“赵建国,”他头也不回地叫了一声,“看看还能不能恢复。”
赵建国挤过来,额头上一层细密的汗珠。他弯下腰操作我的电脑,手指在键盘上噼里啪啦地敲了一阵,打开磁盘管理器,查看分区表,运行了几个恢复检测命令。然后他直起腰,脸色白得像纸。
“赵总……擦除命令是直接覆写物理扇区的,数据恢复的几率……”他咽了口唾沫,“几乎为零。”
赵鹤鸣没有说话。他站在那里,俯视着坐在工位上的我,脸上的表情从愤怒变成了无奈,又从无奈变成了一种我说不清道不明的东西。他沉默了很久,久到整个办公区的空气都凝固了。
然后他做出了一个让所有人都没想到的举动。
他拉过旁边一把空着的转椅,在我对面坐了下来。他的膝盖几乎碰到了我的膝盖,这个距离对于一个CEO和一个基层工程师来说,近得有些离谱。
“沈言,”他开口了,声音比电话里轻了很多,像是在跟我说一个秘密,“今天评审会的事,你应该早一点告诉我。”
“我……我以为是走正常流程——”
“正常流程?”赵鹤鸣苦笑了一下,那种苦笑里带着一种“年轻人你真是什么都不懂”的无奈,“我问你,评审委员会给你的评分表上,五个维度的打分理由写了吗?”
“没有。只写了零分,没有写理由。”
“你知道为什么没写吗?”
我摇头。
“因为写不出来。”赵鹤鸣靠在椅背上,手指交叉放在腹部,姿态像一个准备讲长篇故事的老人,“程志宏他们不是不认可你的项目,他们是怕你的项目。”
“怕?”这个词让我觉得荒诞。
“怕。”赵鹤鸣的语气斩钉截铁,“你的‘回声’项目,从立项到现在,在我这里的优先级一直排在前三。你知道为什么吗?因为你的底层技术——那个语音情感分析引擎——它不仅仅是用来做社交匹配的。它可以被用在至少六个完全不同的商业场景里:智能客服情绪监测、在线教育专注度评估、车载语音安全预警、金融风控声纹识别、远程医疗情绪筛查,还有——”
他停了一下,目光直直地看着我。
“还有我们公司接下来两年最重要的战略项目——‘暮光’。”
“暮光”两个字落进我的耳朵里,像一块石头砸进了水面。这个代号我在公司内部论坛上看到过几次,但每次都只是只言片语,没有完整的信息。据说那是赵鹤鸣亲自抓的一个绝密项目,连参与人员的名单都是单独管理、不跟公司其他部门交叉的。
“暮光是什么?”我问。
赵鹤鸣没有直接回答。他转过头看了一眼跟在身后的总裁办主任,那个女人立刻从文件夹里抽出一份文件递给他。赵鹤鸣把文件放在我的桌上,封面朝下,压住了标题。
“这份文件是公司最高级别的商业机密,知道它完整内容的人,在整个公司不超过五个。”赵鹤鸣说,“评审委员会的五个人,只知道你的项目在‘暮光’的技术链条上占了一个位置,但他们不知道具体占的是什么位置。他们今天给你的五个零分,不是因为你的项目不行,恰恰相反——”
他翻开了文件的第一页。
“是因为你的项目太行了。如果‘回声’继续推进下去,你的技术成果会成为一个独立的业务板块,而在公司目前的组织架构里,有至少三个部门会因为你的项目而被整合甚至裁撤。程志宏手底下的传统社交业务部,邱敏负责的外部咨询板块,还有赵建国管理的技术中台——你的算法一旦成熟,他们的部门都会受到影响。”
我的目光落在翻开的那页文件上。密密麻麻的字和图表,但我只看到了最上方的标题——三个黑体大字:《暮光计划——基于声纹识别的下一代人机交互系统总体方案》。
标题下面有一行小字,写的是项目时间表。我顺着时间轴往下看,看到了“2025年Q3:完成语音情感分析核心算法部署”这一条。旁边标注的责任人一栏,赫然写着我的名字。
沈言。
“这个项目,”我抬起头看着赵鹤鸣,声音有些发抖,“你们从什么时候开始规划的?”
“两年前。”
“两年前我刚进公司——”
“对。”赵鹤鸣靠在椅背上,语气变得复杂起来,“你在面试的时候提过一个语音社交的点子,讲了不到三分钟,当时面试官里有一个技术出身的VP——他已经离职了,现在在硅谷——他当天晚上给我打了个电话,说老赵,今天面试了一个应届生,他说的那个方向,可能是下一代交互的入口。”
“所以你们——”
“所以我们把你招进来了。给你开了独立的项目空间,给了你最大的技术自由度,三年不给你设KPI,不让你参与任何跟‘回声’无关的业务。”赵鹤鸣的语气里有一种非常克制的懊恼,“你以为你一个应届生,凭什么能在公司里独立带项目带三年?你以为你三年不出业绩,部门总监从来没有找过你谈话,是为什么?”
我的后背贴在了椅背上,脑子嗡嗡作响。三年。我一直以为我之所以能安安静静地写代码,是因为公司不在意我、不在意这个项目。没想到恰恰相反,是因为太在意了。
“但评审会不知道这些。”赵鹤鸣把文件合上,推到我面前,“‘暮光’是绝密项目,所有的技术储备都是用代号和灰色预算推进的。评审委员会只能看到‘回声’作为一个独立产品的表现,他们看不到它在整个战略版图里的位置。程志宏和邱敏他们看到的是一个两年没出成果、演示还出了故障的烂项目,他们当然给零分。”
“可是赵建国——”我忽然想起技术总监的秃顶,“他知道‘暮光’的存在吗?”
“知道一部分,但不完整。”赵鹤鸣摇了摇头,“他只知道他的技术中台未来会有一个大项目需要语音算法支持,但他不知道那个算法就是你的核心引擎。在他眼里,你就是一个三年没出活的基层工程师,他给你零分,是因为他觉得自己能招到更好的人来替代你。”
原来如此。原来每一个零分背后都有各自的算盘。程志宏怕我的项目冲击他的部门,邱敏觉得我一个毛头小子不配被她认可,赵建国想拿我的位置去换他自己的招聘名额。五个零分,没有一个是真正冲着技术来的。
而我,在不知情的情况下,用了十分钟,把两年心血和公司最重要的战略项目的前置技术,一起删了个干干净净。
“赵总,”我的声音很低,“代码……真的回不来了。我用的是逐扇区覆写,相当于把一本书连纸带墨一起烧了,骨灰都扬了的那种。”
赵鹤鸣沉默了很久。整个办公区安静得落针可闻,所有人都屏着呼吸看着这一幕。
“我知道。”他终于开口了,声音疲惫得像是老了十岁,“但你知道我现在在想什么吗?”
“什么?”
“我在想,也许不是你的错。”他站起来,把那本封面朝下的文件留在了我桌上,“一个公司把最重要的技术储备压在一个三年都不知道真相的年轻人身上,然后让一群不明就里的人去给他的心血打零分——这是管理层的失误,不是你的。”
他转过身,往电梯的方向走了两步,然后停下来,回头看了我一眼。
“沈言,这件事还没完。明天上午九点来我办公室,我告诉你接下来怎么办。”
说完他就进了电梯,门缓缓关上,赵建国和总裁办主任跟在后面一路小跑,像两条被拽着跑的尾巴。
办公区恢复了安静。所有人都在偷偷看我,但没有人敢过来搭话。我坐在工位上,面前是那份封面朝下的文件,手边是那台已经被我删得干干净净的电脑。
手机在兜里又震了一下。还是苏敏。
“听说赵鹤鸣亲自下来找你了?沈言你到底干了什么惊天动地的事?”
我把手机翻过来扣在桌上,没有回她。我的目光落在文件封面下方露出的一行小字上,那行字被文件本身的阴影遮住了一半,但我还是看清了。
“项目代号:暮光。技术基石:回声核心算法 v3.7.1。责任人:沈言。”
v3.7.1。那是上周我刚迭代完的版本。我自己都不知道它的版本号已经被写进了公司的最高机密文件里。
窗外的雨越下越大,雨点砸在落地窗上噼啪作响。整座城市笼罩在一片灰蒙蒙的水雾中,远处的建筑群只剩下模糊的轮廓。我的手指无意识地敲着桌面,脑子里一片混沌。
两年。两年来我写了六万行代码,以为自己在一间透明的玻璃房子里做着一个没人看好的梦。但这间玻璃房子外面一直站着一群人,他们看着我的每一个动作,把我的心血悄悄地写进了另一个更宏大更疯狂的故事里。
而我对此一无所知。
我把文件翻开,从头开始看。第一页是项目概述,第二页是技术架构,第三页是应用场景图。我翻到第四页的时候,手指停住了。
第四页是一张人员配置表,上面列了三十几个名字,几乎囊括了公司所有核心技术骨干。每个名字旁边都标注了对应的技术模块和预计接入时间。我的名字旁边写着“核心算法·已完成”。
但在我名字下面还有一行小字,那行字我之前翻得太快没有注意。
“备选方案:如核心算法不可用,项目整体延期十八至二十四个月。替代技术路径需从零搭建,预估成本追加九千万至一亿两千万。”
我盯着那行小字看了很久,久到窗外的天色从深灰变成了墨黑。
九千万到一亿两千万。延期十八到二十四个月。
就因为我删了十分钟的代码。
办公室里的人陆陆续续下班了,走廊里的脚步声越来越稀疏。头顶的灯管还在嗡嗡地响,茶水间的水箱咕噜噜地烧着水。我坐在工位上,面前摊着那份绝密文件,手指无意识地摸着键盘上被磨损得发亮的空格键。
这台电脑陪了我三年,键盘上的字母有些已经被磨得看不清了——磨损得最厉害的是E、N、T、R、回车,以及删除键。讽刺的是,删除键上的油漆已经完全掉光了,露出下面白色的塑料底座,在黑色键盘上格外扎眼。我每天都在删除。删除写错的代码,删除不够好的逻辑,删除那些走了弯路的尝试。写了删,删了写,反反复复三年,最后一把全删光了。
手机又震了。我以为又是苏敏,拿起来一看,是一个陌生号码发来的短信。号码我不认识,但短信内容让我愣了一下。
“沈工,我是老周,机房夜班运维。刚才赵总走的时候让我盯着你的机器,说有什么异常随时汇报。你别嫌烦,我就跟你说一句:我在这机房干了八年,没见过赵鹤鸣为谁下过楼。你是第一个。”
老周。机房夜班运维。我跟他打过几次照面,他大概五十出头,头发花白,值夜班的时候喜欢泡一搪瓷缸的浓茶,整个机房都是茶香味。他平时不怎么说话,见谁都点头笑笑,存在感低到几乎透明。但他在这家公司待了八年,见过的人和事可能比任何一个高管都多。
我想了想,回了一条消息:“老周,赵鹤鸣这个人到底怎么样?”
过了大概两分钟,老周回了一段很长的话,显然是在机房值班室里闲着没事,一个字一个字打出来的。
“我跟你讲个事。六年前公司差点倒闭,账上的钱只够发一个月工资。赵鹤鸣把自己在上海的房子卖了,把钱打进了公司账户。他老婆为这事跟他闹了半年。后来公司缓过来了,他在年会上说了一句话,我一直记到现在。他说,我赵鹤鸣这辈子只信两样东西:一是技术,二是做技术的人。沈工,你知道他为啥下来找你吗?因为你删掉的不只是代码,你删掉的是他信的东西。”
我盯着这条消息看了很久,老周又追了一条过来。
“对了,我刚才检查服务器日志的时候发现了一个东西,你可能不知道。你的代码在过去一年里,被调用了四百三十七次。不是你自己调的,是另外几台机器通过内网调的。调用的节点IP我查了一下,全部指向顶楼的独立服务器——赵鹤鸣的私人服务器。意思就是说,他一直在用你的代码做测试,测了整整一年,测了四百三十七次。”
四百三十七次。
赵鹤鸣,这家估值七十亿的公司的老板,用我的代码在他的私人服务器上跑了四百三十七次测试。他从来没有告诉过我,评审委员会也完全不知道。他像一个蹲在实验室里的老教授,每隔几天就把学生的作业拿来反复验证,然后把结果锁进自己的抽屉里。
而我刚才把那四百三十七次测试的源头,一键清空了。
我把老周的短信截图发给了赵鹤鸣的助理——总裁办主任走之前留了她的企业微信给我,说有事随时联系。过了大概三分钟,助理回了一条消息,语气官方而克制:“赵总已知悉,说明天跟你面谈的时候会提到这件事。他让我转告你,今晚好好休息,不要想太多。”
好好休息。不要想太多。
我挂了电话,靠在椅背上,看着天花板上明暗闪烁的灯管。不要想太多?我现在的脑子就像一台被格式化的硬盘,所有东西都被清空了,只剩下一片白茫茫的空白。而这片空白上唯一清晰的东西,是刚才那份绝密文件里的一段话。
“暮光计划的核心目标:构建基于声纹识别的下一代人机交互系统,实现从‘识别声音’到‘理解情绪’的技术跃迁。底层算法需求:实时语音情感分析引擎,支持至少三十二种情绪维度,延迟低于零点五秒。”
零点五秒。
我的算法做到了。v3.7.1版本,在标准测试环境下,情绪识别延迟是零点四三秒,支持的情绪维度是三十六种。这个指标放在整个行业里都是一流的,甚至超过了一些大厂的实验室数据。但我从来没有跟任何人炫耀过这些指标,因为我觉得它们还远远不够好。我总觉得我的代码应该更快一点、更准一点、更稳定一点,直到它配得上“让每一个声音都被听见”这句话。
而赵鹤鸣把这些指标写进了公司最高机密的文件里,在指标旁边用红字标注了四个字——“国内领先”。
这四个字我自己都不敢用,是他替我用的。
我站起来,走到窗边。雨水顺着玻璃往下淌,把外面的霓虹灯分割成无数破碎的光点。这座城市到了夜晚格外漂亮,但这种漂亮跟我无关。我只是一个删了自己两年心血的蠢货,站在二十一层的高楼上,看着大雨把整个世界洗得面目全非。
手机又震了。这次不是短信,是微信视频通话。屏幕上显示的名字让我心口一紧。
“念念。”
我女儿。六岁,刚上小学一年级。她妈——我前妻方雯——这个时候让她打视频过来,显然不是巧合。
我接了。屏幕亮起来,念念的小脸占满了整个画面。她穿着一件粉色的睡裙,头发刚洗完,湿漉漉地贴在脑门上,背景是她姥姥家的客厅。她凑得很近,近到我能看清她鼻尖上那颗小小的痣。
“爸爸!”她喊得很大声,声音清脆得像打翻了一盒玻璃弹珠,“你今天过得好不好?”
“挺好的。”我扯出一个笑容。
“妈妈说你今天工作很辛苦,让我给你唱首歌。”她一本正经地清了清嗓子,然后开始唱。唱的是《虫儿飞》,她刚学会的,调子跑了一半,歌词也只记得六七成,但她唱得极其认真,每一个字都咬得圆圆的,“黑黑的天空低垂,亮亮的繁星相随,虫儿飞,虫儿飞,你在思念谁……”
我的眼眶忽然酸了。
念念三岁那年,我跟方雯离了婚。原因是“性格不合”,但真正的原因是两个人都太忙了。她在外企做市场总监,我在互联网公司做技术宅,念念出生以后我们像两台永远对不上频道的对讲机,各自说着各自的话,谁也听不见谁。离婚的时候没有吵没有闹,去民政局办手续那天甚至还一起吃了个饭。方雯说她唯一的要求就是念念的抚养权,我说好。不是因为我无所谓,而是因为我知道她说得对——念念跟着她比跟着我好。
此刻念念在视频里唱着跑调的歌,唱完了还自己带头鼓掌,两只小手拍得啪啪响。
“爸爸我唱得好不好?”
“特别好。”我的嗓子发紧,尽量让自己的声音听起来正常一些。
“那你有没有开心一点?”
“开心了,真的开心了。”
她满意地点了点头,然后忽然凑近屏幕,把小脸压成一个变形的大特写,压低声音说了一句悄悄话:“爸爸,我告诉你一个秘密——妈妈今天偷偷看你朋友圈了,看了好久好久。我觉得妈妈还在想你。”
我还没来得及消化这句话,视频那头就传来了方雯的声音:“念念,你在跟谁视频呢?来,把手机给姥姥——”然后视频断了。
我看着黑掉的屏幕,嘴角还保持着刚才那个僵硬的笑容。
方雯看我朋友圈了。这倒是稀奇事,因为离婚三年来,她的微信朋友圈对我始终是一条横线——不删除,不拉黑,但也从不对我开放。逢年过节她会在朋友圈发念念的照片,我能看到,因为那是通过“共同好友可见”的方式转到我这里来的。除此之外,她的世界对我关闭得严严实实。
今晚她让念念给我打视频,让念念给我唱歌,自己还在偷偷翻我的朋友圈——如果念念说的“偷偷看”是真的话。她大概是听说了什么。方雯在这座城市的互联网圈子里有自己的人脉,赵鹤鸣的公司在业内也算小有名气,今天评审会的事说不定已经传到了她的耳朵里。
她想确认我还好吗?还是只是单纯的好奇?
我把手机放回兜里,不想再去琢磨了。今天一天我脑子里已经装了太多东西,塞不下了。
收拾东西准备下班的时候,我无意中瞥见了桌上的一个文件夹——那是上个月的代码迭代日志,我打印出来做备份用的,纸质版,存在抽屉里,没有被删除命令波及。我抽出那份文件夹翻了翻,里面是密密麻麻的代码段和流程图,全部是手写的标注和箭头。最后一页的空白处,我那天随手写了一句批注。
“v4.0方向:引入多模态情绪交叉验证,将声纹特征与语义分析做深度耦合。预计延迟可降至零点三秒以内。”
v4.0。那是我在删代码之前正在构思的下一个版本。我还没来得及写一行v4.0的代码,但我把所有思路都画在了纸上。这张纸,连同这个文件夹,大概是“回声”项目在这个世界上仅存的最后一点遗骸了。
我把文件夹卷起来塞进了背包里,关了电脑,站起来。办公区已经空无一人,只有走廊尽头还有一排灯亮着。电梯门打开的时候,我最后回头看了一眼我的工位——那张堆满了杂物、贴满了备忘贴纸的旧桌子,在走廊昏暗的光线下显得又小又破。
“别看了,”我对自己说,“走吧。”
电梯缓缓下降,数字从二十一跳到一。门打开,一楼大厅空荡荡的,保安大叔趴在台子上打瞌睡,嘴角挂着一丝口水。我轻轻推开门走进了雨里。
雨水劈头盖脸地砸下来,我没有打伞,就这么站在公司门口,仰着头让雨水浇了满脸。十月的雨水已经很凉了,凉得人头皮发麻,但那种凉意让我混沌了一天的脑子稍微清醒了一些。
赵鹤鸣说明天早上九点去他办公室。他要告诉我怎么办。但不管他告诉我什么,“回声”的代码已经没了,这是铁一样的事实。九千万到一个亿的追加预算,十八个月到两年的延期——这个窟窿大到足以让任何一家公司伤筋动骨。
而我,就是那个捅窟窿的人。
我在雨里站了一会儿,然后坐上了回家的地铁。车厢里稀稀拉拉坐着几个夜归的人,每个人都低着头看手机,屏幕的光映在脸上,蓝幽幽的。我对面坐着一个二十出头的女孩,戴着耳机闭着眼,嘴唇无声地动着,大概是在跟着音乐哼歌。她的脸上有一种年轻人才有的无忧无虑,好像整个世界都是她的游乐场。
我忽然想,三年前我刚进公司的时候,大概也是这个样子。那时候我觉得自己无所不能,觉得“回声”一定会改变世界,觉得每一个声音都值得被听见。三年后我坐在深夜的地铁里,浑身湿透,背包里装着项目的最后一点纸质遗骸,被五个零分和一份绝密文件反复碾压。
改变世界的不是我,是世界改变了我。
回到家已经快十一点了。我租的房子在五楼,没有电梯,楼道灯坏了两盏,我摸黑爬上去,掏钥匙开门。屋里黑漆漆的,空气里有一股久不通风的闷味。我开了灯,把湿透的外套脱下来挂在门后,背包扔在沙发上,然后走进卫生间,对着镜子看了一眼自己。
镜子里的男人二十八岁,但今晚看起来像三十八。胡茬冒出来了,眼睛底下两团青黑,头发被雨浇得一绺一绺地贴在额头上。水滴顺着发梢滴下来,落在洗手台上,滴答滴答的。
我盯着镜子里的人,忽然问他:“你是不是傻?”
他没有回答我,只是瞪着一双布满血丝的眼睛回看我。
我洗了把脸,换了身干衣服,坐在沙发上。背包里的文件夹露出一个角,我抽出来翻了两页,翻到那张v4.0的批注。零点三秒。如果我真的做到了零点三秒的延迟,那将是整个行业里无人能及的指标。但那行批注现在看起来像一个笑话——v4.0连一行代码都没来得及写,v3.7.1已经变成了一堆被覆写的磁畴。
可是那些思路还在我的脑子里。六万行代码可以删,一万两千行核心算法可以被擦除,但我在那两年里学到的每一条经验、踩过的每一个坑、建立的每一个模型直觉,都还锁在我的大脑皮层里,删不掉。
备份。大脑才是最好的备份。
这个念头冒出来的时候,我被自己吓了一跳。但越想越觉得对——代码可以被删除,物理数据可以被覆写,但一个工程师在两年里积累的对某个领域的理解和洞察,是任何删除命令都抹不掉的。那四百三十七次测试里积累的经验曲线,那个从零点八秒一路优化到零点四三秒的调参过程,那些在无数个深夜被解决又被推翻的算法思路——它们全都在我的脑子里,完好无损。
也许赵鹤鸣要我明天早上去他办公室,要跟我谈的也是这件事。他不是傻子,他一定知道代码虽然没了,但写代码的人还在。如果他真的在我的代码上跑了四百三十七次测试,他对我的能力应该有一个超越任何评审委员会的评价。
手机在茶几上震了一下。老周又发消息来了。
“沈工,我刚才又查了一下,发现了一个有意思的事。赵鹤鸣的私人服务器上那四百三十七次测试数据,大部分还在。因为测试数据存在另一个分区里,你的删除命令只影响到了主分区。换句话说,你的算法是怎么从零点八秒优化到零点四三秒的——这个进化过程的所有中间数据,全都在。”
紧接着他又发了一条。
“还有,你别太自责。我跟你说句实在话,代码这个东西就像一棵树的叶子,掉了还能再长。但种树的人如果走了,那棵树就真的死了。你就是那个种树的人。”
我坐在沙发上,看着老周的这两条消息,沉默了很久。楼道里的风从门缝灌进来,吹得窗帘一鼓一鼓的。雨声渐渐小了,窗外的街灯在湿漉漉的地面上投下一片橙黄的光。
然后我做了一个决定。
我把茶几上的笔记本电脑打开,新建了一个空白文档。文档的名字我犹豫了几秒,最后打了四个字——“回声 v4.0”。
光标在空白的页面上闪烁着,像一个刚出生的心脏在跳动。我的手指悬在键盘上方,停了一会儿,然后落了下去。
第一行代码,重新开始生长。
零点五
后半夜我几乎没有合眼。笔记本电脑的风扇嗡嗡转了一整夜,屏幕的蓝光在黑暗的客厅里亮成一个孤岛。我把那份打印出来的迭代日志摊在茶几上,一页一页地翻,手写的批注、箭头、圈画,密密麻麻铺满了每一张纸。有些批注是半年前写的,字迹潦草得连我自己都要辨认半天;有些是最近的,墨水还是新的,写的时候我大概正在为某个参数调优兴奋不已。
v4.0的架构在凌晨三点左右渐渐成形了。不是代码,是一张手绘的流程图,画在日志最后一页的背面。多模态情绪交叉验证——用声纹特征和语义分析做深度耦合,让两个模型互相校准而不是各跑各的。这个思路我之前想了很久,一直没动手,因为总觉得还差一个关键的连接点。但今晚在重新翻阅日志的时候,我发现半年前有一次失败的实验数据里藏着一个我当初没有注意到的规律——当声纹模型和语义模型在某个特定维度上产生矛盾时,反而是情绪识别最准确的时刻。
矛盾即信号。这个发现如果被验证,可以把延迟从零点四三秒压缩到零点三秒以内。
凌晨四点半,我靠在沙发背上闭了会儿眼。脑子里还在跑那行代码,像一台停不下来的机器。窗外的天从漆黑变成深蓝,又变成灰白,楼下的早餐摊开始出摊了,油锅滋啦滋啦的声音从窗户缝里钻进来。我洗了把脸,换了件干净的衬衫,把那叠日志塞回背包里,出门。
到公司的时候才七点四十,整栋大楼还没什么人。前台小姑娘正在擦桌子,看见我进来愣了一下,大概是因为我平时都是踩点到的,从来没这么早过。我打了卡,坐电梯上了二十一楼。
工位还是昨天那个样子——电脑黑着屏,桌上散落着便签纸和数据线,喝了一半的矿泉水瓶盖子都没拧。我在椅子上坐下来,没有开电脑,只是安静地坐着,看着窗外渐渐亮起来的天色。
八点整,老周发来一条消息:“沈工,昨晚我帮你把服务器上那些测试数据全部备份到离线硬盘里了,放在机房三号柜,密码是你的工号。赵总来之前你可以先看看。”
我回了一句“谢谢”,然后起身去了机房。三号柜在机房最里面,我输入工号,柜门弹开,里面躺着一块黑色的移动硬盘,贴着一张手写的标签——“回声 测试数据 完整”。标签的边角被剪刀裁得整整齐齐,老周这个人的细心程度跟他泡的茶一样浓。
我把硬盘带回工位,接上电脑。四百三十七次测试的完整数据,从第一次到最后一次,每一次都记录了时间戳、参数配置、测试结果和性能指标。我顺着时间轴往下翻,像在看一本关于自己过去一年的日记。
第一次测试记录的时间是一年前的九月份,算法版本还是v1.2,情绪识别延迟高达零点八二秒,准确率只有百分之六十七。赵鹤鸣在那次测试的日志末尾写了一行备注,用的是手写体扫描进去的:“方向是对的,继续打磨。”
第二十次,延迟降到了零点六九秒。他的备注是:“进步明显,但还不够。场景噪声干扰是瓶颈。”
第一百零三次,准确率突破了百分之八十五。他写了两个字:“快了。”
第三百二十一次,延迟零点四七秒,准确率百分之九十一。他的备注变长了,不再只是技术评价:“今天让市场部做了一个盲测对比,我们的引擎在嘈杂环境下的表现已经超过了市面最优方案。沈言还不知道这件事。等合适时机告诉他。”
我看着那行字,手里的鼠标停住了。赵鹤鸣在一年前就知道我的算法已经超过了市面上所有的竞品,但他选择了不告诉我。不是不想说,是没有找到“合适时机”。他像一个守着一块璞玉的匠人,宁愿花更多时间去打磨,也不愿在它还没成型的时候拿出来给人看。
第四百三十七次测试,发生在评审会前三天。v3.7.1版本,延迟零点四三秒,准确率百分之九十三点七。赵鹤鸣写了最后一条备注:“可以上‘暮光’了。下周安排沈言接触项目核心信息。”
下周。评审会发生在这一周的周五。赵鹤鸣计划下周就告诉我一切,但评审委员会在周五提前行动了,五个零分像五把刀一样扎下来,然后我在十分钟内删光了所有代码。
一切都差了一点点。
我靠在椅背上,看着屏幕上那四百三十七条测试记录,忽然觉得胸口堵得慌。不是因为后悔——后悔的情绪已经在昨天消耗完了——而是一种更复杂的东西。赵鹤鸣用了整整一年,在我的代码上跑了四百多次测试,他比我自己都更清楚我的算法是怎么一步一步进化的。他像一个站在实验室单向玻璃后面的观察者,看着我埋头写代码、改bug、调参数,什么都不说,只是默默地记录、测试、验证。
这种隐忍和耐心,让我后背发凉,也让我心头发热。
八点四十分,办公区的人渐渐多起来了。同事们陆陆续续走进来,看到我坐在工位上,表情各异——有人装作没看见,有人微微点头打了个招呼,有人窃窃私语地跟旁边的人说着什么。我没有在意,把所有注意力都放在了那块移动硬盘的数据上。
八点五十分,赵建国的身影出现在走廊尽头。他今天穿了一件崭新的白衬衫,领带打得一丝不苟,但脸色并不好看。他路过我工位的时候脚步顿了一下,像是想说什么,嘴唇动了动,最终只是干巴巴地说了句:“赵总让你九点上去,别迟到。”
“知道了。”我头也没抬。
八点五十五分,我合上笔记本电脑,把移动硬盘装进背包里,拿着那份绝密文件起身走向电梯。电梯里只有我一个人,镜面墙壁映出我的脸——昨晚没睡,眼睛里全是血丝,但精神出奇地清醒。我拉了拉衬衫领子,把背包带子紧了紧,按下了顶楼的按钮。
电梯一路上升,数字跳到顶楼的时候叮的一声响了。门打开,迎面是一道磨砂玻璃墙,墙上嵌着公司的logo,下面是五个字——“未来实验室”。这就是“暮光”项目的所在地,独立楼层,独立门禁,全公司百分之九十九的人连这层楼的电梯按钮都按不亮。
门口站着一个穿西装的年轻男人,戴着蓝牙耳机,应该是赵鹤鸣的助理。他看见我出来,微微欠了欠身,说:“沈工,赵总在里面等您。请跟我来。”
我跟在他身后穿过一道需要刷脸认证的玻璃门,走进了一条安静的走廊。走廊两侧全是会议室和实验室,透过玻璃可以看到里面摆满了各种设备——声学测试舱、隔音室、一排排的服务器机柜。有一间实验室里摆着一个人头模型,周围环绕着一圈微型麦克风阵列,屏幕上跳动着实时采集的声波图形。我边走边看,心里涌起一种奇怪的感觉——这些东西,这些设备,这些实验场景,跟我过去三年做“回声”时设想的几乎一模一样。
原来他什么都准备好了。他只是没有告诉我。
走廊尽头是一扇胡桃木色的门,门牌上写着“首席执行官办公室”。助理替我敲了敲门,里面传来赵鹤鸣的声音:“进来。”
门推开了。
赵鹤鸣的办公室比我想象中简朴得多。没有落地窗,没有老板台,没有真皮沙发,只有一张普普通通的木桌子,桌上堆满了文件和书,旁边立着一块白板,上面画满了各种我看不太懂的商业逻辑图。墙上挂着一幅书法,写的是“敬事而信”四个字,落款是某个我不认识的书法家。整间办公室最值钱的东西大概就是角落里那台咖啡机,德产的手压式,旁边摆着一排咖啡豆罐子,标签上密密麻麻地写着产地和烘焙日期。
赵鹤鸣坐在桌子后面,穿着一件深灰色的棉麻衬衫,袖子卷到肘关节,露出一截被晒得黝黑的小臂。他看起来不像一个估值七十亿的科技公司CEO,倒更像一个在大学实验室里泡了几十年的老教授。他面前摆着两台笔记本电脑,一台开着,一台合着,旁边是一杯已经凉透了的黑咖啡。
“坐。”他指了指对面那把椅子。
我坐下来,把背包放在脚边。助理退了出去,轻轻带上了门。办公室里安静下来,只剩下空调送风的微弱声响和窗外远处传来的汽车鸣笛声。
赵鹤鸣看了我一眼,没有绕弯子,开门见山地说:“昨晚没睡好?”
“基本没睡。”我老实说。
“正常。换我我也睡不着。”他从桌上拿起一个保温杯,拧开盖子喝了一口,然后放下,“不过你眼睛里有光,不像一个刚删了自己两年心血的人。昨晚干什么了?”
我把手绘的v4.0流程图从背包里抽出来,放在他桌上。他低头看了看,拿起来,转过角度对着台灯的光仔细端详。他看了大概有两分钟,目光沿着我画的每一个箭头和每一个批注移动,表情从好奇变成了专注,又从专注变成了一种我说不清道不明的激动。
“多模态交叉验证,用矛盾信号做校准源。”他把纸放下,抬头看我,眼神亮得惊人,“这个思路你是怎么想到的?”
“半年前有一次实验失败了,声纹模型和语义模型在愤怒情绪上给出了完全相反的结果。我当时觉得是bug,把它跳过去了。昨晚重新翻日志的时候发现,那次‘失败’的数据里,反而是两个模型各自最擅长的部分被凸显出来了。声纹模型捕捉到了语气的愤怒,语义模型识别出了措辞的克制,而真实情绪是‘压抑的愤怒’——两个都对,但都不完整。”
“矛盾即信号。”赵鹤鸣重复了我写在流程图最上方的那五个字,用手指在桌上轻轻敲了两下,然后忽然笑了一下。那个笑容很轻,转瞬即逝,但确实是一个笑容。
“你知道为什么评审会给你零分的时候,我第一时间想到的不是骂评审,而是给你打电话吗?”他问。
“不知道。”
“因为在这四百三十七次测试里,我发现了一个规律。”他打开那台合着的笔记本电脑,转过来让我看屏幕。上面是一张曲线图,横轴是测试次数,纵轴是“创新性指标”。曲线从第一次测试开始就一直在稳步上升,但在第一百五十次左右出现了一个陡峭的跳跃,之后维持了一段时间的平台期,然后又开始上升。
“这个跳跃点,”赵鹤鸣指着曲线上最陡的那一段,“对应的就是你引入情感分析引擎的那次更新。在此之前,你的算法只是一个优秀的语音匹配工具;在此之后,它开始真正‘理解’情绪了。而据我所知,那次更新你是在没有任何人指导的情况下独立完成的。一个二十七岁的年轻人,在公司的角落里闷头写出了国内领先的情感分析算法——评审委员会给这样的项目打零分,他们不是在否定你,他们是在否定自己看不懂的东西。”
他合上电脑,十指交叉放在桌上,身体微微前倾。
“沈言,我今天叫你来,不是要追究你删代码的事。代码已经没了,追究没有意义。我要跟你谈的是另一件事。”
“什么事?”
“暮光计划在下个月有一个关键节点——向董事会做技术演示。这次演示的结果将决定项目下一阶段的融资额度和资源倾斜力度。原本我们计划用你的v3.7.1做核心演示,现在v3.7.1没了,我们有两个选择。”他竖起两根手指,“第一,用市面上的开源替代方案顶上去。效果会大打折扣,但至少能跑通流程。演示结束后,董事会大概率会削减百分之四十的预算,项目延期一年半。”
“第二呢?”
“第二,”他把第二根手指收回去,只留一根食指,指着我,“你用一个月的时间,把你脑子里那个v4.0做出来。没有原代码参考,没有版本历史,从零开始重新写。如果写出来了,并且指标真的达到你说的零点三秒以内,那这次演示不仅不会受影响,反而会因为全新的架构而让董事会眼前一亮。”
我张了张嘴,还没来得及说话,他追了一句:“你觉得自己能写出来吗?”
办公室里的空气忽然变得很稠,稠得像一锅还没烧开但马上就要冒泡的粥。我看着赵鹤鸣的眼睛,那双眼睛里有审视,有期待,还有一点点不易察觉的紧张——他怕我说“不能”。
“一个月,”我说,“从零开始,六万行代码。”
“对。”
“正常进度下,六万行代码需要至少六到八个月。”
“那是正常的进度。”赵鹤鸣端起那杯凉透的咖啡喝了一口,眉头都没皱一下,“但你我都知道,写代码最花时间的不是敲键盘,而是想清楚逻辑。如果逻辑已经在你的脑子里了,敲键盘只是体力活。”
他说得对。那两年来我花在敲键盘上的时间并不多,大部分时间都花在了思考、试错、推翻重来上。那些弯路已经在两年的迭代里走完了,所有的教训都浓缩成了我脑子里的经验和那张手绘的v4.0流程图。如果我现在重新写,我不会再走那些弯路,我走的将是一条已经被思维打磨过的直路。
“但我有个条件。”我说。
“说。”
“这一个月,我需要一个独立的工作环境,不受任何人干扰。评审委员会、部门总监、所有跟项目无关的人,都不能进来。我不需要管理,不需要汇报,不需要参加任何会议。我只需要三样东西——一台高配的服务器,一个能随时跟我讨论技术的人,以及每天中午十二点准时送到工位上的盒饭。”
赵鹤鸣看着我,忽然哈哈大笑起来。他笑得很大声,笑声在简朴的办公室里回荡,把窗台上的一盆绿萝都震得叶子抖了抖。外面走廊里助理大概听到了笑声,探头进来看了他一眼,他摆了摆手示意没事。
“三年了,”他笑完之后靠在椅背上,用一种复杂的目光看着我,“我招你进来三年,你在我面前说的话加起来不超过十句。每次开会你坐在角落里,问你有什么想法你说没有。我一直以为你就是一个只会写代码的技术宅。结果今天你一口气提了三个条件,还都是合理的。”
“那您是答应了?”
“服务器今天下午到位,顶楼实验室靠窗那间,最好的机器,双卡并行,内存管够。”他从抽屉里拿出一张门禁卡推到我面前,“这张卡能刷开这一层所有的门,包括我的办公室。技术讨论,你随时可以来找我,但我丑话说在前头——我技术上帮不了你太多。我今年五十三了,写代码的水平大概相当于你们部门实习生里最差的那个。我唯一能做的就是在你钻牛角尖的时候把你拉出来,因为我不懂技术细节,但我懂技术方向。”
他站起来,走到白板前面,拿起一支马克笔,在白板最上方写了三个大字——“一个月”。然后他转过身来看着我。
“沈言,我知道你现在心里在想什么。你在想,这个老板是不是疯了,把公司最重要的战略项目押在一个刚把自己的代码删光了的年轻人身上。”他的语气变得认真起来,“我告诉你我没疯。我之所以敢押你,不是因为我信任你的人品——说实话昨天你删代码那一下确实气得我差点把保温杯摔了——而是因为我读了你一年多的测试数据。四百三十七次测试,你的每一次迭代都踩在了正确的方向上。一个人踩对一次是运气,踩对四百次是能力。”
他把马克笔丢回白板槽里,走到我面前,一只手撑着桌子,微微俯身。
“还有一件事你要知道。昨天评审会结束后,邱敏——就是那个说不看好你的外部顾问——她私下给我打了个电话。她说老赵,有件事我必须告诉你,今天评审的时候我给沈言打了零分,是因为程志宏事先跟我打了招呼,说这个项目如果过了,他在公司的位置就不保了。我当时没觉得有什么,但晚上回去以后越想越睡不着。我干了十五年咨询,见过无数项目,沈言那个底层算法的质量,说实话放在大厂也是第一梯队。我为了一个私人的面子给了零分,这事我做得不地道。”
我愣了一下。邱敏,那个在评审会上说“你凭什么觉得自己能切进去”的女人,晚上私下给赵鹤鸣打了电话,说她睡不着。
“所以我今天早上做了一个决定。”赵鹤鸣直起身来,恢复了正常的音量,“评审委员会的评审结果作废。‘回声’项目从今天起并入‘暮光’,由我直接管理,不再经过任何中层审核。程志宏和邱敏那边我已经打过电话了,他们不会再来找你麻烦。”
“赵建国呢?”
“赵建国……”赵鹤鸣轻轻叹了口气,“他是你的技术总监,按理说他应该是你最直接的支持者。但他不是。你知道为什么吗?”
我摇头。
“因为去年他主导的那个智能客服项目,底层用的就是语音交互技术。他那个项目花了公司七百万,做出来的东西延迟零点九秒,被客户退了三次货。你的算法延迟零点四三秒,是他的一半。他不是看不到你的能力,他是太看到了,看到心里发慌。”赵鹤鸣的语气变得有些低沉,“在职场里,比你差的人不一定会帮你,他们可能会更恨你。因为你的存在本身就是一种对他们的否定。”
我沉默了。赵建国跟我抬头不见低头见三年,偶尔在茶水间遇到还会聊两句球赛、吐槽一下食堂的饭。我从来不知道他花了七百万做一个延迟零点九秒的语音交互,也不知道他每次看到我的时候心里在想什么。
“行了,这些都不重要了。”赵鹤鸣摆了摆手,“接下来一个月,你不用管任何人,只管做一件事——把你脑子里那个v4.0变成现实。人力、物力、任何资源,你直接跟我说。”
他走回办公桌后面,拿起一个黑色的硬壳笔记本,翻开第一页,在上面写了几个字,然后把那一页撕下来递给我。
纸上只有一行字,是他的笔迹,苍劲有力——“敬事而信,不破不立。”
“这是我创业第一天写在第一个笔记本第一页的八个字。”他说,“前面四个字是给自己看的,告诉自己要对每一件事抱有敬畏之心。后面四个字是给公司看的,告诉团队不要害怕打破旧东西,因为真正的好东西都是在废墟上长出来的。你昨天删掉的代码就是旧东西,虽然它很好,但它已经是过去时了。现在你有一个机会,在废墟上建一栋更好的楼。”
我接过那张纸,小心翼翼地折好,放进了背包夹层里。这个动作被赵鹤鸣看到了,他嘴角动了一下,没有说什么。
从赵鹤鸣办公室出来的时候已经快十点了。走廊里的灯光比刚才更亮了一些,大概是感应器检测到了更多的人在走动。我拿着那张门禁卡刷开了实验室的门——靠窗的那间,赵鹤鸣说留给我的。房间不大,大概十五个平方,但配置确实拉满了。一台双卡工作站已经摆在了桌上,旁边是两台二十七寸的显示器,墙上挂着一块白板,角落里有一台小型服务器机柜,指示灯一闪一闪的。
窗户正对着公司的中庭花园,能看到楼下种的那棵银杏树,叶子已经开始泛黄了,在阳光里金灿灿的一片。我把背包放在桌上,在椅子上坐下来,对着那台顶配的工作站发了会儿呆。然后我打开了白板旁边挂着的马克笔盒,挑了一支黑色的,在白板正中央写了四个字——“从零开始”。
字迹歪歪扭扭的,没有赵鹤鸣写得那么好看,但落笔的时候我的手是稳的。
从零开始。说起来轻巧,做起来是一座山。六万行代码,核心算法一万两千行,加上v4.0的新架构,总量大概还要往上加三四千行。一个月,三十天,平均每天要写两千行高质量的、能跑通的、经过初步验证的代码。这个强度放在任何一个工程师身上都是极限挑战,而且我没有原代码可以参考——所有的函数逻辑、变量命名、模块接口,全部要从脑子里重新调出来。
但赵鹤鸣说得对,最难的部分不是敲键盘,而是想清楚逻辑。而逻辑,已经在我的脑子里了。
我打开工作站,新建了一个项目文件夹,命名为“回声v4.0”。光标在空白的集成开发环境里闪烁,跟昨晚在茶几上那个新建文档一样,像一个等待被激活的心脏。我把手绘的流程图用磁铁贴在白板上,然后在左侧写下了整个项目的模块拆分——语音采集与降噪、声纹特征提取、语义分析引擎、多模态交叉验证、动态学习层、输出接口。一共六大模块,十四个子模块,每个模块后面都标注了预估的代码量和难点。
写到最后一个子模块的时候,我的马克笔停了一下。这个模块叫“情绪校准层”,是v4.0的核心创新——利用声纹和语义的矛盾信号来反向校准两个模型的输出权重。这个思路我在脑子里已经转了很久了,但真正落实到代码层面,还需要解决一个非常棘手的数学问题:如何在极低的延迟下实现两个异构模型的实时互校准?传统的做法是串行——先跑声纹,再跑语义,然后比对。但串行会把延迟翻倍,零点四三秒变成零点八六秒,那就完全失去了意义。
我需要的是并行。让两个模型同时跑,在输出的瞬间做比对,比对的结果反过来微调下一轮的参数。这需要一个全新的调度架构,而且对内存管理的要求极高。双卡并行的话,每张卡各自跑一个模型,中间通过共享内存做数据交换——理论上是可行的,但实现起来有无数的细节需要处理。
我站在白板前面,拿着马克笔,陷入了沉思。脑子里各种各样的技术方案像烟花一样炸开又熄灭,炸开又熄灭。我大概站了有十分钟,一动不动,直到门口传来敲门声。
是老周。
他端着一个搪瓷缸子站在门口,缸子里泡着浓得发黑的茶,热气袅袅地往上冒。他探头看了看实验室里的设备,咂了咂嘴。
“好家伙,双卡工作站,赵总这是下了血本了。”他把搪瓷缸子放在门口的台子上,从兜里掏出一个U盘递给我,“昨晚我值夜班闲着没事,整理了一下你之前的代码提交记录。虽然源代码没了,但每次提交时的commit message还在,我帮你按时间顺序排好了。你可以对着这个回忆当时的逻辑。”
我接过U盘,心里涌起一股说不出的感动。老周跟我非亲非故,一个值夜班的运维,他完全可以什么都不做。但他先是在昨晚备份了测试数据,又整理了我过去两年的提交记录。
“老周,我真的不知道怎么谢你。”
“谢啥。”他摆摆手,端起搪瓷缸子喝了一口浓茶,“我在这机房待了八年,来来往往见了多少工程师。有的人来了半年就走了,有的人混了三年五年,写出来的代码跟流水线罐头一样,千篇一律。你是少数几个让我觉得‘这小伙子写的东西有意思’的人。你那六万行代码,每一行我都看过——不是因为我有权限看,是因为你提交到服务器上的时候,我正好值夜班,没事就翻出来读。”
他笑了一下,眼角的皱纹堆在一起,像干涸的河床上裂开的纹路。
“我一个搞运维的,代码水平不行,但眼光还是有一点的。你那个语音情感分析引擎,里面有一段处理噪声环境下的声纹提取逻辑,我看完之后跟旁边的小王说,这段代码不是一般人能写出来的。后来我查了一下,那段逻辑是你大半夜提交的,时间戳是凌晨三点二十六分。”
凌晨三点二十六分。他说的时间点我完全没有印象,但我知道他说的那段逻辑是什么——那是我花了整整三天才攻克的噪声鲁棒性问题,写完的时候天都快亮了,我趴在桌上睡了两个小时,然后继续起来调试。那段日子像被泡在咖啡里的海绵,吸饱了疲惫和焦虑,挤出来的全是酸涩。
但老周记得。他甚至能精确到分钟。
“老周,”我把U盘插上电脑,打开文件列表,里面是一百多条commit message,按时间排列得整整齐齐,“这个月我可能天天都要熬夜,机房那边你会值夜班吗?”
“值啊,我专职夜班,一年到头都是夜班。”
“那我到时候找你喝茶。”
他笑了,端起搪瓷缸子朝我举了举,转身走了。走廊里传来他拖鞋在地板上趿拉趿拉的声音,渐渐远了。
我关上实验室的门,把“请勿打扰”的牌子翻过来挂在门把手上,然后坐回电脑前,开始对着那排commit message一条一条地往下看。
第一条消息的时间戳是三年前的七月十五号,下午三点零二分——“初始化项目结构,搭建基础框架。”那大概是我刚进公司第二周,从HR手里领了工牌和电脑,第一天坐到那个角落的工位上,打开IDE,敲下了“回声”的第一行代码。
最后一条消息的时间戳是评审会前一天,下午五点四十七分——“v3.7.1发布,修复高并发下内存泄漏问题。”修完那个bug我就下班回家了,第二天站在评审会的投影幕布前,被五个零分判了死刑。
一百多条消息,串起了整整两年的人生。我一条一条地读,很多当时写的代码逻辑随着那些消息的描述重新浮现在脑海里——不是模糊的印象,而是具体的、精确的代码结构。函数名、参数列表、判断逻辑、异常处理、那个我反复调整了十几次才定下来的哈希算法……它们像沉在海底的沉船碎片,被这一百多条消息一根一根地打捞上来,拼回了一艘完整的船。
中午十二点整,有人敲门。我打开门,外面站着一个食堂的工作人员,手里拎着一个保温袋,里面装着盒饭——两荤一素一汤,还冒着热气。赵鹤鸣说到做到,连盒饭都安排好了。
我端着盒饭坐在窗边吃,一边吃一边继续看commit记录。吃到一半的时候手机震了,是方雯的消息。这次不是让念念打电话,是她自己发的。
“念念昨晚给你打完电话以后特别高兴,今天早上起来还在哼《虫儿飞》。谢谢你陪她聊那几分钟。”
我回了一句:“是我该谢她。昨晚是我这段时间最难的时候,她那个电话来得刚刚好。”
过了两分钟,方雯回了一段话,比刚才长了很多。
“沈言,我听说了你们公司评审会的事。其实你这三年在那家公司在做什么,我一直有关注。不是因为别的,是因为念念长大以后一定会问——我爸爸是做什么的?我希望到时候我能回答她,你爸爸做了一件很厉害的事。”
我拿着筷子,看着这段话,嘴里的饭忘了嚼。方雯离婚后对我的朋友圈关了三年的横线,但她其实一直在关注我在做什么。她说她是为了念念才关注的,但昨晚念念在视频里说“妈妈偷偷看你朋友圈看了好久好久”。那个“好久好久”是念念的表述,一个六岁孩子的表述,但它传递的信息是清晰的——方雯没有她表现出来的那么无所谓。
“那我得更努力一点,”我回她,“不能让她爸爸成为一个被五个零分打败的人。”
方雯回了一个笑脸。离婚三年,这是她第一次给我发表情。那个小小的黄色笑脸,在手机屏幕上亮着,像一个遥远的、微弱但真实存在的信号。
我把手机放下,快速扒完了剩下的饭,然后坐回了电脑前。下午的工作正式开始了。我按照白板上的模块拆分,从最底层的语音采集与降噪模块开始写起。这个模块是整个系统的入口,所有后续处理都依赖它输出的音频质量。v3.7.1时代,这个模块的代码量大概有三千多行,包含了十几种噪声场景的自适应处理逻辑。现在重新写,我不再需要那三千多行——因为那些弯路已经走过了,我直接用最优解。
手指落在键盘上,久违的节奏响了起来。咔嗒咔嗒咔嗒,机械键盘的青轴在安静的实验室里格外清脆。我写代码的时候有一个习惯——先一口气写完整个函数的主体逻辑,然后再回头逐行检查、调试、修改。这种写法的好处是思路不会被打断,坏处是第一次运行的时候通常会冒出一大堆报错。
下午四点,语音采集模块的主体写完了。大概一千八百行,比原来的版本精简了将近一半。不是因为我偷工减料,而是因为我终于知道哪些是必要的哪些是多余的。好的代码不是写出来的,是删出来的——这句话我在某本技术书上看到过,当时不以为然,现在终于明白了它的意思。
下午六点,第一次编译。二十三个报错。我一个个排查,一个个修。修到第十七个的时候,有人敲实验室的门。我说了声“进来”,门推开了,进来的不是老周,是赵建国。
他站在门口,表情有些局促。他的领带不知道什么时候被他自己扯松了,歪歪斜斜地挂在脖子上,白衬衫的袖口解开了一只,另一只还扣着。他看起来像是一个鼓了很大勇气才来敲这扇门的人。
“忙吗?”他问。
“还行。”我没有停下敲键盘的手。说实话,我不太想跟他说话。虽然赵鹤鸣已经跟我解释了他打零分的原因,但知道原因不代表能释怀。被人在评审会上当众打零分,那种滋味不是一句“我理解你的苦衷”就能抹掉的。
他走进来,站在我身后,看着屏幕上密密麻麻的代码。沉默了一会儿,他开口了:“你在重写?”
“嗯。”
“从零开始?”
“嗯。”
他又沉默了。实验室里只剩下我敲键盘的声音和服务器风扇的低鸣。过了大概两分钟,他从口袋里掏出一个U盘放在我桌上。
“这是什么?”我扫了一眼。
“v3.5.2版本的核心算法备份。”他的声音有些干涩,“去年你做那个版本的时候,技术中台做了一次全量代码备份,你的项目也在里面。这个备份不在云端,存在技术中台的离线服务器上,你昨天的删除命令没有影响到它。”
我的手指停住了。v3.5.2,那是半年前的版本,比被删掉的v3.7.1早了两个大版本。延迟大概在零点五五秒左右,准确率百分之八十九。虽然比不上v3.7.1,但它是一个完整的、可以跑通的版本。
“赵总知道吗?”我问。
“我刚从他办公室出来。是他让我把这个给你的。”赵建国把U盘往我这边又推了推,“他说要不要用是你的自由。如果你觉得参考旧代码能加快进度,就用;如果你觉得从头写反而更快,就不用。”
我拿起那个U盘,在指尖转了转。v3.5.2,半年前的自己写的代码。那时候“矛盾即信号”的发现还没有出现,多模态交叉验证的思路也还没有成型,整个架构还是传统的串行模式。它有用,但用处有限——我已经决定要做v4.0了,v4.0的架构跟v3.5.2完全不同,能参考的部分并不多。
但我还是把U盘插上了电脑。不是要照搬,而是要对比。我想看看半年前的自己是怎么处理的,跟今天下午重新写的版本做一下比较。好的保留,不好的改进,绕过的弯路不走第二遍。
赵建国看到我插上了U盘,脸上的表情松弛了一些。他站在原地没有走,像是还有什么话想说。
“还有事吗?”我问。
“沈言,”他深吸了一口气,“评审会的事,我知道我欠你一个交代。”
“不用了,赵总已经跟我说了。”
“不,赵总跟你说的是他的视角,我欠你的是我的视角。”他把另一只袖口也解开了,整个人看起来不像一个技术总监,倒像一个被叫到教导处训话的学生,“去年我主导的智能客服项目,花了七百万,延迟零点九秒。你的项目花了公司多少?三年加起来,算上你的工资和服务器成本,不超过八十万。八十万的东西,性能是我七百万的两倍。你知道这对我来说意味着什么吗?”
我没有接话。
“意味着我在公司做了七年,爬到了技术总监的位置,然后一个刚毕业三年的年轻人用一个角落里的项目,把我七年的积累全部否定了。”他的声音微微发颤,“评审会之前,程志宏来找我,说要在评审会上把你的项目按死。他说只要你也打零分,五个零分就能让你彻底翻不了身。我犹豫了很久,最后同意了。”
“你为什么要同意?”我转过来看着他,这是我今天第一次正眼看他。
“因为我害怕。”他直视我的眼睛,没有躲闪,“我四十三岁了,房贷还有十八年,儿子明年高考。如果公司的技术栈全面转向你的算法,我的部门会被裁掉一半,我自己的位置也保不住。我不是不知道你的算法更好,我是太知道了——正是因为我太知道了,所以我才害怕。”
他说这些话的时候,声音一直在抖,但他的目光是诚实的。他没有给自己找借口,没有说“我也是被逼的”,他只是坦诚地说出了那个最不堪的理由——他害怕。一个四十三岁的技术总监,在行业里泡了二十年,面对一个二十八岁的年轻人时,感到了彻骨的恐惧。
“昨天晚上我一夜没睡,”他继续说,“我儿子问我,爸你怎么了。我说工作上出了点事。他说,是很严重的事吗?我说是。他说,那你打算怎么办?我被他问住了。一个十七岁的孩子问的问题,我这个四十三岁的人答不上来。”
他停了一下,把手揣进裤兜里,摸出一个皱巴巴的烟盒,看了一眼实验室天花板上的烟雾报警器,又把烟盒塞回去了。
“今天早上我来公司,直接去找了赵总。我把评审会之前程志宏找我的事、我的恐惧、我的决定,全部说了。赵总听完之后沉默了很久,然后说了一句话。”
“他说什么?”
“他说,赵建国,你在公司七年,从基层工程师做到技术总监,你的能力我不怀疑。但你忘了一件事——技术这条路,永远不是你守得住的。你越想守住自己的地盘,你的地盘就越小。你敢把地盘让出来给比你强的人,你的地盘反而会越来越大。因为公司大了,你作为技术总监的位置才会更稳固,而不是相反。”
赵建国把赵鹤鸣的这段话复述完,眼眶已经有些红了。
“我今天来找你,不是求你原谅。我知道被人在评审会上打零分是什么感觉——那种感觉就像你花了两年时间画了一幅画,然后五个人走过来,一人往上面吐了一口唾沫。这个伤害是我造成的,我认。我来只是想告诉你,从今天起,我不会再做任何阻碍你的事。不管你需要什么技术支持,你说一声,我尽全力配合。”
他说完,没等我回答,转身就走了。他的背影在走廊里显得有些佝偻,领带歪在一边,白衬衫的下摆从裤腰里跑出来了一截。一个四十三岁的男人,在这一刻看起来像一个终于放下了包袱的疲惫的旅人。
我转回电脑前,屏幕上还是v3.5.2的代码。我翻了几页,然后关掉了。赵建国说了一大段掏心窝子的话,但我现在没有时间消化。一个月太短了,短到我没有余裕去恨任何人,也没有余裕去原谅任何人。我能做的就是把全部注意力集中在屏幕上那行闪烁的光标上,把脑海里的v4.0一行一行地敲出来。
晚上八点,第一个模块——语音采集与降噪——基本完成,编译通过,本地测试跑了一组标准噪声场景,指标跟v3.7.1持平。这个结果让我松了一口气,因为这说明我脑子里记住的逻辑是对的,重新写出来的代码质量没有下降。
晚上十点,第二个模块——声纹特征提取——写了一半。这个模块比上一个复杂得多,涉及到信号处理和深度学习模型的交叉,每一行代码都要格外小心。我写到一段关于梅尔频率倒谱系数的提取逻辑时忽然卡住了——这段逻辑在v3.7.1里我优化过一个很巧妙的方法,但具体细节记不太清了。我试了三个方案都不满意,屏幕上的代码写了删删了写,反复了好几遍。
然后我想起了老周给我的commit记录。我翻到对应的时间段,找到了那条消息——“优化MFCC提取流程,解决高频段能量泄漏问题,延迟降低零点零四秒。”这条消息下面还有一行我自己写的备注,当时觉得没用就随手打上去了,现在看起来却像是一把钥匙——“窗函数从汉明窗改为布莱克曼窗,重叠率调整至百分之六十二。”
布莱克曼窗。重叠率百分之六十二。
我盯着这行字,脑子里那扇卡住的门忽然就开了。对,我当时用的就是布莱克曼窗,不是汉明窗。汉明窗在高频段的旁瓣泄漏太大了,换成布莱克曼窗之后问题迎刃而解。我怎么把这件事给忘了?而如果没有老周整理的这些commit记录,我可能还要花好几个小时才能想起来。
有了这个突破之后,我的进度明显加快了。到凌晨两点,声纹特征提取模块基本跑通了。我在白板上用马克笔把这个模块的进度条涂满——是的,我在白板上画了六个进度条,每个代表一个模块,每完成一个就涂满一格。这个方法是念念教我的,她每次做完一件事就会在自己的小本子上画一颗星星,攒满了十颗星星就找方雯要一个奖励。我给她开视频的时候她跟我炫耀过,我当时觉得幼稚,现在却觉得那是世界上最有效的进度管理方法。
凌晨两点半,老周端着搪瓷缸子敲了敲门。他值夜班巡楼,看到实验室的灯还亮着,就过来看看。
“怎么样?”他把搪瓷缸子放在门口的台子上,探头看了看我的屏幕。
“刚跑通声纹模块,还有四个半没写。”我揉了揉酸胀的眼睛。
“你这一天写了多少?”
“大概……四五千行吧。”
老周咂了咂嘴,脸上的表情说不清是佩服还是心疼。他从搪瓷缸子里倒了一杯茶递给我,浓得发黑的普洱,苦中带着一丝回甘。我接过来喝了一口,滚烫的茶水顺着嗓子流下去,整个人都精神了一截。
“我在这儿值了八年夜班,见过加班的人多了去了。但像你这样一天写四五千行代码的,头一回见。”老周在我旁边的椅子上坐下来,抱着他的搪瓷缸子,“不过你也别太拼了,身体要紧。你今年才多大?二十八?我二十八岁的时候在东莞的电子厂做流水线,一天站十二个小时,也觉得身体是铁打的。现在五十了,腰椎间盘突出,下雨天疼得直不起腰。”
“老周,你以前是做流水线的?”
“是啊,初中毕业就出来打工了,什么都干过。流水线、建筑工地、送快递、开叉车。后来在工地上被一块掉下来的模板砸断了腿,养了半年,瘸了一条腿,工地不要我了。正好有个老乡在这边做网管,介绍我过来当机房保安。干着干着就学会了运维,一干就是八年。”
他讲这些的时候语气很平淡,像是在讲别人的故事。但我看到他端茶的手背上有一道很长的疤,从虎口一直延伸到手腕,应该是当年在工地上留下的。
“所以我特别羡慕你们这些搞技术的,”他喝了口茶,咂了咂嘴,“你们能用脑子赚钱,能用代码做出那么多厉害的东西。我呢,一辈子就会开个机器、接个网线、换个硬盘。有时候我在机房里看着那些服务器,心里就想,这些机器里跑的东西,我连看都看不懂。但我知道它们是重要的,是有人在上面花了心血的。”
他站起来,拍了拍我的肩膀。他的手粗糙得像是砂纸,掌心全是老茧。
“所以我虽然看不懂你写的代码,但我知道它是心血。心血不能白费。加油,小伙子。”
他端着搪瓷缸子走了,拖鞋趿拉趿拉的声音渐渐消失在走廊尽头。我转回电脑前,屏幕上的代码还停在声纹模块的最后一行。我端起那杯老周倒给我的浓茶,一口一口地喝完了,然后把杯子放在一边,继续敲键盘。
凌晨四点,我开始写第三个模块——语义分析引擎。这个模块是v4.0里工作量最大的部分,因为多模态交叉验证要求语义分析和声纹分析同步进行,这意味着语义模型必须做大幅度的架构调整。原来的语义模型是一个相对独立的自然语言处理流程,输入文本,输出情感标签。但在v4.0里,它需要在输出情感标签的同时,生成一个中间层的语义特征向量,用于跟声纹特征向量做交叉比对。
这个改动听起来简单,做起来极其复杂。语义特征向量的维度需要跟声纹特征向量对齐,否则没法做比对;对齐又意味着要重新训练语义模型的嵌入层;重新训练嵌入层又需要大量的标注数据——而这些数据目前还不存在。
我写到一半,停了下来。这个问题不是靠敲键盘能解决的,需要停下来想一想。我站起来走到白板前面,在那个“语义分析引擎”的进度条旁边画了一个大大的问号。
特征向量对齐。这是一个架构级的难题,v3.7.1里没有这个问题,因为那时候声纹和语义是各自独立的,不需要对齐。v4.0要做交叉验证,就必须让两个模型的中间层输出在同一个向量空间里。用技术术语来说,就是需要一个共享嵌入空间。构建这个共享嵌入空间的方法有几种——联合训练、迁移学习、或者直接设计一个对齐层。三种方法各有利弊,需要在纸上推演一下才能决定。
我在白板上画了三列,分别对应三个方案,然后在每个方案下面列出优缺点和预估的工程周期。写到第三个方案的时候,我忽然想到了一个在v3.7.1里被废弃的模块——那个模块做的是跨模态注意力机制,当时因为效果不稳定被我砍掉了。但现在回头看,那个模块的核心思想——用注意力权重来桥接不同模态之间的语义鸿沟——恰好可以解决眼前的对齐问题。
我翻开老周给我的commit记录,找到关于跨模态注意力模块的那几条消息。消息的内容印证了我的记忆——我确实做过这方面的尝试,只是当时因为数据量和算力的限制没有做透。现在有了双卡并行的服务器,算力不再是个问题;数据量方面,赵鹤鸣手里有四百三十七次测试的完整记录,那里面包含了大量的声纹和语义对应数据,可以作为训练集。
方案确定了。我回到电脑前,开始重新设计语义分析引擎的架构。不是修修补补,而是从嵌入层开始重新搭建,把跨模态注意力机制直接集成进去。这意味着工作量比原计划翻了一倍——但一旦做成了,它不仅是v4.0的核心,甚至可能成为整个“暮光”项目最底层的技术基石。
我深吸一口气,开始在键盘上敲下新架构的第一行代码。
窗外的天已经蒙蒙亮了。银杏树的轮廓在晨曦中渐渐清晰起来,金黄色的叶子在微风里轻轻摇动。实验室里的灯还亮着,白板上六个进度条里填满了两个半,老周的搪瓷缸子放在门口的台子上,茶已经不冒热气了。
我敲完最后一行初始化代码,靠在椅背上,闭了会儿眼。脑子里还在嗡嗡地转,像一台永远不关机的服务器。我想到明天——不对,已经是今天了——今天下午念念要去学钢琴,方雯说送完她顺路给我带点吃的。她说这话的时候语气轻描淡写,但我知道她不顺路。她住在城西,我们公司在城东,中间隔了一整座城市。她说“顺路”,意思只是“我想来”。
但我现在没心思想这些。我睁开眼,坐直身体,继续敲键盘。
第四天,语义分析引擎的架构搭建完成。第六天,跨模态注意力层跑通了第一版测试,效果比预期好,但延迟比目标值高了零点一秒。第七天,老周从机房搬了一台额外的GPU服务器过来,帮我做分布式训练加速。第十天,延迟压到了零点三五秒,离目标只差零点零五秒。
第十二天晚上,方雯带着念念来了。
念念穿着一件红色的小风衣,头发扎成了两个小揪揪,背着一个粉色的小书包,一蹦一跳地跑进实验室,脆生生地喊了一声“爸爸”。她的声音在安静的实验室里像一颗跳跳糖炸开来,把我从代码的世界里猛地拉回了现实。
“你怎么来了?”我从椅子上站起来,蹲下去接住了扑过来的念念。她的身上带着外面的凉气,小脸被秋风吹得红扑扑的,两只小手捧着我的脸左看右看。
“爸爸,你是不是好久没刮胡子了?”她认真地说,用指尖戳了戳我的下巴,“扎人。”
方雯站在门口,手里拎着一个保温袋。她穿着一件驼色的大衣,头发剪短了一些,看起来比三年前干练了不少。她目光越过我落在实验室里——白板上密密麻麻的流程图、桌上的三个空咖啡杯、墙角堆着的外卖盒子和毯子。
“你就住这儿了?”她问。
“这几天比较赶。”我有些心虚地把毯子往墙角踢了踢。
方雯没说什么,把保温袋放在桌上,拉开拉链,里面是一层一层的饭盒。红烧排骨、清炒虾仁、凉拌黄瓜、还有一盒还冒着热气的米饭。都是我以前最爱吃的菜。她把这些饭盒一个一个拿出来摆好,动作利落得像在布置一个临时的餐桌。
“念念,别闹爸爸,让爸爸先吃饭。”她把念念从我怀里拉过去,按在旁边一把椅子上坐下。
我坐在电脑前,对着那排饭盒愣了一下。离婚三年,这是方雯第一次给我做饭。以前在一起的时候她从来不进厨房,她说过一句话,我到现在都记得——“我宁愿加班到十二点也不要围着灶台转。”那时候我们家的厨房基本上是摆设,全靠外卖和念念姥姥的接济过活。但现在她站在实验室里,从一个保温袋里变出了一整桌菜,每一道都像是精心准备的。
“你做的?”我问。
“跟网上学的。”她说这话的时候没看我,低头帮念念解开小风衣的扣子,“念念说你天天吃盒饭,脸都瘦了一圈。非要我多做一点带过来。”
念念在旁边猛点头,两个小揪揪一甩一甩的:“爸爸你看你脸上的坑都变大了!”
脸上的坑。她说的是我颧骨下面的凹陷。这个小丫头的观察力比她妈还敏锐。
我拿起筷子,夹了一块排骨塞进嘴里。味道出乎意料地好,排骨炖得很烂,酱汁咸甜适口。我连着吃了好几块,又扒了一大口米饭,两颊鼓鼓囊囊的,形象全无。方雯看着我的吃相,嘴角微微弯了一下。
“你们那个评审会的事,我在圈里听说了。”她靠在实验台旁边,双手抱在胸前,语气随意但目光认真,“赵鹤鸣跟我的老板认识,前两天一起吃饭的时候提到了你。他说你是他见过的最有天赋的年轻工程师。”
“他当着我的面可没这么说过。”我嘴里塞着饭含糊不清地应了一句。
“当着你的面当然不会说,怕你飘。”方雯的语气里带着一丝若有若无的笑意,“他还说,你在重写那个项目,一个月要完成六万行代码。我老板说赵鹤鸣疯了,让一个工程师一个月写六万行,不出十天就得进医院。赵鹤鸣说,别人不行,沈言行。”
她把最后那句话说得格外清晰,像是在强调什么。我不知道她为什么要特意转述这些,也许是想让我知道我的价值,也许只是想找个话题聊下去。但不管是哪种,她说这些话的时候眼神是认真的,那种认真跟三年前跟我吵架时完全不一样。
“方雯,”我放下筷子,看着她,“你今天来,不只是为了送饭吧?”
她沉默了几秒,然后从大衣口袋里掏出一个信封放在桌上。信封是白色的,右下角印着一家外企的logo。
“下个月我可能要去德国总部待半年,”她说,语速比刚才慢了一些,“公司有一个新的业务线要我去带,机会很难得,但念念不能跟我去。我本来想让我妈帮忙带的,但她最近腰不太好,我怕她吃不消。”
我放下筷子,看着那个信封。
“所以我在想……”她的声音变得有些犹豫,这在方雯身上是极少见的。她是那种永远知道自己想要什么、永远毫不犹豫的女人,但此刻她犹豫了,“如果到时候念念能在你这边住一段时间,会不会更好?”
“当然可以。”我说,几乎是脱口而出。
“但你现在的状态——”她看了看实验室里那堆外卖盒子和毯子,“你真的能照顾好她吗?”
“我现在的状态是暂时的。”我把信封推回她面前,“一个月以后,不管这个项目是成是败,我都会恢复正常。那时候念念过来,我可以每天接送她上下学,周末带她去科技馆,她不是一直想去科技馆看那个机器人展吗?”
方雯看着我,目光里有一种我说不清的东西,像是意外,又像是感动。也许她没想到我会答应得这么爽快,也许她只是没想到我会把念念去年随口说的一句“想看机器人展”记到现在。
“那等你这个项目结束了,我们再具体商量。”她把信封收回去,语气恢复了平时的干练,“不过现在,你先吃饭。念念,让爸爸好好吃饭,不许闹他。”
念念乖乖地从椅子上滑下来,跑到白板前面,看着上面那些她完全看不懂的流程图和进度条。她仰着小脑袋看了好一会儿,然后转过来问我:“爸爸,这些字都是你写的吗?”
“是啊。”
“写得真丑。”
方雯没忍住,噗地一声笑了出来。我也笑了,笑得呛了一口饭,咳了好半天。念念看着我们两个笑,不知道发生了什么,但她也跟着笑了起来,露出两颗缺了的门牙。
那天晚上方雯和念念走的时候,念念在电梯口抱着我的腿不肯松手。她说爸爸你一定要来看我的钢琴表演,下周五学校有汇报演出,每个小朋友都要上台弹一首曲子。我说好,爸爸一定去。她说你拉钩。我蹲下来跟她拉钩,她的小拇指勾着我的,用力晃了三下。
“拉钩上吊,一百年不许变。”
电梯门关上之后,我站在走廊里,看着电梯的数字一格一格往下跳。方雯最后进电梯之前回头看了我一眼,嘴唇动了动,像是想说什么,但最终只是点了点头,转身上了电梯。
我回到实验室,关上门,坐回电脑前。桌上还留着方雯带来的饭盒,保温袋的拉链没拉严,露出里面一包没拆封的湿巾。我在饭盒堆里翻了一下,发现最下面还压了一张便签纸,是念念写的——歪歪扭扭的字,铅笔写的,旁边画了一个歪嘴笑的小人。
“爸爸加油,我给你画了十颗星星。”
便签纸的空白处画了十颗歪歪扭扭的五角星,每一颗的大小形状都不一样,但每一颗都是被认认真真涂满的。
我把便签纸贴在了白板上,就在六个进度条的正下方。然后我拧开马克笔,把刚才被念念说丑的那几个字描了一遍,描得整整齐齐的。描完之后我退后一步看了看,虽然还是比不上赵鹤鸣那八个字的功力,但至少不再是一个六岁孩子口中的“写得真丑”了。
时钟指向晚上九点。距离一个月的期限,还剩十八天。
第十三天,跨模态注意力层的第二轮测试出来了——延迟零点三二秒,准确率百分之九十四点一。这两个数字出现在屏幕上的时候,我愣了好几秒。零点三二秒,比我原来的目标零点三秒只差了零点零二秒。百分之九十四点一的准确率,比v3.7.1还高了零点四个百分点。
我拿起马克笔,把白板上“多模态交叉验证”那个进度条涂满了。六个模块,已经完成了四个半。还剩一个半——动态学习层和输出接口。
第十五天,赵鹤鸣来了。
他没有带助理,一个人穿着那件深灰色的棉麻衬衫,手里端着两杯咖啡。他把一杯放在我桌上,自己端着另一杯坐在了实验室角落的椅子上。他看了一眼白板上密密麻麻的进度条和那张画着十颗星星的便签纸,什么都没说,只是安静地喝着咖啡。
“赵总,有事?”我一边敲代码一边问。
“没事,就是来看看。”他说,“项目下周三向董事会做演示,还有九天。程志宏今天来找我了,说他可以帮你分担一些外围模块的开发。我说不用了,沈言自己搞得定。”
“你确定?”
“不确定。”他喝了一口咖啡,表情坦荡,“但我愿意赌。你要知道,我赵鹤鸣这辈子赌过很多次——卖房子赌公司能活下来,赌一个应届生能写出国内领先的算法,赌一个删了自己代码的年轻人能用一个月从零重建。前两次我都赢了。”
“这次呢?”
“这次,”他站起来,端着咖啡走到白板前面,看着那六个被涂得满满当当的进度条,“我看了你第十四天跑出来的测试数据。零点三二秒,九十四点一。这个数据,放到去年这个时候,我会说这是国内实验室里最好的成绩之一。”
他把咖啡杯放在桌上,转过来看着我。他的目光很平静,但那种平静里有一种极深的笃定。
“沈言,你知道我最欣赏你哪一点吗?不是你技术好。技术好的人我见多了,清华的、北大的、MIT的、斯坦福的,都见过。你最让我欣赏的是,你在所有人都否定你的时候,还有勇气删掉一切从头来过。大部分人在面对五个零分的时候会崩溃、会放弃、会妥协。你没有。你用十分钟删掉了过去,然后用一个晚上画出了未来。这种素质,比任何技术都稀缺。”
他拍了拍我的肩膀,力道不重,但很扎实。
“下周三,让他们看看。”
他走了以后,实验室里重新安静下来。窗外的银杏树落了一半的叶子,金黄的叶片铺了一地,在夕阳里闪闪发光。我端起赵鹤鸣留下的那杯咖啡喝了一口,现磨的,不加糖,苦得人眉心发紧,但后味醇厚。
第二十天,最后一个模块写完了。v4.0的全部代码,加上注释和文档,一共六万四千行。比原来的六万行多了四千行,但架构的清晰度和可扩展性完全不是一个量级。我坐在电脑前,对着那个绿色的“编译通过”提示框,一时间不知道该做什么。
二十天。每天平均三千两百行代码,睡在实验室的毯子上,吃老周带的夜宵和方雯送来的饭,喝赵鹤鸣的咖啡,把念念的十颗星星贴在白板上最显眼的位置。现在代码写完了,进度条全部涂满了,屏幕上的绿色提示框安静地亮着,像一个句号。
但这不是句号。代码写完了,接下来是测试、调优、演示准备。离下周三还有六天,时间不算充裕但也不算紧张。我给赵鹤鸣发了一条消息:“v4.0初版完成,可以安排内部测试。”
他秒回了两个字:“收到。”然后追了一条:“念念是谁?”
我愣了一下,然后意识到他大概是看到了白板上那张便签纸上写的字。“爸爸加油,念念。”念念的署名太明显了。
“我女儿。”我回他。
“你有个女儿?”他的语气里带着意外。
“六岁了,刚上小学。”
过了好一会儿,赵鹤鸣回了一条消息。不是文字,是一张照片。照片里是他办公室的书架,上面摆着一排相框,全是孩子的照片——一个小男孩,从婴儿时期到大概七八岁的样子,虎头虎脑的,笑容灿烂。
“我儿子,今年十八了,刚考上大学。他十岁那年问过我一句话:爸爸,你每天那么晚回家,是不是不爱我了?我当时不知道怎么回答。后来我想了很久,跟他说,爸爸每天那么晚回家,是因为在做一件很厉害的事,等这件事做成了,全世界的人都会知道你爸爸的名字。他似懂非懂地点了点头。”
我看着这条消息,手指悬在屏幕上方,迟迟打不出一个字。赵鹤鸣发来了最后一条。
“沈言,等‘暮光’发布那天,带你女儿来。让她看看她爸爸做的是一件多厉害的事。”
第二十二天,第一次全系统压力测试。赵鹤鸣调了公司整个测试团队过来配合,在实验室里临时搭了一组模拟环境——上百个虚拟用户同时发起语音交互请求,各种噪声场景轮番轰炸,从安静的室内到嘈杂的街道再到呼啸的地铁车厢。我和测试团队的人盯着屏幕上跳动的数字,心提到了嗓子眼。
测试结果在下午四点出来了。延迟零点三一秒,准确率百分之九十四点六,高并发下的系统稳定性比v3.7.1提升了将近一倍。测试团队的负责人摘下耳机,转过头看了我一眼,说了一句话,声音里带着难以置信。
“沈工,你这个引擎……比市面上一流的方案快了将近一倍。”
我没有说话,只是靠在椅背上,长长地呼了一口气。那一口气吐出来的时候,我感觉二十多天压在心口的石头终于松了一点。不是因为数据好,而是因为数据证明了我在白板上画的那张流程图是对的。矛盾即信号。跨模态注意力。多模态交叉验证。这些在评审会上连提都没人提的技术概念,在这里变成了实实在在的数字。
第二十五天,我请了半天假。去念念的学校看她的钢琴汇报演出。小姑娘穿着一件白色的蓬蓬裙,头发上别了一个亮晶晶的发卡,坐在比她人还大的钢琴前面,两条腿悬在琴凳外面够不到踏板,但她的手指落在琴键上的时候格外认真。她弹的曲子是《小星星》,简单得不能再简单,但她一个音都没有弹错。弹完之后她站起来向台下鞠了一个躬,然后踮起脚尖在观众席里找我的位置,找到之后用力地朝我挥手。
方雯坐在我旁边,看到念念挥手的样子,眼眶忽然红了。她悄悄用手背擦了一下眼角,然后转过头来跟我说:“谢谢你今天能来。”
“我答应了她的。”我说。
“你知道她为什么非要弹《小星星》吗?”
“为什么?”
“因为她三个月前刚开始学琴的时候跟我说,妈妈,等我学会了小星星,我要弹给爸爸听。因为爸爸的名字里有一个‘星’字。”
沈言。言是说话的言,但念念不认识“言”字,她只认识“星”。在她的小脑袋里,爸爸的名字是“沈星”,天上的星星。她花了三个月学一首《小星星》,就是为了弹给我听。
我坐在小学礼堂的硬板凳上,看着念念从舞台上蹦蹦跳跳地跑下来扑进我怀里,把脸埋在她汗湿的头发里,嗓子堵得说不出一句话。
方雯在一旁安静地看着我们,手里拿着念念的外套。阳光从礼堂的窗户照进来,落在她脸上。她的表情很平静,但眼神里有一种久违的温柔,像冰面下涌过的暖流。
“念念,”我把女儿抱起来,在她耳边轻声说,“爸爸最近在做一件很重要的事,等做完了,带你去看机器人展。”
“真的吗?”她的眼睛一下子亮了,“那拉钩!”
“拉钩。”
我们的小拇指又勾在了一起。方雯在旁边轻轻叹了一口气,听不出是无奈还是别的什么。
第二十七天,距离董事会演示还有两天。实验室里灯火通明,测试团队在做最后一轮稳定性验证。赵鹤鸣每天都来实验室坐一会儿,有时候不说话,就坐在角落里看我们忙碌,有时候会带几杯咖啡或者一盒点心。老周的搪瓷缸子也成了实验室的固定配置,每天晚上他值夜班巡楼的时候都会进来给我续一杯浓茶。
第二十九天晚上,所有的准备工作都做完了。演示文稿、技术文档、测试报告、应急方案,全部整理完毕,打印成册,一式五份,整整齐齐地放在会议室的桌上。我站在空无一人的会议室里,看着投影幕布上那句改了无数遍的slogan——“让每一个声音都被听见”,忽然觉得恍惚。
一个月前,我站在另一间会议室的投影幕布前,手里拿着激光笔,屏幕上显示着同样一句话。那时候等待我的是五个零分。三十天后,我站在这里,带着从零重建的六万四千行代码和零点三一秒的测试指标,等待另一场审判。
手机在兜里震了一下。我掏出来看,是老周发来的消息。
“沈工,我刚才在机房检查明天演示用的服务器,一切正常。另外我注意到一个事——赵总的私人服务器上,今天凌晨又开始跑你的代码了。v4.0版本的,他跑了整整一宿。刚才停了,我看了日志,他写了一条备注。”
消息后面跟了一张照片,拍的是赵鹤鸣手写的那条备注,字迹有些潦草,显然是凌晨写的。
“v4.0测试完毕。延迟零点三一秒,准确率百分之九十四点六。比v3.7.1提升百分之二十六的效率,延迟降低百分之二十八。沈言二十天从零重建,完成了我认为至少需要半年才能完成的工作。这个年轻人让我想起了二十三年前的自己。不同的是,他比我更强。明天董事会演示,我有信心。”
我把这条备注看了三遍。赵鹤鸣从来没有当面跟我说过这些,他跟我说的最多的话是“继续”“加油”和“收到”。但在凌晨的私人服务器上,他用一条备注写下了他对我全部的评价。二十三年。二十三年前,赵鹤鸣跟我现在差不多大,那时候他应该刚刚开始创业,在某个出租屋里写了第一行代码。二十三年后,他在一条测试日志里说,这个年轻人让他想起了二十三年前的自己。
我把手机收起来,最后检查了一遍明天的演示流程。一切就绪之后,我关了会议室的灯,准备回家洗个澡、刮个胡子、换身干净衣服——念念前两天在视频里专门强调过,爸爸你要刮胡子,不然扎人。
电梯下到一楼,我刚走出大门,手机响了。是一个陌生号码。
“喂?”
电话那头没有人说话,只有呼吸声,粗重而不均匀,像一头被困在笼子里的野兽。
“哪位?”我又问了一遍。
“沈言。”电话那头终于开口了,声音低沉而沙哑,我花了两秒钟才辨认出来——是程志宏,评审委员会的组长。
“程老师?”
“你明天要演示了。”他说,语气不是疑问,是陈述。
“对。”
电话那头又沉默了几秒。然后他说了一句让我握着手机的手瞬间收紧的话。
“明天的演示,你小心一点。不是技术的问题——有人不想让你的项目上线。比评审委员会更高层的人。”
“谁?”
“我不能说。”他的声音压得更低了,低到几乎要被听筒里的电流声淹没,“我只能告诉你,赵鹤鸣不是唯一能做决定的人。董事会里有一个席位,一直在反对‘暮光’,因为一旦你的技术上线,他参股的另一家公司会直接受到冲击。评审会的事,不是我跟邱敏的主意。是有人在背后推。”
我的后背瞬间冒出了一层冷汗。十月底的夜晚已经很凉了,但我的衬衫后面湿了一片。
“你为什么要告诉我?”我问。
电话那头安静了很久。久到我以为他挂断了。然后程志宏的声音再次响起来,沙哑的、疲惫的、带着一种被压抑了很久终于找到出口的诚实。
“因为我是你的面试官。三年前校招,是我把你招进来的。你当时说的那个语音社交的点子,我在面试记录里写了一句话——‘此人有改变行业格局的潜力’。三年后,我亲手给你的项目打了零分。”他停顿了一下,呼吸声在听筒里起伏,“这几天我一直在想赵鹤鸣跟我说的那句话。他说,程志宏,你在这个位置上坐得太久了,久到你忘了自己当初为什么要做技术。我现在告诉你这件事,不是因为我想弥补什么,只是因为我还没有完全忘了。”
电话挂断了。
我站在公司门口的台阶上,十月的夜风从街道尽头灌过来,吹得我浑身发冷。手里的手机屏幕暗了下去,映不出任何东西。
全部评论