ChatGPT 的相關話題應該算是繼 AlphaGo 以來,最出圈的人工智慧熱點了。簡單來說,它是一個可以用自然語言對話的機器人,你可以問它任何問題(當然它有可能會答錯,但你可以引導並糾正它),它都會以非常流暢、標準的自然語言回答你。不僅如此,它還能回答程式碼問題、數學問題等等,你可以和它在任何問題上聊得不亦樂乎。
我們可以用一個經典的雞兔同籠問題來感性地認識一下ChatGPT 的能力:
##從這個回答可以觀察到幾個特點。首先是對自然語言的理解和轉換為數學問題的能力,其次它透過將一個較為複雜的推理問題分步拆解,一步步獲得最後的答案。這個能力被業界稱為「思維鏈」(Chain of thought)。接下來換問法,看看它會怎麼回答。
從這個圖中可以發現,ChatGPT 對自己所說的內容是有感知的,可以給出這麼說的原因。另外也可以發現,它確實也會出錯(第一次計算耳朵數量錯了。這裡有個冷知識,雞是有類似於“耳朵”一樣的功能器官),但可以通過引導的方式讓它給出正確的答案,並且會告訴你自己為什麼錯了。
如果不事先告訴你這是一個人工智慧模型,ChatGPT 給人的感覺確實像一個真正有邏輯思維和語言溝通能力的真人。 它的出現第一次讓大家覺得,人工智慧似乎終於能夠和人正常溝通了,雖然有時候會出錯,但在溝通的過程中至少沒有語言和邏輯上的障礙,它能「懂」你在說什麼,並且依照人類的思考模式和語言規範給你回饋。這種非常聰明的體驗感,是它突破業界小圈子,帶給大眾衝擊感的原因。
這裡也希望再次強調這種體驗感的問題,因為也許過去業界由於技術的限制,為了完成場景中的特定任務而忽略了這一點。如今 ChatGPT 的出現代表了人工智慧不再是過去那種「有用,但是也挺蠢」的形態了。
為了更好地理解 ChatGPT 這種非常聰明的感覺是怎麼產生的,難免要從過去那種「很蠢」的人工智慧說起。確切地說,ChatGPT 背後使用的依然是自然語言處理(NLP)技術,但卻打破了原有的典範。
要理解這一點,可以先看看目前的主流做法是怎麼樣的。人類交流依賴的是語言,甚至也有很多人認為人類的思維也是建立在語言上的。因此,理解運用自然語言一直是人工智慧的重要課題。但語言實在太複雜,因此為了讓電腦理解運用語言,通常會將這個過程拆分為許多的細分項,這就是在技術領域中常說的「任務」。舉幾個例子:
這樣的任務還有很多,都是從某個細分的側面去對自然語言進行分析、處理。這樣做有很多好處,例如有了這些拆分,就可以從不同的維度來考察一個自然語言處理系統的細分能力;也可以針對某一個細分的項專門做系統或者模型的設計等。從技術的角度來說,將一個複雜的任務(理解並運用自然語言)拆分為很多的簡單任務(各種各樣的NLP 任務)確實是一種比較典型的解決複雜問題的路徑,這也是目前的主流做法。然而在 ChatGPT 出現之後,以馬後炮視角去看,也許在讓電腦理解並運用自然語言這條路上,這種拆分並不是最有效的途徑。
因為單一任務上的優秀表現,並不能代表系統就掌握了自然語言。 人類對於人工智慧體的「智能感」,是基於對它應用自然語言的整體能力而產生的,這一點在 ChatGPT 上有明顯的體現#。雖然OpenAI 沒有開放ChatGPT 的API 服務,外界還無法測評它在各個細分NLP 任務上的具體效果,但以過往外界對它的前身GPT-3、InstructGPT 等模型的測試情況表明,對於某些特定的任務,一個用專門資料精調的小模型,確實可以得到更好的效果(詳細分析請參考《深入理解語言模型的突現能力》)。但這些在單一任務上有較好表現的小模型,並沒有造成很大的出圈效應。歸根究底,是因為它們只有單一的能力。單一的能力出眾並不能代表它們具有了理解和運用自然語言的能力,從而也無法獨自在實際應用場景中發揮作用。正因如此,通常在一個真實的應用場景中,都是多個具有單點能力的模組經過人為的設計拼湊而成,這種人為的拼湊方式是過去的人工智慧系統讓人感覺並不聰明的原因之一。
從人類理解和運用自然語言的角度去看,這個現像其實很好理解。一般人在理解、運用自然語言的時候,並不會在腦內將它拆分為很多步不同的任務,逐個任務進行分析,然後再匯總,這不是人類使用自然語言的方式。就好比一個人,在聽到一句話的時候,並不會對它的句法結構、實體內容與關係、情感傾向等這些內容逐一分析,然後拼湊出這句話的含義,人對語言的理解過程是一個整體過程。再進一步,人對這句話的整體理解,會以自然語言的形式,透過回應的方式整體地表現出來。這個過程並不是像人工智慧系統那樣,拆分單一任務,然後逐一輸出情緒分析的標籤、實體資訊的片段、或是別的某個單一任務的結果,然後用這些東西拼湊出回應。
而以ChatGPT 為代表,GPT 系列模型所做的事情才真正接近了人類理解和運用語言的能力—— 直接接收自然語言,然後直接回覆自然語言,並保證了語言的流暢性與邏輯性。這是人與人的交流方式,所以大家對它抱以「很聰明」的體驗感。也許很多人會認為,如果能做到 ChatGPT 這樣當然很好,過去那種任務的拆分是因為技術的限制不得已而為之。從技術應用的角度來看,這樣迂迴的方式當然是需要的,這種方法也在很長的一段時間內被採用,並且確實也能夠解決許多實際場景中的問題。但如果回顧 GPT 系列模型的發展過程,就會發現 OpenAI「賭」了另一條路,而他們「賭」贏了。
GPT 初代,一切開始的地方
#早在2018 年,OpenAI 就發布了最初版本的GPT 模型,從OpenAI 公開的論文(Improving Language Understanding by Generative Pre-Training)可以了解到,這個模型採用了12 層的Transformer Decoder 結構,用了大約5GB 的無監督文字資料進行語言模型任務的訓練。雖然第一代GPT 模型採用的就已經是生成式的預訓練(這也是GPT 名字的由來,Generative Pre-Training,即生成式預訓練),但使用的是無監督預訓練下游任務微調的範式。這個範式其實並不是什麼新的發明,它在 CV(電腦視覺)領域已經有比較廣泛的應用,只是由於當年 ELMo 模型的出色表現,把它重新「介紹」到了 NLP 領域。
GPT 模型的出現在那一年確實引來了一些業內的關注,但它並不是那一年的 C 位主角。因為就在同年,Google 的BERT 模式橫空出世,以優異的效果吸引了幾乎全部的目光(這個景像有點像現在的ChatGPT,不禁感嘆Google 和OpenAI 之間的「恩恩怨怨」真是天道好輪迴) 。
圖片來自BERT 論文,從圖示中可以一窺當年BERT 對標的就是GPT,並引以為傲地指出雙向編碼能力。
BERT 模型雖然也是採用和 GPT 一樣的 Transformer 模型結構,但它幾乎就是為「無監督預訓練 下游任務微調」的範式量身定制的模型。和GPT 相比,BERT 所使用的掩碼語言模型任務(Masked Language Model)雖然讓它失去了直接生成文本的能力,但換來的是雙向編碼的能力,這讓模型擁有了更強的文本編碼性能,直接的體現則是下游任務效果的大幅提升。而 GPT 為了保留生成文字的能力,只能採用單向編碼。
以當年的眼光來看,BERT 絕對是個更優秀的模式。因為既然BERT 和GPT 兩者都是採用「預訓練微調」的範式,而下游任務依然是分類、匹配、序列標註等等「經典」的NLP 任務形式,那麼像BERT 模型這種更注重特徵編碼的質量,下游任務選一個合適的損失函數去配合任務做微調,顯然比GPT 這種以文本生成方式去“迂迴地”完成這些任務更加直接。
從BERT 模型出來以後,「無監督訓練下游任務微調」的範式便奠定了它的霸主地位,各類沿著BERT 的思路,琢磨「如何獲得更好的文本特徵編碼」的方法大量湧現,以至於GPT 這個以生成式任務為目標的模型顯得像「異類」。馬後炮地說,如果當時 OpenAI「順應大勢」,放棄生成式預訓練這條路,也許我們要等更長的時間才能見到 ChatGPT 這樣的模型。
GPT-2 帶來的希望
#當然,我們現在見到了ChatGPT,所以OpenAI 沒有放棄生成式預訓練的路線。實際上堅持的「回報」隱約出現在了第二年,也就是 2019 年。 OpenAI 發布了有 48 層 Transformer 結構的 GPT-2 模型。在發布的論文(Language Models are Unsupervised Multitask Learners)中,他們發現透過無監督資料配合生成式訓練後,GPT 展示了零樣本(zero-shot)的多任務能力。而奇妙的是,這些多任務的能力並不是明確地、人為地加入訓練資料中的。用通俗的話來舉個例子,GPT-2 其中一個展示出來的能力是做翻譯,但令人吃驚的是,通常專門用來做翻譯的模型是需要大量的平行語料(即兩種不同語種之間配對的數據)進行監督訓練,但GPT-2 並沒有使用這種數據,而僅僅是在大量的語料上進行生成式的訓練,然後它就“突然”會做翻譯了。這個發現或多或少地帶有點顛覆性的意味,它向人們展示了三個重要的現象:
雖然以現在的眼光來看,當時的GPT-2 所展示出來的各種能力還比較初級,效果距離使用監督數據微調後的一些其它模型還有明顯的差距,但這並沒有妨礙OpenAI 對它所蘊含的潛在能力充滿期待,以至於在論文摘要中的最後一句話中,他們提出了對GPT 系列模型未來的期望:
「These findings suggest a promising path towards building language processing systems which learn to perform tasks from their naturally occurring demonstrations.」
後來一系列事情的發展也證明了他們確實是一直是一直朝著這個promising path 的方向在前進。如果說在2018 年,GPT 初代模型出來的時候,GPT 的生成式預訓練還面臨著被BERT 這類以「提取特徵」為目地的預訓練模型在各方面碾壓,那麼在GPT-2 中的發現,給了生成式預訓練一個BERT 類別模型無法取代的潛在優勢,也就是語言模型任務所帶來的多任務能力,而這種多任務能力是無需標註資料的。
當然,在那個時間點上,生成式的技術路徑依然面臨風險和挑戰。畢竟當時的 GPT-2 在各任務上的表現還是差於經過微調的模型,這導致了 GPT-2 雖然有著翻譯、摘要等等能力,但效果太差以至於無法實際使用。因此,如果在當時想要一個可用的翻譯模型,最好的選擇仍然是老實實用標註資料訓練一個專門用來翻譯的模型。
GPT-3,資料飛輪的開始
#從ChatGPT 時代往回看,也許OpenAI 在GPT- 2 中的發現確實堅定了他們對GPT 系列模型的信心,並決定加強研發投入力度。因為在隨後的 2020 年他們發布了 1750 億參數量的 GPT-3,一個即便以現在的眼光去看也大得讓人驚嘆的模型。雖然 OpenAI 沒有明確公開訓練這個模型的費用,但大家的估算是當時花了 1200 萬美元。同時公開的還有一篇長達 60 多頁的論文(Language Models are Few-Shot Learners),其中詳細闡述了這個新的龐然巨物所展示出來的新能力。最重要的發現莫過於論文標題中所說的,語言模型具有小樣本(few-shot)學習的能力。
小樣本學習是一個機器學習領域的專業術語,但它有著很樸素的理念,即「人類是可以透過少量的幾個例子就學會一個新的語言任務」。想像在語文課上學習怎麼掌握「把」字換成「被」字句樣(雨把衣服淋濕了-- 衣服被雨淋濕了)的情形,老師會舉幾個例子,同學就能夠掌握這項能力。
但對於深度學習模型來說,它通常需要學習(訓練)成千上萬的例子才能掌握一項新的能力,但大家發現GPT-3 像人類一樣具有類似的能力。而且重點在於,只需要給它幾個例子,它就會「有樣學樣」地完成例子給出的任務,而不需要進行額外的訓練(即不需要進行常規訓練中的梯度反傳和參數更新)。後來的研究表明,這種能力是巨型模型所特有的,被業內叫做「在上下文中學習」(in context learning)的能力。
GPT-3 論文中所展示的英文翻譯法文的 In context learning 能力。
實際上,小樣本學習能力本身並不是很驚人的發現。畢竟業界一直都在對小樣本學習進行研究,許多專攻小樣本學習的模型都有優秀的小樣本學習能力。但GPT-3 展示出來的這種「在上下文中學習」的小樣本能力卻非常出人意料,其原因也和GPT-2 所展示的多任務能力一樣:
除了這個能力以外,GPT-3 也展現了優秀的文字產生能力,比起GPT-2,它產生的內容更流暢,而且可以產生很長的內容。這些能力綜合體現在一個模型上,讓 GPT-3 在當時成為了大家的焦點,它也成為 OpenAI 正式對外提供服務的模式。
但隨著這個模型服務的開放,越來越多的人嘗試使用這個模型。從這時起,OpenAI 透過開放給大眾的方式,同時也在收集更具有多樣性的資料(使用者使用時輸入的內容可能會被用於模型的訓練,這一點是寫在使用者條款中的) ,這些數據在後來的模型迭代中也扮演著重要的角色。 自此 GPT 系列模型的數據飛輪便轉動了起來,越多優質的用戶數據,迭代出效果越好的模型。
與ChatGPT 不同的是,GTP-3 並不是採用對話的形式互動的模型,而是文字的續寫模型(也就是在你輸入的文字後面接著往下寫),因此它並不具備現今的ChatGPT 所擁有的多輪對話能力。但它已經能夠幹很多的事情,例如寫故事、為郵件做自動補全等等。但同時,大家也慢慢發現了一些問題,例如它會一本正經地輸出不符合事實的內容,並且會輸出一些有害的言論等等。這是這種文本生成模型最突出的弊端,雖然經過多次迭代,但 ChatGPT 如今仍面臨類似的問題。
CodeX,讓電腦自己寫程式碼
OpenAI 在對GPT-3 的研究中還有一個意外的發現,它能夠根據一些註解產生很簡單的程式碼。因此在隨後的 2021 年,他們對生成程式碼這件事情進行了專門的研究投入,並發布了 CodeX 模型。 它可以看作是一個有著程式碼專精能力的 GPT 模型,能夠根據自然語言輸入產生比較複雜的程式碼。
從外部觀點來看,我們無法判斷程式碼產生的研究與 GPT 系列模型的研發是否在同時進行。但放在當時,讓模型具有產生程式碼的能力,從實用化的角度來說確實更加有意義,畢竟 GPT-3 還未擁有如今 ChatGPT 如此強悍的能力。另一方面,讓模型去產生程式碼也能規避它產生危害文字內容所帶來的風險。
在CodeX 論文中提及了幾個要點,首先是讓經過文字資料預訓練的GPT 模型在專門的程式碼資料(資料來自github 的開源程式碼,一共159G)上訓練確實能夠明顯提升模型對程式碼的理解和輸出能力。其次是論文中用的是一個 120 億參數的「小」模型,這個資訊從側面反映出 OpenAI 內部除了對外開放介面的 1750 億參數的 GPT-3 模型外,還有別的不同大小的模型版本。
而加入程式碼訓練,讓模型獲得理解和產生程式碼的決定,原本的初衷也許只是希望 GPT 能夠多一種應用場景。它看似與GPT 系列模型在理解和運用自然語言的能力沒有太大的聯繫,但根據後續的研究(詳細的分析請參考文章《#拆解追溯GPT- 3.5 各項能力的起源#》),增加對程式碼資料的訓練很有可能觸發了後來的GPT 模型在自然語言上的複雜推理和思維鏈的能力。
也許在OpenAI 做CodeX 之初並沒有預料到會有這樣的結果,但就像他們一直使用文本生成任務來做GPT 模型,然後在GPT-2 和GPT -3 中「解鎖」了「多任務的能力」和「在上下文中學習的能力」那樣,代碼資料的引入又一次讓他們獲得了意料之外的收穫。雖然看起來似乎有些偶然,但對技術路線的前瞻性認知,加上堅持與持續的投入顯然是一個至關重要的因素。
InstructGPT,讓GPT 好好說話
#在前面我們提到了GPT-3 雖然已經有很強的能力,但上線以後隨著使用的人越來越多,也發現了很多問題,最嚴重的應該要數“一本正經地胡說八道”和“輸出帶有危害性的內容”這兩點了。雖然在 2021 年 OpenAI 似乎暫時將重點放在了讓模型理解和產生程式碼這件事上,但他們應該一直在嘗試解決 GPT-3 的這些問題。
在 2022 年初,OpenAI 發表了 InstructGPT 的論文(Training language models to follow instructions with human feedback),從中我們可以一窺解決這些問題的方法。 論文的核心概念是讓模型接受人類的教導(回饋),這一點在標題中就已經開宗明義了。
GPT-3 之所以會出現「一本正經地胡說八道」和「輸出有害的內容」這樣的問題,其根源來自於它所使用的訓練資料。像 GPT-3 這樣的龐然大物,對資料的需求是大量的。我們可以從 GPT-3 的論文中找到它的資料來源,大致可以分為三類:網頁內容、百科內容以及書籍。雖然網頁內容的量非常大,但也非常「髒、亂、差」,自然會包含許多非真實性和有害的內容。 GPT-3 在這些資料上進行訓練,自然也就學到了這些。
但作為一款對外提供服務的產品,GPT-3 的回答應該更小心一些。要解決這個問題,其中的一難在於怎麼去定義模型該怎麼說話。因為生成模型的輸出內容是自然語言本身,而不是一個分類的標籤或一個實體名詞這種有明確的、客觀對錯的內容。沒有明確的對錯,就導致無法像訓練經典的 NLP 模型那樣直接針對目標設計訓練任務。
而InstructGPT 給出的解決思路是非常直接的,既然對於「好的回答」這個評價指標有很多不同的影響因素,這些因素又相互交織在一起,那就讓人來教它怎麼寫答案。因為人類是比較善於處理這種「既有明確的要求,又有模糊的範圍」的問題的,讓真人寫一些「優秀範例」,讓模型去學習這些「優秀範例」,這正是InstructGPT 提出的總體思路。
具體而言,InstructGPT 提出了兩個階段的路徑來讓GPT 學習人類給出的「優秀範例」,第一階段是監督學習,第二階段是強化學習。在第一階段中(對應下圖中最左邊的Step 1),讓真人根據不同的Prompt(粗淺可以認為是我們使用ChatGPT 時,在對話框裡輸入的那條文本,在業界這個東西叫做指令)寫出真實的、無害的、有用的答案。實際操作過程中,為了確保這些內容的質量,會給寫回答的標註人員一些規範性的指引,然後讓已經經過預訓練的 GPT 模型在這些人類編輯的數據上繼續訓練。這階段可以看作是對模型的一種「規訓」,用一個不嚴謹的類比來說,就像語文老師讓你默寫優秀範文那樣。
圖片來自 InstructGPT 論文,提出透過監督式的指令微調 人類回饋的強化學習來讓模型的輸出變得合理。
第二階段是強化學習,技術上分為兩個步驟。第一步(對應上圖中間的 Step 2)是讓被「規訓」後的模型根據不同的 Prompt 產生多個不同的回答,並由人來給這些答案按照好與差的標準來排序。然後用這些標註了優劣之分的資料訓練一個打分模型,讓它可以自動給更多的資料進行排序評分。強化學習階段的第二步(對應上圖右邊的Step 3)就是利用這個打分模型作為強化學習中的環境回饋,以策略梯度(Policy Gradient,準確地說是PPO 演算法)的方式對已經「規訓」後的GPT 模型進行訓練。整個第二階段的過程可以看作是對模型的一種「強化」,再用一個不嚴謹的類比來說,就像語文老師給你寫的作文打分,讓你從分數中分辨什麼是好與不好,然後不斷進步。
因此,用一種非常不嚴謹,但普通人或許也能夠理解的方式來說,InstructGPT 先是讓一個「口無遮蔽」的GPT透過「默寫人類的優秀範文」的方式初步學會「好好說話」,然後再「給它獨自寫出來的東西打個分,讓它回去好好領悟,繼續進步」#。當然,在技術上牽涉事情會更複雜一些,比如“優秀範文”的具體規範和數量等數據上的問題,以及強化學習中打分模型的選擇,算法參數的設置等算法上的問題,都會對最後的效果產生影響。但最終的結果表明,這種方式是非常有效的,論文中也指出一個透過上述方式訓練出來的 13 億的小模型,效果就能夠超過沒有經過這種訓練的更大的模型。
另外論文中還有一些非常值得一提的內容。首先是關於 Prompt 的一些發現。 InstructGPT 訓練時所使用的Prompt 主要由兩部分構成,一部分是專門的AI 訓練師編寫的,另一部分自來OpenAI 的模型在線服務期間,由用戶使用中編寫的內容,這時數據飛輪的作用就體現了。可以發現,無論是哪一種,這些Prompt 都是由真人寫出來的,雖然文章中沒有對這些Prompt 的具體涵蓋範圍、分佈情況以及提問的方式展開詳細的分析,但可以合理地猜測這些Prompt 具有一定的多樣性和較高的品質。其實文章中比較了使用這些真人編寫的Prompt 訓練的模型和使用一些開源NLP 任務資料集中構建的Prompt(例如T0 資料集、FLAN 資料集)訓練出來的模型,結論是由真人編寫Prompt 訓練出來的模型,所給的答案更能被評測的人接受。
另外一點是關於訓練好的模型對新的Prompt 的泛化能力的問題,可想而知的是,如果訓練完成的模型無法產生Prompt 的泛化能力,那麼現在ChatGPT 所表現出來的,幾乎百問百答的能力是不太可能產生的。因為在模型做微調的階段,即便是再多的數據,也不可能把人們有可能會輸入的內容都涵蓋完整。而 InstrctGPT 論文中點明了文中所採用的方法是可以產生 Prompt 的泛化能力的。
之所以花了更多的文字對InstructGPT 做介紹,因為根據ChatGPT 官方頁面的介紹,InstructGPT 中的方法正是用來訓練ChatGPT 的方法,不同的只是ChatGPT使用了對話式的資料組織方式。
GPT-3.5 時代與 ChatGPT 的誕生
在隨後的時間內,OpenAI 發布了多個被稱為GPT-3.5 系列的模型,雖然這些模型並未有相關的論文跟隨發表,但根據#這篇文章#的分析,GPT-3.5 系列應該是融合了OpenAI 在GPT-3 時代累積的技術、數據以及經驗開發出來的。由於沒有詳細的官方公開資訊參考,關於這些模型的具體資料,外界主要是透過分析使用的體驗、相關的技術論文以及 OpenAI 的 API 文件介紹來進行推測。
根據分析,GPT-3.5 系列的模型有可能並不是在GPT-3 上繼續微調而來,而很可能是將程式碼和自然語言的資料融合在一起,重新從零開始訓練了一個基礎模型。這個模型可能比 GPT-3 的 1750 億參數量更大,它在 OpenAI 的 API 中被命名為 codex-davinci-002。然後在這個基礎模型上,透過指令微調和人類回饋得到了一系列後續的模型,包括 ChatGPT。
GPT 系列模型的發展路徑。
簡單地說,從 code-davince-002 這個模型開始,經過有監督的指令微調得到 text-davinci-002。以及後續的 text-davinci-003 和 ChatGPT,也是在 GPT-3.5 系列的某個模型上透過指令微調以及人類強化學習回饋所得到的。而 text-davinci-003 和 ChatGPT 都是在 2022 年 11 月發布的,不同的是 text-davinci-003 和 GPT-3 一樣,是一個文字補全模型。而根據 ChatGPT 的官方介紹,它是透過將過往的資料處理成對話互動的形式,並增加了新的對話資料訓練出來的。
至此,我們大致回顧了 OpenAI GPT 系列模型從 2018 年的第一代 GPT 到現在的 ChatGPT,一路發展迭代的過程。在這個過程中,OpenAI 一直保持著對生成式預訓練模型這條技術路徑的「執拗」#,並且也一直在不斷發展的NLP 技術中吸收新的方法,從最初的Transformer 模型結構,到後來的指令微調(Prompt tuning)等技術的出現,這些因素共同促成瞭如今ChatGPT 的成功。有了對 GPT 系列模型發展的了解,我們可以再回過頭來看看如今的 ChatGPT。
在第一章中我們闡述了ChatGPT 出圈的原因主要是:「它以流暢、符合邏輯的自然語言來回饋人類對它輸入的自然語言」,從而給與它交流的人帶來了很強的「智能感」。在第二章節中透過回顧 GPT 系列模型的發展歷史來了解 ChatGPT 成功之路。而這一章節會嘗試以盡可能讓圈外人都能理解的方式,稍微深入一些技術的內容,並且探討一下當前的一些大型文本生成式模型為什麼未能做到相同的效果。這部分的主要參考來自於《深入理解語言模型的突現能力》和《拆解追溯GPT-3.5 各項能力的起源》這兩篇文章以及相關的一些論文,建議希望詳細了解細節的讀者閱讀原文。
雖然在第一章中指出,ChatGPT 所帶來的驚艷效果是由許多不同的NLP 任務綜合體現出來的,但在分析它背後的技術時,還是透過將它的能力進行拆解會更加清晰明了一些。整體而言,ChatGPT 所體現的能力可以大致劃分為以下幾個維度:
- 文本生成的能力:ChatGPT 的所有輸出都是即使生成出來的文本,所以文本生成的能力是它最基本的要求。
#這項能力其實是來自於它的訓練方式,ChatGPT 在預訓練時,是一個標準的自回歸語言模型任務,這是 OpenAI 所有 GPT 系列模型的基底。所謂的自回歸語言模型任務,通俗的理解是這樣的:它可以根據已經輸入的文本,預測下一個 token 應該是什麼。這裡所說的token,所代表的是模型所使用的最小單位的字符片段,它可以是字(在中文裡採用字是很常見的),也可以是詞(英文的每個詞天然地被空格隔開了,所以常採用詞),甚至是字母。但現在的方法通常採用的是子詞(subword,介於字母和單字之間,主要的目的是減少詞表數量)。但不論是哪一種,自回歸語言模型任務的基本思路都是根據已經輸入的文本,預測下一個要輸出的文本是什麼,就像下圖的例子中那樣:
在這個範例中,BOS 代表了輸入的開頭,而每個token 是一個詞,GPT 模型根據輸入的「今天」和“天氣」兩個詞,預測下一個要輸出的是「不錯」。
在訓練的時候,會準備很多文字數據,像是網頁上的文章、各類書籍等等,只要是正常的文字內容,都可以用來訓練。值得說明的是,這種數據不需要額外的人工標註,因為這類數據本來就是人寫的,模型要做的事情就是根據這些人寫出的文本,去學習“給定了前面的文字,接著這些文字後面這個地方應該是什麼」的問題。這便是業界所稱的「無監督訓練」,實際上模型並不是真的沒有監督(不然模型學什麼呢?),只是它的數據不需要額外的人工標註。也因為這個任務是不需要額外標註的,因此可以「免費」獲得大量的數據,得益於互聯網的普及,可以「輕鬆地」獲得海量的由真人寫出的文本內容用來訓練。這點也是 GPT 系列模型的特色之一,用大量的數據,去訓練很大的模型。
那麼在我們使用 ChatGPT 的時候,它是怎麼運作的呢?其實和它的訓練方式一樣,模型會根據我們在對話框裡輸入的內容,去預測接在這些內容的下一個token 是什麼,得到這個token 後,會將它與前面的內容拼接成一個新的文本給模型,模型再預測下一個token,如此反复,直到滿足某個條件後停止。這個停止的條件有很多不同的設計方式,例如可以是輸出的文字達到特定的長度,又或者是模型預測出某個用來代表停止的特殊 token。另外值得一提的是,模型預測下一個 token 時,其實背地裡是一個採樣的過程。換句話說,模型在預測 token 時,輸出的其實是所有可能出現的 token 的機率,然後從這個機率分佈裡取樣一個 token。因此,在使用 ChatGPT 時,會發現即使對於相同的輸入,它的輸出每次也會不一樣,因為在背地裡它採樣了不一樣的 token 作為輸出。
了解這些之後,可以再回頭思考模型在學什麼。它在學習怎麼回答問答嗎?又或者說它在學習怎麼理解自然語言所蘊含的訊息、邏輯、情感?還是說它在學習海量的知識?從訓練任務的設計來看,似乎都沒有,它只是從海量的文本數據裡,學習了“根據輸入的這些文本,一個人類在後面會接著寫什麼”這件事。但正是這樣的模型,在「進化」到 ChatGPT 時,它卻掌握了豐富的知識、複雜的邏輯推理等等,它似乎掌握了一個人類運用語言所需的幾乎所有的能力。這是一件非常神奇的事情,它的「進化」歷程將會在下一章做更深入的介紹。
- 豐富的知識儲備:ChatGPT 能夠正確回答非常多的問題,包括歷史、文學、數學、物理、程式設計等等。因為目前版本的 ChatGPT 並沒有利用外部知識,因此這些知識的內容是「儲存」在模型內部的。
#ChatGPT 所擁有的豐富知識儲備,來自於它的訓練數據,以及它足夠大的體量,以便學會這些內容。雖然官方並沒有公開 ChatGPT 所使用的訓練資料的具體細節,但從它的前身 GPT-3 的論文可以推測,這些資料大致可以分為三個大的範疇:網頁內容、書籍內容以及百科內容。可想而知的是,這些內容天然地蘊含了大量的知識,百科和書籍自然不必說,而網頁內容也包含了許多新聞、評論、觀點等,並且網頁也包括了很多專門的問答垂直類網站,這些都是ChatGPT 的知識來源。在官方的介紹裡指出 ChatGPT 無法回答 2021 年以後發生的事情,因此合理的猜測是訓練的資料收集截止到 2021 年。
但數據量只是其中一個方面,要讓模型「掌握」這些數據,其自身的體量是不可能小的。以GPT-3 為例,它有1750 億參數,可以粗淺地理解為,這些數據的內容以及模型的各項能力,都以這一個個參數的具體數值的形式,固定在了訓練完成的模型中。感性的理解是,假設一個模型只有 1 個參數,那它就什麼也乾不了。更嚴謹的分析和對比可以參考這篇論文《Holistic Evaluation of Language Models》的測評,方向性的結論是越大的模型,在需要知識來完成的任務上表現得越好。
論文網址:https://arxiv.org/pdf/2211.09110.pdf
-邏輯推理與思考鏈的能力:從第一章圖片中的雞兔同籠的例子可以看出,ChatGPT 具有很強的邏輯推理能力。並且它能夠將複雜的內容,透過拆解,分成多個小的步驟,一步步地進行推理,得到最後的答案,這種能力被稱為思維鏈。
從前面的介紹我們知道,模型在訓練的時候並沒有針對邏輯推理以及思考鏈做特定的設計。而目前的主流觀點認為,邏輯推理和思考鏈很可能和兩個因素相關,第一個是模型的體量,第二個是模型是否在程式碼資料上進行過訓練。
關於模型體量與推理、思考鏈能力的關係,在《深入理解語言模型的突現能力》中有對應的介紹。下面這張圖展示了思維鏈能力與模型體量的關係。
不同模型不同尺寸的思考鏈效果對比,圖來自論文。 GSM8K,SVAMP 和 MAWPS 是三個需要邏輯推理的數學應用題資料集,LaMDA,GPT 和 PaLM 分別是 3 個不同的模型。
簡單地說,圖表中給出了三個不同的模型,在三個數學應用問題資料集上的答對率。而值得關注的是以下幾個面向:
用通俗的話來說,就是在模型足夠大的時候,思維鏈的能力突然展現了出來,能夠達到、甚至超過那些在推理資料集上專門進行有監督訓練的模型。這個圖也許部分解釋了現在我們看到的 ChatGPT 所具有的優異推理和思考鏈能力。
而另一個關於推理以及思考鏈能力的產生因素,與模型是否在程式碼資料上做過訓練有關。目前這一點只是一個推論,《拆解追溯GPT-3.5 各項能力的起源》中的分析顯示體量類似的大型模型,沒有在代碼上做過訓練的話,只有很弱或幾乎沒有思維鍊和推理能力。而 ChatGPT 確實是在程式碼資料上進行過訓練的,這一點從它能夠理解並產生程式碼也可以看出來。在第二章回顧發展歷程中提到了,OpenAI 在 2021 年就發布了專門針對程式碼的 CodeX 模型,將程式碼資料加入 GPT 的訓練資料應該就是從那時開始的。
- 依照人的提問或指示給予回覆的能力:ChatGPT 除了可以用狹義的基於「問答」形式的互動以外,還能夠按照輸入的要求進行回复。例如,在處理「幫我寫一封信」這類指示式的要求時,它同樣也展現出了優秀的能力。這種能力讓它不僅是一個提供答案的「進階搜尋引擎」,更是一種可以用自然語言來互動的文字處理工具。
雖然目前大眾普遍將目光聚焦在將 ChatGPT 作為一種類別搜尋引擎的工具,但查閱相關知識並給予答案並不是它的唯一能力。實際上,單就 ChatGPT 本身而言,回答知識性的問題並不是它的強項,畢竟它本身的訓練資料被定格在了 2021 年。即便用更新的資料去訓練,但它終究跟不上時事的變化,因此要將它用作知識性的問答工具,還是需要與搜尋引擎等外部知識源做結合,就像現在 Bing 做的一樣。
但換一個角度來看,ChatGPT 像是一個「語言完備」的文字工具,也就是它能夠按照你給它的要求,完成指定的、可以用文字形式表達出來的內容,就像下面這個例子。
依照給定的計畫內容產生英文郵件進行報告。
這裡所說的「語言完備」,指的是運用語言的能力。可以看出上面這個例子裡,其實不涉及知識性的內容,因為需要它寫的內容已經提供給它了。但要寫出這封郵件,牽涉到的是運用語言的能力,例如遣詞造句、語種切換、郵件格式等等。
現在我們回過頭來,試著分析它的這種「依照指令完成任務」的能力是怎麼獲得的。在學界中,這種指令被稱為 prompt,實際上對話中的使用者輸入、問答中的問題也是一種 prompt,因此可以粗淺地理解為,在聊天框裡輸入的所有內容都是 prompt。如果了解我們在本章第一節介紹語言模型的內容,那麼更嚴謹一些的說法應該是「輸入給模型的上文」都是 prompt。
ChatGPT 根據輸入的指令(prompt)回覆的能力,是來自於一種稱為指令微調的模型訓練方式(prompt tuning)。其實原理很簡單,模型依然還是「根據輸入的內容,預測下一個token 是什麼」,只是在指令微調的階段,輸入的內容被換成了這些事先寫好的prompt,而prompt 後面需要生成的內容,則是事先寫好的答案。因此在這一階段和一開始所說的無監督自回歸語言模型訓練,最大的差異在於資料。這裡的數據,也就是 prompt 以及對應的回复,都是人寫的,換句話說,這一階段用的是人工標註的數據進行的監督訓練。
提到人工標註的數據,就自然牽涉到了所需的數據量了,因為每一條標註數據都是需要成本的。如果是不需要標註(就像第一階段的訓練),那麼自然有大量的文字資料可供訓練,但如果要標註,那到底需要多少這種資料呢?要知道,讓標註人員手寫一個 prompt,然後再手寫一個幾百字的、真實詳盡的回答,成本是很高的。根據論文《Training language models to follow instructions with human feedback》的介紹,所需要的數據其實不需要太多(比起無監督階段所使用的數據)。雖然具體到 ChatGPT 到底使用了多少沒有確切的信息公開,但可以確定的是在數量級上一定遠比用來進行無監督訓練的網頁、百科和書籍所構成的數據集要小非常多。
論文網址:https://arxiv.org/pdf/2203.02155.pdf
只需要相對少量的人工標註的prompt 資料就能達到讓模型依照指令做出回應的目的,這點背後其實隱含了一個現象,在學界內被稱為prompt 的泛化能力。可以想像一下,如今全世界都在不停的向 ChatGPT 提問,所提的問題也必定是千奇百怪的,這些問題其實就是一個個的 prompt。但用來對ChatGPT 進行指令微調的prompt 肯定不會有這麼多,這說明模型在學習到了一定量的prompt 和相應的答案以後,它能夠“舉一反三”地對它沒有見過的prompt 進行回答,這就是prompt 的泛化能力。文章《#拆解追溯GPT-3.5 各項能力的起源##》分析指出,這種泛化能力與在指令微調階段讓模型學習的標註資料數量以及多樣性相關。
此外,用少量的prompt 資料就能微調出類似ChatGPT 這樣擁有強大能力的模型,背後還隱含了另一個猜測,即模型所表現出來的各項能力,可能在無監督訓練的階段就已經存在於模型當中了。其實這也很好理解,畢竟相較於無監督的數據,這些人工標註的 prompt 數量太少了,很難想像模型是透過對這些僅有的標註數據學習而產生了各種各樣的能力。從這個角度來說,指令微調的過程更多只是讓模型學會按一定的規範來進行回复,而它的知識、邏輯等能力是早已存在的。
- 「客觀公正」的能力:如果對ChatGPT 詢問一些有害或有爭議的問題,可以看到ChatGPT 的回答都是非常「小心」的,很像是經過訓練的新聞發言人般的回答。雖然它目前依然做得不夠好,但這種能力是 OpenAI 敢將它公開作為一款產品使用的核心因素。
讓模型的輸出符合人類的價值是 OpenAI 一直在做的事情。早在 2020 年 GPT-3 的時候,OpenAI 就發現這種透過網路上的資料訓練出來的模型,會產生帶有歧視、危險、爭議的內容。作為一個對外提供服務的產品,這些有害的內容顯然是不合適的。而現在的ChatGPT 在這一點上有著明顯的改善,讓模型做出這種「行為改變」的主要方法也來自於InstructGPT 的論文,更確切地說,是透過有監督的指令微調加上人類反饋的強化學習共同完成的,這一點在第二章也已經做過介紹了。
透過上述的分析可以發現,從技術方法的角度來說,ChatGPT 相關的內容都是已知的,但為什麼目前只有它擁有如此驚豔的表現。實際上從 ChatGPT 推出之後,NLP 社群就一直在分析這其中的原因,雖然許多結論是推測性的,但也為同類模型的國產化帶來一些啟示。
模型體量的因素
#能力湧現出現的前提是模型體積達到一定的規模,雖然沒有具體的指標指引,但從目前的事實情況來看,類似於思維鍊等比較「高級」的能力,需要在數百億參數量以上的模型中才表現得足夠優異。
資料量的因素
模型的大小不是唯一的因素。 DeepMind 在這篇論文《Training Compute-Optimal Large Language Models》提供了一些分析性的結論,指出訓練的數據量需要隨著模型的體積相應地增加,更確切地說,是模型訓練時“見過的token”數量,需要隨著模型體積增加。
論文網址:https://arxiv.org/pdf/2203.15556.pdf
數據品質的因素
對於無監督的數據,數據量相對而言並不是很大的障礙,但數據品質往往更容易被忽略。其實在 GPT-3 的論文中,就有專門的內容介紹資料的處理工作。為了清洗 GPT-3 的訓練數據,OpenAI 專門訓練了一個資料過濾模型,來從海量的網頁資料中取得更高品質的資料。相較而言,與 GPT-3 體積相當的一些開源模型,例如 Meta 的 Opt 和 BigScience 的 Bloom,似乎沒有進行這一步清洗。這也許是這兩個開源模型效果劣於 GPT-3 的原因之一。
此外,資料品質的衡量維度不是單一的,諸如資料的多樣性、內容重複度以及資料的分佈都是需要考慮的因素。例如雖然 GPT-3 所使用的網頁、百科全書、書籍這三大類資料中,網頁資料的總量是最多的,但在訓練時這三類資料的取樣並不是依照實際資料的數量進行的。
另外值得一提的是,在指令微調的階段,採用人工編寫指令也許是一個重要的影響因素。 InstructGPT 的論文明確指出在評估過程中,採用人工編寫的指令訓練出來的模型,比採用現有的 NLP 資料集透過模版的方式來建構指令訓練出來的模型有更好的效果。這也許解釋了在 T0、FLAN 等由 NLP 資料集構成的指令資料集訓練出來的模型為什麼效果會差一些。
訓練過程的影響
#這類巨型模型在訓練時透過叢集進行訓練,同時採用資料並行、模型並行以及ZeRO 優化器(一種降低訓練過程顯存佔用的方法),這些方式為訓練的穩定性引入了更多的變數。如下這篇分析指出甚至模型是否採用 bfloat16 精度都對結果有明顯的影響。
分析連結:https://jingfengyang.github.io/gpt
相信了解了上面的這些內容,大家對復刻一個類ChatGPT 的方式以及會面臨的問題會有一個大致的了解。有幸的是 OpenAI 已經證明了這條技術路徑是能夠走通的,ChatGPT 的出現也確實正在改變 NLP 技術的發展方向。
ChatGPT 從 2022 年 11 月上線以來,引起了極大的關注。相信即便是非專業領域,甚至是與電腦也很少打交道的群體,或多或少地都知道它的存在,這個現象本身就已經反映出它的出現有些不同尋常。圈外的大眾更多的是以好奇、驚訝或驚嘆的方式感性地認識它的出現。而對從業者來說,它的出現更多的是對未來技術走向的思考。
從技術的角度來說,ChatGPT 的出現標誌著 NLP 領域的另一個範式切換##。之所以說是「又」一次,是因為在2018 年,也就是初代GPT 發布的那一年,與之同年發布的BERT 模型以自身優異的表現,開創了NLP 的「預訓練微調」範式的時代,具體內容在第二章已經做過介紹了。這裡主要介紹由 ChatGPT 開啟的「文字產生 指令」的範式#。具體來說,就是利用訓練好的 ChatGPT 或類似的文本生成模型,透過輸入適當的指令(prompt)來完成某一項特定的場景。
這個範式與先前的 NLP 技術應用有很大的不同。不論是早期的利用LDA、RNN 等統計模型或很小的深度學習模型的時代,還是後來利用BERT 等預訓練配合微調的時代,技術所提供的能力是相對原子化的,距離實際的應用場景有一定的距離。
就拿前面舉的讓ChatGPT 根據要求寫英文郵件的例子,按照先前的做法,可能需要先抽取實體、事件等內容(例如時間、地點、事件等),然後透過模版或是模型形成郵件的樣式,再透過一個翻譯模型轉換為英文。當然如果資料量足以訓練端到端模型的情況下,也可以跳過中間的若干步驟。但不論採用哪一種方式,要嘛需要將最終的場景拆解成原子化的 NLP 任務,要嘛需要對應的標註資料。而對 ChatGPT 來說,只需要一個合適的指令。
三個階段的 NLP 技術範式。
這種生成式模型搭配prompt 的方式,直接略過了中間的各項NLP 能力組件,用最直接的方式解決應用場景的問題。在這個範式下,完成終端應用的技術路徑將不再是用單點 NLP 能力模組以搭積木的方式組合起來。
當然,這個過程不是一蹴而就的,也不代表 NLP 的單點能力變得不重要。從評測的角度來說,每一個單點能力的好壞仍可作為評價模式效果的指標。並且,就某些場景來說單點能力依舊是一個強需求。例如在訂票系統中本身就需要針對時間、地點進行提取。但與先前不同的是,ChatGPT 本身也可以完成單點能力,而不需要使用額外的功能模組。
ChatGPT 進行資訊擷取。
#ChatGPT 進行情緒判斷。
從這個角度來說,可以把 ChatGPT 看作是一個以自然語言作為互動媒介的 NLP 工具。如果說在過去,我們是透過模型 資料 設計訓練任務的方式來完成某項 NLP 能力,那麼 ChatGPT 是透過設計指令來完成這些能力。
可想而知,ChatGPT 的出現大大降低了 NLP 技術的應用門檻。但它目前還不是全能的。最重要的一點在於它缺乏準確可靠的垂直領域知識,為了讓它的回答可靠,最直接的方式是為它提供外部的知識來源,就像微軟將 Bing 的搜尋結果作為它回答的資訊來源那樣。
因此,「傳統」的NLP 技術並不會就此完全消亡,而是會以「輔助」的角色,作為目前ChatGPT 短板的補充,這也許會是未來NLP 技術應用的新典範。
以上是ChatGPT的前世今生:OpenAI的技術「執拗」與「豪賭」的詳細內容。更多資訊請關注PHP中文網其他相關文章!