在軟體研發過程中,“代碼補全”至關重要,它可以有效的提升開發效率、減少拼寫錯誤和輸入代碼量。本期《雲效說碼》分享邀請斑馬網絡技術專家旭倫分享了《技術紅利下的代碼補全》,介紹了深度學習革命帶來的技術紅利,在代碼補全業務中對于這些“紅利”的應用,以及在阿裡雲上低成本落地的方法。
【以下為旭倫分享實錄,有删減】
深度學習革命帶來的三個技術紅利
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平台,源于阿裡巴巴先進的管理理念和工程實踐,緻力于成為數字企業的研發效能引擎!雲效提供從“需求 ->開發->測試->釋出->運維->營運”端到端的線上協同服務和研發工具,通過人工智能、雲原生技術的應用助力開發者提升研發效能,持續傳遞有效價值。