一文讀懂 ChatGPT 原理!

前言

最近一週多的時間,只要不是生活在火星,喜歡技術的同學一定都被 OpenAI 的 ChatGPT 給刷屏了。ChatGPT 與以往的公開提供服務的對話機器人相比,性能有了顯著的提高。它可以相對可靠地提供一些日常對話、知識獲取的功能,也可以它根據人類提供的需求幫忙寫文檔、寫代碼,甚至可以修改文本中的各類錯誤或者代碼中的 Bug。我相信很多非 AI 圈的同學肯定會有一種 “爲什麼 AI 突然變得這麼強?“的感受。這篇文章的目的也是爲了回答這個問題。在開始之前,我覺得有必要先表達一下我自己的看法:NLP 技術發生跨越式發展的標誌並不是 ChatGPT 本身,而應該是 2017 年 - 2018 年間相繼被提出的 Transforme1r[1] 和 GPT[2]。

ChatGPT 是 Transformer 和 GPT 等相關技術發展的集大成者。總體來說,ChatGPT 的性能卓越的主要原因可以概括爲三點:

機器學習模型

在步入正題之前,我們可以先梳理一下 NLP 發展的歷史。

基於文法的模型

這個階段,大家處理自然語言的主要思路就是利用語言學家的智慧嘗試總結出一套自然語言文法,並編寫出基於規則的處理算法進行自然語言處理。這個方法是不是乍聽起來還行?其實我們熟悉的編譯器也是通過這種方法將高級語言編譯成機器語言的。可惜的是,自然語言是極其複雜的,基本上不太可能編寫出一個完備的語法來處理所有的情況,所以這套方法一般只能處理自然語言一個子集,距離通用的自然語言處理還是差很遠。

基於統計的模型

在這個階段,大家開始嘗試通過對大量已存在的自然語言文本(我們稱之爲語料庫)進行統計,來試圖得到一個基於統計的語言模型。比如通過統計,肯定可以確定 “喫” 後面接 “飯” 的概率肯定高於接其他詞如 “牛” 的概率,即 P(飯 | 喫)>P(牛 | 喫)。

雖然這個階段有很多模型被使用,但是本質上,都是對語料庫中的語料進行統計,並得出一個概率模型。一般來說,用途不同,概率模型也不一樣。不過,爲了行文方便,我們接下來統一以最常見的語言模型爲例,即建模 “一個上下文後面接某一個詞的概率 “。剛纔說的一個詞後面接另一個詞的概率其實就是一元語言模型。

模型的表達能力

在這裏,我們很適合插播一下模型表達能力這個概念。

模型表達能力簡單來說就是模型建模數據的能力,比如上文中的一元語言模型就無法建模 “牛喫草” 和“我喫飯”的區別,因爲它建模的本質統計一個詞後面跟另一個詞的概率,在計算是選 “草” 還是選 “飯” 的時候,是根據 “喫” 這個詞來的,而 “牛” 和“我”這個上下文對於一元語言模型已經丟失。你用再多的數據讓一元語言模型學習,它也學不到這個牛跟草的關係。

模型參數數量

有人說,既然如此,爲啥我們不基於更多的上下文來計算下一個詞的概率,而僅僅基於前一個詞呢?OK,這個其實就是所謂的 n 元語言模型。總體來說,n 越大,模型參數越多,表達能力越強。當然訓練模型所需要的數據量越大(顯然嘛,因爲需要統計的概率的數量變多了)。

模型結構

然而,模型表達能力還有另一個制約因素,那就是模型本身的結構。對於基於統計的 n 元語言模型來說,它只是簡單地統計一個詞出現在一些詞後面的概率,並不理解其中的各類文法、詞法關係,那它還是無法建模一些複雜的語句。比如,“我白天一直在打遊戲” 和 “我在天黑之前一直在玩遊戲 “兩者語義很相似,但是基於統計的模型卻無法理解兩者的相似性。因此,就算你把海量的數據餵給基於統計的模型,它也不可能學到 ChatGPT 這種程度。

基於神經網絡的模型

上文提到,統計語言模型的主要缺點是無法理解語言的深層次結構。曾有一段時間,科學家們嘗試將基於文法的模型和基於統計的模型相結合。不過很快,風頭就被神經網絡搶了過去。

RNN & LSTM

剛開始,流行的神經網絡語言模型主要是循環神經網絡 (RNN) 以及它的改良版本 LSTM。

RNN 的主要結構如下, x 是輸入,o 是輸出,s 是狀態。

如果 RNN 作爲語言模型的話,那 x 可以作爲順序輸入進去的詞彙,而 o 就可以作爲輸出的詞彙,而 s 就是通過 x 計算 o 的過程中生成的狀態變量,這個狀態變量可以理解爲上下文,是對計算當前詞彙時前文所有出現過的所有單詞的濃縮並在一次次的計算中不斷迭代更新。這也是爲啥 RNN 可以建模詞與詞關係的根本原理。

與簡單的基於統計的模型相比,循環神經網絡的主要亮點就是能夠對一段文字中不同詞之間的關係進行建模,這種能力在一定程度上解決了基於統計的模型無法理解深層次的問題。

Attention Mechanisms

在更進一步之前,我們不得不提一下注意力(Attention)機制。

這個機制主要針對 RNN 語言模型中狀態 S 作爲上下文這一機制進行改進。。在 RNN 中計算當前詞後的狀態 Si 主要是通過計算上一個詞時的狀態 Si-1 迭代出來的。它的主要缺點就是它假設了距離較近的詞彙之間的關係更密切。但是我們都知道,在自然語言中,這一假設並不是一直成立的。引入 Attention 之後,計算第 i 個詞後的狀態從單純的 Si 變成了 S0,S1...Si 的組合,而具體 “如何組合”,即哪個狀態比較重要,也是通過數據擬合出來的。在這樣的情況下,模型的表達能力又得到了進一步的提高,它可以理解一些距離較遠但是又非常密切的詞彙之間的關係,比如說代詞和被指代的名詞之間的關係。

Transformer

接下來,我們終於可以祭出之前提過的 NLP 跨越式發展的標誌之一,Transformer 的提出!

其實在有了 Attention 之後,Transformer 的提出已經是順理成章了。Transformer 的主要貢獻在於

  1. 將 Multi-Head Self-Attention 直接內建到網絡中。所謂 Multi-Head Self-Attention 其實就是多套並行的 Self-Attention,可以用於建模的詞與詞之間的多類不同地關係。

  2. 利用專用位置編碼來替代之前 RNN 用輸入順序作爲次序,使得並行計算成爲了可能。

舉一個形象但不準確的例子,對於句子 I often play skating board which is my favorite sport. 如果使用 Multi-Head Self-Attention,那就可以有一套 Attention 專門用來建模 play 和 skating board 的謂賓關係,有一套 Attention 用來建模 skating board 與 favorite 的修飾關係。從而使得模型的表達能力又得到了提高。

ChatGPT 所依賴 GPT3.5 語言模型的的底層正是 Transformer。

訓練數據

OK,我們現在有一個名爲 Transformer 模型了,這個模型通過 Multi-head Self-Attention,使得建立詞與詞之間的複雜關係成爲了可能。因此可以說是一個表達力很強的語言模型了。然而,單有語言模型沒有數據就是巧婦難爲無米之炊。

GPT-3.5 的相關數據並未被公開。我們就只說說它的上一代 GPT-3。GPT-3 整個神經網絡就已經有 1750 億個參數了。這不難理解,想一想 Attention 憑什麼確定在當前上下文下哪些詞比較重要?而網絡又怎樣通過 Attention 和輸入生成輸出?這些都是由模型裏面的參數決定的。這也是爲啥模型結構一樣的情況下參數越多表達能力越強。那這些模型的參數怎麼拿到?從數據中學習!其實大多數所謂的神經網絡的學習就是在學參數。

好傢伙,要訓練 1750 億個參數的神經網絡要喂多少數據呢?這麼多!(from wikipedia)

8VuJyi

可以預想的是,表達能力如此之強的模型,在喂入萬億級的數據之後,其對語言本身的理解已經開始接近人類了。比如它處理句子的時候,會通過訓練 Attention 參數理解到句子中哪些詞之間存在關係的?哪些詞和哪些詞之間是同義的?等一系列比較深度的語言問題。

這還只是 2020 年的 GPT-3。如今已經 2022 年了,相信 GPT-3.5 的模型表達能力比 GPT-3 又有相當大地提升。

訓練方法

監督學習 vs 無監督學習

簡單來說,監督學習就是在 “有答案” 的數據集上學習。如果我們要用監督學習 (supervised learning) 訓練一箇中文到英文的機器翻譯模型,我們就需要有中文以及其對應的英文。整個訓練過程就是不斷地將中文送入到模型中,模型會給出一個英文的輸出,這個時候我們對比一下英文的輸出與標準答案的差距遠不遠(Measured by Loss Function),如果差距比較大,那我們就調整模型參數。這也成爲早期針對機器翻譯模型的主要訓練方法。

遷移學習

然而,“有答案”的數據終究是有限的。這也是限制之前很多自然語言學習的模型設計複雜度的原因。不是不想提高模型的表達能力,而是提上去之後,參數太多,我們沒有足量的 “有答案” 的數據來訓練這個模型。

2018 年,另一個我認爲 NLP 跨越式發展的標誌來了,那就是 GPT 的提出。

GPT 的主要貢獻在於,它提出了自然語言的一種新的訓練範式。即現通過海量的數據的無監督學習來訓練一個語言模型。正如我們之前提到過的,所謂語言模型即是在一個上下文中預測下一個詞,這個顯然是不需要帶有標註的數據的,現有的任何語料都可以作爲訓練數據的。由於 GPT 的底層借用了表達能力很強的 Transformer,互聯網經過長時間的發展,海量的無標記的自然語言數據也並不再是稀缺的事物。導致了訓練出來的模型其實對語言有了相當深入地理解。

這個時候,如果你想讓這個語言模型能夠陪你聊天,那在一個已經理解語言的模型的基礎上,你只需要喂一些聊天的對話數據,使用監督學習來對模型進行鍼對性的微調 (fine-tune),就可以使它學會如何聊天了。這個操作也叫做遷移學習 (Transfer Learning)。

在遷移學習的過程中,微調一般是通過簡單的監督學習來進行。簡單來說,ChatGPT 通過構建一些聊天的 Prompt,讓人類標註一些想要的回覆,並用這些數據進行監督學習來微調。

強化學習

ChatGPT 在使用進行微調之外,還使用了一種叫做 reinforcement learning from human feedback (RLHF) 的技術。這個技術在 ChatGPT 的主要作用是將預訓練的模型的目標對齊到聊天這一具體的下游應用上。它也較大地提升了 ChatGPT 的聊天能力。

其總體原理如下圖所示,在完成模型微調之後,先在人類的幫助下訓練一個獎賞網絡,這個獎賞網絡具有對多個聊天回覆好壞進行排序的能力。接着,利用這個獎賞網絡,進一步通過強化學習 (reinforcement learning) 優化了聊天模型。該訓練方法的細節可以參考論文[3]

在這一通操作之後,ChatGPT 就變成了我們現在看到的這樣子。

其他

至此,我們基本上就已經能明白爲什麼 ChatGPT 這麼強了,但是我相信很多同學肯定會表示 “就這?我不信,它都會改 bug 了,給他一段代碼他都知道代碼是幹什麼的了。”

Okay,我們可以首先解釋一下爲什麼它可以做到修改代碼中的 bug,根據 OpenAI 提供的信息 :"GPT-3.5 series is a series of models that was trained on a blend of text and code from before Q4 2021.",我們可以知道 GPT-3.5 中的訓練數據其實是包含了海量的代碼數據。所以說 GPT-3.5 對代碼的理解也是相當強的。從論文 [4] 可以看到,將代碼放入語言模型中進行訓練後,訓練出的語言模型已經可以做到代碼語義級的搜索。

而 ChatGPT 又是怎麼知道代碼的功能的呢?目前我還沒看到相關論文,不過可以參考一下 OpenAI 在 GPT-3 上做的代碼訓練的工作 [5],大概就是將代碼和其功能 docstring 註釋放在一起做對比預訓練 (contrastive pretrain),這樣可以讓語言模型理解代碼和其功能的關係。

總結

總之,ChatGPT 並沒有那麼神祕,它本質上就是將海量的數據結合表達能力很強的 Transformer 模型結合,從而對自然語言進行了一個非常深度的建模。對於一個輸入的句子,ChatGPT 是在這個模型參數的作用下生成一個回覆。

有人會發現 ChatGPT 也經常會一本正經胡說八道,這也是這一類方法難以避免的弊端。因爲它本質上只是通過概率最大化不斷生成數據而已,而不是通過邏輯推理來生成回覆。

向 ChatGPT 詢問比較嚴肅的技術問題也可能會得到不靠譜的回答。

Reference

作者:Atum

來源:zhuanlan.zhihu.com/p/590220208

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/IxLYvCjwQzGg1VLwjOkZiQ