我们前几天讲了计算机科学里的一些思维方式,但是科学要通过工程才能变成产品,才能改变世界,具体做工程时,思维方式和科学研究又有所不同,今天我们就来看看它们之间的不同之处。我在昨天讲,提高两倍的速度对科学并没有什么意义,因为还是在一个量级上,但是对工程确实有意义,假如你的计算机快了两倍,你肯定会很高兴。很多人问我,计算机科学和工程有什么差别?今天我们就这个话题聊一聊,我们从三个方向分析。
1. 方向和道路之分别。
科学常常指出正确的方向,而工程则是沿着科学指出的方向建设道路。如果没有计算机科学给出最好的算法,我们修的道路通常缺乏方向性,是在绕路,但是,有了科学后,最终还需要工程把道理修通。
2. 科学和工程需要关注不同的事情,工作的环境也不同。
我在周一讲,计算机科学家需要聚焦在量级上提高性能,为了做到这一点,他们需要构建理想的环境,摒除一些不必要的干扰,把主要矛盾突出出来。比如提高计算机算法的速度时,不要过分考虑加载数据的处理器时间、计算机内存的极限等边界效应,要想办法把所有没必要的数据比较都省略掉。
但是,具体到工程上,节省几倍的时间,甚至20%的时间是很有意义的。另外,理论上最好的解决方案,遇到极其糟糕的情况,可能会失去通常的表现,这种时候需要有预案,这就是工程师们要考虑的问题。对于一个好的工程师来讲,他最重要的能力是了解最新的科学进展,并且根据实际情况使用最新的技术解决实际问题。
在大学教育上,一个巨大的缺陷在于科学和工程分不清,大学做了很多原本是公司应该做的事情,比如今天中国一些大学津津乐道于制造超级计算机,这根本就是工程的事情,应该是联想这样的公司去做。这样的教育导致了创新性的研究非常少,虽然发表论文不少,但大多是别人提出问题并给出了初步的答案后,中国的大学来完善。中国在今天,计算机工程做得不错,科学还是比较弱。
3. 科学家和工程师跟钱的距离不同。
坦率地讲,科学家通常是离钱比较远的,即使是因为发明快速排序算法而获封爵士头衔的霍尔,也没有多少钱。相反,在工程上实现了自己所发明的"网页排名算法"搜索的佩奇和布林,即使所创办的Google公司不上市,钱也少不了。要想当科学家,就要离短期的利益远一点,这样才能把目光放远。不仅大学教授挣钱可能没有工程师多,即使在大公司里,搞研究的收入常常不如做产品的。我在Google挣钱最少的四年,就是中间单纯做研究的四年。
而科学家要想成为工程师,也不是说变就变的,思维方式需要改变,要从理想状态进入到现实状态。我们经常发现,很多教授办公司反而不如他们的学生,因为教授是科学家,思维方式不适合做产品。
接下来,我就讲讲自己的亲身经历,说说我的关注点是怎样从工程到科学,再到工程的,从这个过程中你可以看出计算机科学家和工程师在不同身份时所应该采取的不同做事策略。
我27年前在中国做语音识别,那时中国这方面的工作刚起步,我们通常是把英语的方法改一改用于中文的识别。在此之前世界上也没有什么人做中文的识别,这种工作算是科学还是工程呢?其实很难说清楚,但是工程的成分大一些。等我在美国做博士论文时,就必须做一些别人没有做过的研究了,具体讲,主要的工作是提出一个新算法,这个算法今天大家还在用,而且还时不时写邮件向我询问细节。直接联系我的原因并非我论文写得不通顺,而是大部分计算机专业的博士生懒得读我的博士论文,因为它读起来更像是一篇数学论文,里面有20%的篇幅是公式的推导,我所提出的几个引理和定理的证明。
这样一项研究带来什么结果呢?它比过去的机器学习算法简化掉了很多重复的计算,以至于可以让运行速度提高几百倍到上千倍。在2000年之前,世界上做语音识别和机器翻译的人开始尝试一种在数学上非常漂亮的机器学习算法,当时IBM一个非常聪明的科学家,想办法把整个沃森研究中心所有的计算机在空闲时都拿来使用,这样计算了两年,才得到一个结果,发表了一篇论文。于是接下来的两年,全世界所有做语音识别的科学家对这种算法都望洋兴叹。
当时我也想使用那种机器学习方法解决一些实际问题,但是要按照过去的速度运行程序,我显然就不用毕业了。对我来讲,三五倍地提高速度是没有意义的事情,要提高就得从根本上提高,提高几十甚至几百倍。于是在大约半年的时间里,我就是一沓纸,一支笔地工作,推导数学公式,最后终于让我发明了一种在量级上更好的算法,于是计算速度提高了好几百倍,使得原来需要计算两年的事情在当时缩短到一周左右。就这样我得以在半年内做了十几次实验,完成了论文。
不过,当时我在写程序实现我自己的算法时,并没有去省最后10%、5%的计算机资源,因为即使再将程序速度提高10%,也不可能让我早一天毕业,更何况那么做还会花更多写程序的时间。从这里可以看出,计算机科学所关心的问题是什么,是将注意力放在量级上,而不要太在意细小的成本。
好了,等到我毕业加入了Google,思维方式就不得不再从科学转变成工程了。我的第一个项目是搜索反作弊,具体的方法是一种简单的机器学习。既然是机器学习,就需要用数据训练一个统计模型,当然模型就要占内存。我当时产生的模型有多大呢?大约20M,也就是今天一张2000万像素照片原图的大小。这对搞科学的人来讲,根本不是个事儿。
但是辛格博士(曾经一度负责Google整个搜索部门)和我讲了,你的方法很有效,但是我无法给你这么多内存空间,因为我们是很多人一同在写服务器的代码,如果每个人都将代码增加20兆字节(20MB),程序就太大(内存),装不下了。后来他教会我一种高度压缩的、近似的模型,使得占用的内存从20MB降低到3MB。20M和3M只差一个六倍的常数,从算法的空间复杂度上讲是毫无意义的事情,但这就让我们的工作成果可以用于产品了。这是Google给我上的一堂计算机工程课。
我在那里接受的第二堂课是在工程上需要计较2%的运行时间。2002年,我在Google写了它的中、日、韩文处理算法,由于要对这些语言采用特殊的搜索排序算法,使得搜索运算的时间长了2%。这在计算机科学上也不是个事,因此当产品部门的人要我提高速度时,我非常不愿意再花几周时间修改代码,于是我和产品部门的人争执了起来。
我的观点是,随着摩尔定律让计算机的速度不断提升,半年后新的服务器会让我这点"减速"的副作用变得可以忽略不计。不过产品部门的人不是这么算账的,他的负责人和我讲,Google当时有2万多台服务器服务于全球搜索,大约10%的流量是中日韩文的,也就是说占用掉了2000台服务器,增加2%的计算量,相当于多用40台服务器,当时一台服务器一年的折旧和使用成本大约是1000美元,40台服务器就是4万美元,足足值得一个工程师花一个季度的时间优化代码。没办法,我只好花了几周时间优化代码,才获准推出相应的服务。
我在后面还会不断地讲我在Google接受的工程训练。总之,在从事了几年的工程工作,我想问题的出发点就和过去不同了。等到几年后,我离开工程部门,又跑到Google做研究了之后,想法又改变了,又不太在意工程的细节了。这倒不是我偷懒,而是对于搞研究的人来讲,是要不断尝试新方法的,很多代码只有我和小组的几个人用,用不了几个月就得更新,因此花很大的时间改进代码,让算法运行的时间快个一两倍,最后节省一点运行时间没有意义。
从这里,你可以看出不同的目的,对边际成本的看法是不一样的。因此,在现实工作中,没有绝对的最好,只有在给定条件下相对比较好。
从计算机科学到工程的转变,在思维上以下两点最为重要。
第一,前者要在一个相对理想的状态下工作,这样可以将注意力集中在量级的改进上,也就是捡西瓜上。但是在产品中,并不存在理想的条件,各种细节都要考虑周到。
第二,也是最重要的,在工程中必须首先使用在科学上最好的方法,然后再作细节的改进。否则在细节上改进,提高了一点点效率,但是在宏观上损失了几十、上百倍的效率,一定做不成好产品。我在2007年之所以要写《数学之美》,就是告诉从事IT的人别丢了西瓜。
网友评论