这两天在给小龙虾做流式语音,我想分享一个挺有意思的研发过程。为了让语音合成听起来足够实时,而且中间尽量不停顿,从研发直觉上看,最容易想到的方法,就是把每一句话都拆成片段,然后每句话都用流式的方式依次合成,最后再把这些音频拼起来。
但是昨天 AI 第一次给我生成代码的时候,它采用的方案并不是“所有句子都流式”。它的做法是:前两句话走流式,保证用户一开始就能听到声音;后面的内容提前预生成,也就是预取,而不是继续完全流式。这个方案我第一次听的时候,就觉得已经很好了。但从研发的直觉出发,我当时还是会想:既然流式已经可以做到很快响应,那为什么不把后面所有内容也都改成流式?这样岂不是更快?
于是我花了半个小时,把所有句子都改成了流式实现。结果做完以后我才发现,效果反而不如第一种“前面流式,后面预取”的方案。原因很简单:如果所有句子都严格按顺序流式生成,那么每一句都依赖前一句的生成完成。一旦网络有一点波动,中间某些句子就可能来不及生成出来。最后表现出来的效果,就是 AI 说话会跳着说,甚至中间断掉,体验非常差。
后来我让 AI 帮我总结这个问题,它说,其实业界很多类似场景都是这么做的,比如音频生成、视频下载,常见方案都是前面用流式保证首屏速度,后面用预取保证整体稳定性。这个组合不是折中,而是最稳的工程方案。所以回过头看,这件事最有意思的地方在于:AI 一开始其实就已经给了我更优的实现方式,只是我当时还在用人类的想象,试图把方案“再优化一点”。等真的自己踩完坑,才发现那个“看起来更快”的方案,背后其实有很大的工程问题。
最后,我又回到了 AI 最开始推荐的方法:前面流式,后面预取。有时候,研发经验能帮你发现问题;但有时候,真正的经验是承认一个方案为什么已经是最优解,而不是总觉得自己还能再想出一个更聪明的办法。