本科生60行代碼教你手搓GPT大模型,技術(shù)介紹堪比教程
當(dāng)前,大型語(yǔ)言模型(LLM)被認(rèn)為是人工智能突破的方向。人們正在嘗試用它們做各種復(fù)雜的事情,比如問(wèn)答、創(chuàng)作、數(shù)學(xué)推理以及編寫(xiě)代碼等。近段時(shí)間 ChatGPT 持續(xù)的爆火是最好的例證。
然而,對(duì)于機(jī)器學(xué)習(xí)從業(yè)者來(lái)說(shuō),大模型的門(mén)檻很高:因?yàn)轶w量太大難以訓(xùn)練,很長(zhǎng)時(shí)間里這個(gè)方向一直被大公司壟斷。不過(guò)最近,簡(jiǎn)化 GPT 模型的方法越來(lái)越多了。1 月中旬,前特斯拉 AI 高級(jí)總監(jiān) Andrej Karpathy(現(xiàn)已回歸 OpenAI)就發(fā)布了??從零開(kāi)始構(gòu)建 GPT 模型的完整教程???。不過(guò)訓(xùn)練出的 GPT 和 OpenAI 的 GPT-3 比較,兩者規(guī)模差距達(dá) 1 萬(wàn) - 100 萬(wàn)倍。
近日,加拿大麥克馬斯特大學(xué)的一位軟件工程本科生 Jay Mody 在導(dǎo)入 NumPy 庫(kù)下,僅用 60 行代碼就從頭實(shí)現(xiàn)了一個(gè) GPT 模型,并將其命名為 PicoGPT。不僅如此,他還將經(jīng)過(guò)訓(xùn)練的 GPT-2 模型權(quán)重加載到自己的實(shí)現(xiàn)中,并生成了一些文本。下面為 60 行代碼展示。
不過(guò)要做到這些,你需要熟悉 Python 和 NumPy,還要有一些訓(xùn)練神經(jīng)網(wǎng)絡(luò)的基本經(jīng)驗(yàn)。作者表示,這篇博客旨在對(duì) GPT 進(jìn)行簡(jiǎn)單易懂的完整介紹。因此,作者只使用已經(jīng)訓(xùn)練的模型權(quán)重來(lái)實(shí)現(xiàn)前向傳遞代碼。
代碼地址:
?https://github.com/jaymody/picoGPT/blob/29e78cc52b58ed2c1c483ffea2eb46ff6bdec785/gpt2_pico.py#L3-L58?
對(duì)于此項(xiàng)研究,Andrej Karpathy 給出了四個(gè)字:雖遲但到。想當(dāng)初,Karpathy 構(gòu)建的 minGPT 和 nanoGPT 還要 300 行代碼。
值得一提的是,這篇教程不是完全零門(mén)檻的。為了讓讀者明白,作者首先介紹了什么是 GPT、它的輸入、輸出如何等其他內(nèi)容,介紹得都非常詳細(xì)。
至于 GPT 到底能干什么,作者給出了幾個(gè)示例,它能寫(xiě)電子郵件、總結(jié)一本書(shū)、給你 instagram 標(biāo)題的想法、向 5 歲的孩子解釋黑洞、用 SQL 編寫(xiě)代碼等。
通過(guò)仔細(xì)閱讀這部分內(nèi)容后,你能大致了解 GPT 的一些基礎(chǔ)知識(shí)。有了這些背景介紹,接下來(lái)就是如何設(shè)置了。
項(xiàng)目介紹
設(shè)置
這一章節(jié)主要介紹了如何設(shè)置編碼器、超參數(shù)以及參數(shù)。
你要做的,首先是克隆代碼庫(kù):
然后安裝依賴項(xiàng):
注意,如果你使用的是 M1 Macbook,在運(yùn)行 pip install 之前,你需要在 requirements.txt 中將 tensorflow 更改為 tensorflow-macos。在這個(gè)項(xiàng)目下,文件包括 encoder.py、utils.py、gpt2.py、gpt2_pico.py:
- encoder.py:包含 OpenAI BPE Tokenizer 的代碼,直接取自 gpt-2 repo;
- utils.py:包含下載和加載 GPT-2 模型權(quán)重、tokenizer 和超參數(shù)的代碼;
- gpt2.py:包含 GPT 模型和生成代碼,可以將其作為 python 腳本運(yùn)行;
- gpt2_pico.py:與 gpt2.py 相同,但是代碼行數(shù)更少。
其中 gpt2.py 需要從頭開(kāi)始實(shí)現(xiàn),因此你要做的是先刪除 gpt2.py 并重新創(chuàng)建一個(gè)空文件:
然后將下列代碼復(fù)制到 gpt2.py 中:
上述代碼包含 4 個(gè)主要部分:
- gpt2 函數(shù)是本次實(shí)現(xiàn) GPT 的實(shí)際代碼;
- generate 函數(shù)實(shí)現(xiàn)自回歸解碼算法;
- main 函數(shù);
- fire.Fire (main) 將文件轉(zhuǎn)換為 CLI 應(yīng)用程序,以便最終可以運(yùn)行代碼:python gpt2.py "some prompt here"。
main 函數(shù)包含有 encode、hparams、params 參數(shù),執(zhí)行下列代碼:
接著必要的模型以及 tokenizer 文件將被下載到 models/124M 文件。
設(shè)置完成之后,作者開(kāi)始介紹編碼器、超參數(shù)、參數(shù)的一些細(xì)節(jié)內(nèi)容。就拿編碼器來(lái)說(shuō),本文的編碼器和 GPT-2 使用的 BPE tokenizer 一樣。下面是該編碼器編碼和解碼的一些文本示例:
實(shí)際的 token 長(zhǎng)這個(gè)樣子:
需要注意,有時(shí) token 是單詞(例如 Not),有時(shí)它們是單詞但前面有一個(gè)空格(例如 ?all,? 代表一個(gè)空格),有時(shí)是單詞的一部分(例如 capes 被拆分為 ?cap 和 es),有時(shí)它們是標(biāo)點(diǎn)符號(hào)(例如 .)。
BPE 的一個(gè)好處是它可以對(duì)任意字符串進(jìn)行編碼,如果遇到詞匯表中不存在的內(nèi)容,它會(huì)將其分解為它能理解的子字符串:
更細(xì)節(jié)的內(nèi)容不再贅述。接下來(lái)介紹基礎(chǔ)神經(jīng)網(wǎng)絡(luò),這一部分就更加基礎(chǔ)了,主要包括 GELU、Softmax 函數(shù)以及 Layer Normalization 和 Linear。
每一小部分都有代碼示例,例如在 Linear 部分,作者展示了標(biāo)準(zhǔn)矩陣乘法 + 偏置:
線性層從一個(gè)向量空間投影到另一個(gè)向量空間的代碼如下:
GPT 架構(gòu)?
這部分介紹 GPT 自身架構(gòu)。
Transformer 架構(gòu)如下:
Transformer 僅使用解碼器堆棧(圖的右側(cè)部分):
需要注意,由于擺脫了編碼器,中間的交叉注意力層也被刪除了。?
在高層次上,GPT 體系架構(gòu)有以下三個(gè)部分:
- 文本 + 位置嵌入;
- Transformer 解碼器堆棧;
- 投影到詞匯表。
代碼就像下面這樣:
代碼部分截圖
接下來(lái)更詳細(xì)地分解以上三個(gè)部分中的每一個(gè)部分,這里也不再贅述。
以上就是作者對(duì) GPT 的實(shí)現(xiàn),接下來(lái)就是將它們組合在一起并運(yùn)行代碼,得到 gpt2.py。它的全部?jī)?nèi)容只有 120 行代碼(如果刪除注釋和空格,則為 60 行)。
作者通過(guò)以下方式測(cè)試結(jié)果:
輸出結(jié)果如下:
正如作者說(shuō)的:這次實(shí)驗(yàn)成功了。
本文只是跟著作者的思路大概介紹了整體流程,想要了解更多內(nèi)容的小伙伴,可以參考原文鏈接。
原文鏈接:https://jaykmody.com/blog/gpt-from-scratch/#basic-layers