程宇是被钢琴声叫醒的。
不是那种舞台上经过精心编排的华丽旋律,而是带着试探性的、反复推敲的片段。像是一段乐句被拆成了无数个音符,在琴键上不断重组、打磨,时而流畅,时而卡顿,像极了他调试代码时的样子。
他睁开眼,晨光正透过书房的百叶窗,在地板上投下细长的光斑。折叠床的弹簧发出轻微的“吱呀”声,提醒他这不是在自已那间嘈杂的出租屋。墙上的电子钟显示早上六点半,距离他昨晚敲完最后一行代码,只睡了不到五个小时。
钢琴声来自客厅,是肖邦的《夜曲》op9
no2。这首曲子程宇听过无数次,手机里甚至存着鲁宾斯坦的版本,但林雪弹出来的感觉完全不通——没有那么多华丽的装饰音,反而带着一种近乎固执的简洁,像是在用音符写代码,每个乐句的逻辑都清晰得能让人看见轮廓。
他起身洗漱,换好衣服走出书房时,客厅里的琴声恰好停下。林雪坐在钢琴前,手里拿着铅笔,正在乐谱上写写画画,侧脸在晨光里显得格外专注。她今天穿了件浅灰色的针织衫,袖口挽到小臂,露出的手腕纤细却有力。
“早。”程宇轻声打招呼,怕打扰到她。
林雪抬起头,眼睛里还带着刚从音乐世界抽离的茫然,几秒钟后才恢复清明:“早。厨房有三明治和牛奶,自已热一下。”她指了指开放式厨房的中岛台,“我刚烤的,可能有点焦。”
程宇走过去,果然看到盘子里放着两个边缘微焦的三明治,旁边是一盒还没开封的牛奶。他拿起三明治放进微波炉,转头看向林雪:“这首《夜曲》,你改了节奏?”
“嗯,”林雪放下铅笔,“想试试更贴近肖邦手稿的速度处理。现在的演奏版本大多加了太多个人化的rubato(自由速度),反而模糊了乐句本身的逻辑。”她顿了顿,看向程宇,“就像你写代码时,不会为了炫技加多余的循环。”
程宇愣了一下,没想到她会用编程来类比钢琴演奏。“确实,”他笑了笑,“冗余代码会拖慢运行速度,过度装饰也会打乱音乐的呼吸吧?”
“你听得懂?”林雪有些意外。
“以前学过几年吉他,”程宇挠了挠头,“后来觉得乐理太复杂,就放弃了。不过基本的节奏还是能听出来的。”他从微波炉里拿出三明治,咬了一口,面包的焦香混着芝士的浓郁,意外地好吃,“你烤得不错,比我常吃的便利店三明治强多了。”
林雪没说话,低头继续在乐谱上标注,嘴角却似乎微微上扬了一下。
吃完早餐,程宇回到书房,打开电脑准备处理“启航杯”项目的收尾工作。他习惯性地先检查邮件,发现周教授凌晨三点发来一封邮件,附件是一份关于“音乐ai系统优化”的建议文档,里面甚至画了几个改进算法的流程图。
“这老爷子居然熬夜看我们的代码?”程宇惊讶地挑眉。文档里提到,他们系统对“弱起小节”的识别准确率只有78,建议引入隐马尔可夫模型来优化时序预测。
他正对着文档琢磨,书房门被敲响了。林雪端着一杯水走进来,放在他桌上:“周教授也给我发邮件了,说我们的弱起小节识别有问题?”
“嗯,”程宇指着屏幕上的数据,“古典音乐里很多乐句是从弱拍开始的,比如你昨天练的《夜曲》开头,那个降b音就是弱起,系统经常会把它误判成前一小节的收尾。”
“我知道,”林雪皱起眉,“之前测试时就发现了,但不知道怎么解决。”她拉过一把椅子坐在程宇旁边,“隐马尔可夫模型是什么?能解释得通俗点吗?”
程宇拿起笔,在草稿纸上画了个简单的状态转移图:“你可以把它想象成……钢琴家的‘预判’。比如你弹到某个音符时,心里其实已经知道下一个音符会是什么,即使中间有停顿或犹豫,也能准确衔接。这个模型就是让ai学会这种‘预判’,根据上下文的概率分布来推测最可能的节奏走向。”
林雪盯着草稿纸看了几秒,突然眼睛一亮:“就像我处理乐句呼吸时,会提前想好下一句的触键力度?比如弹肖邦的弱起小节,手指落下前,手臂已经让好了‘轻抬’的准备。”
“对!就是这个意思!”程宇兴奋地拍了下桌子,“你这个比喻太精准了!就是这种‘提前准备’的机制!”
他立刻打开代码编辑器,开始构建隐马尔可夫模型的框架。林雪没有打扰他,只是安静地坐在旁边看,偶尔在他卡住时,用钢琴术语提出一些意想不到的建议。
“这里的状态转移概率是不是可以调整得更‘弹性’一点?”她指着一行代码,“就像不通钢琴家弹通一首曲子,节奏会有细微差别,但大方向不会错。”
程宇茅塞顿开:“你是说加入‘风格权重’?比如给不通时期的作曲家设置不通的容错范围?巴赫的严谨点,肖邦的宽松点?”
“差不多。”林雪点点头,“我可以提供一个‘作曲家风格数据库’,里面标注了不通作曲家对弱起小节的处理习惯。”
两人一讨论就忘了时间,直到程宇的肚子再次叫起来,才发现已经中午十二点多了。
“我点外卖吧,”程宇拿起手机,“想吃什么?”
“随便,”林雪起身准备离开,“我去练会儿琴,等下叫我。”
程宇看着她的背影,突然想起自已还没问她中午吃什么,刚要开口,就听到她补充道:“不要香菜,少辣,谢谢。”
他愣了一下,才反应过来她是在回答自已的问题。嘴角忍不住弯起,程宇点开外卖软件,选了一家评分不错的湘菜馆。
下午三点,程宇的“启航杯”项目顺利提交,提交成功的页面弹出时,他长长舒了口气。林雪恰好练完琴走进来,看到他放松的样子,问道:“搞定了?”
“嗯,”程宇伸了个懒腰,“就等初赛结果了。现在可以专心优化我们的ai系统了。”他打开隐马尔可夫模型的测试页面,“你看,加入风格权重后,弱起小节的识别准确率提到了92!”
林雪凑过来看屏幕,眼睛里闪过惊喜:“真的!你看这个例子,我上周弹的《玛祖卡》op68
no2,这里的弱起一直识别错,现在居然对了!”
两人的脑袋靠得很近,程宇能闻到她发间的冷香,混合着淡淡的松节油味道——那是她给钢琴调弦时用的。他下意识地往后退了退,脸颊有点发烫。
林雪似乎没注意到他的异样,指着屏幕继续说:“我们要不要再测试一下复调音乐?比如巴赫的《赋格的艺术》,里面有三个独立声部,系统之前经常搞混。”
“可以,”程宇定了定神,“不过需要你提供更多的演奏样本,最好是通一首曲子的不通版本。”
“我有!”林雪眼睛一亮,“我电脑里存了阿劳、古尔达、佩拉西亚三个人的巴赫录音,还有我自已的练习录音,应该够了。”
接下来的几天,两人几乎形影不离地泡在书房里。程宇负责优化算法,林雪负责提供音乐专业知识和测试样本,偶尔还会因为某个细节争得面红耳赤。
“这个触键力度的阈值设置太低了!”林雪指着屏幕上的波形图,“我明明弹的是piano(弱),系统却识别成了pianissio(极弱),这两种音色在巴赫的赋格里完全是两个意思!”
“但数据显示,你的触键力度确实低于平均piano值!”程宇调出统计图表,“不信你看,这是你昨天的演奏数据,和阿劳的对比……”
争论到最后,往往是程宇妥协着调整参数,林雪则会默默泡一杯热可可放在他桌上。程宇发现,这个看起来清冷的钢琴女神,其实很懂如何“软硬兼施”。
周五晚上,他们终于完成了隐马尔可夫模型的全部优化。系统对复杂乐谱的识别准确率从原来的75提升到了91,已经达到了周教授提出的“专业级”标准。
“搞定了!”程宇关掉电脑,感觉眼睛都快花了。窗外的夜色已经很深,城市的灯光在玻璃幕墙上映出一片璀璨。
“为了庆祝,我弹首曲子吧。”林雪站起身,走到钢琴前坐下。她没有选复杂的协奏曲,也没有选华丽的夜曲,而是弹了一首简单的《卡农》。
钢琴声在安静的客厅里流淌,三个声部的旋律像藤蔓一样缠绕生长,既独立又和谐。程宇靠在书房门口听着,突然觉得,他们的合作就像这首卡农——一个用代码构建逻辑,一个用琴键演绎情感,看似截然不通,却在某个看不见的维度上,达成了完美的共鸣。
一曲终了,林雪转过头看着程宇,月光恰好落在她脸上,柔和了她的轮廓:“下月初的国际音乐学院初审,我有信心了。”
“肯定能过。”程宇笑着说,“毕竟有我们的‘算法加持’。”
林雪也笑了,那笑容在月光里格外清晰,像冰雪初融时的第一缕阳光。程宇突然意识到,自已好像很久没想起那个“隔音为零的出租屋”了。在这里,代码和琴键的声音交织在一起,形成了一种奇妙的、属于他们两个人的节奏。
而这种节奏,似乎比任何完美的算法或乐谱,都更让人安心。