作者丨Severus
來源丨夕小瑤的賣萌屋
編輯丨極市平臺
寫在前面:本文完全基於我個人的工作經驗,沒有經過任何形式的行業調研,所以我的理解也有相當濃厚的個人印記,可以認作一家之言。如果能對讀者朋友們起到任何幫助,都是我的榮幸。如果不贊同我的看法,則還請一笑了之。
大家好,我是Severus,一個在某廠做中文文字理解的程式設計師。
今天我想要分享的是,在演算法崗工作6年之後,我心中對“演算法崗”的理解,以及我在這個職業中,是如何生存的。
我時常提到,“AI演算法工程師”分為兩個部分,“AI演算法”和“工程師”。二者的關係是:演算法工程師,首先得是個工程師。有了 idea,還得有能力高效、優美、完整地實現出來,還要去解決一系列工程上的問題。
同時,除了有產生想法的能力,還要有及時放棄想法的能力。因為我做出來的東西,要面對的從來不是那幾個資料集,幾個指標,而是實打實的使用者。我向來認為,指標可以控制,gold 集合只能定性,最終的作用才是最重要的。所以,在工業中做演算法,又必須要嚴謹,那麼除了紮實的背景知識,還需要分析能力,以及下這些笨功夫的耐心。
紮實的分析能力
我認為合格的演算法工程師,應當具備相當的分析能力。遇到問題的時候,能一步一步地找到問題的根源,並提出紮實的方法去解決它。紮實的方法指的是,每一步都是在切實地解決問題,有可靠的邏輯、理論支撐。而不是一拍腦門,就覺得某一個方法可以用,唯 SOTA 論,看了論文就覺得這個方法肯定 work。這種分析能力和提出紮實方法的能力,其實就是一個演算法工程師的方法論。
例如,我一直說,模型預測時的表現通常反映了訓練樣本中的現象。所以,通常我們解決 case 的流程為:
- 觀察 case,假設 case 的發生原因
- 按照假設,到大規模資料中過濾復現 case,驗證假設是否正確。如果不正確,就根據復現結果更正假設;如果一直假設不出來,就記錄 case,看能否找到更多的相似 case,繼續更新假設。
- 驗證原因正確後,估算規模,看是否需要特化解決,如需要,就特殊解決一下。
- 看相同或相似的原因還有多少,設計新的通用最佳化方案。
所謂做演算法,尤其是想要落地或者推廣,大多數時候的確更像是做資料,下這些笨功夫。相對來講,很多“靈光一現”,或者僅僅以指標為基準,看到的論文中的方法,多數在腦暴會議中就會被 fail 掉。那些方法要麼在理論上不靠譜,要麼徒增演算法的複雜度,卻僅僅解決了一小部分問題。
畢竟,部分學術打榜任務,更像是先有了指標,後有了任務或資料,而不是以實際需求為基準,去定義相關的任務及資料。例如,充斥著大量遠監督資料的各路關係抽取資料集(不僅僅是在 train 中,也在 test 中),但又僅僅給出了文字資料;中文需要自然語言推斷任務,則機翻了一個數據集,得到了某中文推斷資料集;中文需要自己的理解榜單,就有了高 bias 的某文字相似判定資料集;有著大量不可推斷關係的某知識圖譜補全資料集(知識圖譜補全本身也是個指標大於需求的任務)等等。
例如,ACL2021 某方法在某資料集上的實驗結果中,隨機初始化引數的模型和 BERT 模型對比,召回相差10個點左右,而在 tuning 好的模型上,將頭尾實體 span 替換成對應的 type (如 China 替換成 country),抹去三元組本身可能過擬合的資訊後,召回下降40個點有餘。case 分析發現,替換後的正確召回的確是透過文字理解得到的,而遠監督得來的三元組,的確大多被判定成了 unrelated。使用先驗知識的增益可能僅僅是10個點(所有方法用 BERT 和不用 BERT 的區別都是10個點左右),那麼其餘的30多個點,大概就是三元組名字過擬合了吧。
這些任務,以及發論文唯指標論的風氣,也就造成了演算法相關工作從學生到工作最大的 gap。
我在工作中見到的刷分團隊,其成果很多都是兩隻腳皆踩在虛空之上。他們在試圖將自己研發的所謂“演算法”落地時,做的事情往往就是:管應用方要一份資料集,把分數刷上去,超過某些方法,就算是交付了,卻完全不分析問題。刷分的手段包括但不限於搜引數(提幾百個任務爆搜,連訓幾個 epoch 都要搜),堆大模型,搞整合。不會優先考慮工程上是否能接受,是否具備應對其他情況的泛化能力,或者這個“演算法”是否還有未來成長空間。於是就會導致——一波又一波地趕著熱點,或許能發不少 paper,但很難做出來一個能夠落地應用的演算法。
說了這麼多,看上去我描述了一種極端——就是演算法工程師就是在悶悶地做分析,做工程最佳化等,似乎與前沿研究毫不相關。不是的,演算法工程師也要花費相當的時間去刷論文,瞭解相關的前沿領域發生了什麼。只不過,擁有了這些分析能力及經驗後,在遇到前沿論文時,就會具備能力去拆解一篇論文提出的方法中的每一個元件,吸收其中有價值的 idea 用到自己的專案當中(而非一定要全盤複用論文,或者糾結論文中方法之外的細枝末節);或者受到論文中某一個 idea 的啟發,提出適用於自己的方案。畢竟,AI 領域,大家的方法都是明牌,資料也是海量。真正理解了“為什麼”,才能讓它們發揮作用。
舉個例子。在過去一年的工作中,我根據 Cross-Thought 的論文,提出了一種簡化版的最佳化方案,應用到了我的預訓練語言模型中,在序列標註任務上取得了一定的成績,用一種相對樸素的方法就能得到十分有效的句子的表示。再比如,我們還將 prompt 方法直接應用到了細粒度分類任務中,並根據模型測試時的一些表現,得出了用 prompt 去清洗訓練資料,最佳化其他模型的方法。這個方法已經在我們的一個落地專案,以及某一個學術任務上有了初步成效。同時也孵化了一個文字挖掘框架,今年完成了開源,填補了某一個空白,在相關領域的開發者中頗受好評。小弟不才,在接下來的 WAVE SUMMIT 峰會上,會上場介紹我們最新的成果。
列位可能要問了:有些 idea 可能就是靈光一現,完全憑藉靈感和直覺想到的,而非基於繁瑣的資料/任務分析。以我說的這種工作風格,這類想法就應該直接放棄?那不就相當於只能做些細枝末節的改進工作了麼?
不,紮實的工作風格不代表會錯過變革。近些年的經典論文,如 Transformer 、BERT、RoBERTa 等工作,都有相當的理論依據做支撐,其核心思想的立足點,都是相當紮實的,它們自然他們也就成為了經典。而我們看後面湧現了很多不知所謂的改進,哪怕不斷地重新整理SOTA,卻往往又掀不起什麼其他的浪花(更有一些直接被其他研究者用理論去推翻或證明某種改進是有相當的限制的,或過於繁瑣的)。
這裡我也分享一下我在看待一篇工作時常用的視角。我在觀察一個模型的時候,觀察的重點一般是這模型計算某一答案時,利用的資訊是什麼。例如,我曾看到一篇用圖神經網路建模依存關係樹的工作,任務是關係抽取。作者的假設是:語法依存關係是對關係抽取能起到作用的。當我看到這一模型後,心路歷程是:首先,一些依存關係的確可以直接表明實體間關係。使用部分依存關係去強化文字 token 之間的關係看上去也是合理的。但是,做過關係抽取的也都知道,並不是所有的依存關係都可以去抽取實體間關係的。有些關係引入了、強調了,則是在引入噪音。所以我當時的第一個疑慮就是:在建模的時候是否對邊的關係有所區分(比如用門控結構去控制強調,或者用不同的矩陣往不同的空間上投影)。另外,依存關係的不可傳遞性與統計模型的連續空間上存在的一種天然衝突,是否會造成問題。
強悍的工程能力
援引我最近讀的一本書中看到的一句話:搞深度學習的人,都應該學習一下計算理論。
工作以來,我越來越感受到,自己得以將各類方法拆解改造、化為己用,這份能力主要都仰賴於我接受過的資料結構與演算法訓練。
高效選資料
上面提到,與其是做演算法,更多時間則是在做資料。而在工業界,我們最不缺的就是資料——與其說是“做資料”,不如說是“選資料”。從海量的資料獲取合適的訓練樣本,則需要繁瑣的策略、高效的方法作為支撐。用對了方法,執行效率可能就是幾百倍的差異,迭代模型的週期亦是天壤之別。
頂層設計能力
除資料結構和基礎演算法外,頂層設計能力同樣重要。無論是單兵作戰,還是團隊協同,紮實、漂亮的工程設計都會讓我們在效率(甚至心情)上有質的變化。
具體的實施細則在大學 CS 課程中已經多有強調。不過,光關注那些說教型的細則還是遠遠不夠,更多的其實還是多寫,多想,多看。看一看別人的程式碼中,有什麼設計或編碼技巧可以吸收借鑑的。想一想自己在某個工程中寫出來的基礎模組,之後在其他工程裡還是否願意複用?在團隊協同的時候,別人呼叫你開發的模組是否會遇到困難?
工程方案的選擇
除此之外,工程能力還有一個重要方面,就是工程方案的選擇。
工作過程中,總是不可避免會應用其他人開發的東西。而當我們擁有選擇權時,就要能清楚哪個方案更加適合自己的任務。
基於個人的工作經驗,我也總結出了一些原則:
- 明確的,而非黑盒的。比如,有個分散式工具,它可能“看上去方便”——用簡單的幾行指令即可完成較為複雜的需求。但沒有任何文件說明它中間如何生成各種複雜邏輯,也不提供任何程式碼可供研究。相比之下,我還是寧願選擇自己下一些笨功夫。
- 簡潔的,而非複雜的。還是以分散式工具為例。如果原本三兩個節點就可以解決的問題,它卻生成數倍的節點。當然,也就造成了數倍的排程和I/O,以及數倍的資源佔用。即使它其他方面做得再好,我還是會盡量棄之不用。
- 可控的,而非限制的。也舉個例子。如果一個模型訓練套件,定死了輸入樣本和輸出的格式,或者測試步數、儲存邏輯也定死了(不寫文件四捨五入也差不多算定死了)。再有甚者,可能連給出的模型也是加密的。相比之下,我肯定願意選擇更可控的方案,或者乾脆完全自己寫。
- 魯棒的,而非漏洞的。例如,框架版本選擇,一定選擇有人維護且完善的版本,而非久遠的舊版本。部署中臺,也一定選擇 log 明確,錯誤好查,容易定位,部署過程穩定的,而非每一個步驟都有崩潰的風險,更換一個開發版本直接 bomb 的。
(上面列舉出的都是一些虛構的極端例子...如有雷同,純屬巧合。)
小結
寫這篇文章,是因為看到了知乎上關於演算法工程師的“職業護城河”的一些討論,也有感於工作過程中見過的一些事情。希望上面的內容能幫助一些小夥伴剛在入行的時候迅速跨過心理落差,更好地投入業界。
正如開篇所說,這些經驗和想法,帶有非常濃厚的個人印記。全都是一家之言。如果不贊同,還請一笑了之。