超級編程AI登上Science封面!AlphaCode編程大賽卷趴一半程序員
這個12月,正當OpenAI的ChatGPT勢頭正旺時,那個曾經卷趴一半程序員的AlphaCode登上Science封面了!
論文鏈接:https://www.science.org/doi/10.1126/science.abq1158
說到AlphaCode,想必大家并不陌生。
早在今年2月,它就在著名的Codeforces上,悄悄地參加了10場編程比賽,并一舉擊敗了半數的人類碼農。
卷趴一半碼農
我們都知道,程序員中非常流行這樣一種測試——編程競賽。
在競賽中,主要考察的就是程序員通過經驗進行批判性思維,為不可預見的問題創建解決方案的能力。
這體現了人類智能的關鍵,而機器學習模型,往往很難模仿這種人類智能。
但DeepMind的科學家們,打破了這一規律。
YujiA Li等人,使用自監督學習和編碼器-解碼器轉換器架構,開發出了AlphaCode。
AlphaCode的開發工作,還是在居家期間完成的
雖然AlphaCode也是基于標準的Transformer編解碼器架構,但DeepMind對它進行了「史詩級」的強化——
它使用基于Transformer的語言模型,以前所未有的規模生成代碼,然后巧妙地篩出了一小部分可用的程序。
具體步驟為:
1)多問詢注意力:讓每個注意力塊共享鍵和值的頭,并同時結合編碼器-解碼器模型,使AlphaCode的采樣速度提高了10倍以上。
2) 掩碼語言建模(MLM):通過在編碼器上加入一個MLM損失,來提高模型的解決率。
3)回火:讓訓練分布更加尖銳,從而防止過擬合的正則化效應。
4)值調節和預測:通過區分CodeContests數據集中正確和錯誤的問題提交,來提供一個額外的訓練信號。
5)示范性異策略學習生成(GOLD):通過將訓練的重點放在每個問題最可能的解決方案上,讓模型為每個問題產生正確方案。
結果嘛,大家都知道了。
憑借著1238的Elo得分,AlphaCode讓自己在這10場比賽中的排名達到了前54.3%。放眼之前的6個月,這一成績更是達到了前28%。
要知道,為了達到這個排名,AlphaCode必須「過五關斬六將」,解決融合了批判性思維、邏輯、算法、編碼和自然語言理解相結合的種種新問題。
從結果來看,AlphaCode不僅解決了CodeContests數據集中29.6%的編程問題,而且其中有66%是在第一次提交時解決的。(總提交次數限制在10次)
相比起來,傳統的Transformer模型求解率都比較低,只有個位數。
對于這個結果,就連Codeforces創始人Mirzayanov都非常驚訝。
畢竟,編程比賽考驗的是發明算法的能力,這一直是AI的弱項,人類的強項。
我可以肯定地說,AlphaCode的結果超出了我的預期。開始我持懷疑態度,因為即使在簡單的競賽問題中,不僅需要實施算法,而且還需要發明算法(這是最困難的部分)。AlphaCode已經讓自己成為很多人類的強勁對手。我迫不及待地想知道,未來會發生什么!
——Mike Mirzayanov,Codeforces 創始人
所以,AlphaCode這是能搶程序員的飯碗了?
當然還不行。
AlphaCode還只能完成簡單的編程任務,如果任務變得更復雜,問題更加「不可預見」,只會將指令翻譯成代碼的AlphaCode就束手無策了。
畢竟,1238的得分從某種角度來說,也就相當于一個初學編程的中學生菜鳥的水平。這個level,還威脅不到真正的編程大牛。
但毫無疑問的是,這類編碼平臺的開發,會對程序員的生產力產生巨大的影響。
甚至,整個編程文化都可能會被改變:或許,以后人類只要負責制定問題就可以,而生成和執行代碼的任務,就可以交給機器學習了。
編程競賽有啥難的?
我們知道,雖然機器學習在生成和理解文本方面取得了巨大進步,但是大部分AI目前仍然局限于簡單的數學和編程問題。
它們會做的,更多是檢索和復制現有的方案(這一點相信最近玩過ChatGPT的人都深有體會)。
那么,讓AI學習生成正確的程序,為什么這么困難呢?
1. 要生成解決指定任務的代碼,就需要在所有可能的字符序列中搜索,這是一個海量的空間,而其中只有一小部分對應有效的正確程序。
2. 、一個字符的編輯,可能會完全改變程序的行為,甚至會導致崩潰,而且每個任務都有許多截然不同的有效解決方案。
對于難度極高的編程比賽,AI需要理解復雜的自然語言描述;需要對以前從未見過的問題進行推理,而不是簡單地記住代碼片段;需要掌握各種算法和數據結構,并精確地完成可能長達數百行的代碼。
此外,為了評估自己生成的這些代碼,AI還需要在一套詳盡的隱藏測試上執行任務,并且檢查執行速度和邊緣情況的正確性。
(A)問題1553D,中等難度評分為1500;(B)AlphaCode生成的問題解決方案
就拿這個1553D問題來說,參賽者需要找到一種方法,使用一組有限的輸入將一串隨機重復的s和t字母轉換成另一串相同的字母。
參賽者不能只是輸入新的字母,而必須使用「退格」命令刪除原始字符串中的幾個字母。賽題具體如下:
對此,AlphaCode給出的解決方案如下:
并且,AlphaCode的「解題思路」也不再是黑箱,它還能顯示代碼和注意力高亮的位置。
AlphaCode的學習系統
參加編程比賽時,AlphaCode面臨的主要挑戰是:
(i)需要在巨大的程序空間中搜索,(ii)只能獲得約13,000個用于訓練的示例任務,以及(iii)每個問題的提交數量有限。
為了應對這些問題,AlphaCode整個學習系統的構建分為三個環節,預訓練、微調、采樣與評估,如上圖所示。
預訓練
在預訓練階段,利用在GitHub收集的715GB人類碼農的代碼快照,對模型進行預訓練,并使用交叉熵next-token預測損失。在預訓練過程中,隨機地將代碼文件分成兩部分,將第一部分作為編碼器的輸入,并訓練模型去掉編碼器生成第二部分。
這種預訓練為編碼學習了一個強大的先驗,使隨后的特定任務的微調能夠在一個更小的數據集上進行。
微調
在微調階段,在一個2.6GB的競爭性編程問題數據集上對模型進行了微調和評估,數據集是DeepMind創建的,命名為CodeContests公開發布。
CodeContests數據集中包括問題以及測試案例。訓練集包含13,328個問題,每個問題平均有922.4個提交答案。驗證集和測試集分別包含117個和165個問題。
在微調過程中,將自然語言的問題陳述編碼為程序注釋,以使其看起來與預訓練期間看到的文件更加相似(其中可以包括擴展的自然語言注釋),并使用相同的next-token預測損失。
采樣
為了選出10個最好的樣本進行提交,采用過濾和聚類的方法,利用問題陳述中包含的例子測試來執行樣本,并刪除未能通過這些測試的樣本。
通過過濾篩除了近99%的模型樣本,再對剩下的候選樣本進行聚類,在一個單獨的transformer模型生成的輸入上執行這些樣本,并將在生成的輸入上產生相同輸出的程序歸為一類。
然后,從10個最大的聚類中各挑選一個樣本進行提交。直觀地說,正確的程序行為相同,并形成大的聚類,而不正確的程序的失敗方式是多種多樣的。
評估
上圖所示為在10@k指標上,模型性能是如何隨著更多的樣本量和計算量而變化的。從對采樣結果的性能評估上看,研究人員得出了以下4點結論:
1. 解決率隨著更大的樣本量而呈對數線性擴展;
2. 更好的模型在比例曲線上有更高的斜率;
3. 解決率與更多的計算量呈對數線性比例;
4. 樣本選擇對解決率的擴展至關重要。
純粹的「數據驅動」
毫無疑問,AlphaCode的提出,代表了機器學習模型在發展上已經邁出了實質性的一步。
有趣的是,AlphaCode并不包含關于計算機代碼結構的明確的內置知識。
相反,它依靠一種純粹的「數據驅動」方法來編寫代碼,也就是通過簡單地觀察大量現有代碼來學習計算機程序的結構。
文章地址:https://www.science.org/doi/10.1126/science.add8258
從根本上說,使AlphaCode在競爭性編程任務上勝過其他系統的原因歸結為兩個主要屬性:
1. 訓練數據
2. 候選解決方案的后處理
但計算機代碼是一個高度結構化的媒介,程序必須遵守定義的語法,并且必須在解決方案的不同部分中產生明確的前、后條件。
而AlphaCode在生成代碼時采用的方法,卻和生成其他文本內容時完全一樣——一次一個token,并且只在整個程序寫完后檢查程序的正確性。
鑒于適當的數據和模型的復雜性,AlphaCode可以生成連貫的結構。然而,這個順序生成程序的最終配方被深埋在LLM的參數中,難以捉摸。
不過,無論AlphaCode是否真的能「理解」編程問題,它的確在代碼競賽方面達到了人類的平均水平。
「解決編程競賽的問題是一件非常困難的事情,需要人類具有良好的編碼技能和解決問題的創造力。AlphaCode能夠在這一領域取得進展,給我留下了深刻的印象,我很高興看到,該模型如何利用其語句理解來生成代碼,并引導其隨機探索以創建解決方案?!?/span>
——Petr Mitrichev,谷歌軟件工程師和世界級競技程序員
AlphaCode在編程競賽中名列前54%,展示了深度學習模型在需要批判性思維的任務中的潛力。
這些模型優雅地利用現代機器學習,將問題的解決方案表達為代碼,這就回到幾十年前AI的符號推理根源。
而這,僅僅是一個開始。
在未來,還會誕生更多解決問題的強大AI,或許這一天已經不遠了。