AI 學習紀錄 – 單步GPT推論 (2)

接著上一篇的AI 學習紀錄 – 單步GPT推論, 網頁架設 (1),接下來就是做單步推論了。單步推論所需要安裝的東西,差不多跟完整的訓練差不多。所以還是 follow 之前的 AI 學習文章,儘量提供完整的步驟。

基本環境安裝

一些基本的環境 (如 anaconda、共用 script) 的設定,已經寫在【共同操作】 這篇文章裡,請先看一下,確保所以指令可以正確運作。

建立 conda env

由於每個專案的相依性都不同,這裡會為每個案子都建立環境。

建立專案目錄

使用下面的命令,將專案下載(如附件)下來,並建立環境切換檔。

其中的一個目錄 tokenizations 是由 GPT2-Chinese 專案(https://github.com/Morizeyao/GPT2-Chinese.git)借用過來的。

安裝套件

執行下列命令來安裝所需套件

執行程式

下達以下命令,來看每一步的選詞。這一步會下載 huggingface 的 gpt2-large 模型,第一次會比較久 (約3GB)。

主程式 single_infer.py 會推論 “A bartender is ” 後面的10句話,每次都選取機率最高的那個。其輸出整理前5個如下

單步推論的機率

程式是選第一個(機率最高的),所以輸出總是固定的。若做出不同的選擇,就可以獲得不同的輸出。GPT 是以前文內容,來推測下一個字的機率,但符不符合文法或現實的用法,則不是它能判斷的。若要有更好的推論,則應該會引如其它的選擇機制,我想這也是各 AI 大廠的獨門秘技吧。

程式輸出

程式碼解析

 

L14~18: 由於單純的推論比較快,可以不用使用 GPU,這邊僅在 CPU  執行推論。這樣另外的好處是可以進行多個不同模型的推論,畢境系統的RAM還是遠多於顯卡的。
L54~58: 指定要使用的模型、字典與字典類型。這裡是使用huggingface的預訓練模型,分別是 “gpt2-large”, “gpt2-large” 與 “gpt2″。
L61~64: 載入字典檔以並建構分詞器。
L68: 載入模型,以使用訓練好的資料
L77~83: 推論下一個字詞,並將推論的字詞加入原文,進行下一次推論

最關鍵的部份在於 L77~83 這部份。其中 token_to_text() 行83, 最後呼叫的是 tokenizer.decode() 將一個 token ID (數字) 轉換為文字。而由於取到的是數個 ID (依機率排列),其中有可能是一些符號,所以我們濾掉了ID 4(好像是換行或空白)。

而推論的部份是行78的 infer()。 infer() 會推論文字 text 下一個字詞的5個候選字,並且依機率排序。並將之存在 idx (token index)與prob(機率)。

infer() 最先會將一串文字轉換為一個一個的 token ID,也就是字詞所代表的ID。而至於有幾個ID,取決於所使用的 tokenizer分詞器,簡單的就用字,難一點的就用詞,這邊我們就用gpt2提供的,就不煩腦這些了。取得這些 token ID 後,將之丟入模型內去推測下一個字詞。

predictions 取得的是所有字詞用於下一個字的機率, 其是從 outputs[0] 取得的。至於 outputs[1:] 後是什麼,沒仔細研究。接著我們呼叫了另一個函式 select_top_k(),來取得前5個最可能的機率與其所代表的 token ID。

其實 prediction 是表達了原文中的第一個到最後一個字詞的下一個字的機率。而這邊我們是要推論最後一個字的下一字,所以只要看最後一個就行了(上圖行3)。

我們將最後一個字詞的 prediction 進行排序,就可以將機率最高的排在前面,進而就可以形成機率與其所代表的tokenID變數, sorted_p與sorted_i。機率的部份,先將 predictions[last]先進行排序,取得[0] (機率權重)進行 softmax,轉成機率。而字詞的部份,則是將predictions[last] 排序後取得[1](字詞 ID), 並只有前k個。

取得每個字詞的機率與ID後,自然就可以決定下個字了。在行 79~83,我們將推論的機率印出來,並將最高機率的字加入原文再進行推論。這樣就可以觀察中間的結果與最終的文字。

 

推論概觀

以下是個人推論,未必正確囉~

所謂的 tokenizer 就是一個分詞的功能,再將一個數字代表一個字詞,然後用於模型當中。所以模型與tokenizer是密不可分的,訓練後就不可提換。因為這個字詞的 ID 在另一個 tokenizer 中所代表的字詞又會不同。可以在原本的 tokenizer 最後加上新的,因為這不會影響既有的 ID 所代表的字。

由上述可知,tokenizer 也是一門學問,可能跟各種語言或所要求的實體資源有關。通常與訓練過程的資料有關,以中文為例。可以簡單的以”字”為單位,或以詞為單位。以詞為單位,可以推論出更符合語言的內容,但組合也更多。

tokenizer 的產生是一個步驟,而模型的訓練又是另外一個。tokenizer 是在建立所有可能出現的字詞,所以至少要包含單字,不然在訓練時就會出現 [UNK] (unknown) 這種 ID。而模型的訓練在於建立不同字詞順序時,對於下一個字詞的推論的機率。

結語

對於 GPT 雖然有基本的認知,但過一陣子又會忘了。基本使用不難,而進階的使用才是決勝關鍵吧!

附件

程式碼

Leave a Reply(Name請以user_開頭,否則會被判定會垃圾息)

請輸入答案 8 + 2 =