開發(fā)者狂喜!Meta最新發(fā)布的LLM Compiler,實(shí)現(xiàn)77%自動(dòng)調(diào)優(yōu)效率
三大 AI 巨頭 OpenAI、Google、Meta 組團(tuán)發(fā)布自家大模型最新研究成果 ——
OpenAI 推出基于 GPT-4 訓(xùn)練的專門找 bug 的新模型 CriticGPT,谷歌開源 9B、27B 版 Gemma2,而 Meta 則拿出了一項(xiàng)最新的人工智能突破 ——LLM Compiler。
這是一套強(qiáng)大的開源模型,旨在優(yōu)化代碼并徹底改變編譯器設(shè)計(jì)。這項(xiàng)創(chuàng)新有可能改變開發(fā)者處理代碼優(yōu)化的方式,使其更快、更高效、更經(jīng)濟(jì)。
據(jù)悉,該 LLM Compiler 的優(yōu)化潛力達(dá)到了自動(dòng)調(diào)優(yōu)搜索的 77%,這一結(jié)果可以顯著減少編譯時(shí)間,并提高各種應(yīng)用的代碼效率,并且在反匯編方面,其往返反匯編的成功率為 45%。
有網(wǎng)友表示,這像是代碼優(yōu)化和反匯編的游戲規(guī)則改變者。
這對(duì)于開發(fā)者來說是個(gè)讓人難以置信的好消息。
概述
大語言模型在眾多軟件工程和編程任務(wù)中表現(xiàn)出了卓越的能力,然而它們?cè)诖a優(yōu)化及編譯器領(lǐng)域的應(yīng)用尚未得到充分挖掘。訓(xùn)練這些 LLMs 需要消耗大量的計(jì)算資源,包括昂貴的 GPU 時(shí)間和龐大的數(shù)據(jù)集,這往往使得許多研究和項(xiàng)目難以為繼。
為了彌補(bǔ)這一空白,Meta 研究團(tuán)隊(duì)引入了一種 LLM Compiler,以專門優(yōu)化代碼并徹底改變編譯器設(shè)計(jì)。通過在包含 5460 億個(gè)標(biāo)記的 LLVM-IR 和匯編代碼的龐大語料庫上訓(xùn)練模型,他們使模型能夠理解編譯器中間表示、匯編語言和優(yōu)化技術(shù)。
論文鏈接:https://ai.meta.com/research/publications/meta-large-language-model-compiler-foundation-models-of-compiler-optimization/
研究人員在他們的論文中解釋說:「LLM Compiler 增強(qiáng)了對(duì)編譯器中間表示(IR)、匯編語言和優(yōu)化技術(shù)的理解。」這種增強(qiáng)的理解使模型能夠執(zhí)行以前僅限于人類專家或?qū)I(yè)工具的任務(wù)。
LLM Compiler 的訓(xùn)練流程如圖 1 所示。
LLM Compiler 在代碼大小優(yōu)化方面取得了顯著成果。在測試中,模型的優(yōu)化潛力達(dá)到了自動(dòng)調(diào)優(yōu)搜索的 77%,這一結(jié)果可以顯著減少編譯時(shí)間,并提高各種應(yīng)用的代碼效率。
模型在反匯編方面的能力更為出色。LLM Compiler 在將 x86_64 和 ARM 匯編代碼轉(zhuǎn)換回 LLVM-IR 時(shí),往返反匯編的成功率為 45%(其中 14% 完全匹配)。這種能力對(duì)于逆向工程任務(wù)和舊代碼維護(hù)可能具有無法估量的價(jià)值。
項(xiàng)目的核心貢獻(xiàn)者之一 Chris Cummins 強(qiáng)調(diào)了這項(xiàng)技術(shù)的潛在影響:「通過提供兩種大小的預(yù)訓(xùn)練模型(7 億和 13 億參數(shù))并通過微調(diào)版本展示其有效性,」他說,「LLM Compiler 為探索 LLM 在代碼和編譯器優(yōu)化領(lǐng)域未被開發(fā)的潛力鋪平了道路?!?/span>
用于編譯器優(yōu)化的 Code Llama
在匯編代碼和編譯器 IR 上進(jìn)行預(yù)訓(xùn)練
用于訓(xùn)練編程 LLMs 的數(shù)據(jù)通常主要由像 Python 這樣的高級(jí)源語言組成,匯編代碼在這些數(shù)據(jù)集中的比例微乎其微,編譯器 IR 的比例更小。
為了構(gòu)建一個(gè)對(duì)這些語言有良好理解的 LLM,研究團(tuán)隊(duì)用 Code Llama 的權(quán)重初始化 LLM Compiler 模型,然后在一個(gè)以編譯器為中心的數(shù)據(jù)集上訓(xùn)練 4010 億個(gè) token,這個(gè)數(shù)據(jù)集主要由匯編代碼和編譯器 IR 組成,如表 1 所示。
數(shù)據(jù)集 LLM Compiler 主要在由 LLVM(版本 17.0.6)生成的編譯器中間表示和匯編代碼上進(jìn)行訓(xùn)練,這些數(shù)據(jù)來源于用于訓(xùn)練 Code Llama 的同一數(shù)據(jù)集,已在表 2 中概述了該數(shù)據(jù)集。與 Code Llama 一樣,我們也從自然語言數(shù)據(jù)集中獲取少量訓(xùn)練批次。
編譯器模擬的指令微調(diào)
為了理解代碼優(yōu)化的機(jī)制,研究團(tuán)隊(duì)對(duì) LLM Compiler 模型進(jìn)行指令微調(diào),以模擬編譯器優(yōu)化,如圖 2 所示。
其思路是從有限的未優(yōu)化種子程序集合中,通過對(duì)這些程序應(yīng)用隨機(jī)生成的編譯器優(yōu)化序列,生成大量示例。然后他們訓(xùn)練模型預(yù)測優(yōu)化生成的代碼,還訓(xùn)練模型預(yù)測應(yīng)用優(yōu)化后的代碼大小。
任務(wù)規(guī)范。給定未經(jīng)優(yōu)化的 LLVM-IR(由 clang 前端輸出),一個(gè)優(yōu)化過程列表,以及一個(gè)起始代碼大小,生成應(yīng)用這些優(yōu)化后的結(jié)果代碼以及代碼大小。
這個(gè)任務(wù)有兩種類型:在第一種中,模型預(yù)期輸出編譯器 IR;在第二種中,模型預(yù)期輸出匯編代碼。兩種類型的輸入 IR、優(yōu)化過程和代碼大小是相同的,提示決定了所需的輸出格式。
代碼大小。他們使用兩個(gè)指標(biāo)來衡量代碼大?。篒R 指令數(shù)和二進(jìn)制大小。二進(jìn)制大小通過將 IR 或匯編降級(jí)為目標(biāo)文件后,.TEXT 和 .DATA 段大小的總和計(jì)算得出。我們排除 .BSS 段,因?yàn)樗挥绊懘疟P上的大小。
優(yōu)化 pass。在這項(xiàng)工作中,研究團(tuán)隊(duì)針對(duì) LLVM 17.0.6,并使用新的過程管理器 (PM, 2021),它將 pass 分類為不同的級(jí)別,如模塊、函數(shù)、循環(huán)等,以及轉(zhuǎn)換和分析 pass 。轉(zhuǎn)換 pass 改變給定的輸入 IR,而分析 pass 生成影響后續(xù)轉(zhuǎn)換的信息。
在 opt 的 346 個(gè)可能的 pass 參數(shù)中,他們選擇了 167 個(gè)使用。這包括每個(gè)默認(rèn)優(yōu)化流水線 (例如 module (default<Oz>)),單獨(dú)的優(yōu)化轉(zhuǎn)換 pass (例如 module (constmerge)),但排除了非優(yōu)化實(shí)用程序 pass (例如 module (dot-callgraph)) 和不保留語義的轉(zhuǎn)換 pass (例如 module (internalize))。
他們排除了分析 pass,因?yàn)樗鼈儧]有副作用,我們依賴 pass 管理器根據(jù)需要注入依賴的分析 pass。對(duì)于接受參數(shù)的 pass,我們使用默認(rèn)值 (例如 module (licm<allowspeculation>))。表 9 包含了所有使用的 pass 列表。我們使用 LLVM 的 opt 工具應(yīng)用 pass 列表,并使用 clang 將結(jié)果 IR 降級(jí)為目標(biāo)文件。清單 1 顯示了使用的命令。
數(shù)據(jù)集。研究團(tuán)隊(duì)通過對(duì)表 2 中總結(jié)的未優(yōu)化程序應(yīng)用 1 到 50 個(gè)隨機(jī)優(yōu)化 pass 列表生成編譯器模擬數(shù)據(jù)集。每個(gè) pass 列表的長度是均勻隨機(jī)選擇的。pass 列表是通過從上述 167 個(gè) pass 集合中均勻采樣生成的。導(dǎo)致編譯器崩潰或在 120 秒后超時(shí)的 pass 列表被排除。
LLM Compiler FTD :擴(kuò)展下游編譯任務(wù)
優(yōu)化標(biāo)志調(diào)優(yōu)的指令微調(diào)
操作編譯器標(biāo)志對(duì)運(yùn)行時(shí)性能和代碼大小都有顯著影響。研究團(tuán)隊(duì)訓(xùn)練 LLM Compiler FTD 模型執(zhí)行下游任務(wù),即為 LLVM 的 IR 優(yōu)化工具 opt 選擇標(biāo)志,以生成最小的代碼大小。
標(biāo)志調(diào)優(yōu)的機(jī)器學(xué)習(xí)方法以前已經(jīng)顯示出良好的結(jié)果,但在不同程序之間的泛化方面存在困難。以前的工作通常需要編譯新程序數(shù)十或數(shù)百次,以嘗試不同的配置并找出性能最佳的選項(xiàng)。該研究團(tuán)隊(duì)通過預(yù)測標(biāo)志來最小化未見程序的代碼大小,在這個(gè)任務(wù)的零樣本版本上訓(xùn)練和評(píng)估 LLM Compiler FTD 模型。
他們的方法不依賴于所選擇的編譯器和優(yōu)化指標(biāo),他們打算在未來針對(duì)運(yùn)行時(shí)性能。目前,優(yōu)化代碼大小簡化了訓(xùn)練數(shù)據(jù)的收集。
任務(wù)規(guī)范。研究團(tuán)隊(duì)向 LLM Compiler FTD 模型呈現(xiàn)一個(gè)未優(yōu)化的 LLVM-IR (由 clang 前端生成),并要求它生成應(yīng)該應(yīng)用的 opt 標(biāo)志列表,這些優(yōu)化應(yīng)用前后的二進(jìn)制大小,以及輸出代碼,如果無法對(duì)輸入代碼進(jìn)行改進(jìn),則生成一個(gè)只包含未優(yōu)化二進(jìn)制大小的簡短輸出消息。
他們使用了與編譯器模擬任務(wù)相同的受限優(yōu)化 pass 集,并以相同的方式計(jì)算二進(jìn)制大小。
圖 3 說明了用于生成訓(xùn)練數(shù)據(jù)的過程以及如何在推理時(shí)使用模型。
在評(píng)估時(shí)只需要生成的 pass 列表。他們從模型輸出中提取 pass 列表,并使用給定的參數(shù)運(yùn)行 opt。然后,研究人員可以評(píng)估模型預(yù)測的二進(jìn)制大小和優(yōu)化輸出代碼的準(zhǔn)確性,但這些是輔助學(xué)習(xí)任務(wù),不是使用所必需的。
正確性。LLVM 優(yōu)化器并非無懈可擊,以意外或未經(jīng)測試的順序運(yùn)行優(yōu)化 pass 可能會(huì)暴露出微妙的正確性錯(cuò)誤,從而降低模型的實(shí)用性。為了緩解這種風(fēng)險(xiǎn),研究團(tuán)隊(duì)開發(fā)了 PassListEval,這是一個(gè)工具,用于幫助自動(dòng)識(shí)別破壞程序語義或?qū)е戮幾g器崩潰的 pass 列表。圖 4 顯示了該工具的概覽。
PassListEval 接受候選 pass 列表作為輸入,并在一個(gè)包含 164 個(gè)自測試 C++ 程序的套件上對(duì)其進(jìn)行評(píng)估,這些程序取自 HumanEval-X。每個(gè)程序都包含一個(gè)編程挑戰(zhàn)的參考解決方案,例如「檢查給定數(shù)字向量中是否有兩個(gè)數(shù)字之間的距離小于給定閾值」,以及驗(yàn)證正確性的單元測試套件。他們將候選 pass 列表應(yīng)用于參考解決方案,然后將它們與測試套件鏈接以生成二進(jìn)制文件。執(zhí)行時(shí),如果任何測試失敗,二進(jìn)制文件將崩潰。如果任何二進(jìn)制崩潰,或者任何編譯器調(diào)用失敗,我們就拒絕該候選 pass 列表。
數(shù)據(jù)集。該團(tuán)隊(duì)在一個(gè)源自 450 萬個(gè)未優(yōu)化 IR 的標(biāo)志調(diào)優(yōu)示例數(shù)據(jù)集上訓(xùn)練了 LLM Compiler FTD 模型,這些 IR 用于預(yù)訓(xùn)練。為生成每個(gè)程序的最佳 pass 列表示例,他們進(jìn)行了廣泛的迭代編譯過程,如圖 3 所示。
1. 研究團(tuán)隊(duì)使用大規(guī)模隨機(jī)搜索為程序生成初始候選最佳 pass 列表。對(duì)每個(gè)程序,他們獨(dú)立生成最多 50 個(gè) pass 的隨機(jī)列表,從之前描述的 167 個(gè)可搜索 pass 集合中均勻采樣。每次他們?cè)u(píng)估一個(gè)程序的 pass 列表時(shí),都記錄生成的二進(jìn)制大小,然后選擇產(chǎn)生最小二進(jìn)制大小的每個(gè)程序 pass 列表。他們運(yùn)行了 220 億次獨(dú)立編譯,平均每個(gè)程序 4,877 次。
2. 隨機(jī)搜索生成的 pass 列表可能包含冗余 pass,這些 pass 對(duì)最終結(jié)果沒有影響。此外,一些 pass 順序是可交換的,重新排序不會(huì)影響最終結(jié)果。由于這些會(huì)在訓(xùn)練數(shù)據(jù)中引入噪聲,他們開發(fā)了一個(gè)最小化過程,并將其應(yīng)用于每個(gè) pass 列表。
最小化包括三個(gè)步驟:冗余 pass 消除、冒泡排序和插入搜索。在冗余 pass 消除中,他們通過迭代刪除單個(gè) pass 來最小化最佳 pass 列表,看它們是否對(duì)二進(jìn)制大小有貢獻(xiàn),如果沒有,就丟棄它們。重復(fù)此過程,直到不能再丟棄 pass。然后冒泡排序嘗試為 pass 子序列提供統(tǒng)一排序,根據(jù)關(guān)鍵字對(duì) pass 進(jìn)行排序。最后,插入排序通過遍歷 pass 列表中的每個(gè) pass 并嘗試在其之前插入 167 個(gè)搜索 pass 中的每一個(gè)來執(zhí)行局部搜索。如果這樣做改善了二進(jìn)制大小,就保留這個(gè)新的 pass 列表。整個(gè)最小化管道循環(huán)直到達(dá)到固定點(diǎn)。最小化后的 pass 列表長度分布如圖 9 所示。平均 pass 列表長度為 3.84。
3. 他們將之前描述過 PassListEval 應(yīng)用于候選最佳 pass 列表。通過這種方式,他們確定了 1,704,443 個(gè)獨(dú)立 pass 列表中的 167,971 個(gè) (9.85%) 會(huì)導(dǎo)致編譯時(shí)或運(yùn)行時(shí)錯(cuò)
4. 他們將 100 個(gè)最常見的最優(yōu) pass 列表廣播到所有程序,如果發(fā)現(xiàn)改進(jìn)就更新每個(gè)程序的最佳 pass 列表。之后,唯一最佳 pass 列表的總數(shù)從 1,536,472 減少到 581,076。
上述自動(dòng)調(diào)優(yōu)管道相比 -Oz 產(chǎn)生了 7.1% 的幾何平均二進(jìn)制大小減少。圖 10 顯示了單個(gè) pass 的頻率。對(duì)他們來說,這種自動(dòng)調(diào)優(yōu)作為每個(gè)程序優(yōu)化的黃金標(biāo)準(zhǔn)。雖然發(fā)現(xiàn)的二進(jìn)制大小節(jié)省很顯著,但這需要 280 億次額外編譯,計(jì)算成本超過 21,000 個(gè) CPU 天。對(duì) LLM Compiler FTD 進(jìn)行指令微調(diào)以執(zhí)行標(biāo)志調(diào)優(yōu)任務(wù)的目標(biāo)是在不需要運(yùn)行編譯器數(shù)千次的情況下達(dá)到自動(dòng)調(diào)優(yōu)器性能的一部分。
反匯編的指令微調(diào)
將代碼從匯編語言提升到更高層次的結(jié)構(gòu),可以運(yùn)行額外的優(yōu)化,例如直接集成到應(yīng)用程序代碼中的庫代碼,或者將遺留代碼移植到新架構(gòu)。反編譯領(lǐng)域在將機(jī)器學(xué)習(xí)技術(shù)應(yīng)用于從二進(jìn)制可執(zhí)行文件生成可讀和準(zhǔn)確的代碼方面取得了進(jìn)展。在本研究中,研究團(tuán)隊(duì)展示了 LLM Compiler FTD 如何通過微調(diào)進(jìn)行反匯編,學(xué)習(xí)匯編代碼和編譯器 IR 之間的關(guān)系。任務(wù)是學(xué)習(xí) clang -xir - -o - -S 的逆向翻譯,如圖 5 所示。
往返測試。使用 LLM 進(jìn)行反匯編會(huì)導(dǎo)致正確性問題。提升的代碼必須通過等價(jià)性檢查器進(jìn)行驗(yàn)證,這并不總是可行的,或者需要手動(dòng)驗(yàn)證正確性,或經(jīng)過充分的測試用例以獲得信心。然而,可以通過往返測試找到正確性的下限。也就是說,通過將提升的 IR 重新編譯成匯編代碼,如果匯編代碼是相同的,則 IR 是正確的。這為使用 LLM 的結(jié)果提供了一條簡單途徑,并且是衡量反匯編模型效用的一種簡單方法。
任務(wù)規(guī)范。研究團(tuán)隊(duì)向模型提供匯編代碼,并訓(xùn)練它發(fā)出相應(yīng)的反匯編 IR。這項(xiàng)任務(wù)的上下文長度設(shè)置為輸入?yún)R編代碼 8k 個(gè) token 和輸出 IR8k 個(gè) token。
數(shù)據(jù)集。他們從之前任務(wù)中使用的數(shù)據(jù)集中派生出匯編代碼和 IR 對(duì)。他們的微調(diào)數(shù)據(jù)集包含 470 萬個(gè)樣本,輸入 IR 在降低到 x86 匯編之前已經(jīng)使用 - Oz 進(jìn)行了優(yōu)化。
訓(xùn)練參數(shù)
數(shù)據(jù)通過字節(jié)對(duì)編碼進(jìn)行標(biāo)記化,使用與 Code Llama、Llama 和 Llama 2 相同的標(biāo)記器。他們對(duì)所有四個(gè)訓(xùn)練階段使用相同的訓(xùn)練參數(shù)。他們使用的大部分訓(xùn)練參數(shù)與 Code Llama 基礎(chǔ)模型相同,使用 AdamW 優(yōu)化器,β1 和 β2 的值為 0.9 和 0.95。他們使用余弦調(diào)度,預(yù)熱步驟為 1000 步,并將最終學(xué)習(xí)率設(shè)置為峰值學(xué)習(xí)率的 1/30。
與 Code Llama 基礎(chǔ)模型相比,該團(tuán)隊(duì)將單個(gè)序列的上下文長度從 4096 增加到 16384,但保持批量大小恒定為 400 萬個(gè) token。為了適應(yīng)更長的上下文,他們將學(xué)習(xí)率設(shè)置為 2e-5,并修改了 RoPE 位置嵌入的參數(shù),其中他們將頻率重置為基本值 θ=10^6。這些設(shè)置與 Code Llama 基礎(chǔ)模型進(jìn)行的長上下文訓(xùn)練一致。
評(píng)估
該研究團(tuán)隊(duì)評(píng)估 LLM Compiler 模型在標(biāo)志調(diào)優(yōu)和反匯編任務(wù)、編譯器模擬、下一個(gè) token 預(yù)測以及軟件工程任務(wù)上的表現(xiàn)。
標(biāo)志調(diào)優(yōu)任務(wù)
方法。他們?cè)u(píng)估 LLM Compiler FTD 在未見程序的優(yōu)化標(biāo)志調(diào)優(yōu)任務(wù)上的表現(xiàn),并與 GPT-4 Turbo 和 Code Llama - Instruct 進(jìn)行比較。他們對(duì)每個(gè)模型運(yùn)行推理,從模型輸出中提取優(yōu)化 pass 列表,然后他們使用這個(gè) pass 列表來優(yōu)化特定程序并記錄二進(jìn)制大小,基線是使用 -Oz 優(yōu)化時(shí)程序的二進(jìn)制大小。
對(duì)于 GPT-4 Turbo 和 Code Llama - Instruct,他們?cè)谔崾竞蟾郊右粋€(gè)后綴,提供額外上下文以進(jìn)一步描述問題和預(yù)期輸出格式。
所有模型生成的 pass 列表都使用 PassListEval 進(jìn)行驗(yàn)證,如果驗(yàn)證失敗則使用 -Oz 作為替代。為進(jìn)一步驗(yàn)證模型生成的 pass 列表的正確性,他們鏈接最終的程序二進(jìn)制文件,并將其輸出與使用保守的 -O2 優(yōu)化管道優(yōu)化的基準(zhǔn)輸出進(jìn)行差分測試。
數(shù)據(jù)集。研究團(tuán)隊(duì)使用從 MiBench 基準(zhǔn)套件提取的 2,398 個(gè)測試提示進(jìn)行評(píng)估。為生成這些提示,他們?nèi)?gòu)成 24 個(gè) MiBench 基準(zhǔn)的所有 713 個(gè)翻譯單元,并從每個(gè)單元生成未優(yōu)化的 IR,然后將它們格式化為提示。如果生成的提示超過 15k tokens,他們使用 llvm-extract 將代表該翻譯單元的 LLVM 模塊分割成更小的模塊,每個(gè)函數(shù)一個(gè),這導(dǎo)致 1,985 個(gè)提示適合 15k token 上下文窗口,剩下 443 個(gè)翻譯單元不適合。在計(jì)算性能分?jǐn)?shù)時(shí),他們對(duì) 443 個(gè)被排除的翻譯單元使用 -Oz。表 10 總結(jié)了基準(zhǔn)。
結(jié)果。表 3 顯示了所有模型在標(biāo)志調(diào)優(yōu)任務(wù)上的零樣本性能。只有 LLM Compiler FTD 模型比 -Oz 有所改進(jìn),13B 參數(shù)模型略優(yōu)于較小的模型,在 61% 的情況下生成比 -Oz 更小的目標(biāo)文件。
在某些情況下,模型生成的 pass 列表導(dǎo)致比 -Oz 更大的目標(biāo)文件大小。例如,LLM Compiler FTD 13B 在 12% 的情況下有退化。這些退化可以通過簡單地編譯程序兩次來避免:一次使用模型生成的 pass 列表,一次使用 -Oz,然后選擇產(chǎn)生最佳結(jié)果的 pass 列表。通過消除相對(duì)于 -Oz 的退化,這些 -Oz 備份分?jǐn)?shù)將 LLM Compiler FTD 13B 相對(duì)于 -Oz 的總體改進(jìn)提高到 5.26%,并使 Code Llama - Instruct 和 GPT-4 Turbo 相對(duì)于 -Oz 有適度的改進(jìn)。圖 6 顯示了每個(gè)模型在各個(gè)基準(zhǔn)上的性能細(xì)分。
二進(jìn)制大小準(zhǔn)確性。雖然模型生成的二進(jìn)制大小預(yù)測對(duì)實(shí)際編譯沒有影響,但研究團(tuán)隊(duì)可以評(píng)估模型在預(yù)測優(yōu)化前后的二進(jìn)制大小方面的性能,以了解每個(gè)模型對(duì)優(yōu)化的理解程度。圖 7 顯示了結(jié)果。
LLM Compiler FTD 的二進(jìn)制大小預(yù)測與實(shí)際情況相關(guān)性良好,7B 參數(shù)模型對(duì)未優(yōu)化和優(yōu)化的二進(jìn)制大小分別達(dá)到了 0.083 和 0.225 的 MAPE 值。13B 參數(shù)模型的 MAPE 值相似,分別為 0.082 和 0.225。Code Llama - Instruct 和 GPT-4 Turbo 的二進(jìn)制大小預(yù)測與實(shí)際情況幾乎沒有相關(guān)性。研究人員注意到,LLM Compiler FTD 對(duì)優(yōu)化代碼的錯(cuò)誤略高于未優(yōu)化代碼。特別是 LLM Compiler FTD 偶爾有高估優(yōu)化效果的趨勢(shì),導(dǎo)致預(yù)測的二進(jìn)制大小低于實(shí)際情況。
消融研究。表 4 對(duì)模型在 500 個(gè)提示的小型保留驗(yàn)證集上的性能進(jìn)行了消融研究,這些提示來自與他們訓(xùn)練數(shù)據(jù)相同的分布 (但未在訓(xùn)練中使用)。他們?cè)趫D 1 所示訓(xùn)練管道的每個(gè)階段進(jìn)行標(biāo)志調(diào)優(yōu)訓(xùn)練,以比較性能。如圖所示,反匯編訓(xùn)練導(dǎo)致性能從平均 5.15% 略微下降到 5.12%(相對(duì)于 -Oz 的改進(jìn))。他們還展示了用于生成第 2 節(jié)所述訓(xùn)練數(shù)據(jù)的自動(dòng)調(diào)優(yōu)器的性能。LLM Compiler FTD 達(dá)到了自動(dòng)調(diào)優(yōu)器 77% 的性能。
反匯編任務(wù)
方法。研究團(tuán)隊(duì)評(píng)估 LLM 生成的代碼在將匯編代碼反匯編到 LLVM-IR 時(shí)的功能正確性。他們?cè)u(píng)估 LLM Compiler FTD 并與 Code Llama - Instruct 和 GPT-4 Turbo 進(jìn)行比較,發(fā)現(xiàn)需要額外的提示后綴才能從這些模型中提取最佳性能。
后綴提供了關(guān)于任務(wù)和預(yù)期輸出格式的額外上下文。為評(píng)估模型的性能,他們將模型生成的反匯編 IR 往返降級(jí)回匯編。這使我們能夠通過比較原始匯編與往返結(jié)果的 BLEU 分?jǐn)?shù)來評(píng)估反匯編的準(zhǔn)確性。從匯編到 IR 的無損完美反匯編將有 1.0 的往返 BLEU 分?jǐn)?shù) (精確匹配)。
數(shù)據(jù)集。他們使用從 MiBench 基準(zhǔn)套件提取的 2,015 個(gè)測試提示進(jìn)行評(píng)估,取用于上述標(biāo)志調(diào)優(yōu)評(píng)估的 2,398 個(gè)翻譯單元,生成反匯編提示。然后他們根據(jù)最大 8k token 長度過濾提示,允許 8k tokens 用于模型輸出,剩下 2,015 個(gè)。表 11 總結(jié)了基準(zhǔn)。
結(jié)果。表 5 顯示了模型在反匯編任務(wù)上的性能。
LLM Compiler FTD 7B 的往返成功率略高于 LLM Compiler FTD 13B,但 LLM Compiler FTD 13B 具有最高的往返匯編準(zhǔn)確性 (往返 BLEU) 和最頻繁產(chǎn)生完美反匯編 (往返精確匹配)。Code Llama - Instruct 和 GPT-4 Turbo 在生成語法正確的 LLVM-IR 方面存在困難。圖 8 顯示了所有模型的往返 BLEU 分?jǐn)?shù)分布。
消融研究。表 6 對(duì)模型在 500 個(gè)提示的小型保留驗(yàn)證集上的性能進(jìn)行了消融研究,這些提示取自之前使用的 MiBench 數(shù)據(jù)集。
他們?cè)趫D 1 所示訓(xùn)練管道的每個(gè)階段進(jìn)行反匯編訓(xùn)練,以比較性能。往返率在通過整個(gè)訓(xùn)練數(shù)據(jù)堆棧時(shí)最高,并隨每個(gè)訓(xùn)練階段持續(xù)下降,盡管往返 BLEU 在每個(gè)階段變化不大。
基礎(chǔ)模型任務(wù)
方法。該研究團(tuán)隊(duì)在下一個(gè) token 預(yù)測和編譯器模擬兩個(gè)基礎(chǔ)模型任務(wù)上對(duì) LLM Compiler 模型進(jìn)行消融研究。他們?cè)谟?xùn)練管道的每個(gè)階段進(jìn)行這種評(píng)估,以了解為每個(gè)連續(xù)任務(wù)訓(xùn)練如何影響性能。對(duì)于下一個(gè) token 預(yù)測,他們?cè)谒袃?yōu)化級(jí)別的 LLVM-IR 和匯編代碼的小樣本上計(jì)算困惑度。他們使用兩個(gè)指標(biāo)評(píng)估編譯器模擬:生成的 IR 或匯編代碼是否編譯,以及生成的 IR 或匯編代碼是否與編譯器產(chǎn)生的完全匹配。
數(shù)據(jù)集。對(duì)于下一個(gè) token 預(yù)測,他們使用從與我們訓(xùn)練數(shù)據(jù)相同分布但未用于訓(xùn)練的小型保留驗(yàn)證數(shù)據(jù)集。他們使用混合的優(yōu)化級(jí)別,包括未優(yōu)化代碼、用 -Oz 優(yōu)化的代碼和隨機(jī)生成的 pass 列表。對(duì)于編譯器模擬,他們使用從 MiBench 生成的 500 個(gè)提示進(jìn)行評(píng)估,這些提示使用第 2.2 節(jié)描述的方式隨機(jī)生成的 pass 列表。
結(jié)果。表 7 顯示了 LLM Compiler FTD 在所有訓(xùn)練階段在兩個(gè)基礎(chǔ)模型訓(xùn)練任務(wù) (下一個(gè) token 預(yù)測和編譯器模擬) 上的性能。下一個(gè) token 預(yù)測性能在 Code Llama 之后急劇上升,后者幾乎沒有見過 IR 和匯編,并在隨后的每個(gè)微調(diào)階段略有下降。
對(duì)于編譯器模擬,Code Llama 基礎(chǔ)模型和預(yù)訓(xùn)練模型表現(xiàn)不佳,因?yàn)樗鼈儧]有在這個(gè)任務(wù)上訓(xùn)練過。在編譯器模擬訓(xùn)練之后直接達(dá)到最高性能,其中 LLM Compiler FTD 13B 生成的 95.6% 的 IR 和匯編可以編譯,20% 與編譯器完全匹配。在進(jìn)行標(biāo)志調(diào)優(yōu)和反匯編微調(diào)后,性能下降。
軟件工程任務(wù)
方法。雖然 LLM Compiler FTD 的目的是為代碼優(yōu)化提供基礎(chǔ)模型,但它建立在為軟件工程任務(wù)訓(xùn)練的基礎(chǔ) Code Llama 模型之上。為評(píng)估 LLM Compiler FTD 的額外訓(xùn)練如何影響代碼生成的性能,他們使用與 Code Llama 相同的基準(zhǔn)套件,評(píng)估 LLM 從自然語言提示生成 Python 代碼的能力,如「編寫一個(gè)函數(shù),找出可以從給定的對(duì)集合形成的最長鏈?!?/span>
數(shù)據(jù)集。他們使用 HumanEval 和 MBPP 基準(zhǔn),與 Code Llama 相同。
結(jié)果。表 8 顯示了從 Code Llama 基礎(chǔ)模型開始的所有模型訓(xùn)練階段和模型大小的貪婪解碼性能 (pass@1)。它還顯示了模型在 pass@10 和 pass@100 上的分?jǐn)?shù),這些分?jǐn)?shù)是用 p=0.95 和 temperature=0.6 生成的。每個(gè)以編譯器為中心的訓(xùn)練階段都導(dǎo)致 Python 編程能力略有退化。在 HumanEval 和 MBPP 上,LLM Compiler 的 pass@1 性能最多下降 18% 和 5%,LLM Compiler FTD 在額外的標(biāo)志調(diào)優(yōu)和反匯編微調(diào)后最多下降 29% 和 22%。所有模型在這兩個(gè)任務(wù)上仍然優(yōu)于 Llama 2。
局限性
Meta 研究團(tuán)隊(duì)已經(jīng)展示了 LLM Compiler 在編譯器優(yōu)化任務(wù)上表現(xiàn)良好,并且相比先前的工作,對(duì)編譯器表示和匯編代碼的理解有所改進(jìn),但仍存在一些局限性。主要限制是輸入的有限序列長度 (上下文窗口)。
LLM Compiler 支持 16k tokens 的上下文窗口,但程序代碼可能遠(yuǎn)遠(yuǎn)超過這個(gè)長度。例如,當(dāng)格式化為標(biāo)志調(diào)優(yōu)提示時(shí),67% 的 MiBench 翻譯單元超過了這個(gè)上下文窗口,如表 10 所示。
為了緩解這一問題,他們將較大的翻譯單元拆分為單獨(dú)的函數(shù),盡管這限制了可以執(zhí)行的優(yōu)化范圍,而且仍有 18% 的拆分翻譯單元對(duì)模型來說太大,無法作為輸入接受。研究人員正在采用不斷增加的上下文窗口,但有限的上下文窗口仍然是 LLM 的一個(gè)普遍問題。
第二個(gè)限制,也是所有 LLM 的共同問題,是模型輸出的準(zhǔn)確性。建議 LLM Compiler 的用戶使用特定于編譯器的評(píng)估基準(zhǔn)來評(píng)估他們的模型。鑒于編譯器并非無 bug,任何建議的編譯器優(yōu)化都必須經(jīng)過嚴(yán)格測試。當(dāng)模型反編譯匯編代碼時(shí),其準(zhǔn)確性應(yīng)通過往返、人工檢查或單元測試來確認(rèn)。對(duì)于某些應(yīng)用,LLM 生成可以被限制在正則表達(dá)式內(nèi),或與自動(dòng)驗(yàn)證相結(jié)合以確保正確性。