根据我的观察,CMU优秀博士生的一个共同特点就是自己主导研究,推着(push)导师走,而不是被导师催着干活。不论是早期的李开复,后来的沈向洋,还是现在年轻的一辈,都有这个特点。我觉得毕竟博士这5年是人生中最美好的时光,一定要对得起自己,做一些有意义的事情,争取推动科技进步(哪怕一点点)。
——UC Santa Barbara计算机科学系助理教授王威廉
前言
12 年 8 月提着一个行李箱降落在匹兹堡机场。没找住的地方,也不知道 CMU 应该怎么去。对未来一片迷茫,但充满乐观。现在,刚完成了博士期间最后的一场报告,在同样的机场,不过是在等待离开的航班。
回想过去的五年,是折腾的五年,也是自我感悟和提升的五年。这里我尝试记录这五年主要做过的事情和其中的感想,希望对大家有所启发。
第 0 年:3/11-8/12
我第一次申请美国的博士是在 11 年,但拿到的 offer 并没有特别合适的导师,于是就北上投奔文渊去了。我当时在百度商务搜索部门做广告的点击预估。具体是使用机器学习来预测一个广告是不是会被用户点击。这时候离「大数据」这个词流行还有两年,但百度那时候的数据即使现在来看仍然是大的。我的任务是如何高效的利用数百台机器快速的在数十 T 的数据上训练出模型。
当时产品用的算法基于 LBFGS,我于是想是不是可以换个收敛更快的算法。没几天就找到个不错。但实现上发现了各种问题,包括性能,收敛,和稳定性。而且那时有的就是一个裸的 Linux 和很老版本的 GCC,什么都是需要从头开始写。花了大量时间做系统优化,算法改动,和线上实验,最后一年后在整个广告流量上上了线。
现在再回顾会觉得整个一年时间都在打磨各种细节上,有时候为了 5% 的性能提升花上上千行代码。这些都导致算法过于复杂,有过度设计之嫌。但深入各个细节对个人能力提升很大,而且很多遇到的问题成为了之后研究方向的来源。一些算法上的思考曾写在这里,当时候深度学习刚刚出来,冥冥中觉得这个应该是大规模机器学习的未来,不过真正开始跟进是好几年以后了。
11 年 12 月中的时候突然心血来潮随手把材料重新寄了一遍,就选了 CMU 和 MIT,结果意外收到了 CMU 的 offer。有天在百度食堂同凯哥(余凯)和潼哥(张潼)吃饭,我说收了 CMU offer,在纠结去不去。他们立马说去跟 Alex Smola 啊,他要要加入 CMU 了,我们给你引荐下。
记得是离开的前一天才开始打包行李,早上去公司开完会,中午离职,跟小伙伴打招呼说出个国,然后就奔机场了。那天北京天气特别好,完全不记得前一天雾霾刚爆了表。
第一年:9/12-8/13
第一年的主要事情是熟悉环境和上课。CMU 课程比较重,博士需要学 8 门课,每门课工作量巨大。而且要求做两门课助教,做助教比上课更累。
这一年上的课中对我最有用的是「高级分布式系统」。之前在上交 ACM 班的时候已经学过很多质量都还不错课,纯知识性的课程一般对我帮助不大。但这门课主要是读论文,然后大家讨论。不仅仅是关于知识,很多是对设计理念的领悟。大家知道对于系统而言,设计是一门艺术而不是科学,这是设计者审美和哲学理念的体现。同时系统界历史也是由一波又一波的潮流组成,了解历史的发展以及其中不断重复的规律非常有意义。
那年这门课上课老师是 Hui Zhang(神人之一,20 多岁就在 CMU 任教了,学生包括了 Ion Stoica,他是 Spark 作者 Matei 的导师),他有非常好的大局观,对于「Why」这个问题阐述非常到位。我是通过这门课才对分布式系统有了比较清晰的认识。两年之后我偶然发现我的一篇论文也在这门课的阅读列表里了,算是小成就达成。
除了上课,更重要是做研究。我去 CMU 的时候 Alex 那时还在 Google,而且没经费,所以把我丢给了 Dave Andersen。于是我有了两个导师,一个做机器学习,一个做分布式系统。
前面半年都是在相互熟悉的过程。我们每周会一起聊一个小时。前半年因为 Alex 不在,所以我们只能视频。Alex 那边信号经常不好,而且他有德国和澳大利亚口音,外加思维跳跃,经常我听不懂他说啥只能卖萌傻笑。还是靠着 Dave 不断的打字告诉我 Alex 说了什么才度过了前几次的会。
两个导师风格迥异。Alex 是属于反应特别快,通常你说一点,他已经想好了接下来十点,要跟上他节奏很难。一般抛出问题的时候他就想好了好几个解决方法。这时候要证明自己的想法比他的更好不容易,需要大量的沟通和实验数据支撑。我想我大概是花了两年证明了在某些方向上我的方案一般更好,所以这时候他就不那么 hands-on 了。
Dave 不会给很多想法,但会帮助把一个东西理解透,然后讲得很清楚。因为我研究方向主要是机器学习上,基本上前两年基本都是我在教 Dave 什么叫机器学习,而且是尽量不用公式那种教法。
我的第一个研究工作是关于如果划分数据和计算使得减少机器学习求解中的网络通讯量。Alex 体现了他的强项,几分钟就把问题归纳成了一个优化问题,然后我们三各自提出一个解法。我做了做实验发现 Dave 的算法更好。接下来两个月把算法做了很多优化,然后又做了点理论分析就把论文写了。
可惜这个想法似乎有点超前,虽然我们一遍又一遍的改进写作,但投了好几个会审稿人就是不理解,或者觉得这个问题不重要。那个时候学术界已经开始吹嘘「大数据」,但我觉得其实大部分人是不懂的,或者他们的「大数据」仍然是几个 GB 的规模,烤 U 盘需要十来分钟的那种。
这是我在 CMU 的一个工作,我觉得挺有用,但却是唯一没能发表的。
当时跟我坐同一个办公室的是 Richard Peng,他做的是理论研究。我经常跟他讨论问题,然后有了些想法合作了一个工作。大体思想是把图压缩的快速算法做到矩阵的低秩近似上。这个工作写了三十页公式但没有任何实验,我主要当做写代码间隙的悠闲娱乐,不过运气很好的中了 FOCS。
坦白说我不是特别喜欢纯理论这种,例如在 bound 的证明中很多大量的项直接丢掉了,导致我觉得 bound 特别的近似。对于做系统的人来说,最后拼的是常数。这个工作中这种大开大合的做法我觉得很不踏实。所以我觉得以后还是应该做更实在点的东西。
在 CMU 回到了去百度前的一周七天工作无休的节奏。每周至少 80 个小时花在学校。如果累了就去健身房,我一般晚上 12 点去。不仅是我一个人,大家都很努力,例如凌晨的健身房,早 3 点的办公室,四处都可以见到中国或者印度学生。我那时候的室友田渊栋花在学校的时候比我多很多。
那一阵子有读了很多关于优化的文章。其中对我启发最大的是 Bertsekas 写于 80 年代末的那本关于分布式计算的书。此书可以认为是 MIT 控制领域黄金一代研究成果总结,换到现在仍然不过时。
受启发我转去研究异步算法,就是分布式下不保证数据的及时性来提升系统性能。我基于在百度期间做的算法,做了一些改进和理论分析,然后投了 NIPS。
投完 NIPS 就动身去了 Google Research 实习。那时候 Google Brain 成立不久,在「宇宙的答案」42 楼,包括 Jeff Dean,Geoffrey Hinton,Prabhakar Raghavan 好些大牛挤在一起,加起来论文引用率能超 80 万。
Alex 跟我说,你去读读 Jure Leskovec 的文章,学学人家怎么讲故事。我在 Google 也尝试用了些用户 GPS 数据来对用户行为建模。可是写文章的时候怎么也写不出 Jure 的那种故事感,发现自己不是那块料。这篇文章因为用了用户数据,恰逢 Snowden 让大家意识到隐私的重要性,历经艰辛删了一半结果 Google 才允许发出来。有些累觉不爱。
不过在 Google 期间我主要时间花在研究内部代码和文档上。Google 的基础架构很好,文档也很健全。虽然没有直接学到了什么,但至少是开了眼界。
第二年:9/13-8/14
这学期上了 Tuomas Sandholm 的机制设计,此乃另一大神,例如最近德州扑克赢了专业选手,之前开公司也卖了上亿。不过这门课我是完完全全没学懂,连承诺的课程大作业都没怎么做出来。之后的两年里我一遇到 Tuomas 他都会问下有什么进展没。我只能远远看见他就绕开。
NIPS 被拒了,发现审稿人不懂线程和进程的区别,有点沮丧。隔壁实验室一篇想法类似但简单很多的论文倒是中了 oral,所以那阵子压力很大。Alex 安慰说这种事情常有发生,看淡点,然后举了很多自己的例子。
之后想了想,一篇好文章自然需要有足够多的「干货」,或者说信息量,但一篇能被接受的文章需要满足下面这个公式:
- 文章的信息量 / 文章的易读性 < 审稿人水平 * 审稿人花的时间
对于机器学习会议,因为投稿量大,所以审稿人很多自然平均水平就会下降。而且很多审稿人就花半个小时到一个小时来读文章,所以公式右边数值通常是很小,而且不是我们能控制。
如果文章的信息量不大,例如是改进前面工作或者一些简单的新想法,那么公式成立的概率很大。而对于信息量大的文章,就需要努力提升易读性,包括清晰的问题设定,足够的上下文解释等等。而前面投的那篇 NIPS,以及更早的那个被拒工作,就是因为我们假设了审稿人有足够多的相关专业知识,而我们塞进了太多干货使得大家都读糊涂了。
即使对于已经发表的文章,上面那个公式同样可以用来衡量一篇论文的引用率。例如经常见到干货很多的文章没有什么人引用,而同时期的某些工作就是考虑了其中简单特殊情况结果被大引特引。
接下来的半年我主要在做一个通用的分布式机器学习框架,是想以后做实验方便些。名字就叫 parameter server,沿用了 Alex 10 年论文提出的名字。花了很多时间在接口设计上,做了好几个版本实现,也跑了些工业界级别的大规模的实验。
不过真正花了我大量时间的是在写论文上。目标是把这个工作投到 OSDI 上,OSDI 是系统界两大会之一。我们预计审稿人跟 Dave 两年前状态差不多,不会有太多机器学习和数学背景,所以需要尽量的少用公式。整整一个月就花在写论文上,14 页的文章满满都是文字和示意图。不过努力没有白费,最终论文被接受了。随后又花了好几周准备大会报告上。相对于平时花一周写论文,两三天准备报告,这次在写作和报告水平上有了很大的提升。没有放进去的公式和定理投了接下来的 NIPS,这次运气很好的中了。
有了文章后稍微心安了点可以更自由的做些事情。
寒假回了趟国,跑去百度找了凯哥和潼哥。潼哥说他最近有个想法,于是快糙猛的把实验做了然后写了篇论文投了 KDD。同时期 Alex 一个学生也把他一个一直想让我做但我觉得这个小 trick 不值得我花时间的想法投了 KDD,结果中了最佳论文。作报告那天我在的会场稀稀疏疏几个人,他们隔壁会场人山人海。这个使得好长一段时间我都在琢磨是不是还是要跟着导师走比较好。
那时凯哥在百度搞少帅计划,觉得蛮合适就加入了。这时凯哥正带着一大帮兄弟轰轰烈烈的搞深度学习,我自然也是跳坑了。试过好几个想法后,我觉得做做分布式的深度学习框架比较对胃口。我挑了 CXXNet 作为起点,主要是因为跟天奇比较熟。同时也慢慢上手跑一些 Alexnet 之类的实验。
我是因为少帅计划才开始开始做深度学习相关项目,凯哥也很支持我做开源开发回馈社会而不是只做公司内部的产品。但在少帅期间并没有做出什么对公司有帮助的事,很是惭愧。
第三年:9/14-8/15
回 CMU 后 Alex 看见深度学习这么火,说我们也去买点 GPU 玩玩。但我们比较穷,只能去 newegg 上掏点便宜货。这个开启了轰轰烈烈的机器折腾之旅。整个一年我觉得我都在买买买装装装上。最终我们可能就花了小几万刀攒出了一个有 80 块 GPU 的集群。现在想想时间上花费不值得,而且为了图便宜买了各种型号的硬件导致维护成本高。但当时候乐在其中。具体细节可以看这篇 blog
这一年写了很多 parameter server 代码,同时花了很时间帮助用户使用这些代码。很难说做得很成功,现在想想有几个原因。写代码时我会优先考虑性能和支持最多的机器学习算法。但正如前面的错误,忽略了代码的易读性,从而导致只有少部分人能理解代码从而做一些开发。例如我尝试让 Alex 组的学生来使用这些代码,但其中的各种异步和 callback 让他们觉得很是难懂。其次是没有人能一起审核代码接口,导致这些接口有浓浓的个人味道,很难做到对所有人都简单明了。
不过幸运的是找到一帮志同道合的小伙伴。最早是我发现天奇在写 xgboost 的分布式启动脚本,我看了看发现挺好用,就跟他聊了聊。聊下的发现有很多基础部件例如启动脚本,文件读取应该是可以多个项目共同使用,而不是每个项目都造一个轮子。于是跟天奇在 Github 上创建了一个叫 DMLC 的组织,用来加强合作和沟通。第一个项目是 dmlc-core,放置了启动和数据读取代码。
DMLC 的第二个新项目叫 wormhole。想法是提供一系列分布式机器学习算法,他们使用差不多相同的配置参数来统一用户体验。我把 parameter server 里面的机器学习相关算法移植了过来,天奇移植了 xgboost。Parameter server 原有的系统代码简化到了 ps-lite。
中途我听百度同学说 factorization machine(FM)在广告数据上效果不错,所以在 wormhole 上实现了下。针对分布式做了一些优化,然后投了 WSDM。前后没有花到一个月,但神奇的竟然拿了最佳论文提名。
在 wormhole 的开发中发现一个问题,就是各个算法还是挺不一样,他们可以共用一些代码,但又有各自的特点,需要特别的优化来保证性能。这样导致维护有些困难,例如对共用代码的改动导致所有项目都要检查下。总结下来觉得一个项目最好只做一件事情。所以天奇把 xgboost 代码放回原来项目,我也把 FM 独立出来一个项目叫 difacto。
通过一系列的项目,我学到的一点是,以目前的水平和人力,做一个通用而且高效的分布式机器学习框架是很难的一件事情。比较可行的是针对一类相似的机器学习算法做针对性的项目。这个项目的接口必须是符合这类算法结构,所以做算法开发的同学也能容易理解,而不是过多暴露底层系统细节。
真正的让 DMLC 社区壮大的项目是第三个,叫做 MXNet。当时的背景是 CXXNet 达到了一定的成熟度,但它的灵活性有局限性。用户只能通过一个配置项来定义模型,而不是交互式的编程。另外一个项目是 zz 和敏捷他们做的 Minerva,是一个类似 numpy 的交互式编程接口,但这个灵活的接口对稳定性和性能优化带来很多挑战。我当时候同时给两个项目做分布式的扩展,所有都有一定的了解。然后一个自然的想法是,把两个项目合并起来取长补短岂不是很好。
召集了两个项目的开发人员讨论了几次,有了大致的眉目。新项目取名 MXNet,可以叫做 mixed-net,是前面两个名字(Minerva 和 CXXNet)的组合。放弃开发了几年的项目不是容易的决定,但幸运的是小伙伴都愿意最求更好,所以 MXNet 进展挺顺利。很快就有了可以跑的第一个版本。
第四年:9/15-8/16
前半年为 difacto 和 MXNet 写了很多代码。其实一开始的时候我觉得 difacto 更重要些,毕竟它对于线性算法的提升非常显著而且额外的计算开销并不大,这对广告预估之类的应用会有非常大的提升。但有次遇到 Andrew Ng,我跟他说我同时在做这两个项目,他立即告诉我我应该全部精力放在 MXNet 上,这个的未来空间会大很多。我一直很佩服 Andrew 的眼光,所以听了他的建议。
11 月的时候 MXNet 就有了很高的完成度。写了个小论文投去了 NIPS 的 workshop 也算是歇了口气。但随后就听到了 TensorFlow(TF)开源的消息。由 Jeff Dean 领导大量全职工程师开发,Google 庞大的宣传机器支持,不出意料迅速成为最流行的深度学习平台。TF 对我们压力还是蛮大,我们有核心开发者转去用了 TF。不过 TF 的存在让我领悟到一点,与其过分关心和担忧对手,不如把精力集中在把自己的做得更好。
NIPS 的时候 MXNet 的小伙伴聚了一次,有好几个我其实是第一次见面。随后 Nvidia 的 GTC 邀请我们去做报告。在这两次之间大家爆发了一把,做了很多地方的改进。同时用户也在稳步增长。我们一直觉得 MXNet 是小开发团队所以做新东西快这是一个优势,但随着用户增加,收到抱怨说开发太快导致很多模块兼容性有问题。有段时间也在反思要在新技术开发速度和稳定性之间做一些权衡。
这时一夜之间大数据不再流行,大家都在谈深度学习了。
我也花了很多力气在宣传 MXNet 和争取开发者上。包括微博知乎上吼一吼,四处给报告。在大量的点赞声中有些陶醉,但很多中肯的批评也让我意识到重要的一点,就是应该真诚的分享而不是简单的吹嘘。
因为大量的媒体介入,整个深度学习有娱乐化的趋势。娱乐化的报道很多都只是一些简单信息,(有偏见)的观点,而没有太多干货。不仅对别人没营养,对自己来说也就是满足虚荣心。与其写这些简单的水文,不如静下心做一些有深度的分享,包括技术细节,设计思路,和其中的体会。
此类分享一个容易陷入的误区是只关注自己做了什么,结果多么好。这些确实能证明个人能力,对于想重复这个工作的人来说会有很大帮助。但更多的人更关心的是适用范围在哪里,就是什么情况下效果会减弱;为什么结果会那么好;insight 是什么。这个需要更多深入的理解和思考,而不是简单的展示结果。
这个对写论文也是如此。只说自己的结果比基线好多少只能说明这是不错的工作,但结果再好并不能意味这个工作有深度。
深度学习的火热导致了各种巨资收购初创司不断。Alex 也有点按耐不住,结果是他,Dave,Ash(曾经是 YahooCTO)和我合伙弄了一家公司,拿了几十万的天使投资就开工了。Alex 写爬虫,Dave 写框架,我跑模型,风风火火干了好一阵子。可惜中途 Dave 跑路去跟 Jeff 做 TF 了。后来这个公司卖给了一个小上市公司。再后来我们觉得这个公司不靠谱也就没考虑跟他们干了。
第一次创业不能说很成功,从中学到几点:一是跟教授开公司一定要注意有太多想法但没死死的掐住一个做,二是找一堆兼职的博士生来干活不是特别靠谱,尤其是产品不明确的时候,三是即使要卖公司也一定要做一个产品出来。我们卖的时候给很多人的感觉是团队人太强但产品太弱,所以他们只想要人而已。四是试图想要通过技术去改变一个非技术公司是很难的事情,尤其是过于新的技术。
然后我们就奔去折腾下一个公司。Ash 早财务自由所以想做一个大的想法,但这时 Alex 刚在湾区买了个房,有还贷压力,他选择去了 Amazon。于是算是胎死腹中。
随后收到 Jeff 的邮件说有没有兴趣加入 Google,自然这是一个很诱人的机会。同时我觉得小的创业技术性强的公司是不错的选择。但从 MXNet 的发展上来书,去 Amazon 是最好选择之一。自己挖的坑,总是要自己填的。所以我以兼职的身份去了 Amazon,领着一帮小弟做些 MXNet 开发和 AWS 上深度学习的应用。
第五年:9/16-2/17
早在 15 年初 Alex 就表示我可以毕业了,但作为拖延晚期患者,迟迟没开始准备。这时候感觉不能再拖了,于是窝在湾区写毕业论文。Alex 觉得毕业论文应该好好写,但我对把前面都做完的东西再捣鼓写写实在是没兴趣,尤其是加州太阳那么好,大部分时间我都是躺在后院晒太阳。此时 B 站已经完全被小学生占领,这边买书也不方便,无聊之余刷了很多起点。然后还写了篇炼丹文。
CMU 要求答辩委员会需要有三个 CMU 老师和一个学校外的。除了两个导师外,我找了 Jeff Dean 和刚加入 CMU 的 Ruslan Salakhutdinov. 结果 Russ 随后就加入了 Apple,整个委员会的人都在湾区了。Jeff 开玩笑说可以来 Google 答辩。可惜跟 CMU 争吵了好多次,还是不允许在校外答辩,而且必须要三个人委员会成员在场。这些限制导致答辩一拖再拖,而且临时加了 Barnabas Poczos 来凑人数。最后是 Jeff 的助理快刀斩乱麻的协调好了时间把所有东西定好了。没有她估计我还可以拖几个月。
答辩的时候是一个比较奇异的状态,委员会里有 Google, Amazon, Apple 的 AI 负责人,剩下两个和我又分别在这三家公司兼职。这个反应了当下 AI 领域学术界纷纷跑去工业界的趋势。
不过答辩这个事情倒是挺简单,跟平常做个报告没什么太多区别。一片祥和,即使 Russ 问了 MXNet 和 TensorFlow 哪家强这个问题也没有打起来。
答辩后我问委员会说,我在考虑找个学术界的工作,有什么建议没。大家介绍了一大堆经验,不过大家都强调的一个重点是:学术界好忙好忙,而且好穷好穷,工业界的薪水(就差指自己脸了)分分钟秒掉 CMU 校长。你要好好想。
总结
答辩前一天的晚上,我想了两个问题,一个是「博士收获最大的是什么」,另一个是「如果可以重来会怎么办」。对于第一个问题,这五年时间自然学到了很多东西,例如系统的学习了分布式系统,紧跟了机器学习这五年的发展,写文章做幻灯片做报告水平有提升,代码能力也加强了些。自信上有所提高,觉得既可以做一流的研究,也可以写跟大团队 PK 的代码。只要努力,对手没什么可怕的。
但更重要的是博士的五年的时间可以专注的把一些事情从技术上做到最好,做出新的突破,这个氛围没有其他地方能给予。
第二个问题的一个选项是当年留在国内会怎么样?当年百度的伙伴们多数现在都做得很好,都在引领这一波 AI 的潮流,甚至有好几个创造了上亿价值的公司。所以从金钱或者影响力角度来看,一直在工业界也不差,说不定现在已经是土豪了。
不过我觉得还是会选择读博。赚钱以后还有大把时间可以,但是能花几年时间在某个领域从入门到精通甚至到推动这个领域发展的机会就一次。站在这个领域的高点会发现世界虽然很大,但其实其他领域也使用差不多的技术,有着同样的发展规律。博士期间领悟到的学习的方法可以在各个方向上都会大有作为。
更重要的是理想和情怀。人一生要工作五十年,为什么不花五年来追求下理想和情怀呢?