--- title: LLM-stat # 簡報的名稱 tags: LLM # 簡報的標籤 slideOptions: # 簡報相關的設定 theme: black # 顏色主題 transition: 'fade' # 換頁動畫 spotlight: enabled: true --- # 統計數據 AI 基於大語言模型的發展,我們希望能夠訓練出專門回答統計與機器學習相關問題的 AI 模型 ## 數據蒐集 我們採用了 stackoverflow 上面網友們的問題與答案,我們用問題的 tag 來區分該問題主要關注的領域,我們收錄了擁有回答的問題,並且只收錄 upvote 最高的相關回答,以下是該數據的相關統計資訊 | Info/Dataset | Overall | Math | Stat | ML | Python | | -------------- | -------- | ------- | ------- | -------- | -------- | | samples | 88873 | 12879 | 13062 | 34546 | 28386 | | tokens | 50014715 | 5392047 | 6132554 | 21163892 | 17326222 | | avg input len | 562.77 | 418.67 | 469.50 | 612.63 | 610.38 | | max input len | 25549 | 24637 | 25537 | 24237 | 25549 | | med input len | 324 | 268 | 250 | 336 | 382 | | avg output len | 315.60 | 373.80 | 329.35 | 272.55 | 335.27 | | max output len | 24336 | 24336 | 20411 | 12405 | 18157 | | med output len | 190 | 218 | 205 | 166 | 202 | Dataset columns 分別代表不同 tag 下我們蒐集資料的部分統計,我們分別計算每次問題與回答的 token 數量 (這裡我們並無節錄 instruction 統計量) - **instruction:** 問題 - **input:** 問題詳細內容 - **output:** upvote 最高之回答 我們關注於 token 長度的中位數,可以發現皆坐落於 200 ~ 400 附近,因此在訓練過程中,我們可以設置參數 max_len 至 512 或者 2048 來減少模型顯存占用 ### 數據清洗 網路上蒐集來的數據品質良莠不齊,因此我們需要做適當的資料清洗,在 stackoverflow 上面抓到的文本是 html 格式,以下我們介紹對於 html 文本的修飾方法。 我們使用下列代碼來修飾 html 文本 ```python= import html import re CLEANR = re.compile('<.*?>') def cleanhtml(raw_html): cleantext = re.sub(r'<pre.*code>', '\n```r\n', raw_html) # Replace </code></pre> with triple backticks cleantext = re.sub(r'</code></pre>', '```\n', cleantext) cleantext = re.sub(CLEANR, '', cleantext) cleantext = html.unescape(cleantext) return cleantext ``` 主要使用正則表達式來移除 html 中的 tag,並且在代碼區塊,改為用一對引號包含,具體作用如下 - 原始文本 ``` <div class="s-prose js-post-body" itemprop="text"> <p>It doesn't make much sense to talk about the R-squared of individual variables in a multivariate model. Delta R-squared, as Zephryl mentions, or partial R-squared are two measures that will do something like what you want.</p> <p>Discussion on delta R-squared and partial R-squared: <a href="https://stats.stackexchange.com/questions/64010/importance-of-predictors-in-multiple-regression-partial-r2-vs-standardized">https://stats.stackexchange.com/questions/64010/importance-of-predictors-in-multiple-regression-partial-r2-vs-standardized</a></p> <p>Partial R-squared can be calculate like this:</p> <pre><code>fm1 &lt;- lm(rating ~ ., data=attitude) # summary(fm1 &lt;- lm(sr ~ ., data=LifeCycleSavings)) # summary(fm1 &lt;- lm(Employed ~ ., data=longley)) # summary(fm1 &lt;- lm(stack.loss ~ stack.x)) reduced &lt;- lapply(seq_len(ncol(fm1$model)-1), function(x) update(fm1, terms(fm1)[-x])) reduced.sse &lt;- sapply(reduced, function(x) deviance(x)) fm1.sse &lt;- deviance(fm1) partial.r2 &lt;- c(0, (reduced.sse - fm1.sse)/reduced.sse) (fm1.coefs &lt;- cbind(summary(fm1)$coefficients, partial.r2)) # Estimate Std. Error t value Pr(&gt;|t|) partial.r2 # (Intercept) 10.787076386 11.58925724 0.93078238 0.36163372105 0.0000000000 # complaints 0.613187608 0.16098311 3.80901816 0.00090286788 0.3868076082 # privileges -0.073050143 0.13572469 -0.53822295 0.59559392051 0.0124382943 # learning 0.320332116 0.16852032 1.90085160 0.06992534595 0.1357684079 # raises 0.081732134 0.22147768 0.36903102 0.71548008844 0.0058861866 # critical 0.038381447 0.14699544 0.26110638 0.79633426421 0.0029554369 # advance -0.217056682 0.17820947 -1.21798623 0.23557704863 0.0605914609 </code></pre> </div> ``` - 修飾後文本 ``` It doesn't make much sense to talk about the R-squared of individual variables in a multivariate model. Delta R-squared, as Zephryl mentions, or partial R-squared are two measures that will do something like what you want. Discussion on delta R-squared and partial R-squared: https://stats.stackexchange.com/questions/64010/importance-of-predictors-in-multiple-regression-partial-r2-vs-standardized Partial R-squared can be calculate like this: fm1 <- lm(rating ~ ., data=attitude) # summary(fm1 <- lm(sr ~ ., data=LifeCycleSavings)) # summary(fm1 <- lm(Employed ~ ., data=longley)) # summary(fm1 <- lm(stack.loss ~ stack.x)) reduced <- lapply(seq_len(ncol(fm1$model)-1), function(x) update(fm1, terms(fm1)[-x])) reduced.sse <- sapply(reduced, function(x) deviance(x)) fm1.sse <- deviance(fm1) partial.r2 <- c(0, (reduced.sse - fm1.sse)/reduced.sse) (fm1.coefs <- cbind(summary(fm1)$coefficients, partial.r2)) # Estimate Std. Error t value Pr(>|t|) partial.r2 # (Intercept) 10.787076386 11.58925724 0.93078238 0.36163372105 0.0000000000 # complaints 0.613187608 0.16098311 3.80901816 0.00090286788 0.3868076082 # privileges -0.073050143 0.13572469 -0.53822295 0.59559392051 0.0124382943 # learning 0.320332116 0.16852032 1.90085160 0.06992534595 0.1357684079 # raises 0.081732134 0.22147768 0.36903102 0.71548008844 0.0058861866 # critical 0.038381447 0.14699544 0.26110638 0.79633426421 0.0029554369 # advance -0.217056682 0.17820947 -1.21798623 0.23557704863 0.0605914609 ``` ## 數據對齊 要微調 LLM,並且保證回答的質量,資料品質自然非常重要,在訓練模型 backbone 部分,我們可以找網路上各種 paper 或相關論壇的回答來保證數據的高質量,然而,在問答模型中,我們對於數據需求是高質量的 "對齊" 數據,也就是 "問題" 與 "回答" 都要是高質量數據,才能夠保證模型品質。在網路論壇獲取的資料多半是良莠不齊的問答,進而可能產生數據污染的難題,那麼要如何獲取高質量對齊數據呢? 目前已知的管道如下 - **Self-Instruct:** - 讓 ChatGPT 為你量身訂做一筆高質量的對齊數據,因為 ChatGPT 本身就是高質量的模型,但是該方案需要申請 API,並且也違反了 OpenAI 的規章 :::danger 禁止使用 ChatGPT 的輸出對 OpenAI 進行競爭 ::: - **私有數據:** - 由機構各自蒐集數據,數據的問答主要由該機構提供,並非調用 API 生成 - **[ShareGPT](https://sharegpt.com/):** - ShareGPT 是一個公開網站,讓用戶自主公開與 ChatGPT 的對話內容 ## 模型選擇 目前問答模型的先驅有 Alpaca、Vicuna 等等。在 hf 網站上提供了一個 LLM 競技場,來比較不同 LLM 之間的能力 - [Leaderboard](https://huggingface.co/spaces/lmsys/chatbot-arena-leaderboard) | Model Name | LLaMA | Alpaca | Vicuna | Bard/ChatGPT | | ------------------- | -------------------------------------- | ------------------------------------------------ | --------------------------------------- | ------------ | | Dataset | Publicly available datasets (1T token) | Self-instruct from davinci-003 API (52K samples) | User-shared conversations (70K samples) | N/A | | Training code | N/A | Available | Available | N/A | | Evaluation metrics | Academic benchmark | Author evaluation | GPT-4 assessment | Mixed | | Training cost (7B) | 82K GPU-hours | $100 (training) $500 (data) | $140 (training) | N/A | | Training cost (13B) | 135K GPU-hours | N/A | $300 (training) | N/A | Alpaca 和 Vicuna 皆使用了 LLaMA 作為基礎模型,接下來我們來看看兩者之間的差別吧 ### Alpaca Standford Alpaca 在 Meta 開源的 LLaMA 上面進行全參數的微調。主要的目的是要讓 AI 學會 - 強大的基礎 LM - 高質量的 instruction data 在 Alpaca 的設計中,Standford 選用 Meta 的 LLaMA-7B 做為 base model,並使用 Self-Instruct 的方式微調,所謂的 "Self-Instruct" 指的是使用較大的模型生成數據來訓練小的模型,其概念類似於知識蒸餾。 ![image](https://hackmd.io/_uploads/Hki_3HRYT.png) ### Vicuna Vicuna 使用 ShareGPT 來獲取 "多樣性" 的數據,在 ShareGPT 中,用戶多上傳自己認為有趣的問答,因此在多樣性上,相較於調用 API 生成的 Alpaca,Vicuna 表現更生動。但是相較於調用 API 生成的數據,用戶上傳數據多半包含格式錯誤,語法等問題,因此在數據清洗方面作者下了很大的功夫。 ![image](https://hackmd.io/_uploads/rJRhua4cT.png) 在訓練方面,作者改進了以下三點: - **Multi-turn conversations:** 在一些問題中,答案不是通過一次提問就可以獲得的,當要透過多次提問才能夠獲取答案,我們就稱為 Multi-turn conversations,作者在計算 loss 時,只單獨計算 chatbox's output 作為損失 - **Memory Optimizations:** 為了讓模型在長文任務上表現更好,作者將 max_length 從 512 提升為 2048。並使用了 [gradient checkpoint](https://arxiv.org/pdf/1604.06174.pdf) 和 [FalshAttention](https://arxiv.org/pdf/2205.14135.pdf) 減少內存占用 - **Cost Reduction via Spot Instance:** 訓練長文本數據是一個非常耗時的任務,作者使用開源項目 [SkyPilot](https://github.com/skypilot-org/skypilot) [manage spot](https://skypilot.readthedocs.io/en/latest/examples/spot-jobs.html) 的方式減少開支與時間 ## Reference - [https://lmsys.org/blog/2023-03-30-vicuna/](https://lmsys.org/blog/2023-03-30-vicuna/) - [https://zhuanlan.zhihu.com/p/618389519](https://zhuanlan.zhihu.com/p/618389519)