啟動項代碼,GPT系列:Codex【使用GPT-3完成代碼自動生成任務】
啟動項代碼,GPT系列:Codex【使用GPT-3完成代碼自動生成任務】
OpenAI Codex
Evaluating Large Language Models Trained on Code
- 根據函數名和注釋自動補全代碼
- 根據你寫的代碼,猜出你接下來可能要寫的代碼
- 自動補充測試樣例
- 支持多種語言
- ....
啟動項代碼?總之,就是可以幫你寫代碼
簡介
- 提出了一個新問題:代碼補全
- 采用的解決方案是:將GitHub上采集到的Python代碼作為數據集重新訓練一下GPT-3,他就把這一套權重叫做Codex
- 一個值得注意的點:
- 代碼補全這個任務的特殊性:具體來說,傳統的NLP任務,生成的結果越接正確答案,那么模型得分越高,但是代碼不是這樣的,代碼但凡有一點點小Bug,都可能造成毀滅性的結果。所以對于代碼補全任務,判斷生成代碼的正確與否就是使用的單元測試(unit test)。---所以對于代碼補全任務需要新的評估指標和數據集。
評估
評估指標---pass@k
NLP中最常見的評估方法是BLUE score(bilingual evaluation understudy)即:雙語互譯質量評估輔助工具。BLEU的設計思想:機器翻譯結果越接近專業人工翻譯的結果,則越好。BLEU算法實際上就是在判斷兩個句子的相似程度。想知道一個句子翻譯前后的表示是否意思一致,直接的辦法是拿這個句子的標準人工翻譯與機器翻譯的結果作比較,如果它們是很相似的,說明我的翻譯很成功。
ussd代碼是什么意思,可以看出,BLUE score是一個模糊匹配的過程,意思大差不差就行。但是編程是一個比較特殊的問題,一個小的差別可能就會帶來災難性的影響(永無止盡的Bug Fix)。
針對代碼補全這樣一個特殊問題,作者提出了一個pass@k的一個指標,生成k個結果,只要有一個通過就算通過(k如果比較大,就會對模型的能力過度樂觀,當k比較大的時候,雖然模型分數比較高,但是在使用時,會給用戶返回一大堆代碼,讓用戶去選,這個也是很難的,所以說需要排算法,但這個分數并沒有反映排序)。

pass@k
n生成的候補答案總數,k每次選的答案,c代表能通過單元測試的答案(n=200,k<=100,c<=n)
評估數據集---HumanEval
HumanEval(Hand-Written Evaluation Set)包含164個人工設計的編程問題,每個問題包含函數名、注釋、函數體、多個單元測試
手動實現是非常重要的:因為如果直接從網上找,比如說從leetcode上去扒,很有可能你的這個問題就在你在訓練集里面(數據泄露)
模型
訓練數據
從GitHub上收集到了179GB的Python代碼。對文件進行簡單的過濾(自動生成、平均長度大于100行、最大長度大于1000行、包含很少的字母/數字),最后得到159GB的Python代碼文件
使用GPT-3訓練得到Codex
用上面數據集在GPT-3的預訓練模型上再訓練一下得到了Codex
后面作者又收集了一個跟HumanEval更相近的訓練集,在上面訓練得到的模型叫Codex-S
作者有提到不管是在GPT-3的預訓練模型訓練,還是從頭開始訓練得到的模型,在精度上基本上沒有差別。
但是在GPT-3的預訓練模型訓練收斂會更快一點
注意:
- 訓練時,會對代碼里的空格,換行進行處理
- 生成代碼時,什么時候停止:遇到了 ‘\nclass’, ‘\ndef’, ‘\n#’, ‘\nif’, ‘\nprint’ 等就停掉代碼
評估采樣時,使用p=0.95的核采樣(nucleus sampling):就是說將所有候補答案,按概率從高到低排序,依次拿出來,指導所有選出來的候補的概率和大于0.95,就停止采樣。
結果

模型大小和損失之間的關系
模型大小和損失之間的關系:模型參數指數級上升時,損失線性下降
作者在算softmax前,會除以某一個T。T較大時,各個候選的概率比較相近,T較小時,各個候選的概率分的比較開。如果用一個較小的T,最好的幾個候選,概率較大,采樣的時候總能把最好的幾個取出來,如果用一個較大的T,不是最好的幾個候選也能被采樣出來

采樣次數和T之間的關系:不同的T,隨著采樣次數的增加,pass@k的變化

反映不同采樣次數下最好的T:隨著允許采樣的數目增加,最好的T越大(假如說我只允許你選一個,那么你最應該選擇出最好的候選答案,那就對應比較小的T)
下圖反映不同排序算法(從生成的k的答案里面選出最好的):Oracle代表使用了先驗(就是把取出來的k的候選,放到單元測試上測一下,選擇能通過的候選出來),那么明顯隨著k增大,通過率越高。

不同排序算法
關于BLUE score:作者在HumanEval的4個隨機任務上測了BLUE score,可以看出,BLUE分數的高低與答案正確并沒有直接關系,也印證了作者前面說的不能使用BLUE score的原因
驗證BLUE score是否有效
Codex和GPT-NEO、GPT-J、TABNINE的性能對比
與不同方法的對比
Codex-S
使用跟HumanEval更相近數據集作為的訓練集,在上面訓練得到的模型叫Codex-S
HumanEval(Hand-Written Evaluation Set)包含164個人工設計的編程問題,每個問題包含函數名、注釋、函數體、多個單元測試
得到訓練集的方法:
- 程序競賽的題目
- CI里面拿
- 過濾:使用Codex-12B生成100個候選答案,如果其中至少有一個能通過單元測試,就把問題留下來,否則,作者覺得可能是這個問題的單元測試不正確,或者問題太復雜(作者認為太難的問題對模型訓練沒有太大幫助),就過濾掉

Codex-S和Codex間在模型增大時,pass@k的分數:實線Codex-S,虛線就是Codex

Codex-S和Codex不同使用排序算法間的差別
另外的應用---生成文檔(Codex-D)
數據集調整:把docstring放到最后面(函數名和函數體后面)
使用這樣數據集訓練得到的模型叫Codex-D
判斷生成的docstring是否合格:
- 眼睛去看
- 先用Codex-D生成docstring,再用docstring和函數名生成函數體,如果代碼能過單元測試,則認為生成的docstring質量很高
局限性
- 樣本有效性不夠(使用100G的代碼去訓練得到的模型只能處理比較簡單的代碼任務)
- 受注釋影響較大
- 做數學相關的代碼比較差

處理簡單數學問題的示例
可能影響
- 過度依賴模型生成的代碼
- 模型可能能生成你想要的答案,但是他會按照訓練數據集的風格去寫,可能跟你想要的風格不一樣
- 偏見(GitHub男性用戶較多)
- 程序員失業(感覺作者有點杞人憂天)
- 模型經常使用一些特定的包,可能導致其他的包使用概率下降(比如openai自己開發一個深度學習框架,讓Codex生成的代碼都用這個框架,如果這個模型比較火,那么可能就沒有TensorFlow PyTorch的生存空間了)
- 安全問題(使用Codex寫病毒)
- 環境問題(模型訓練耗電)
- 法律(爬GitHub上的代碼訓練模型可能會有法律問題?生成的代碼可能會有抄襲問題,且這種問題用戶還不知道)
總結
說白了就是,作者把GitHub上的Python代碼爬爬下來,用GPT-3訓練了一個模型(Codex),發現可以解決部分代碼問題,為了能解決更多問題(把通過率刷上去?),又收集了一個跟測試集(HumanEval)更近似的數據集訓練得到(Codex-S),然后作者覺得只生成代碼沒意思,又把數據集里的docstring放到函數名和函數體后面得到一個新的數據集,訓練得到(Codex-D)
這篇論文在模型上并沒有什么創新,主要就是提出了一個新的問題(代碼生成,后續有很多相關工作,比如說AlphaCode),然后就是花精力收集數據集甚至更好的數據集。
參考資料
Codex 官網:OpenAI Codex
Codex paper:Evaluating Large Language Models Trained on Code
Copilot 官網(Codex的實際應用):GitHub Copilot · Your AI pair programmer
沐神講解Codex:OpenAI Codex 論文精讀【論文精讀】嗶哩嗶哩bilibili
TabNine官網:Code Faster with AI Code Completions | Tabnine
AlphaCode paper:Competition-Level Code Generation with AlphaCode
Codex: 使用GPT-3完成代碼自動生成任務 - 知乎