<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          我用Transformer修復(fù)代碼bug

          共 5382字,需瀏覽 11分鐘

           ·

          2022-01-09 04:15

          來(lái)源:機(jī)器之心

          本文約3900字,建議閱讀7分鐘

          本文介紹了一種預(yù)訓(xùn)練模型transformer進(jìn)行自動(dòng)debug的方法。

          本地化 Bug 并修復(fù)程序是軟件開(kāi)發(fā)過(guò)程中的重要任務(wù)。在本篇論文中,來(lái)自微軟 Cloud+AI 部門(mén)的研究者介紹了 DeepDebug,一種使用大型預(yù)訓(xùn)練模型 transformer 進(jìn)行自動(dòng) debug 的方法。

          首先,研究者基于 20 萬(wàn)個(gè)庫(kù)中的函數(shù)訓(xùn)練了反向翻譯模型。接下來(lái),他們將注意力轉(zhuǎn)向可以對(duì)其執(zhí)行測(cè)試的 1 萬(wàn)個(gè)庫(kù),并在這些已經(jīng)通過(guò)測(cè)試的庫(kù)中創(chuàng)建所有函數(shù)的 buggy 版本。這些豐富的調(diào)試信息,例如棧追蹤和打印語(yǔ)句,可以用于微調(diào)已在原始源代碼上預(yù)訓(xùn)練的模型。最后,研究者通過(guò)將上下文窗口擴(kuò)展到 buggy 函數(shù)本身外,并按優(yōu)先級(jí)順序添加一個(gè)由該函數(shù)的父類(lèi)、導(dǎo)入、簽名、文檔字符串、方法主體組成的框架,從而增強(qiáng)了所有模型。

          在 QuixBugs 基準(zhǔn)上,研究者將 bug 的修補(bǔ)總數(shù)增加了 50%以上,同時(shí)將誤報(bào)率從 35%降至 5%,并將超時(shí)(timeout)從 6 小時(shí)減少到 1 分鐘。根據(jù)微軟自己的可執(zhí)行測(cè)試基準(zhǔn),此模型在不使用跟蹤的情況下首次修復(fù)了 68%的 bug;而在添加跟蹤之后,第一次嘗試即可修復(fù) 75%的錯(cuò)誤。為評(píng)估可執(zhí)行的測(cè)試,作者接下來(lái)還將開(kāi)源框架和驗(yàn)證集。


          論文標(biāo)題:

          DeepDebug: Fixing Python Bugs Using Stack Traces, Backtranslation, and Code Skeletons

          論文鏈接:
          https://arxiv.org/pdf/2105.09352.pdf


          引言


          自動(dòng)程序修復(fù)中的主要范例是"生成和驗(yàn)證"方法。研究者遵循該方法,假設(shè)存在可以識(shí)別 bug 存在的一組測(cè)試函數(shù),然后本地化 bug 并考慮候選的修補(bǔ)程序,直到找到滿(mǎn)足測(cè)試的補(bǔ)丁程序?yàn)橹埂?/span>

          在整個(gè)實(shí)驗(yàn)過(guò)程中,研究者使用了錯(cuò)誤已被本地化為單個(gè) buggy 方法的合成 bug,將其與其他上下文(例如函數(shù)文件中的上下文以及暴露 buggy 函數(shù)的棧追蹤)作為輸入,并將該輸入提供給嘗試生成修復(fù)好的函數(shù)的序列到序列 transformer。

          研究者在部署方案中還嘗試使用了棧追蹤來(lái)本地化 bug。目前,研究者基于來(lái)自開(kāi)發(fā)人員自己的代碼行的棧追蹤來(lái)應(yīng)用一種簡(jiǎn)單的啟發(fā)法,因?yàn)樽罱{(diào)用的行是最可疑的。在未來(lái),作者還有興趣使用可以對(duì)給定棧追蹤的方法進(jìn)行重新排序的編碼器 transformer 來(lái)改進(jìn)啟發(fā)法。

          如下圖所示,利用了經(jīng)過(guò)廣泛預(yù)訓(xùn)練的 transformer,研究者使用了用于微調(diào) PyMT5 的相同的 DeepDev-py 序列到序列模型。他們首先使用 commit 數(shù)據(jù)來(lái)訓(xùn)練基線(xiàn) bug 修補(bǔ)程序模型和 bug 創(chuàng)建模型。Bug 創(chuàng)建(bug-creator)模型向 DeepDebug(反向翻譯)提供的數(shù)據(jù)量是原來(lái)的 20 倍。最后,研究者針對(duì)具有可執(zhí)行測(cè)試并產(chǎn)生追蹤的函數(shù)中的神經(jīng)錯(cuò)誤微調(diào)了此模型,從而獲得其最終的 DeepDebug(追蹤)。

          ▲訓(xùn)練 pipeline


          模型


          研究者重復(fù)使用了具有 12 個(gè)編碼器層和 12 個(gè)解碼器層的 4.06 億參數(shù)的序列到序列 transformer。在實(shí)驗(yàn)棧追蹤時(shí),他們?yōu)榇a框架分配了 1024 個(gè) token,為追蹤分配多達(dá) 896 個(gè) token,并且為了適應(yīng)這個(gè)規(guī)模更大的上下文,還需要擴(kuò)展 transformer 的位置嵌入矩陣。為此,研究者受 reformer 的啟發(fā)使用了軸向嵌入,復(fù)制了已有 1024 個(gè)位置嵌入中的前 896 個(gè),生成一個(gè)隨機(jī)的軸向向量,并將該向量添加到所有 896 個(gè)重復(fù)嵌入中。在初步實(shí)驗(yàn)中,此方法的性能優(yōu)于隨機(jī)初始化的嵌入。

          數(shù)據(jù)


          研究者使用四個(gè)不同的訓(xùn)練數(shù)據(jù)集:
          • 用于預(yù)訓(xùn)練的原始 python 代碼;
          • 用于訓(xùn)練神經(jīng) bug 創(chuàng)建和 bug 修補(bǔ)程序的 commit 數(shù)據(jù);
          • 從原始代碼中提取的方法,其中插入了神經(jīng) bug 以訓(xùn)練更強(qiáng)大的 bug 修補(bǔ)程序;
          • 通過(guò)可執(zhí)行測(cè)試的方法。

          對(duì)于最后一個(gè)數(shù)據(jù)集,研究者還獲得了每個(gè)測(cè)試執(zhí)行的行列表,并通過(guò)再次插入合成 bug 并重新運(yùn)行通過(guò)測(cè)試來(lái)獲得另一個(gè) bug 補(bǔ)丁程序數(shù)據(jù)集,使得他們可以在棧追蹤、錯(cuò)誤消息、打印語(yǔ)句上對(duì) bug 補(bǔ)丁程序進(jìn)行微調(diào)。研究者還實(shí)驗(yàn)了為 bug 修補(bǔ)程序模型提供焦點(diǎn) buggy 方法或整個(gè)文件的"骨架"(skeleton),以?xún)?yōu)先考慮數(shù)據(jù)(例如函數(shù)簽名)的優(yōu)先級(jí)。

          預(yù)訓(xùn)練


          在 DeepDev transformer 平臺(tái)上,研究者重用了 FaceBook 的 BART 模型熱啟動(dòng)的 4.06 億參數(shù)的 DeepDev Python transformer,然后使用 Spanmasking objective 對(duì)其進(jìn)行了預(yù)訓(xùn)練。預(yù)訓(xùn)練數(shù)據(jù)由 20 萬(wàn)個(gè)五星公共 Python 庫(kù)組成,在 DGX-2 盒子上進(jìn)行了為期三周的預(yù)訓(xùn)練。DeepDev 的 token 生成器附加了空白 token,例如四空間和八空間 token,提高了吞吐量和有效上下文長(zhǎng)度。為了最大程度地減少泄漏的風(fēng)險(xiǎn),研究者始終將驗(yàn)證和測(cè)試庫(kù)限制在同一范圍內(nèi),尤其是 CodeSearchNet 中使用的庫(kù)。


          commit 的數(shù)據(jù)


          研究者遍歷了 10 萬(wàn)個(gè)被過(guò)濾為至少 10 星 Python 庫(kù)的 commit 歷史記錄,并進(jìn)一步過(guò)濾所有消息中包含"修復(fù)"一詞的 commit,大約占所有 commit 的五分之一。基于對(duì)示例的檢查,研究者發(fā)現(xiàn)了這個(gè)簡(jiǎn)單過(guò)濾器的精確度似乎與使用"補(bǔ)丁 bug"或"修復(fù)錯(cuò)誤"之類(lèi)語(yǔ)句的限制性過(guò)濾器差不多。但是,數(shù)據(jù)仍然非常嘈雜。

          commit 的數(shù)據(jù)使研究者做到了以下兩點(diǎn):首先,允許他們訓(xùn)練一個(gè)偏向于建設(shè)性的、bug 修復(fù)的編輯模型,讓研究人員可以直接在 bug 修復(fù)中評(píng)估這種模型,或者在過(guò)濾更進(jìn)一層的 bug 數(shù)據(jù)上對(duì)其進(jìn)行微調(diào)。其次,研究者可以反轉(zhuǎn)輸入和輸出,并訓(xùn)練偏向于破壞性的、引發(fā) bug 的編輯模型。研究人員可以使用此模型來(lái)創(chuàng)建神經(jīng) bug,以大幅度增強(qiáng)訓(xùn)練數(shù)據(jù)。這種反向翻譯方法已經(jīng)在 NLP 中被證明是有用的。

          合成 bug


          由于研究者對(duì)通過(guò)合成 bug 進(jìn)行數(shù)據(jù)擴(kuò)充感興趣,所以使用了 GitHub 上的大量無(wú) bug 代碼。與僅使用從 bug 修復(fù)提交中提取的函數(shù)相比,這樣做有可能使目標(biāo)方法的數(shù)據(jù)集擴(kuò)展二十倍。此外,研究者通過(guò)為每種方法創(chuàng)建多個(gè) buggy 版本來(lái)任意地?cái)U(kuò)大規(guī)模。在本篇論文中,他們將規(guī)模限制為來(lái)自 1 萬(wàn)個(gè)庫(kù)中的 130 萬(wàn)個(gè)函數(shù)(與提交數(shù)據(jù)幾乎相等),并通過(guò)反向翻譯擴(kuò)展到了 1800 萬(wàn)個(gè) bug 修復(fù)。

          研究者觀察到了模型注入了以下幾類(lèi)錯(cuò)誤:

          • 將點(diǎn)訪(fǎng)問(wèn)器替換為方括號(hào)訪(fǎng)問(wèn)器;
          • 將截?cái)噫溄拥暮瘮?shù)調(diào)用;
          • 刪除返回行;
          • 將返回值封裝在元組和字典等對(duì)象中然后忘記封裝對(duì)象;
          • 將 IndexError 等精確錯(cuò)誤替換為 ValueError 等不同的錯(cuò)誤;
          • 誤命名變量諸如 self.result 而不是 self._result;
          • 錯(cuò)誤地按引用復(fù)制而不是按值復(fù)制。研究者幾乎應(yīng)用了以前文獻(xiàn)中已報(bào)道的所有啟發(fā)式 bug。

          "啟發(fā)式 bug"一詞被用來(lái)指代使用簡(jiǎn)單規(guī)則手動(dòng)創(chuàng)建的合成 bug,例如在函數(shù)調(diào)用中刪除一行或交換兩個(gè)參數(shù)、替換二進(jìn)制運(yùn)算符(使用!= 代替 ==)、使用錯(cuò)誤變量、忘記『self.』訪(fǎng)問(wèn)器或者刪除代碼。


          "神經(jīng) bug"一詞被用來(lái)指代使用神經(jīng)編輯模型創(chuàng)建的合成 bug,例如訓(xùn)練來(lái)還原 bug 修復(fù)提交的 bug。使用神經(jīng) bug 進(jìn)行數(shù)據(jù)增強(qiáng)具有許多吸引人的功能。靈活的神經(jīng)模型幾乎可以任意生成從開(kāi)發(fā)人員實(shí)際犯錯(cuò)的分布中得出的編輯。例如,神經(jīng)編輯模型可以將 get_key 與 get_value 交換,而簡(jiǎn)單的啟發(fā)法可能會(huì)進(jìn)行隨機(jī)交換,比如從 get_key 切換到 reverse_list。而且,這種方法幾乎與語(yǔ)言無(wú)關(guān),因?yàn)檠芯空呖梢灾赜每蚣軄?lái)進(jìn)行挖掘提交,并且只需要一個(gè)解析器就可以提取類(lèi)和方法,以及組成代碼框架所需的部分。

          上表所示是在測(cè)試集用于訓(xùn)練兩個(gè) transformer 的交叉熵?fù)p失,一個(gè)用于提交數(shù)據(jù),另一個(gè)用于反向提交。在有和沒(méi)有代碼框架的情況下,在向前和向后編輯中對(duì)這兩個(gè)模型進(jìn)行評(píng)估。由于編輯任務(wù)相對(duì)容易,因此交叉熵?fù)p失比通常報(bào)告的生成 Python 代碼的效果提升五倍。此外,反向編輯的損失比正向編輯的損失低三分之一。正向模型在正向編輯時(shí)比反向模型好 6%,反向模型在反向編輯時(shí)反過(guò)來(lái)又好 6%。與僅使用聚焦方法相比,使用框架的兩種模型的性能都高出 2%。


          如上圖所示,bug 創(chuàng)建模型將 kwargs.pop 替換為了 kwargs.get、將. startwith(self.name) 替換為了 ==self.name、并刪除了 break。


          可執(zhí)行測(cè)試的方法


          實(shí)際上,有很多機(jī)會(huì)可以調(diào)試可以實(shí)際執(zhí)行的代碼,尤其是在有附帶測(cè)試驗(yàn)證執(zhí)行正確的情況下。典型的調(diào)試會(huì)話(huà)包括在棧追蹤的幫助下查找可疑的代碼塊、在近似二進(jìn)制搜索中插入打印語(yǔ)句和斷點(diǎn)、修改并執(zhí)行代碼片段、在 StackOverflow 中搜索錯(cuò)誤消息的解釋以及 API 使用示例。相比之下,基線(xiàn)神經(jīng)模型是機(jī)會(huì)更少的,在每次寫(xiě)入一個(gè) token 之前,只能盯著一段代碼幾秒鐘。

          而由可執(zhí)行測(cè)試啟用的"生成并驗(yàn)證"方法可以有多次機(jī)會(huì)提高性能。例如,在短 Java 方法領(lǐng)域,研究者見(jiàn)證了 top-20 精度是 top-1 精度的三倍。盡管先前的工作已經(jīng)表明這些編輯可能會(huì)過(guò)擬合,真正的隨機(jī)編輯仍能確保足夠多的嘗試次數(shù)以通過(guò)測(cè)試組。

          研究者主要運(yùn)用的方法有三種:

          • 追蹤法:除了使用測(cè)試對(duì)不正確的編輯進(jìn)行分類(lèi)之外,還以三種不同的方式將來(lái)自測(cè)試的信息整合到訓(xùn)練中:將錯(cuò)誤消息附加到 buggy 方法中,另外附加了棧追蹤,并進(jìn)一步使用測(cè)試框架 Pytest 提供了故障處的所有局部變量值;
          • 收集通過(guò)測(cè)試法:為了以訓(xùn)練規(guī)模收集可執(zhí)行的測(cè)試,從用于預(yù)訓(xùn)練的 20 萬(wàn)個(gè)庫(kù)開(kāi)始,過(guò)濾到包含測(cè)試和 setup.py 或 requirements.txt 文件的 3.5 萬(wàn)個(gè)庫(kù)。對(duì)于這些庫(kù)中的每一個(gè),都在唯一的容器中執(zhí)行 Pytest,最終從 1 萬(wàn)個(gè)庫(kù)中收集通過(guò)的測(cè)試;
          • 合成 bug 測(cè)試法:在過(guò)濾通過(guò)可執(zhí)行測(cè)試的函數(shù)并插入神經(jīng) bug 之后,重新運(yùn)行測(cè)試以收集 Pytest 追蹤,并濾除仍通過(guò)測(cè)試并因此實(shí)際上不是 buggy 的已編輯函數(shù)。


          實(shí)驗(yàn)及結(jié)果


          研究者對(duì)訓(xùn)練反向翻譯數(shù)據(jù)、添加框架以及添加 Pytest 棧追蹤進(jìn)行了實(shí)驗(yàn),并得到了如下結(jié)果。

          反向翻譯數(shù)據(jù)


          在首個(gè)實(shí)驗(yàn)中,研究者比較了通過(guò)前向提交數(shù)據(jù)進(jìn)行的訓(xùn)練與通過(guò)反向翻譯產(chǎn)生的合成 bug 進(jìn)行的訓(xùn)練,并對(duì)保留數(shù)據(jù)上使用交叉熵進(jìn)行評(píng)估。如下表所示,比起前向提交數(shù)據(jù),DeepDebug(反向翻譯)的損失降低了 10%。令人驚訝的是,反向翻譯模型實(shí)際上在反向提交數(shù)據(jù)上的表現(xiàn)較差。


          總體而言,DeepDebug 比以前的技術(shù)要強(qiáng)大得多。QuixBugs 挑戰(zhàn)是帶有小合成 bug 且 Python 和 Java 版本幾乎相同的 40 個(gè)經(jīng)典算法的基準(zhǔn),最初的 QuixBugs 挑戰(zhàn)是讓開(kāi)發(fā)人員在一分鐘的時(shí)間內(nèi)修復(fù)盡可能多的 bug。下表報(bào)告了模型挑戰(zhàn) QuixBugs 的結(jié)果。


          研究者將模型限制為通過(guò)隨機(jī)采樣生成 100 個(gè)補(bǔ)丁,這大約是在一分鐘跨度內(nèi)可以生成和評(píng)估的數(shù)量。隨后將現(xiàn)有的 bug 數(shù)量提高了 50%以上,同時(shí)將誤報(bào)率從 35%降低到了 5%。值得注意的是,由于此任務(wù)的復(fù)雜性較低,因此所有的模型都會(huì)生成許多重復(fù)的編輯,這表明在采樣上仍有改進(jìn)空間。鑒于先前模型的超時(shí)以及額外信息提供,這些結(jié)果更加令人印象深刻。例如,CoCoNuT 被明確告知哪一行包含該 bug,并被允許六個(gè)小時(shí)來(lái)找到補(bǔ)丁;五個(gè)非神經(jīng)工具找到了 122 個(gè)補(bǔ)丁程序,用于最長(zhǎng)的遞增子序列算法,還進(jìn)行了數(shù)千次的嘗試。

          添加框架


          在第二個(gè)實(shí)驗(yàn)中,研究者比較了僅使用焦點(diǎn)函數(shù)作為輸入以及使用整個(gè)框架作為輸入的訓(xùn)練和評(píng)估。如下表所示,當(dāng)對(duì)神經(jīng) bug 進(jìn)行評(píng)估時(shí),使用框架時(shí),神經(jīng) bug 補(bǔ)丁損失減少了 25%。而實(shí)際上,當(dāng)對(duì)提交數(shù)據(jù)使用框架時(shí),神經(jīng) bug 補(bǔ)丁的表現(xiàn)更差,因?yàn)樘峤煌ǔ?huì)編輯多個(gè)函數(shù)。


          Pytest 棧追蹤


          在第三個(gè)實(shí)驗(yàn)中,研究者將 Pytest 棧追蹤附加到 buggy 輸入中,使用軸向嵌入來(lái)擴(kuò)展上下文窗口,以適應(yīng)其他的 token。在計(jì)劃進(jìn)行開(kāi)源的驗(yàn)證集中篩選了 100 個(gè)庫(kù)中的 523 個(gè)神經(jīng) bug 的基準(zhǔn)。他們觀察到了令人印象深刻的表現(xiàn),與交叉熵結(jié)果相反,使用追蹤大大提高了性能。如下表所示,DeepDebug(反向翻譯)的前 10 個(gè)修補(bǔ)程序成功率為 90%,而 DeepDebug(追蹤)的前 10 個(gè)修補(bǔ)程序成功率為 97%。


          編輯:于騰凱

          校對(duì):龔力

          瀏覽 96
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级a黄色视频 | 黑人蜜桃2黑人 | 先锋影音资源久久久久久久久 | 99免费观看视频 | 国产啊啊啊啊 |