大模型入門指南

隨着 ChatGPT 的到來,大模型 [1](Large Language Model,簡稱 LLM)成了新時代的 buzzword,各種 GPT 產品百花齊放。

大多數人直接用現有產品就可以了,但對於喜歡刨根問底的程序員來說,能夠在本地運行會更有意思。但由於沒有相關背景,筆者一開始在接觸時, 很多 GitHub 上的搭建教程看得是雲裏霧裏,而且這方面的介紹文章要不就是太晦澀難懂,要不就是太大衆小白,於是就有了這篇文章, 主要介紹筆者在搭建大模型過程中學到的知識,以及如何在 macOS 上運行大模型。 筆者水平有限,不足之處請讀者指出。

什麼是大模型

通俗來講,大模型就是輸入大量語料,來讓計算機獲得類似人類的 “思考” 能力,使之能夠理解自然語言,能夠進行『文本生成』、『推理問答』、『對話』、『文檔摘要』等工作。

既然是學習,那我們就可以用『上學參加工作』這件事來類比大模型的訓練、使用過程:

  1. 找學校 :: 訓練 LLM 需要大量的計算,因此 GPU 更合適,因此只有購買得起大量 GPU 的貴族學校纔有資本訓練自己的大模型

  2. 確定教材 :: 大模型顧名思義就是大,需要的數據量特別多,幾千億序列(Token)的輸入基本是標配

  3. 找老師 :: 即用什麼樣的算法講述 “書本” 中的內容,讓大模型能夠更好理解 Token 之間的關係

  4. 就業指導 :: 學完書本中的知識後,爲了讓大模型能夠更好勝任某一行業,需要進行微調(fine tuning)指導

  5. 搬磚 :: 就業指導完成後,下面就要正式幹活了,比如進行一次翻譯、問答等,在大模型裏稱之爲推導(infer)

在 LLM 中,Token[2] 被視爲模型處理和生成的文本單位。它們可以代表單個字符、單詞、子單詞,甚至更大的語言單位,具體取決於所使用的分詞方法(Tokenization)。 Token 是原始文本數據與 LLM 可以使用的數字表示之間的橋樑。在將輸入進行分詞時,會對其進行數字化,形成一個詞彙表(Vocabulary),比如:The cat sat on the mat,會被分割成 “The”、“cat”、“sat” 等的同時,會生成下面的詞彙表:

obTkV8

數字化的好處是便於計算機處理。但爲了讓計算機理解 Token 之間的聯繫,還需要把 Token 表示成稠密矩陣向量,這個過程稱之爲 embedding[3],常見的算法有:

以 Transform 爲代表的大模型採用自注意力(Self-attention)機制來學習不同 token 之間的依賴關係,生成高質量 embedding。

大模型的 “大”,指的是用於表達 token 之間關係的參數多,主要是指模型中的權重(weight)與偏置(bias),例如 GPT-3 擁有 1750 億參數,其中權重數量達到了這一量級,而詞彙表 token 數只有 5 萬左右。參考:

發展歷程

這一切的起源是 2017 年發佈的 Attention Is All You Need[4] 論文,之後基於大量語料的預訓練模型百花齊放,比如:

模型部署

由於在大模型的參數非常多,比如在 GPT-2 中,有 1.5B 參數,每個參數用 float32 表示,那麼需要的內存大小爲 4 bytes * 1,500,000,000 = 6GB ,更先進的模型如 LLAMA 有 65B 參數,那麼需要的內存就需要 260G,這還是在不考慮詞彙表的情況下。因此在進行模型實際部署時,會進行模型的壓縮。

而且,在訓練 LLM 中,CPU 與內存之間的傳輸速度往往是系統的瓶頸,核心數反而不是大問題,因此減小內存使用是首要優化點。使用內存佔用更小的數據類型是一種直接的方式,比如 16 位的浮點數就可以直接將內存使用減倍。目前有幾種相互競爭的 16 位標準,但英偉達在其最新一代硬件中引入了對 bfloat16 的支持,

aASyNd

量化 Quantization

將 16 位降至 8 位或 4 位是可能的,但不能使用硬件加速浮點運算。如果我們想對更小的類型進行硬件加速,就需要使用小整數和矢量化指令集。

這就是量化的過程。量化技術可以應用到現有的 32 位浮點運算模型中,通過將權值轉換爲較小的整數,這些整數的運算可以使用硬件加速指令集,如英特爾的 AVX。

量化模型的簡單方法是,首先找出權重的最大值和最小值,然後將數值範圍劃分爲整數類型中可用的桶數,8 位爲 256 桶,4 位爲 16 桶。這就是所謂的訓練後量化(post-training quantization),也是量化模型的最簡單方法。現在市面上主要有兩類量化方法:

社區用戶 TheBloke[6] 把 Huggingface Transformers 庫中的大多數 LLM 應用這些量化方法,這無疑極大方便了用戶的使用。

動手實驗

由於筆者實用的 macOS 系統,因此採用 GGML 量化後的模型,官方開源出來的模型大都以 Python 爲主,效率可想而知,因此筆者一般會採用社區內的其他實現,比較有名的項目有:

LLama

首先是編譯,爲了利用 Metal 的 GPU,可以用如下命令編譯:

LLAMA_METAL=1 make

之後需要去 Llama-2-7B-Chat-GGML[9] 中下載模型,3G 到 7G 不等,讀者可以按需嘗試即可。

./main -m ~/Downloads/llama-2-7b-chat.ggmlv3.q4_1.bin \
       -p "Building a website can be done in 10 simple steps:" -n 512 -ngl 10

得到輸出

 Building a website can be done in 10 simple steps:

 planning, domain name registration, hosting choice, selecting a CMS or building from scratch, developing the site content, designing the user interface, coding and debugging, testing for usability, and launching it.

 Planning involves setting goals and objectives for your website, identifying your target audience, and determining its purpose.

 Domain name registration is choosing a unique web address that reflects your brand or business identity.

 Choosing the right hosting service ensures that your website loads quickly and efficiently. Popular choices include Bluehost, SiteGround, and
 HostGator.

 Selecting a Content Management System (CMS) or building one from scratch allows you to easily manage and update content without needing technical knowledge. Options include WordPress, Joomla, and Drupal.

 Developing website content involves creating text, images, videos, and other media that convey your message and provide value to users.

 Designing the user interface (UI) focuses on visual aspects of your site such as layout, color scheme, typography, and navigation.

 Coding ensures your site functions correctly by writing clean HTML, CSS, and JavaScript code. Debugging involves identifying and fixing any errors or bugs that arise during testing.

 Testing for usability means checking how easy it is for users to navigate through your site and find the information they need.
Launching involves making your website live for all visitors to access, and promoting it through marketing channels such as social media and search engines. [end of text]

llama_print_timings:        load time =  1267.46 ms
llama_print_timings:      sample time =   204.14 ms /   313 runs   (    0.65 ms per token,  1533.23 tokens per second)
llama_print_timings: prompt eval time =   397.22 ms /    14 tokens (   28.37 ms per token,    35.25 tokens per second)
llama_print_timings:        eval time =  9504.40 ms /   312 runs   (   30.46 ms per token,    32.83 tokens per second)
llama_print_timings:       total time = 10132.02 ms
ggml_metal_free: deallocating

此外,llama.cpp 還提供了 WebUI 供用戶使用,首先啓動 server:

./server -m ~/Downloads/llama-2-7b-chat.ggmlv3.q4_1.bin -ngl 512

它默認監聽 8080 端口,打開瀏覽器就可以對話了

Whisper

和 llama 類似,採用 make 命令編譯,之後去 ggerganov/whisper.cpp[10] 下載量化好的模型,然後轉換音頻即可,目前只接受 wav 格式,可以用 ffmpeg 轉化

ffmpeg -loglevel -0 -y -i "$INPUT" -ar 16000 -ac 1 -c:a pcm_s16le "${INPUT}.wav"

./main -m models/ggml-small.bin -f "$INPUT" \
        -osrt -t 8 -p 4

輸出的 srt 文件如下所示:

1
00:00:00,000 --> 00:00:05,520
 Hello everyone and welcome to another episode of the Form 3 TET podcast.

2
00:00:05,520 --> 00:00:08,800
 My name is Kevin Holtich, head of Pat from Engineering at Form 3.

3
00:00:08,800 --> 00:00:12,560
 Today I'm really excited that I've been joined by Torsten Ball.

4
00:00:12,560 --> 00:00:13,920
 How's it going, State Torsten?

o9kh88

一般來說,英文的音頻 small 模型就有夠了,但是如果是中文,最好用最大的模型。

免費的 LLM 產品

儘管 ChatGPT 是收費的,而且還不面向中國,但現在市面上有非常多的其他選擇,比如 Google 的 Bard[11],下圖給出了一些常用服務, 讀者都可以去體驗試試: 

單就寫代碼這個垂直領域來看,GitHub 的 Copilot[12] 無疑是老大哥,但它並非免費,下面有幾個替代品:

總結

說來可笑,ChatGPT 的開發者 OpenAI 並不像其名字那樣開放,ChatGPT 的源碼與模型數據是不對外開放的,但不久, Meta 在 2023 年 2 月份開源了 LLaMA 1[19],並在 7 月接着發佈了進階的 Llama 2[20],而且允許商用。 Meta 此舉無疑極大推進的大模型的發展,坊間甚至一度流傳這麼一篇文章:[Google "We Have No Moat, And Neither Does OpenAI"](https://www.semianalysis.com/p/google-we-have-no-moat-and-neither "Google"We Have No Moat, And Neither Does OpenAI""),說 Meta 纔是大模型時代的最大贏家, OpenAI、Google 都要靠邊站。

大模型時代到來了,你的工作離被取代還遠嗎?

參考

參考資料

[1]  大模型: https://en.wikipedia.org/wiki/Large_language_model

[2]  Token: https://learn.microsoft.com/en-us/semantic-kernel/prompt-engineering/tokens

[3]  embedding: https://learn.microsoft.com/en-us/semantic-kernel/memories/embeddings

[4]  Attention Is All You Need: https://arxiv.org/abs/1706.03762

[5]  GPTQ: https://arxiv.org/abs/2210.17323

[6]  TheBloke: https://huggingface.co/TheBloke

[7]  ggerganov/llama.cpp: Port of Facebook's LLaMA model in C/C++: https://github.com/ggerganov/llama.cpp

[8]  ggerganov/whisper.cpp: Port of OpenAI's Whisper model in C/C++: https://github.com/ggerganov/whisper.cpp

[9]  Llama-2-7B-Chat-GGML: https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGML

[10]  ggerganov/whisper.cpp: https://huggingface.co/ggerganov/whisper.cpp/tree/main

[11]  Bard: https://bard.google.com/

[12]  Copilot: https://github.com/features/copilot

[13]  Tabnine: https://www.tabnine.com/

[14]  Codeium: https://codeium.com/

[15]  Amazon CodeWhisperer: https://aws.amazon.com/codewhisperer/

[16]  SourceGraph Cody: https://about.sourcegraph.com/cody

[17]  Tabby: https://tabbyml.github.io/tabby/

[18]  fauxpilot/fauxpilot: https://github.com/fauxpilot/fauxpilot

[19]  LLaMA 1: https://ai.meta.com/blog/large-language-model-llama-meta-ai/

[20]  Llama 2: https://ai.meta.com/blog/llama-2/

[21]  Announcing GPTQ & GGML Quantized LLM support for Huggingface Transformers – PostgresML: https://postgresml.org/blog/announcing-gptq-and-ggml-quantized-llm-support-for-huggingface-transformers

[22]  Beginner's guide to Llama models: https://agi-sphere.com/llama-guide/

[23]  Demystifying Tokens in LLMs: Understanding the Building Blocks of Large Language Models 🧱🔍: https://www.linkedin.com/pulse/demystifying-tokens-llms-understanding-building-blocks-lukas-selin/

[24]  Awesome-LLM: a curated list of Large Language Model: https://github.com/Hannibal046/Awesome-LLM

[25]  搞懂語言大模型(番外):40 + 應用案例精選: https://sspai.com/post/80071

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