從HumanEval到CoderEval: 你的程式碼生成模型真的work嗎?

2023-12-04 18:00:16

本文分享自華為雲社群《從HumanEval到CoderEval: 你的程式碼生成模型真的work嗎?》,作者:華為雲PaaS服務小智 。

本文主要介紹了一個名為CoderEval的程式碼生成大模型評估基準,並對三個程式碼生成模型(CodeGen、PanGu-Coder和ChatGPT)在該基準上的表現進行了評估和比較。研究人員從真實的開源專案中的選取了程式碼生成任務來構建CoderEval,並根據對外部依賴的程度為標準將這些任務分為6個等級、根據生成的目標分為3類生成任務,以更多維地評估不同大模型在不同上下文場景中的生成效果。

實驗結果表明,這三個模型在生成自包含函數方面的效果明顯優於其他任務,但實際專案中的函數大部分依賴不同程度的上下文資訊,因此提高模型對上下文資訊的考慮和利用能力對於程式碼生成技術的實際可用性非常重要。該工作由北京大學和華為雲Paas技術創新LAB合作完成,論文已經被軟體工程頂會ICSE 2024錄用。

cke_114.png

從HumanEval到CoderEval

就像ImageNet之於影象識別,Defects4J之於缺陷檢測,在以工具和方法為主要貢獻的研究領域中,一個被廣泛接受和採用的評估資料集及其配套的基準指標,對該領域的研究和發展至關重要。一方面,評估方式作為度量尺,可以在同一維度上起到橫向對比各類方法的水平,並估計距離成熟實用的差距;另一方面,評估方式作為風向標,直接指導著各種方法共同的優化和迭代目標,決定了研究者們前進的方向。

在程式碼生成領域,當前最廣泛被使用的是OpenAI在Codex論文中開源的HumanEval,該基準測試集由164道由OpenAI工程師手動編寫的程式設計任務組成,以一定程度上確保與訓練集的不重疊性。初版的HumanEval僅支援Python語言,每個程式設計任務包括了任務描述、參考程式碼、若干測試樣例等。近期有部分研究者將HumanEval擴充套件到多種程式語言,例如:清華大學CodeGeex團隊基於HumanEval開源了HumanEval-X,將HumanEval擴充套件到C++、Java、JavaScript、Go等語言;於2022年8月19日釋出在arXiv上釋出的一篇論文提出了MultiPL-E,將HumanEval擴充套件到了18種語言。

然而,HumanEval本身存在一些問題,這些問題使得它並不適合成為程式碼生成任務的一個評估平臺,特別是對於以實際開發為目標的程式碼生成研究和工具。基於HumanEval進行擴充套件的一類工作僅僅是將HumanEval中的任務描述、參考程式碼、測試樣例以及執行環境等翻譯或適配到了其他語言,實質上並未解決HumanEval自身存在的一些問題。那麼,這些問題有哪些呢?經過對HumanEval中的任務和測試樣例、以及多個模型生成結果的人工檢視,我們主要歸納出以下問題:

1.領域單一,僅覆蓋了語言本身基礎的程式設計知識,如資料結構操作、簡單演演算法等;

2.任務本身過於簡單,參考程式碼均為自包含的單一函數,並未考慮複雜型別、自定義型別、三方庫、跨過程呼叫等情況。

根據我們對GitHub倉庫資料的統計,HumanEval所對應的自包含單一函數在Top 100的Python專案中只佔11.2%,在Top 100的Java專案中只佔21.3%,因此,HumanEval可能實際上無法準確反映程式碼生成模型在實際專案級開發中的表現。

針對HumanEval的限制和不足,我們提出了CoderEval,一個面向真實場景和實際使用者的程式碼生成模型可用性評測系統。CoderEval在一定程度上解決了當前被廣泛使用的評測基準的問題,主要體現在以下幾點:

1.直接來源於真實的開源專案,覆蓋多個領域,從而可以全面評估程式碼生成在不同領域中的表現;

2. 考慮了複雜資料型別或專案程式碼中開發者自定義的型別,支援物件導向特性和跨過程呼叫;

3. 儘量保證覆蓋率和完備性,從而在一定程度上降低測試誤報率。

綜上所述,相比於HumanEval,CoderEval與實際開發場景中的生成任務更加對齊,在基於大模型的程式碼生成工具逐步落地並商業化的背景下,可能更加真實地反映並比較不同模型在實際落地為工具之後的開發者體驗。接下來,我們將簡要介紹CoderEval的組成部分、構建過程以及使用方法。

CoderEval論文目前已被ICSE2024接收:

https://arxiv.org/abs/2302.00288

CoderEval-GitHub目前已開源:

https://github.com/CoderEval/CoderEval

CoderEval:面向實際開發場景的程式碼生成模型評估

CoderEval組成部分

整體而言,CoderEval主要由三部分組成:

1.生成任務:以函數/方法為基本單位的程式碼生成任務,包括任務描述(即自然語言註釋)、函數簽名、參考程式碼(即原始程式碼實現)、所在檔案所有上下文程式碼、所在專案其他檔案內容等;

2. 測試程式碼:針對某一程式設計任務的單元測試,一個程式設計任務可能對應一到多個測試檔案、一到多個測試方法,以及附加的測試資料(如操作檔案的程式設計任務中的檔案等);

3. 測試環境:由於CoderEval中的函數/方法允許使用自定義型別、呼叫語言標準庫或三方庫、呼叫專案中其他方法等,因此需要在設定好所在專案的環境中執行。為此,CoderEval基於Docker構建了沙箱測試環境,其中包含了所有被測專案及其依賴,並且附有單一入口的自動化執行程式。此測試環境預計將以線上服務的形式提供。

CoderEval構建過程

cke_115.png

圖1 CoderEval的構建過程

圖1展示了針對某一種程式語言(目標語言)構建CoderEval的一般性的過程,主要分為三個部分:

1.目標選取:從GitHub或CodeHub選擇目標語言為主的專案中的高質量目標函數/方法,作為測試任務

2. 資料收集:針對每個候選測試任務,分析和收集目標函數/方法的元資訊、自身資訊、測試資訊等

3. 環境構建:準備目標專案和依賴,為測試程式碼提供執行環境,並通過執行測試驗證測試程式碼和目的碼的正確性

作為第一個版本,CoderEval首先支援了兩大語言:

• CoderEval4Python:包含來自43個專案的230個生成任務

• CoderEval4Java:包含來自10個專案的230個生成任務

為了真實反映程式碼生成模型在實際專案開發中的效果和價值,我們需要從真實、多元的開源專案中選取高質量的生成任務,並配備儘可能完善的測試。為此,我們首先爬取了GitHub上Python和Java專案的所有標籤,根據最頻繁的14個標籤和標星數篩選出若干專案,然後抽取出專案中所有的測試程式碼以及被測函數/方法,僅保留符合以下全部條件的部分:

• 並非以測試為目的的、deprecated的、介面形式的函數/方法

• 包含一段英文自然語言描述作為函數/方法級註釋

• 可以在測試環境中正確執行並通過原始測試

經過這些篩選保留下來的函數/方法,再經過人工篩選和程式分析,構成了CoderEval中的程式碼生成任務,每個生成任務提供的資訊有:

• 元資訊(Meta):所在專案地址、檔案路徑、行號範圍等

• 自身資訊(Native):該函數/方法的原始註釋、簽名、程式碼等

• 上下文資訊(Context,可選):所在檔案內容、可存取上下文資訊、所使用上下文資訊、執行級別分類等

• 測試資訊(Test):人工標註的自然語言描述、在原始程式碼上的若干測試樣例等

CoderEval使用方法

CoderEval支援函數/方法塊級生成(Block Generation):根據註釋形式的任務描述和/或函數簽名,生成實現對應功能的完整函數體。

CoderEval支援的指標:基於執行的指標(Comparison-based Metrics)。與HumanEval一致,我們同樣採取了Pass@k作為測試指標,從而評估所生成程式碼實際的執行效果,允許模型生成不同版本的實現。

CoderEval支援更細粒度的評估:

1. 上下文感知能力評估:我們在研究中發現,對於非自包含函數/方法,其程式碼實現中的外部依賴資訊對於其功能和行為非常關鍵。因此,模型的上下文感知能力(Context-awareness,即正確生成外部依賴資訊的能力)是另一個重要指標。CoderEval提供了生成任務所在專案以及檔案內容可作為輸入,原始程式碼中實際用到的上下文資訊作為期望輸出,因此,可以分析並計算生成程式碼中上下文資訊的準確率以及召回率,作為上下文感知能力的評估指標。

2. 分級評估:如圖2所示,依據所依賴的上下文資訊,CoderEval進一步將生成任務分成了6個級別(self_contained、slib_runnable、plib_runnable、class_runnable、project_runnable),代表所對應程式碼可執行的環境(標準庫、第三方庫、當前檔案、當前專案等)。CoderEval支援更細粒度地測試和分析模型在每個級別上的生成能力,從而可以全面地分析當前模型的不足和待優化的方向(如引入課程學習、針對性微調、上下文可感知度的針對性提升等)。

cke_116.png

圖2 CoderEval中按依賴級別的資料分佈

3. Prompt評估:CoderEval同時提供了原始註釋和開發者另外標註的程式碼功能描述,從而研究模型記憶效應、Prompt形式、Prompt質量對不同模型的影響。

由於CoderEval源於實際的開源專案,並且我們無法精確獲得或控制各個模型訓練資料,因此可能無法避免存在因模型的記憶效應和複製機制產生的誤差。CoderEval緩解此類誤差的主要措施包括:

1.為所有任務補充了人工改寫的註釋替代原註釋,該部分可確保不存在於訓練集中。為此,我們同時會測試。

2. 可增大取樣次數並綜合基於執行的指標和基於比較的指標進行分析,從而分析模型是否能實現與原始碼不同、但又可通過測試的方案。

CoderEval實測結果

我們測試了工業界為主提出的、具有代表性的三個模型在CoderEval上的表現,被測模型包括:

1.CodeGen(Salesforce):採用GPT-2架構,在自然語言上先進行預訓練,再在多種程式語言混合語料上繼續訓練,最後在單一程式語言上進行微調。

2. PanGuCoder(Huawei):基於PanGu-alpha架構,採用<自然語言描述, 程式語言程式碼>對的形式和多階段預訓練方法,專注於Text2Code任務,對中文支援較好。

3. ChatGPT(OpenAI):基於GPT-3.5系列模型使用人類反饋進行微調,可以根據使用者的指令或問題來生成程式碼。

部分實驗結果如下:

1. 如表1所示,在CoderEval和HumanEval上,ChatGPT的效果都大幅超出其他兩個模型,原因可能來自於更大的模型規模、更充分的訓練度、更優的超引數等方面。

表1 三個模型在CoderEval上和HumanEval上的

總體效果對比

cke_117.png

2. 如表1所示,在HumanEval上,ChatGPT的效果更是大幅超過其他模型,幅度要遠大於在CoderEval上三個模型的差距。考慮到HumanEval的侷限性,這一結果從側面表明HumanEval可能已經不適合作為單一的程式碼生成Benchmark。

3. 如圖3所示,在CoderEval上,三個模型正確生成的任務存在較大的交集(Python:32,Java:56),說明三個模型在解決部分任務上有共效能力;同時,對於僅有一個模型能正確生成、而其他兩個模型未正確生成的任務而言,ChatGPT在Python和Java上都是最多的(Python:18,Java:27),說明ChatGPT在解決這部分任務上的能力具有顯著優勢;最後,三個模型一共解決的任務數仍僅佔CoderEval所有任務數的約40%(Python:91/230)和59%(Java:136/230),說明三個模型的能力具有一定的互補性,且各自仍有較大提升空間。

cke_118.png

圖3 三個模型在CoderEval上和HumanEval上

正確生成的題目數對比

4. 如表2所示,在CoderEval的standalone子集上,三個模型的表現與HumanEval上基本接近,ChatGPT的表現大幅超過另外兩個模型;但是,在其他依賴於上下文資訊的生成任務上(佔實際情況的60%以上),三個模型的表現都有較大下降,即使是最強大的ChatGPT的表現也有很大波動,甚至在部分級別上三個模型生成10次的結果均錯誤,這一定程度上說明了依賴上下文的程式碼生成任務是大模型程式碼生成下一步優化的重點方向。

表2 三個模型在CoderEval的兩類子集上的表現對比

cke_119.png

更多的實驗資料以及分析過程,請見CoderEval論文。

總結

CoderEval論文目前已公開在arXiv(https://arxiv.org/abs/2302.00288 ),其開源專案版可在GitHub獲得(https://github.com/CoderEval/CoderEval ),歡迎大家關注並一鍵Follow+Star。我們致力於將CoderEval打造為一個客觀、公正、全面的Benchmark,不過,儘量我們已努力完善,但它仍然不可避免地存在一些限制和錯誤。因此,我們希望藉助程式碼生成研究者社群的力量,持續迭代和更新CoderEval的版本,以擴充套件和完善其語言支援、資料集、測試方式等方面,從而持續推動程式碼智慧社群的研究與落地。

 

點選關注,第一時間瞭解華為雲新鮮技術~