自以為是套路,結果反生技術債,開源代碼應該注意這五大誤區

自以為是套路,結果反生技術債,開源代碼應該注意這五大誤區

作者 | 蔣寶尚

編輯 | 叢末

人工智能的研究該不該開源代碼,一直是社區熱議的話題。畢竟,一項機器學習研究不僅包括理論,算法和應用也是機器學習研究的重要內容。

ICML、ICLR 和 NeurIPS 都在嘗試將實驗代碼和數據作為評審材料的一部分提交,鼓勵作者在評審或出版過程中提交代碼。事實證明,結果能夠復現的研究往往也更能引起討論,也更能促進學科領域的進步發展。

但是,卻一直存在著這樣問題:開源研究中的代碼應該如何寫?提交的時候應該注意什麼樣的事項,才能幫助其他研究者更容易復現論文結果?

一位機器學習研究員,在reddit上發出了倡議,提出了機器學習研究中開源代碼時的五大反面教材(反模式),呼籲在開源代碼的時候,儘量避免一些錯誤。

以下為他的倡議原文:

大家好,鑑於這個話題,我必須先聲明一下:我也很佩服發表論文並有勇氣開放源代碼的研究員,他們非常了不起,我個人也從開源代碼庫中改編過一些代碼,即用於自己的項目,也用於生產代碼。我對此表示最深刻的敬意。

但是,這些代碼有時候也出現問題 **runs for cover**

下面是我個人的筆記,裡面包括五個反面教材,如果你有補充,歡迎評論留言,如果你不同意,指出來哪一個,我們展開討論。

在敲機器學習相關研究代碼,或者其他的啥領域代碼的時候,請儘量避免:

1.做一個單一的配置對象,讓所有的函數不斷傳遞給你。配置文件非常棒,但是如果把他們加載到字典裡面,然後到處mutating,那麼這就會變成一場噩夢。

注意,在頂層這麼操作通常不會有問題,也可以和你的CLI綁定在一起。

2.使用argparse當然可以,但是不要像上面note1那樣使用,另外讓我們廢除 "from args import get_args; cfg = get_args"的模式。用更加直接的方法解析命令行的參數。(例如,如果你使用 argh,自然會讓你圍繞著可重用的函數來架構你的代碼)

3.請不要讓你的CLI接口洩露到你的實現細節中去,首先創建庫,然後將其公開為CLI。這會讓所有東西都更具可重用性。

4.除非有充分的理由(提示,很少有),否則不要使用文件作為進程間通信。如果你調用一個函數保存了一個文件,然後在下一行代碼中加載這個文件,那就說明出了很大的問題。如果這個函數是來自不同的repo,可以考慮cloning它,修復後再PRing回來,使用修改後的形式。當然,還是有副作用的,往往會引起一個“無聲”的Bug。

5.在幾乎所有的情況下,除了最瑣碎的情況,做一個事物列表上操作的函數比在單個事物上操作的函數更麻煩。所以,如果真的需要一個接受列表的接口,可以直接做一個新的函數,調用單個函數就可以了。

1 網友評論:還真是教科書級別的錯誤!

帖子放到reddit上面之後,立即引起了各路網友反響,大家似乎在一些學術論文中或多或少都遇到了這些問題。

自以為是套路,結果反生技術債,開源代碼應該注意這五大誤區

哈哈,期初以為我只會在學術論文中遇到這些問題,隨後我進入業界的時候,發現機器學習中的技術欠債是真實存在的。

自以為是套路,結果反生技術債,開源代碼應該注意這五大誤區

在編寫個人研究代碼的時候,我並未總是提前對最終結果有個清晰的想法,接口需要不斷更改,以前有意義的庫可能在一些改變之後不再有意義。我使用反模式,通常是為了趕DDL時候,加快實現速度。

自以為是套路,結果反生技術債,開源代碼應該注意這五大誤區

一個項目中往往有兩種代碼,一種是作為基礎設施的代碼,另一種是作為研究工作流的代碼。前者應該是相當靜態的,明確的,有很好的軟件工程。後者應該是靈活的,且有可能是混亂的,能夠優化為快速迭代。

自以為是套路,結果反生技術債,開源代碼應該注意這五大誤區

這個話題非常重要,但是,你必須說明為什麼這些事情是壞的,還必須提出替代方案。

2 機器學習中的反模式與技術債務

上面提到的五點寫代碼的反模式與機器學習技術債務息息相關,一般來說,反模式一開始用起來很爽,但是維護起來卻有非常大成本開銷。

自以為是套路,結果反生技術債,開源代碼應該注意這五大誤區

機器學習不同於其他,2015年穀歌曾經貢獻過一篇年度頂級論文《機器學習系統,隱藏多少技術債?》,裡面詳細介紹了機器學習系統一些常見的的反面模式。其中過包括:

粘合代碼 :機器學習研究者傾向於開發普遍適用的解決方案作為自給自足的包(packages)。採用通用軟件包經常會導致粘合代碼的系統設計模式,在這種系統設計模式中,包含了大量支持數據寫入通用軟件包或者數據從通用軟件包中輸出的代碼。

粘合代碼的代價從長遠來看是很高的,因為這會讓機器學習系統非常侷限,如果需要測試其他方法,成本就會變得不可避免的昂貴。

對抗粘合代碼的重要策略之一就是,將黑盒包裝進普通的應用程序接口,以便更多地重複利用,降低更換包的成本。

管道叢林:這是粘合代碼的一種特殊情況,經常出現在數據預備階段。稍不注意,在機器學習系統良好的格式下,預備數據的結果系統可能會成為一個充滿碎片的叢林,經常也會有中間輸出文件在其中。

只有從整體上考慮數據收集和特徵提取的過程,才能夠避免“管道叢林”現象的發生。從頭再來的方式雖然初始投資巨大,但卻能夠大幅度減少持續增加的成本。

失效的實驗代碼路徑:在主要的生成代碼中,通過執行實驗代碼路徑作為條件分支來演示具有選擇性方法的實驗過程,短期內很有誘惑力,但是隨著時間的推移,後臺兼容性的維護會非常困難。

結果辦法是週期性地重複檢查每個實驗分支,果斷捨棄廢物分支非常有益

抽象化債務:當時谷歌認為,明顯缺少強抽象來支持機器學習系統。基於的觀察是:機器學習領域的文獻中,沒有哪一篇將相關數據庫(relational database)作為基本抽象(basic abstraction)的論文得到的結果能達到接近成功的地步。

常見異味(smell):即在一個系統中或者系統中的一個部件中存在的潛在問題。主要包括:1、POD類(Plain-Old-Data)異味,即機器學習系統採用浮點數、整數等普通的數據類型進行編碼。2、多語言異味,用多種語言編寫系統經常會增加測試成本,並且會增加將所有權讓渡給其他人的難度;3、原型異味,定期地依賴原型環境意味著機器學習系統的脆弱性,時間壓力會促使一個原型系統變成了產品解決方案,所以長遠看需要付出更多的成本。

自以為是套路,結果反生技術債,開源代碼應該注意這五大誤區

ACL 2020原定於2020年7月5日至10日在美國華盛頓西雅圖舉行,因新冠肺炎疫情改為線上會議。為促進學術交流,方便國內師生提早了解自然語言處理(NLP)前沿研究,AI 科技評論將推出「ACL 實驗室系列論文解讀」內容,同時歡迎更多實驗室參與分享,敬請期待!


分享到:


相關文章: