同爲工程師,搞算法的憑什麼工資比你高?

本文經原作者授權整理髮布

算法工程師到底有什麼特別之處?這個崗位真的比普通工程師高一等嗎?同爲工程師,算法工程師爲啥工資高几倍?從普通工程師轉爲算法工程師,會有多困難?算法真的那麼難搞嗎?

不知道各位程序員朋友平時有沒有想過這些問題,不知道各位是怎麼看待這些問題的,如果你心裏對算法工程師也有着各種疑惑,你一定不能錯過今天的文章,本文的作者從兩個角度來解答了這些疑問。

在他看來:算法工程師首先要是個工程師,但是,算法工程師又不只是工程師。

是不是聽上去有些繞,但是又彷彿很有道理?先別忙着下結論,看完內容再評論。

上篇:論算法工程師首先是個工程師

引子

最近校招面試到吐,算法崗位有點太熱了,簡直心力憔悴。我們的面試分兩個部分,先是做一兩道編碼題,然後纔是考察機器學習的知識。很多同學不理解,在網上diss我們,說什麼機器學習基本沒有問。這種情況,一般是代碼做的太爛了,面試官都沒有興趣去了解機器學習部分。

機器學習算法崗位,很容易讓大家有個誤解,認爲平時工作就是推推公式,調調參數。鑑於此,本文借用下我們團隊最近的一個重要項目:深度學習在搜索、推薦中的應用,來描述下平時我們是怎麼幹活的,看完之後,大家應該很容易理解爲何我們要求有編碼能力。

其實,我們的編碼題真的很簡單,不用刷題也能做出來,看看其他公司出的題,已經有點類似面試造原子彈,進來賣茶葉蛋的蜜汁感覺。當然,他們有資本,可以通過這種方式選到很聰明的候選人。

回到正題,我們從去年年底開始探索深度學習在搜索、推薦中的應用,包括排序和召回。以前我們常常用和工程同學合作,對系統的理解,比如推薦引擎、搜索引擎來表達編碼能力的重要性,可能對於應屆生來講,有點模糊。這次的項目經歷可能更好一些。

先總結下指導思想

這大半年,我們踩了很多坑,特別是癡迷論文中的各種fancy結構,寄希望於換換模型拿到收益。最終都紛紛被打臉,反而是迴歸到開始,從使用更多的樣本數據,改善樣本清洗、構造的邏輯,謹慎選擇經典的模型結構,對優化算法保持敬畏等等,拿到了不錯的收益。先來幾點務虛的雞湯,大概有以下幾點:

  • 對比傳統模型,深度學習更需要大量的數據去學習,樣本數據的增加能明顯的改善模型的結果。

  • 在初期,請忘記paper裏面各式各樣的奇技淫巧。

  • 一套有效的方案,其效果是多和少的問題,不是有和無的問題。

  • 好好調參,比亂試各種論文idea有效。

  • 深度學習真的可以自稱調參煉丹師,所以比別人試的更快,是煉丹師的核心競爭力。

  • Embedding太神奇,請把主要精力花在這裏,深度模型對id的理解可以震驚到你。

  • 關心你的模型的計算效率,最終還是要上線的,繞不過去的性能問題。

訓練中的工程能力篇,就是各種踩坑各種填坑

樣本規模的問題

一開始,我們把現有基線的特徵數據喂到了深度模型中,試過dnn、dfm、lstm等等,發現效果比lr還差。當時爲了快速嘗試,將所有的數據load到了內存,限制了數據規模,而且有部分數據預處理的工作也是在python中處理,導致計算在cpu和gpu之間頻繁切換,gpu利用率抖動很厲害。基於tf提供的性能工具,做了點分析後,判斷是特徵預處理這部分移太耗時了。另外,模型的參數很大,但是樣本數不夠,急需增加樣本量。我們用spark將樣本數據構造成tfrecord的格式,整個構建過程對比原來基於hive sql,再從hdfs拉到本地,快了近10倍,而且能用的樣本數據量大了很多,發現模型效果好了很多。

embedding id量級過大的問題

深度學習是在圖像、語音等場景起家,經常在nlp的論文中,將幾十萬的word做embedding稱爲大規模。工業界做user和item embedding的同學應該笑了。userid和itemid非常容易過百萬、千萬的量級,導致生成embedding lookup oom。可以參考我上篇文章:https://zhuanlan.zhihu.com/p/39774203。

有些公司會選擇對id進行hash,再做embedding,比如tf的官網就建議這樣:https://www.tensorflow.org/guide/feature_columns#hashed_column。也有些會選擇simhash來替換直接hash。我們目前能做百萬級別的原始id,後續如果需要加大量級,更傾向於只對樣本特別稀疏的id做hash或根據id的metadata做重編碼來做。

Wide模型帶來的稀疏模型訓練問題

大部分的wide & deep代碼實現,其實用的tensor都是dense的。tf基於PS做的模型訓練,當你的特徵規模在億級別時,網絡通信是個災難,加上grpc的垃圾性能,網卡利用率上不去,訓練的時間大部分都耗在通信上了。

但如果花點心思看看tf的源碼,解決方法其實很簡單,採用一些sparse的op就行。比如用sparse_gather,就能解決網絡傳輸的問題。但這個不是徹底的解決方案,tf在計算的時候又會把sparse的tensor轉成dense做。繼續看看源碼,會發現tf自身實現的embedding_lookup_sparse。換個角度來理解,天然就能支持sparse的wide模型訓練。把sparse的wide模型理解成embedding size爲1的情況,上層接個pooling做sum,就是我們要的wide的output結果,方案很優雅。

分佈式下訓練速度不能隨着batch size增加變快

這個問題,單純看性能分析還不好發現。還是去看下TF的代碼實現,其實是TF默認有個dimension壓縮的優化帶來的。TF爲了節省存儲,會對一個batch內的相同的feature做hash壓縮,這裏會有個distinct的操作,在batch size大的時候,性能損耗很明顯。改下參數,就可以取消該操作,不好的地方是浪費點內存。

還有兩個核心問題:TF不支持sparse模型和分佈式下work的checkpoint問題,這裏不展開了。

線上性能篇

真實線上場景與batch size的訓練的差異

真實排序的時候,一個用戶過來,需要精排的候選集可能有幾千。而我們在訓練的時候,基於batchsize方式組織的predict代碼。會將用戶側的feature複製幾千次,變成一個矩陣輸入到模型中。如果給tf自己做,這裏就會有幾千次的embedding lookup,非常的耗時。如果我們選擇在請求的一開始,就把用戶側的lookup做掉,然後去做點內存複製,就能大大減少rt。

另外一個耗時大頭是attention,這個解決方案也很多,比如用查表近似就可以。
還有一些是模型實現的細節不好導致性能很差,比如DCN的cross實現,一個簡單的交換律能帶來巨大的性能提升,參考:https://zhuanlan.zhihu.com/p/43364598

扯淡開始

上面很多工作,都是算法工程師和工程同學一起深入到代碼細節中去扣出來的,特別是算法工程師要給出可能的問題點。做性能profile,工程的同學比我們在行,但是模型中可能的性能問題,我們比他們瞭解的多。當然也有很多同學diss,上面這些都是工程沒有做好啊,工程好了不需要關心。但是,真正的突破必然是打破現有的體系,需要你衝鋒陷陣的時候自己不能上,別人憑什麼聽你的,跟你幹。大概率就是在後面維護點邊緣業務了。

難道機器學習理論不重要嗎

當然不是,這篇已經寫得太長了,只講兩個點。

信念的來源:這個其實是很重要的,一個項目,搞個一年半載的,中間沒有什麼明確的產出,老闆要kpi,旁邊的同事刷刷的出效果,靠什麼支持你去堅持繼續填坑,只有對理論認知的信念。假設總是很美好,現實數據很殘酷,左臉打完打右臉,啪啪啪的響。怎麼一步步的接近真實,解決問題,靠的還是對理論的理解,特別是結合業務的理論理解。

工程和理論的關係就有點像,理論起到是指路者的作用,而工程是你前進道路上披荊斬棘的利刃。沒有理論就沒有方向,沒有編碼能力,就只能當個吃瓜羣衆,二者缺一不可。

最後,總結下:算法工程師首先是個工程師。

PS:Don’t panic!Make your hands dirty!編碼沒有那麼難。

算法工程師首先要是個工程師,不知道看過作者的這篇文章,讀者有沒有對這句話有更深刻的理解?希望你沒有被繞暈,因爲接下來,作者又要談到他的下一個觀點了。

下篇:算法工程師又不只是工程師

繼上篇文章着重描述了工程能力的重要性,對於理論部分提的很少,但不代表它不重要。

談的是提升理論素養

理論深似海,那是人類頂級的頭腦的戰場。

大多數算法工程師,當講和理論相關時,大多是看了點論文、讀點經典教科書,能水下paper已經是很高端了。不能稱這些是做理論,對那些真正從事理論工作的同學太不尊重了,稱爲提升理論素養更合適。

理論素養不直接等價於業績產出

很少人會覺得理論素養不重要,但提升理論素養的投入和產出之間不是線性關係。導致在工業界,經常爭論對理論素養需求程度。比如知乎上的這個問題:有沒有必要把機器學習算法自己實現一遍?​(地址:https://www.zhihu.com/question/36768514)有5k+的關注,100多個回答,可見熱度。

雙方觀點其實都挺有道理,但大家特別容易手裏拿個錘子,看什麼都是釘子

現實中不存在一頭紮在理論學習或者工程實現,就萬事大吉。在二者中來來回回穿梭,試探邊界在何處纔是常態。

就像生活的常態是chaos,就像熵一樣一直增長,是自然規律。維持有序的狀態需要付出了額外的成本。就像IBM大型電腦之父佛瑞德·布魯克斯說的:

No Silver Bullet

我們的CEO也說過,他是一個現實的理想主義,美好的理想就像有序的狀態一樣需要消耗巨大的資源,而我們的資源永遠是有限的,要學着帶着鐐銬跳舞。

爭論的背後:ROI

我們所有人,都太追求效率了,俗話說:

一分錢一分貨,十分錢兩分貨

邊際效用無處不在,當投入過了一個坎,ROI就會劇烈下滑,線性增長的ROI就像泡沫一樣美麗。

工業界的同學,ROI的思維已經是生存的本能,但面對理論時,有時成也ROI,敗也ROI,正如李沐在一篇帖子中說:

在工業界呆過再去讀phd可以少走很多彎路,也會發現很多學術界的idea就是個笑話。但同樣的問題是,習慣了很solid的工作,反而有時候思路打不開,不敢嘗試思路新奇的點子。我phd期間比較後悔的是好幾個地方隱約有點想法,但太專注一些跟工業界經歷很像的想法,結果後面看到別人在這些地方做出了世界級的工作。

我們和大神的距離太遙遠,也很少能接觸世界級的工作。更恰當的例子是公司的短期KPI和長期KPI的矛盾。短期的KPI雖然回報高,但就像下游低端產業,由於門檻低,很容易會變成紅海,要發展就需要升級產業,向上遊、高端的方向去,獲得更大的利益分配權。

再退一步講,浪費一些時間、精力在不能明顯看到ROI的事情,其實也沒什麼,反正它也會被浪費在別的地方。意大利物理學家卡洛•羅韋利在《七堂極簡物理課》中提到:

少年時代的愛因斯坦曾度過一年無所事事的時光。很可惜,現在很多青少年的父母經常會忘記這樣一個道理:一個沒有"浪費"過時間的人終將一事無成。

務實一點,提高理論素養的好處還是很多的

除了以前常說的理論是指路明燈外,還有很多其他好處。

有助於系統化知識點

工作期間,見過不少乾的好但是說不清楚的,在晉升上吃虧。有些同學性格內向,不善表達。改善表達可能比較難,但可以揚長避短,從寫東西入手,寫東西的前提是心裏有貨。好的理論素養,能高屋建瓴將工作經驗、知識點系統化,更利於他人理解。

比如這篇《從FM推演各深度CTR預估模型》:

https://yq.aliyun.com/articles/614262?spm=a2c4e.11163080.searchblog.119.48912ec1Avric7

這篇文章清晰的指出:在wide&deep的基本框架下,上述論文都是在嘗試不同的策略去把輸入向量用一個Embedding層接入到Dense網絡中。裏面的每一篇論文我都看過,捫心自問,能不能寫出類似的文章,遺憾的是不行。

解放思想,見識是阻礙我們發展的最大障礙

我司的圖像做了有一段時間,一直是單機跑模型,有時候一跑要一兩週,不少公司和我們類似。一直也沒有覺得有什麼問題,很少去想是不是要搞分佈式GPU計算平臺。以前的業務,上分佈式大部分是因爲數據規模很大。工程組也很猶豫要不要做,我們自己心裏也沒有個定論,拖了一兩年。直到看了這篇文章:

https://arxiv.org/pdf/1706.02677.pdf

這纔開拓了視野,馬上就下了決心動手幹。

他山之石可以攻玉

Scott Berkun在《Myths of innovation》提出:一個新的idea背後,能找到多個已經存在的idea。

最近把Jared Diamond的書重看了一遍,從《第三種黑猩猩》到《槍炮、病菌與鋼鐵》到《大崩壞–人類社會的明天》,作者兼具演化生物學、生理學、生物地理學等學科,取衆家之長,融會貫通,形成獨特的觀點,寫成如此優秀的作品。

深度學習在圖像和NLP領域大放異彩,涌現出很多建設性的工作,又有多少能應用在工作中呢?

取上者得中,這一場idea的盛宴,不容錯過。

滿足好奇心

深度學習的理論發展遠跟不上應用的發展,但一個個漂亮的結果背後,總是忍不住好奇它背後是爲什麼。

比如圖像中的milestone模型resnet,沒有細看論文,一直認爲是解決了gradient vanishing/exploding問題,而作者在原論文中:

https://arxiv.org/pdf/1512.03385.pdf

明確指出這個問題已經被BN和良好的initialization解決,resnet解決了網絡層數增加後degradation的問題,具體是什麼問題,作者並沒有深入。

後續這篇論文:

https://arxiv.org/pdf/1702.08591v2.pdf

更詳細的描述了這個問題,並指出可以用LL,不需要residual的結構,也能訓練deep模型。

更上一層樓

現實世界中,很多問題需要都不需要太懂理論就能解決的不錯。

這個背後的力量是抽象帶來的,抽象做的好了,能讓你不用懂其原理,也能發揮它的功效。就像我們每天用的手機,裏面有量子力學的原理在發揮作用,但沒有幾個人懂量子力學。

隨着各種工具越做越好,越來越多的細節被屏蔽,這個情況會越來越普遍,但隨之帶來是更多的應用可能性。就像今天的碼農大多不懂編譯器,也不會彙編,但IT業卻前所未有的繁榮。

這幾年在公司,還是做出了點業績,但水平如何,如人飲水冷暖自知。比如58同城上麻利電工不一定懂電路原理,懂了電路原理也不能增加每小時的薪水,和我們何其相像。
居安思危,認清自身所處的產業環節,盡力向上遊發展,而理論素養是其中一把鑰匙。

提升理論素養,悟性低就多動手

深度學習大多數論文偏應用,對理論背景和數學知識要求不高,但就如此,理解他們也不是一帆風順,可見純理論工作之難。

最近被BERT刷爆朋友圈,發現對transformer的理解還不夠。重新回去看下這篇文章:

https://arxiv.org/pdf/1706.03762.pdf

用pytorch動手實現了一把,發現了幾個以前沒有注意的問題:

論文裏自稱可以並行,但decoder部分怎麼並行呢,下一步的output總要依賴上一步吧?然而作者是直接把ground-truth放入。self-attention的理解是錯的KQV讓代碼都簡潔了。
果然資質平庸,還是需要動一遍手才能理解更多,嘆悟性之差。過程中,花了不少時間在處理Tensor的shape變換上了,算是一種浪費吧。

再一次,沒有銀彈

並不是把每個算法都自己實現一遍,就能做出更好的成績的,也不存在把公式推一邊,能找到解決問題的靈丹妙藥。

大多數我們並不是沒有時間,反而是覺得自己在浪費時間,而不肯投入。然而浪費是常態,據說碳基生物的能量利用率不到20%。再比如,公司裏失敗的項目遠大於成功的。
最難的部分是不知道怎麼準確定義問題。一百分的努力中,若有一二十分最終有收益,算很了不起了,沒有銀彈,只能先把量堆起來,量變引起質變。

道理易懂,行動不易

PRML還停留在第5章,ESL買了後在書架上積灰,電腦下面還墊着MLAPP(頸椎是好了一點)。看論文的速度慢,數量也不多。但其間看了好多雜書,其中還有幾本網文,比如大聖傳,美其名曰幫弟弟考察行情。

頭頂的髮際線在告訴我,韶關易逝。現在我常想,20歲的我在幹嘛,估計以後還是會常想30歲的我在幹嘛呢。

如果覺得自己明天起來就能變成意志力超人,那這30年算是白活了。雖然很多事情不及預期,但也收穫了不少,就是這樣,不完美、掙扎、痛苦,構成了生命的組成。只希望未來的時光,能牢記初心,切勿自甘墮落。

送一句話給自己:切勿做井底之蛙,坐井觀天,固步自封。

原文鏈接:

https://zhuanlan.zhihu.com/p/44315278

https://zhuanlan.zhihu.com/p/48249123

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章