AIxiv專欄是機器之心釋出學術、技術內容的欄目。過去數年,機器之心AIxiv專欄接收報導了2000多篇內容,覆蓋全球各大高校與企業的頂級實驗室,有效促進了學術交流與傳播。如果您有優秀的工作想要分享,歡迎投稿或者聯絡報導。投稿郵箱:liyazhou@jiqizhixin.com;zhaoyunfeng@jiqizhixin.com
本文的共同第一作者是墨爾本大學電腦科學碩士黃思明和復旦大學電腦科學碩士程天豪。OpenCoder 專案是二人在 INF 實習期間與 M-A-P 開源專案合作的成果,由 INF 主導,M-A-P 積極參與,通訊作者為汪自力與褚崴。來自 INF 參與者包括:郝嘉然,宋劉一漢,徐陽,汪自力,褚崴,徐盈輝,漆遠。來自 M.A.P 的參與者包括:張舸,張晨晨,柴林政,J.Yang, J.H.Liu。其餘合作者有:J.K.Liu;袁瑞峰;付傑;劉乾,Tiktok 研究員;張兆翔,中國科學院自動化研究所研究員。
程式碼大型語言模型(CodeLLM) 在程式碼生成、推理任務和智慧代理系統等多個領域已變得不可或缺。儘管開源的程式碼大模型效能正逐步接近專有模型的水平,但適合進行科學研究的高質量 CodeLLM 仍然非常稀缺,尤其是資料清理流程、合成資料、模型訓練流程全部可復現的全方位開源 CodeLLM。這一稀缺性源於多種挑戰,包括資源限制、倫理考量、保持競爭優勢等需求。
為彌補這一差距,研究團隊推出了 OpenCoder,這是一系列能力達到第一梯隊的 CodeLLM,不僅在效能上可與領先模型媲美,還為研究社群提供了全方面的構建細節。不同於大多數以往的工作,OpenCoder 不僅公開了模型權重和推理程式碼,還提供了可重複的訓練資料、完整的資料處理流程、嚴謹的實驗消融結果以及詳細的訓練細節,為科學研究開放了全面的資源。
研究團隊發現構建高質量 CodeLLM 的關鍵因素有:(1) 資料質量至關重要,程式碼預訓練資料需要精細的啟發式規則清洗與檔案粒度的去重(2)預訓練資料中新增網際網路網頁中召回的程式碼相關語料(3)在退火和監督微調階段使用高質量的合成資料。
OpenCoder 團隊希望透過更高的開源程度,讓研究人員深入瞭解程式碼大語言模型的各個細節,使 OpenCoder 不僅成為強大的模型,更成為開放的基礎平臺,加速研究進展,推動程式碼 AI 的可復現發展,縮小開源社群與工業界之間的差距。
論文標題:OpenCoder: The Open Cookbook for Top-Tier Code Large Language Model
論文連結:https://arxiv.org/abs/2411.04905
專案主頁:https://opencoder-llm.github.io/
模型/資料集下載:https://huggingface.co/OpenCoder-LLM
程式碼倉庫:https://github.com/OpenCoder-llm/OpenCoder-llm
預訓練階段
預訓練資料構成了大型語言模型能力的基礎。在開源社群中,The Stack v2 (Lozhkov et al., 2024a) 提供了一個有價值的程式碼資料集,有力地支援了程式碼語言模型的訓練。然而,The Stack v2 的訓練資料部分質量不足,無法使語言模型達到頂尖效能。
為此,研究團隊提出了 RefineCode,這是一種高質量、可復現的資料集,包含了 9600 億個標記 (token),涵蓋了 607 種程式語言,並融入了 130 多條語言特定規則及其自定義權重分配。該資料集由兩部分組成:原始程式碼和程式碼相關的網頁資料。
具體來說,團隊主要從 GitHub 上收集原始程式碼(截至 2023 年 11 月),並結合了 The Stack v2 中的非 GitHub 資料。此外,程式碼相關的網頁資料主要來源於網頁語料庫。研究團隊設計了一個複雜的資料處理流程來生成程式碼預訓練語料庫,包含預處理、去重、轉換、過濾與資料重配比。
預處理:排除超過 8MB 的檔案,以避免將非文字檔案納入資料集,同時僅保留 607 種程式語言相關檔案。
去重:首先透過 SHA256 雜湊進行精準去重,其次透過 MinHash+LSH 進行模糊去重,優先保留 star 數更高的檔案
轉換:進行敏感資訊識別檢測
過濾:根據 130 多項啟發式過濾規則,進一步篩選高質量程式碼檔案,確保資料的高質量
資料重配比:在確認保持原始分佈的情況下,對 HTML 和 Java 兩類數量較為龐大的程式語言進行下采樣
在以上一整套針對程式碼清洗流程後,RefineCode 保留了約 730B 的 token 數量。
OpenCoder 首次提出一套針對不同程式語言的詳細過濾規則,並將程式碼、調整引數完全開源。啟發式規則設計準則如下:1) 過濾掉 self-contained 程度過低的程式碼;2) 過濾掉邏輯結構差或結構極簡的檔案;3) 移除顯著偏離標準程式碼格式的檔案。
可以注意到,當使用 PCA 對比 The Stack V2 和 RefineCode 的 codebert embedding 時,觀察到這兩個資料集之間有明顯的區別。具體而言,在圖 3 中,The Stack V2 資料顯示出更多的離群點,而 RefineCode 的嵌入則更為緊密地聚集。此外,透過對離群資料的分析,OpenCoder 發現這些離群點通常表現出許多低質量的特徵,例如純文字註釋、僅包含十六進位制資料,以及缺乏計算邏輯的極短程式碼,這些特徵會擾亂預訓練資料集的分佈,最終影響預訓練的效率。
OpenCoder 同樣從 Common Crawl 資料集中收集高質量程式碼相關資料,透過三輪 FastText 訓練、召回、手工網頁標註,最終成功獲取了 330G 程式碼相關網頁資料。
OpenCoder 採用了 WSD(Warmup, Steady, Decay)學習率排程策略,以在不同訓練階段中確保模型的穩定性與高效性。在訓練初期,模型透過 2000 步的 warmup 階段逐步提升學習率,達到峰值後進入穩定階段,保持較長時間的固定學習率。最後,在退火階段逐步降低學習率,實現模型的快速精細調優。在退火階段中,除原始分佈 RefineCode 外,OpenCoder 加入了演算法相關語料庫,同時合成了高質量程式碼段與程式碼教科書兩種形式的資料,透過新增演算法相關資料以及對演算法知識進行反覆改寫來進一步增強來提高模型的程式碼邏輯能力。
指令微調階段
1. 資料組成
除開原始碼指令資料 (Evol-Instruct, Infinity-Instruct, MCEVal) 外,OpenCoder 從 wildChat,ShareGPT 中取樣了程式碼相關的真實使用者指令資料。此外研究團隊還獨立合成了大規模多樣指令資料、教育意義指令資料集與外部庫呼叫指令資料集,進一步增強了指令微調資料的質量與多樣性。
2. 兩階段訓練策略
OpenCoder 在指令微調期間使用了兩階段的訓練策略。在微調過程的第一階段,重點是廣泛的真實使用者指令與電腦科學理論相關知識。第一階段的微調使 OpenCoder 能夠理解和響應各種真實的使用者需求。這些指令涵蓋了電腦科學的各個方面,從基礎程式設計到高階演算法設計,再到複雜的資料結構操作。由於涵蓋了廣泛的程式碼相關指令,OpenCoder 在處理不同型別的程式設計問題時表現出卓越的適應性,能夠靈活應對多種場景下的編碼需求。
另一個顯著優勢是提升了模型的泛化能力。面對使用者的不同表述和習慣用語,OpenCoder 能夠快速理解意圖並生成適切的解決方案。這種廣覆蓋的訓練使模型不僅在特定任務上表現出色,還能在多樣化的程式設計需求中提供準確、高效的幫助。
在指令微調的第二階段,OpenCoder 使用高質量的下游任務相關資料進行訓練,確保模型接觸到現實世界中維護良好、格式規範的程式碼例項,且能在具體下游任務中表現出色。這種兩階段的微調方法使模型在理論知識和實際程式設計任務上都表現出色,避免了只關注某一方面的侷限性。
消融分析
1. File-level 去重是程式碼資料去重的最優選擇
OpenCoder 在全量 Github 上 485 百萬個 Python 檔案上進行了 repo-level,file-level 的去重處理,並在相同引數下訓練了兩個 1.5B 大小的 LLM。首先 repo-level 去重保留的 token 數量近乎是 file-level 的三倍,其次從下游資料集效能表現發現 file-level 去重效果顯著優於 repo-level
對於 repo-level 的去重,進一步研究發現約有 52B 檔案存在完全相同的另一份檔案,且約 68B token(約佔資料的 68.4%)可以被進一步 file-level 去重,這說明了 repo-level 去重並不充分。綜上,對於大規模程式碼資料集,首先執行精確去重,其次進行檔案層面的 MinHash 去重是一種高效且節省 CPU 的方案。
2. 高質量合成資料對於效能提升至關重要
在退火階段訓練過程中,研究團隊消融了高質量合成資料的影響。從下游 Benchmark 效能可發現,當高質量訓練資料被移除後,模型效能明顯下降,這表明高質量資料在退火階段具有顯著的有效性。
3. Github Star 數並不是好的過濾標準
從直覺角度講,更高 Star 的程式碼往往具有更清晰的註釋,更優秀的程式碼組織方式。研究團隊訓練了兩個 1.5B 的 LLM,其中一個使用原始資料訓練,另一個則使用 GitHub 星級(星級 >=5)過濾後的資料進行訓練,二者的 Benchmark 表現如下圖所示:
可以發現使用原始資料訓練的 LLM 優於使用過濾資料訓練的 LLM,這一結果與 SantaCoder 的研究結果一致。此外,研究團隊進一步展示了這兩個 LLM 的訓練損失,可以觀察到使用過濾資料訓練的 LLM 的損失低於使用原始資料訓練的 LLM。對此現象,研究團隊推測使用星級作為過濾訊號能夠提升資料質量,但相較於原始資料,資料的多樣性有所限制。透過對二者資料分佈的視覺化分析,團隊進一步驗證了星級過濾顯著影響了整體資料分佈,削弱了資料多樣性這一推斷。
此外,透過人工檢查被過濾部分的資料可以發現其仍包含大量結構良好且具有演算法豐富性的程式碼。因此,研究團隊認為星級作為過濾標準並非最佳選擇。
4. 兩階段 SFT 方法在 Benchmark 和實際應用中取得雙重收益
研究團隊在 1.5B 模型上驗證了兩階段 SFT 的收益。透過觀察發現,Stage 1 的資料展現出顯著的多樣性,但平均質量相對較低。相比之下,Stage 2 的資料由高質量的程式碼特定 SFT 資料組成。該兩階段 SFT 策略使得模型在 Stage 1 中獲得廣泛的能力,隨後在 Stage 2 中針對程式碼相關任務進行針對性提升。此外,類似於 Chatbot Arena,研究團隊採用包含近 400 個人工建立樣本的 Code Arena 測試集,以模擬真實環境中的使用者程式碼相關提示。Code Arena 以 GPT-4 作為基準,並用 GPT-4 來判斷哪個大語言模型(LLM)具有更好的響應能力,報告的結果為相對於 GPT-4 的勝率。結果展示了兩階段 SFT 訓練策略在下游 Benchmark 上與體現真實應用能力的 Code Arena 上皆有收益。
評估結果
OpenCoder 模型在 HumanEval、MBPP 兩主流模型評估任務上顯著超過了現有開源模型,驗證了其資料處理流程與合成資料的有效性。
為了檢驗 OpenCoder 的程式碼生成能力,研究團隊在多個基準上將它與其他流行的開源模型(如 StarCoder2 、Qwen2.5-Coder 等)進行了比較,包括 HumanEval、MBPP、BigCodeBench 和 LiveCodeBench。結果表明,OpenCoder 在這些評估中達到了開源模型的一流水準。
此外,在多語言程式碼生成評估基準 MultiPL-E ,綜合多語言程式碼評估基準 McEval 和多語言程式碼除錯基準 MdEval 中,OpenCoder 表現也同樣突出,證實了其出色的多語言效能。