之前有介紹過 whisper.cpp 這個採用 C API、透過 Whisper 來進行深度學習的語音辨識的專案了。而當時也有提到,該專案作者 Georgi Gerganov 其實還有另一個類似架構、是以 C++ 來實作的大語言模型(LLM、large language model)推論專案、llama.cpp(GitHub)。
llama.cpp 最早是為了可以使用 Meta LLaMA 這個模型來在 local 端進行推論而開發的,所以名稱才會叫做 llama.cpp;不過實際上,他現在能支援的模型中類相當地多,除了 LLaMA 1/2/3 外,其他像是 Mistral、Phi、Grok-1 等模型也都支援,算是相當方便。
而他特色包括:
- 單純使用 C/C++ 來實作,可以在沒有任何相依性的狀況建置
- 支援 NVIDIA CUDA、Vulkan、SYCL、OpenCL、AVX 系列指令集等加速方法
- 提供了一個輕量化的 OpenAI API 相容的 HTTP 伺服器,可以給其他 OpenAI 相容的工具使用
由於這個專案算是目前最好用的推論專案之一,所以使用者相當地多,不但基於他開發的東西很多、也有各種語言的 binging 可以使用。
而這邊呢,則是先不管它作為函示庫的功能,先來記錄一下怎麼透過他來架設一個 OpenAI API 相容的伺服器吧~
下載程式
由於這邊只是單純要使用,所以就不先研究怎麼自己建置、而是直接下載官方提供的建置好的版本了。要下載官方建置好的版本,可以直接到 GitHub 的 release 頁面(連結)去找最新版。
而要下載的話,基本上就是要根據自己的作業系統、要使用的加速方法、來選擇要下載的檔案。像是如果要在 Windows 系統上、透過 NVIDIA 顯示卡來做加速的話,就可以選擇「llama-b2901-bin-win-cuda-cu12.2.0-x64.zip
」這樣名稱的檔案。不過因為他更新的很頻繁,所以版本更動的也很快、所以前面版本的數字會一直變。
下載完成解壓縮後,裡面會又大量的可執行檔,可以拿來做簡單的操作、測試。
如果只是要透過命令提示字元來玩看看的話,可以執行「main.exe
」;而如果是要建立 OpenAI API 相容伺服器的話,則可以用過「server.exe
」這隻程式來做到。
取得模型
首先,在官方 README.md(連結)裡面,已經提供了他有支援的模型列表,很多也有附上連結可以去下載。不過 llama.cpp 這邊要讀取的模型檔案格式是 gguf,所以大部分官方提供的模型都不能直接用、會需要先轉換格式。
如果是想玩台灣的正體中文的話,可以先拿唐鳳上傳的 Taiwan LLM(連結)來試試看。
在進入 HuggingFace 的頁面後,點選「Files and versions」就可以進到檔案列表的頁面(連結),這邊就可以看到有好幾種透過不同參數轉換出來的 gguf 格式的模型可以下載了。
這邊會看到,這邊有很多檔案、檔案名稱都不完全相同,代表的其實就是從原始模型轉換成 gguf 時的參數。在《Overview of GGUF quantization methods》這邊就做一些說明:
- 傳統量化法:檔名最後會是「
Qn_0
」或「Qn_1
」這樣的形式。 - 「
n
」會是數值、代表量化的參數,理論上的數值越小、代表模型檔案越小、但是精確度可能越低。 - 後面的「
_0
」代表有一個額外的常數、「_1
」則是有兩個額外的常數。
所以「_1
」的模型會更大一點、效果應該也會更好一點。 - K-quants:檔案名稱會是「
Qn_K_x
」這樣的形式。 - 「
n
」會是數值、代表量化的參數,不過實際上模型內部不同的參數可能會用不同的量化參數 - 「
x
」比較常見是S
/M
/L
,基本上會代表最後模型的大小。
其中,K-quants 比較複雜,詳細的說明可以參《k-quants》這篇;以「Q3_K_x
」來說:
- 「
Q3_K_S
」:全部都用「GGML_TYPE_Q3_K
」來量化 - 「
Q3_K_M
」:部分參數用「GGML_TYPE_Q4_K
」、其它的用「GGML_TYPE_Q3_K
」 - 「
Q3_K_L
」:部分參數用「GGML_TYPE_Q5_K
」、其它的用「GGML_TYPE_Q3_K
」
在上面的頁面中,也有提供各種參數的比較;這邊可能就是需要根據自己的記憶體大小(尤其在用顯示卡來跑的時候)、還有想要的速度/效果來選擇了。
Heresy 這邊是先使用唐鳳的「Taiwan-LLM-7B-v2.1-chat-Q5_K_M.gguf
」這個模型來做測試,要下載的話只要在檔案列表頁面中間找到那個下載按鈕(向下的箭頭),點下去就可以下載了。
而這邊也可以注意到,檔案名稱中還有個「7B」,這代表這個模型使用的參數量。而大部分的 LLM 模型其實都有不同參數量的版本,可能會是 7B、13B、20B 這類的數值;基本上也是越大效果會越好,但是所需要的記憶體、處理時所需要的時間也都會增加。
不過太大的模型…像是 LLaMa 2 的 70B 模型就算是 Q4 也快要 40GB、一般顯示卡根本塞不進去了。 XD
執行伺服器
程式和模型都準備好了後,接下來就可以來把伺服器跑起來了~
llama.cpp 的伺服器的完整說明可以參考官方文件(連結),要執行的時候,最簡單的指令會是:
server.exe -m D:\llm_model\Taiwan-LLM-7B-v2.1-chat-Q5_K_M.gguf
執行起來後,可以先透過網頁瀏覽器開啟 http://127.0.0.1:8080/,就可以看到他測試用的頁面了~
這時候只要在最下面的「Say something…」輸入內容、然後按下「Send」就可以開始和 AI 模型開始交談了。(「Upload image」需要特別的模型,這邊不能用)
不過,這樣最簡單的指令基本上「不會」用到 GPU、而是會使用 CPU 來跑,所以回復的速度其實有點慢。如果要讓它使用 GPU 來加速的話,則可以加上「--n-gpu-layers
」這個參數(可以用
-ngl
來簡化)、指定要把多少層(layer)丟到 GPU 上來處理。
像下面的指令就是指定 GPU 要處理的層數為 99,基本上應該會是整個模型,所以速度應該會大幅增加~
server.exe -m D:\llm_model\Taiwan-LLM-7B-v2.1-chat-Q5_K_M.gguf -ngl 99
不過不知道為什麼,在 Heresy 這邊他大多只會回復很短的內容,而且常常會出現「�」、然後會異常地中斷。 XD
這個問題該怎麼處理呢?就先再說吧。 :p
而實際上 llama.cpp 的 server.exe 還有很多參數可以用,這邊就看要根據自己的需求來看要怎麼下參數了。
像是官方的範例就還有加上「-c 2048
」,來增大 prompt context 的大小。
如果還需要使用 embedding 的功能(如果要跑 RAG 等功能的話)的話,那就還需要加上「--embeddings
」這個參數才行。
此外,如果是想讓伺服器固定放著跑、又不想讓其他人可以亂用,也可以透過「--api-key
」或「--api-key-file
」來指定 API Key、做一定程度的存取限制。
這樣的伺服器架起來之後,其實重點不在它的網頁介面,而是它提供相容於 OpenAI API 的服務。所以如果是自己在學習怎麼去使用 OpenAI 的服務、或是在使用基於 OpenAI 服務的第三方軟體的話,那就有可能可以不要去使用 OpenAI 官方的服務、而是使用自己架設的伺服器了!
像是以 OpenAI 官方的 JavaScript 函式庫(文件)來說,本來的範例是:
import OpenAI from "openai"; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY, }); const chatCompletion = await openai.chat.completions.create({ messages: [{ role: "user", content: "Say this is a test" }], model: "gpt-3.5-turbo", }); console.log(chatCompletion.choices);
這邊就可以把建立 openai
的物件那邊改成:
const openai = new OpenAI({ apiKey: "NoNeed", baseURL: "http://127.0.0.1:8080" });
這樣就可以用自己架設的 llama.cpp 的伺服器、來進行相容 OpenAI API 的開發了。
而如果遇到某些現成的 App 有支援 OpenAI、而且可以修改 API 的 URL 的話,那就有機會可以把它改成連到自己的伺服器來使用了!
這樣一來,就不用擔心自己的測試資料跑出去、也不會擔心在亂玩的過程中把 OpenAI 的 token 消耗光了。
不過實際上,llama.cpp 的 OpenAI 伺服器的功能不見得完整、所以某些特殊功能可能不見得可以用(這部分可以參考 Ollama 的功能列表);像是 function calling 在 llama.cpp 在這個時間點應該還沒有實作(issue)。所以如果遇到要呼叫不支援的功能的時候,就會無法正常運作了。
再來,就是由於每個模型的運作方法還是不太一樣、所以直接改用其他模型的時候,回復的模式、呈現出來的結果也不見得好就是了。
最後,不是所有軟體都可以修改 base URL 也是另一個問題了~ XD
像是 PowerToys 在 0.81 加入的「進階貼上」功能就只能連到 OpenAI 官方服務,不能透過改用自己的伺服器,所以連想玩都不行。
最後,使用的模型的部分,如果沒有特別要找中文模型,現階段使用 Meta 最新的 LLaMa 3(連結)會比較好?如果是要搭配 llama.cpp 使用的話,在 HuggingFace 上也可以找到別人轉成 gguf 的版本(連結)。
而如果想要中文模型的話,後來台灣的 TAIDE(官網)有釋出基於 LLaMa 3 的中文版模型(網頁)可以使用。
另外,如果要功能比較多的伺服器的話,改用基於 llama.cpp 開發的 Ollama(官網)也是一個選項;這部分網路上也有很多教學可以參考了。