作者 | Glenn Engstrand
譯者 | 平川
策劃 | Tina
本文要點
- 為了幫助理解當前的 LLM 工具是否可以幫助程式設計師提高生產力,我們進行了一個實驗,並使用經過改進的單元測試代碼覆蓋率作為一個客觀度量指標。
- 我們在這個實驗中選擇了多種免費的 LLM:ChatGPT、CodeWhisperer、codellama:34b、codellama:70b 和 Gemini。它們都是免費的,這也是 Github Copilot 不在這個列表上的原因。
- 我們設計了一個實驗,用於測試上述幾種 LLM 為已經完成編碼的重要 Web 服務生成單元測試的能力。對於上面提到的每一種 LLM,我們都提供同樣的問題和提示。然後,我們將輸出與現有的開源項目結合起來,編譯並運行單元測試。為了再次構建的時候能夠通過,我們需要保存所有的修改記錄。
- 如果沒有人類監督和干預,則沒有一個 LLM 能夠成功地執行任務。不過,許多 LLM 都能夠在一定程度上加速單元測試的編碼過程。
從 OpenAI 發布 ChatGPT 至今尚不足兩年。這是第一個公開發布的基於生成式預訓練轉換器的主流大語言模型,而且簡單易用。
從華爾街到白宮,人們都為它的發布感到興奮不已。幾乎每一家財富 500 強公司和科技初創公司都在設法弄清楚如何利用 LLM。開發生態系統中湧現了很多支持工具和基礎設施,如 Lang Chain,加快了現有應用程式與 LLM 的集成速度。
在最近于丹佛舉行的一次技術會議上,Eric Evans(領域驅動設計的創建者)「鼓勵大家現在就開始學習 LLM 並進行實驗,然後與社區分享實驗的結果和經驗。」
本文記錄了我個人在這方面的貢獻。這項研究不是基於我前僱主或現僱主的任何要求或指示。
實 驗
我決定做一個實驗,在每個比較流行的 LLM 上進行實驗,然後對它們進行比較,探索 LLM 的能力界限(至少短期內如此)。我對 LLM 將如何取代程式設計師並不感興趣,也不擔心。在使用 LLM 時,我們仍然需要有經驗的開發人員,因為需要特別慎重地審查它提供的建議。我更感興趣的是 LLM 如何通過自動化編寫代碼中比較耗時、瑣碎但仍然非常重要的部分,來幫助編碼人員提高生產力。當然,我指的是單元測試。
許多人會說,單元測試不是使用 LLM 的好地方,因為理論上,在測試驅動開發中,首先編寫的是測試,然後才是代碼。不過,我在很多公司都有過這樣的經歷,單元測試幾乎總是到最後才考慮,測試所覆蓋的代碼量與衝刺剩餘的時間成正比。如果編碼人員可以用 LLM 更快地編寫更多的單元測試,那麼就會有更高的代碼覆蓋率和代碼質量。我仿佛聽到 TDD 的死忠分子已在怒火中燒。很抱歉,但這就是冷酷無情的事實。此外,如果不首先了解實現的內部細節,又如何在測試中模擬外部依賴關係呢?
我有一個開源存儲庫,其中我用各種程式語言和技術棧實現了相同的微服務。每個實現都包括對 MySql 前端 Redis 的訪問。為了進行比較,我對每個微服務做了同樣的負載測試,並收集、分析了性能數據。我借用了 Java on Spring Boot 實現中的一個服務類,只保留其中三個可路由的 public 方法。然後,我取出單元測試代碼並刪除了所有單元測試,只保留了其中一個。我保留了導入、設置和基於註解的依賴注入。在提示中,我要求另外生成兩個單元測試。整個提示的長度為 250 行(約 1300 個單詞)。我為什麼使用 Java on Spring Boot 呢?因為網上有很多現成的代碼,而且沒有許可限制,可以作為 LLM 的部分訓練數據。在很大程度上,Spring Boot 所採用的方法是基於註解的,與簡單地研究代碼本身相比,這需要更深入的理解。
我把這個問題當作一個科學實驗來處理,但這並不是一個很好的實驗。實驗只有在可復現的情況下才有價值,但我所評估的所有這些技術都在不斷發展,擁有這些技術的組織在這些產品上花了很多錢進行創新,希望可以改進它們。如果你今天做同樣的實驗,大機率得不到相同的結果。儘管如此,我還是保留了一份我在這個過程中使用的提示,如果你感興趣,可以試一下。
OpenAI ChatGPT
2022 年底,ChatGPT 將基於轉換器的大語言模型和 OpenAI 帶到了媒體的聚光燈下。因此,我的這個實驗中必須包含 ChatGPT。最初,ChatGPT 有許多問題:上下文窗口小,輸出質量低,忘記提示,產生自信的幻覺。它現在已經好很多了。像這裡評估的所有其他技術一樣,我使用的是免費版本。在使用這些商業化的 LLM 時,人們擔心提示會泄露專有信息。這就是為什麼我基於開源版本進行實驗。不會泄露什麼專有的東西。提示泄漏是不可避免的,因為你提供的提示是用於對 LLM 進行調優,隨著時間的推移,LLM 的答案質量將越來越高。
ChatGPT 的表現如何?它做得不錯。對結果的解釋簡明準確。輸出是有用的,但它確實有 Bug,特別是在依賴注入和模擬(mocking)方面。測試覆蓋率也還可以。單元測試代碼有針對單個屬性的斷言、未找到及不為空。即使有 Bug,我仍然認為它的輸出是有用的,因為我覺得自己輸入代碼比修復生成代碼中的錯誤花費的時間更多。
Amazon CodeWhisperer
我用這種方式評估的下一項技術是 Amazon CodeWhisperer。這是一個 Visual Studio Code 插件。總的來說,它的語句補全功能更好。你開始輸入,它就會幫你補全這一行。有時,它可以完成一個代碼塊。然後,你可以選擇接受或拒絕更改建議。大多數時候,我都接受更改,然後進行必要的修改,消除它生成的代碼中的任何錯誤。我覺得使用 CodeWhisperer 生產力最高。
我認為,CodeWhisperer 在方法上與 Github Copilot 類似。因為 Github Copilot 需要付費,所以我沒有評估。CodeWhisperer 是免費的。對於 CodeWhisperer 的內部機制,亞馬遜守口如瓶。它可能不僅僅是一個 LLM,但它確實給人 LLM 的感覺。我懷疑 CodeWhisperer 一直在和伺服器通信,因為 IDE 經常會卡住。禁用 CodeWhisperer,IDE 就又可以正常響應了。
Code Llama
Ollama 是一個開源平台,允許你構建和運行 LLM。它提供了大量經過預訓練的開源模型,其中包括 Meta 的 Code Llama 模型。人們對這些開源 LLM 很感興趣。去年,在加州大學洛杉磯分校的一次峰會上,著名風險投資家 Bill Gurley 指出,Llama 2(包含在 Ollama 的模型庫中)是 OpenAI 最大的威脅。還記得我之前提到的提示泄漏問題嗎?因為你將 Ollama 託管在直接由你控制的 VM 上,所以提示泄漏的可能性很小。
雖然不是必需的,但你肯定希望在 GPU 還算說得過去的系統上運行它。我的個人筆記本電腦上沒有 GPU,所以我使用了谷歌雲平台提供的 a2-highgpu-1g VM,並在上面配置了一個帶有 CUDA 系統的機器學習 Linux 來運行測試。更具體地說,我使用了 codellama:34b 模型。根據 Meta 介紹該模型的博文,「Code Llama 是 Llama 2 的代碼專用版本,它是通過在專門的代碼數據集上做進一步訓練而創建的,從同一數據集中做了更多的數據採樣,而且時間更長。本質上講,Code Llama 是在 Llama 2 的基礎上增強了編碼能力。」我在 NVIDIA A100 40GB 上使用 codelama:70b 運行了相同的測試,並且確實看到,所生成代碼的代碼覆蓋率略有提高。在撰寫本文時,該實例的成本為每小時 3.67 美元。
結果比 ChatGPT 稍微差一點,但不算太壞。它會報編譯錯誤,缺少包和導入,存在 mocking 和依賴注入 Bug。在 34b 模型中,唯一的代碼覆蓋是不為空斷言。在 70b 模型中,這被一個新的斷言所取代。新斷言會匹配從服務調用返回的內容與在底層 DAO 調用模擬中注入的內容。Code Llama 提供的結果中沒有任何說明性文字或在線參考資料。它生成的輸出確實包含沒有多少價值的代碼注釋。
Google Gemini
我在實驗中使用的最後一個 LLM 是 Gemini(之前的 Bard)。與 Code Llama 一樣,它生成的輸出忽略了包聲明或輸入中可用的導入。這很容易解決。我不確定這是一個錯誤,還是僅僅針對我提的問題給出的不同解釋。與所有基於聊天的技術一樣,其輸出在依賴注入和模擬代碼方面也存在類似的 Bug。它的代碼覆蓋率稍微好一點,因為它還有針對緩存命中和緩存未命中的測試。它的說明性文字比 ChatGPT 稍微好一點,它引用了自己使用最多的源,而不是作為實驗中所有代碼來源的開源存儲庫。這很有用,和 ChatGPT 的方法一樣有用。與從頭開始編寫這兩個方法相比,修復 Bug 花費的時間會少一些。
小 結
對於像軟體質量這樣主觀的東西,要進行準確可靠的數值度量是相當具有挑戰性的。在下表中,我嘗試用數值這種便於比較的方式來匯總我的發現。對於生成的單元測試,我使用 Myers Diff 算法來度量修復代碼(你肯定要修復生成的代碼)所需添加和刪除的代碼行數(修改一個代碼行視為添加一行和刪除一行)。Jacoco 代碼覆蓋率是由單元測試覆蓋的指令(比如 Java 位元組碼)除以指令總數(覆蓋的和未覆蓋的)得出的百分比。
基於 LLM 生成單元測試的實驗結果匯總:
顯然,從這些實驗中可以看出,在任何單元測試代碼的生成過程中都沒有通用人工智慧的參與。它們對基於註解的依賴注入和 mock 沒有任何專業級的理解。這讓我清楚地認識到,其背後並沒有什麼非常智能的東西。很簡單,LLM 對大量文檔進行編碼,對輸入做詞法分析,並根據其結構以基於轉換器的有大量權重的神經網絡的形式(即模型)捕獲該輸入的上下文。
當我們提出問題(比如編碼任務)時,該模型通過預測輸入最可能的下文或補全輸入來生成響應。它考慮輸入提供的上下文,並生成連貫、有意義且符合上下文但不一定正確的響應。這樣來看的話,你可以將 LLM 視為一種複雜的上下文搜索形式(儘管比 Web 搜尋引擎或 Lucene circa 2020 的搜索機制更複雜)。
在這個實驗中,我發現 LLM 具有非常好的代碼搜索功能,對於經驗豐富的開發人員來說,這非常有用。對於 ChatGPT、Ollama 和 Gemini,令我失望的是,我希望聊天窗口的另一端有人類智慧的期望落空了。但是,對於語句補全,我沒有這樣的期待。CodeWhisperer 沒有讓人失望,不是因為這個 AI 更好,而是因為其用戶體驗在管理用戶期望方面做得更好。
未來展望
單元測試代碼補全類的生成式人工智慧在退出實驗階段進入生產應用之前,可能還需要解決一些企業關注的問題。
我已經討論過提示泄漏。對於企業來說,這是一個大問題,因為公司的許多代碼需要包含在提示中,而通常,大多數公司認為他們的代碼是專有的。如果提示沒有返回到與其他公司共享的模型實例中,那麼就不必擔心提示會泄露給其他公司。一種選擇是在本地運行 LLM(如 Ollama),這就要求為每個開發人員配備的機器都具有足夠強大的 GPU。另一種選擇是訂閱 ChatGPT 或 Gemini 的單租戶非共享版本。還有一種選擇是完全關閉提示驅動的模型微調。第三種選擇目前已可以選用,但第二種還不可以。
另一個擔憂是成本。我懷疑,如今的生成式人工智慧定價側重於增加市場份額,尚未涵蓋所有成本。為了從增長轉向盈利,價格將不得不上漲。我在上文 Code Llama 一節中提到的 NVIDIA A100 40GB 現如今的價格約為 10000 美元左右。還有電力消耗的問題。這一領域還在不斷創新,但通常情況下,GPU 的功耗大約是 CPU 的三倍。單租戶的方法更安全,但也更昂貴,因為供應商無法從構建基礎模型之外的規模經濟中獲益。生產力的提高微乎其微。成本將成為長期使用的一個考量因素。
正如我之前提到的,這個領域發展迅速。大部分實驗我都是在 2024 年初做的。從那以後,Amazon CodeWhisperer 又升級了他們的產品。ChatGPT 和 Gemini 的一些早期版本都支持 IntelliJ 和 VS Code 插件。Meta 發布了 Llama 3,是的,它已經在 Ollama 中提供。明年這個時候這個領域會有怎樣的發展呢?在產品植入、戰略定位、政府監管、員工干擾、供應商輸贏方面,誰又能說得清呢?會有 AGI 嗎?不會。
原文連結:
https://www.infoq.com/articles/llm-productivity-experiment/
德國再次擁抱Linux:數萬系統從windows遷出,能否避開二十年前的「坑」?
蘋果有史以來最瘋狂的發布會!發布顛覆性個人智能系統Apple Intelligence,並徹底改革Siri
AI 「奸商」的崛起
限制中國人在美國搞 AI,美眾議院提案對AI產業帶來什麼影響?