在軟件研發過程中,“代碼補全”至關重要,它可以有效的提升開發效率、減少拼寫錯誤和輸入代碼量。本期《雲效說碼》分享邀請斑馬網絡技術專家旭倫分享了《技術紅利下的代碼補全》,介紹了深度學習革命帶來的技術紅利,在代碼補全業務中對於這些“紅利”的應用,以及在阿里雲上低成本落地的方法。
【以下為旭倫分享實錄,有刪減】
深度學習革命帶來的三個技術紅利
2012年ImageNet競賽冠軍Hinton和他的學生Alex Krizhevsky設計出AlexNet,從而引領了以深度全連接網絡、深度卷積網絡、循環網絡為代表的第一次深度學習革命,其成果是在圖像識別領域人工智能超越人類。
深度學習和強化學習結合形成了第二次深度學習革命,其代表事件是:2016年阿爾法圍棋(AlphaGo)打敗韓國圍棋九段棋手李世石;2017年,阿爾法圍棋以總比分3比0戰勝世界排名第一的中國棋手柯潔。從此,人工智能在圍棋上打敗人類。
“預訓練模型”的出現和發展帶來了第三次深度學習革命,其成果是在自然語音處理方面人工智能戰勝人類,目前該技術已經在機器翻譯和智能回答機器人領域得到廣泛應用。
其中“預訓練模型”可能是大家瞭解最少的,但是跟代碼補全最相關,我簡要介紹一下,其實目前“各大廠”都在訓練自己的預訓練模型,大家可以登錄“GLUE”網站進行查看,排名幾乎每天都在變化,這張截圖是阿里巴巴達摩院的“StructBERT”登頂時截取的。
目前,深度學習中的預訓練模型已經在很多任務上超越人類,比如CoLA數據集是判斷一個句子是不是符合語法規則;SST-2情感分析數據集用於判斷一條影評語句是正面還是負面的;MRPC數據集用於判斷兩條新聞句子描述的是不是同樣的意義等。這些通過BERT等預訓練模型都可以處理,其最新改進版都可以超越人類標註的值。除此之外,還有GPT2等生成模型,可以實現自動寫作功能。
預訓練模型與代碼補全技術的結合
前面我們提到了“預訓練模型”不僅可以判斷語句是否符合語法規則,分析影評語句是正面還是負面,甚至可以實現自動寫作文。那麼“預訓練模型”是否可以幫助我們做“代碼補全”呢?回答是肯定的。
代碼補全的基礎理論是:代碼大數據理論。“代碼大數據”包含了代碼和代碼元信息,代碼元信息,包括註釋信息,代碼提交時的信息,測試、review時的信息,BUG信息等。這個理論要起作用,需要基於一個公理:基於代碼的自然性原理。
雖然語言可以千變萬化,但是落實到日常生活中,由於認知的限制和實際的需要,我們日常交流所有的語言是重複性的,有規律的,可預測的。這個統計上的結果,導致了統計機器學習方法在語音識別、機器翻譯等領域的巨大成功。於是我們可以假設程序代碼也是自然的,因為它們也是人類在工作中創建的,受到硬件的軟件的各方面的限制,它們也應該是有其統計規律的。
經過研究證明,代碼不但是有自然性的,而且比自然語言的自然性還要好。為此,人們實現了一套基於統計方法的代碼補全系統,併成功應用於eclipse IDE中。
有了理論之後,大家迅速將其應用於解決自己手頭的問題,代碼智能一片繁榮:
2014年代碼智能技術被用於代碼提示與補全和提升代碼可讀性;
2015年用於推薦方法名和類名以及語法錯誤修復;
2016年用於bug修復和源代碼總結和查找代碼克隆;
2018年被用於預測bug和自動為代碼生成註釋以及用於反混淆。
代碼補全的侷限性及解決方案
正在看起來歲月靜好的時候,Vincent J. Hellendoorn和Premkumar Devanbu發表了《深度神經網絡是建模程序源代碼的最佳選擇嗎?》,認為OOV(Out-of-vocabulary)問題導致深度學習處理程序語言的效果還不如傳統機器學習方法。
除此之外,代碼補全系統還有3個要求:總是要給出補全結果,速度要跟上程序員打字速度 ,資源佔用不能太高。
從程序員的視角看,本地發生的開發與最終提交的開發順序和上下文環境非常不同,動態集成本地數據的模型比靜態模型運行得好得多,針對重複典型模式進行了優化,但可能無法提供新的見解。
為了解決此問題,在實踐上,需要實現補全算法,我們需要進行混合模型處理,既要有本地傳統算法引擎,也要有遠程的算法模型。
從落地方法上,我們採用huggingface的Transformers庫,因為其針對多個模型有良好的封裝。
在阿里雲上低成本落地的方法
如下圖所示,這是一張代碼補全系統的架構圖,除了需要有一個主算法引擎外,我們還需要一個帶離線緩存更新的超大規模引擎。為什麼要有超大規模引擎?因為前面也提到了,程序員希望代碼補全系統可以提供他們不知道內容。這樣的結構需要很強的算力,普通的個人筆記本跑不起來。如果要在個人筆記本中實現,就還必須有快速引擎、RNN引擎和注意力引擎。
為了節省成本,我們採用搶佔式GPU的方式進行訓練。但問題是“搶佔式GPU”雖然便宜,但是GPU資源隨時可能被別人搶走。“計算”被搶走了,你的“存儲”存在哪裡呢?這個時候就需要一個本地的存儲,我選擇的是用“本地NAS”。大家可以簡單理解“NAS”就是一個網盤,存儲速度很快,但是費用也很高。為了節省預算,我們還需要配一個“本地OSS”,這樣我們就構成一個訓練服務器集群。
因為我們用到的“模型”太大了,如果直接從國外的服務器上下載,速度很慢,可能幾天也無法下載一個“模型”。於是,我們再次發揮雲計算的優勢。我們可以先在香港租用了臨時ECS,然後通過“香港OSS”再轉移到“本地OSS”中,從而實現下載加速。
以上內容來自旭倫在“雲效開發者交流群”中的視頻直播分享,有刪節,您可以釘釘搜索群號(23362009)入群,觀看完整視頻。
關於雲效:
雲效,企業級一站式DevOps平臺,源於阿里巴巴先進的管理理念和工程實踐,致力於成為數字企業的研發效能引擎!雲效提供從“需求 ->開發->測試->發佈->運維->運營”端到端的在線協同服務和研發工具,通過人工智能、雲原生技術的應用助力開發者提升研發效能,持續交付有效價值。