自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

代碼生成「神?提示」,比新手程序員快100倍!地位堪比make it more X

人工智能 新聞
不斷迭代簡(jiǎn)單的提示詞「write better code」,代碼生成任務(wù)直接提速100倍!不過「性能」并不是「better」的唯一標(biāo)準(zhǔn),還需要輔助適當(dāng)?shù)奶崾竟こ?,也是人類程序員的核心價(jià)值所在。

2023年11月,在ChatGPT支持DALL-3功能后,一個(gè)爆火的圖像生成玩法是,不斷迭代提示詞「make it more X」,生成的圖片越來越抽象。

圖片

圣誕老人越來越嚴(yán)肅

把這個(gè)思路用在LLM任務(wù)上,比如代碼生成,會(huì)怎么樣?

最近,BuzzFeed的高級(jí)數(shù)據(jù)科學(xué)家Max Woolf在博客上分享了一個(gè)實(shí)驗(yàn),通過設(shè)計(jì)不同的提示詞、不斷迭代模型輸出,最終實(shí)現(xiàn)代碼性能的100倍提升!

圖片

完整代碼鏈接:https://github.com/minimaxir/llm-write-better-code/

特別需要注意的是,「性能」并不是唯一優(yōu)化指標(biāo),迭代過程中需要在提示詞中明確定義什么是「好」。

代碼基線

設(shè)計(jì)實(shí)驗(yàn)題目時(shí),為了充分測(cè)試LLM的自主代碼能力,必須保證「測(cè)試提示詞」完全原創(chuàng),不能源于LeetCode或HackerRank等測(cè)試,模型無法通過背誦記憶來作弊;測(cè)試題目要盡可能簡(jiǎn)單,新手也能實(shí)現(xiàn),但還要預(yù)留大量可優(yōu)化空間。

最終選擇Claude 3.5 Sonnet模型,設(shè)計(jì)了一個(gè)Python語言、面試風(fēng)格的編碼提示詞:

Write Python code to solve this problem: Given a list of 1 million random integers between 1 and 100,000, find the difference between the smallest and the largest numbers whose digits sum up to 30.

用Python實(shí)現(xiàn):假設(shè)有一個(gè)包含100萬個(gè)隨機(jī)整數(shù)的列表,介于1到10萬之間,你需要找出其中各位數(shù)字之和等于30的最小數(shù)和最大數(shù)之間的差值。

圖片

第一次給出的代碼實(shí)現(xiàn)就是正確的,與大多數(shù)新手Python程序員的水平相當(dāng):對(duì)于列表中的每個(gè)數(shù)字,檢查其各位數(shù)字之和是否為30:如果是,檢查是否大于最近看到的最大數(shù)字或小于最近看到的最大數(shù)字,并相應(yīng)地更新這些變量;在搜索完列表之后,返回差值。

一個(gè)明顯可優(yōu)化的點(diǎn)是digit_sum()函數(shù):字符串(str)和整數(shù)(int)之間進(jìn)行類型轉(zhuǎn)換的開銷很大。

在M3 Pro Macbook Pro上,代碼的平均運(yùn)行時(shí)間為657毫秒。

第一次Write better code

Claude提供的代碼優(yōu)化版本,不再將所有代碼放在函數(shù)中,而是將其重構(gòu)為 Python class,更面向?qū)ο蟆?/span>

圖片

這段代碼主要進(jìn)行了兩處改進(jìn):

  1. 計(jì)算數(shù)字和時(shí),使用整數(shù)運(yùn)算并避免了類型轉(zhuǎn)換需求;
  2. 預(yù)先計(jì)算所有可能的數(shù)字和,并將其存儲(chǔ)在字節(jié)數(shù)組中以供查找,即一百萬數(shù)字列表中有重復(fù)時(shí),不需要重新計(jì)算數(shù)字和。由于該數(shù)組作為類的字段存儲(chǔ),因此在搜索新的隨機(jī)數(shù)字列表時(shí)也不需要重新計(jì)算。

代碼計(jì)算相比基線提速2.7倍。

第二次Write better code

Claude對(duì)代碼增加了并行處理:

  1. 通過Python的concurrent-futures包進(jìn)行多線程,將大列表分割成可以獨(dú)立處理的塊;
  2. 矢量化NumPy操作,比基礎(chǔ)Python操作快得多,_precompute_digit_sums()函數(shù)實(shí)現(xiàn)了計(jì)算數(shù)字和的矢量化實(shí)現(xiàn);

代碼計(jì)算相比基線提速5.1倍。

圖片

第三次Write better code

Claude返回了一個(gè)聲稱是“使用高級(jí)技術(shù)和現(xiàn)代 Python 特性的更加復(fù)雜和優(yōu)化的版本”的實(shí)現(xiàn),但實(shí)際上代碼并沒有顯示出顯著的算法改進(jìn),并且在數(shù)字求和計(jì)算上實(shí)際上退步了,回歸到類型轉(zhuǎn)換方法。如果有什么的話,代碼庫正在變得更加臃腫,比如添加一個(gè)用于執(zhí)行差的類:

代碼計(jì)算性能略有下降,相比基線提速4.1倍。

圖片

第四次Write better code

Claude這次提供了額外的「尖端、企業(yè)級(jí)優(yōu)化」,比如結(jié)構(gòu)化指標(biāo)日志記錄Prometheus;信號(hào)處理程序,以便在強(qiáng)制終止時(shí)優(yōu)雅地關(guān)閉代碼;使用表格的基準(zhǔn)測(cè)試。

圖片

最終代碼非常長,優(yōu)化操作包括numba Python庫,調(diào)用JIT編譯器,直接優(yōu)化代碼以適應(yīng)CPU,只需使用一個(gè)裝飾器就可以非??焖俚仡A(yù)計(jì)算數(shù)字之和。

圖片

完整類還使用Python的asyncio行化,比子進(jìn)程方法更符合調(diào)度任務(wù)的規(guī)范,與現(xiàn)有的內(nèi)聯(lián)代碼和REPL配合得更好。

這次代碼的運(yùn)行時(shí)間大約為6毫秒,速度提升了100倍。

什么是好?

「速度快」并不代表是「好代碼」,比如用戶可能只是想在算法上改進(jìn),而不是一個(gè)完整的SaaS,過于冗長的代碼在閱讀上還會(huì)帶來額外負(fù)擔(dān)。

所以需要更具體地定義什么是「代碼優(yōu)化」。

圖片

你編寫的所有代碼都必須充分優(yōu)化?!赋浞謨?yōu)化」的含義包括:

  • 盡可能提高算法在內(nèi)存使用和運(yùn)行時(shí)間上的效率;
  • 在合適的時(shí)機(jī)使用并行化和向量化;
  • 遵守代碼語言的正確風(fēng)格規(guī)范,比如盡量重用代碼,避免重復(fù)勞動(dòng);
  • 除了解決用戶提出的問題所必需的代碼外,不添加任何多余的代碼;

如果代碼沒有達(dá)到充分優(yōu)化的標(biāo)準(zhǔn),罰款100美元。

圖片

先規(guī)劃一下優(yōu)化方案:

  1. 算法優(yōu)化:只需要追蹤各位數(shù)字之和等于30的最小數(shù)和最大數(shù),不需要存儲(chǔ)所有這樣的數(shù);可以在讀取數(shù)字的同時(shí)計(jì)算各位數(shù)字之和,無需將數(shù)字轉(zhuǎn)換為字符串;只需要對(duì)列表進(jìn)行一次遍歷,時(shí)間復(fù)雜度為O(n)。
  2. 內(nèi)存優(yōu)化:只需要存儲(chǔ)兩個(gè)變量(最小值和最大值),不需要存儲(chǔ)完整的篩選后的列表;不需要額外的數(shù)據(jù)結(jié)構(gòu)。
  3. 性能優(yōu)化:使用numba的@jit裝飾器來加快計(jì)算速度;使用取模運(yùn)算而不是字符串轉(zhuǎn)換來各位數(shù)字之和;使用numpy來生成隨機(jī)數(shù)(比random.randint更快)。

基線模型

利用提示工程,Claude直接就能意識(shí)到用numpy和numba來計(jì)算數(shù)字和,代碼平均運(yùn)行時(shí)間為11.2毫秒,比原始實(shí)現(xiàn)快59倍。

圖片

第一次迭代

這次不用「write code better」,而是改成更完善的提示詞「Your code is not fully optimized, and you have been fined $100. Make it more optimized.」來迭代優(yōu)化代碼。

圖片

模型成功識(shí)別了parallel=True;數(shù)字求和操作使用位移動(dòng),但實(shí)現(xiàn)是錯(cuò)的。

代碼優(yōu)化還包括多進(jìn)程分塊方法,與numba實(shí)現(xiàn)冗余,并產(chǎn)生了額外的開銷;腳本還使用一個(gè)小測(cè)試數(shù)組預(yù)編譯了JIT函數(shù),也是numba文檔推薦的基準(zhǔn)測(cè)試方法。

但整體性能相比提示工程后的基線大幅下降,僅比樸素版快9.1倍。

第二次迭代

Claude使用SIMD操作和塊大小調(diào)整以實(shí)現(xiàn)「理論上」極致的性能,不過在位移動(dòng)的實(shí)現(xiàn)上仍然不正確,錯(cuò)把十進(jìn)制當(dāng)成十六進(jìn)制,算是一個(gè)幻覺。

與最初的提示工程極限相比,性能有輕微的改進(jìn),比基礎(chǔ)實(shí)現(xiàn)快65倍。

圖片

第三次迭代

LLM放棄了有問題的分塊策略,并增加了兩個(gè)優(yōu)化:全局HASH_TABLE和邏輯微優(yōu)化,即在求和數(shù)字之后,如果數(shù)字超過30,計(jì)數(shù)可以停止,可以立即識(shí)別為無效。

經(jīng)過微小的代碼重構(gòu)后,該代碼的運(yùn)行速度比原始基線的實(shí)現(xiàn)快100倍,與普通提示的四次迭代性能相同,但代碼量少很多。

圖片

第四次迭代

Claude開始抱怨說該代碼已經(jīng)是「這個(gè)問題的理論最小時(shí)間復(fù)雜度」,要求修復(fù)代碼問題后,性能略有下降,為基礎(chǔ)基線的95倍。

下一步,優(yōu)化LLM代碼生成

總的來說,要求LLM「編寫更好的代碼」(write better code)確實(shí)可以使代碼變得更好,但具體取決于你對(duì)「更好」的定義,可以不斷迭代以實(shí)現(xiàn)更好的性能,具體效果因提示詞不同而異,而且最終生成的代碼不是直接可用的,還需要人工干預(yù)解決部分bug

圖片

雖然LLM的優(yōu)化能力很強(qiáng),但想取代程序員仍然很難,需要強(qiáng)大的工程背景來判斷什么是真正的「好代碼」;即使github等倉庫里有海量的代碼,但大模型并沒有能力區(qū)分普通代碼、優(yōu)雅且高性能的代碼。

現(xiàn)實(shí)世界的系統(tǒng)顯然也比面試題要復(fù)雜很多,但如果只是迭代要求大模型,就能實(shí)現(xiàn)100倍的提速,那就相當(dāng)值得。

有些人的觀點(diǎn)是,過早進(jìn)行代碼優(yōu)化在實(shí)踐中并不是一個(gè)好的選擇,但隨時(shí)優(yōu)化代碼總比「技術(shù)負(fù)債」越拉越多要好。

實(shí)驗(yàn)設(shè)計(jì)上還有一個(gè)問題,Python并不是開發(fā)者在優(yōu)化性能時(shí)首先考慮的編程語言,雖然numpy和numba庫可以利用C來繞過Python的性能限制,但一種更流行的方式是利用polars和pydantic庫,結(jié)合Rust編程,相對(duì)于C有很多性能優(yōu)勢(shì)。

除了「好」以外,也可以要求模型生成代碼「make it more bro」(更酷),結(jié)果也非常有趣。

圖片

責(zé)任編輯:張燕妮 來源: 新智元
相關(guān)推薦

2014-12-19 10:12:34

2015-11-25 14:39:51

LiFiWiFi

2024-01-23 11:28:14

Eslint前端Oxlint

2015-01-07 10:24:46

2019-01-02 09:49:42

代碼程序員女朋友

2019-08-06 17:19:22

開源技術(shù) 趨勢(shì)

2022-10-27 08:31:31

架構(gòu)

2024-03-26 10:13:54

日志引擎SigLens

2021-05-08 10:35:02

開發(fā)者技能工具

2012-10-25 15:30:34

臺(tái)式電腦

2023-04-07 08:17:39

fasthttp場(chǎng)景設(shè)計(jì)HTTP

2012-07-27 09:48:01

Google Fibe光纖寬帶寬帶

2021-08-03 06:57:36

Protocol Bu平臺(tái)Json

2017-09-06 11:18:14

2024-11-26 07:43:21

2022-06-16 10:33:14

代碼AI

2015-01-06 09:37:58

2021-12-08 12:50:39

代碼MyBatisJava

2019-12-06 13:59:37

代碼開發(fā)Python

2023-03-29 09:42:32

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)