使用 llama.cpp 自己架一個 OpenAI 相容伺服器

| | 0 Comments| 10:01
Categories:

之前有介紹過 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(官網)也是一個選項;這部分網路上也有很多教學可以參考了。


Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *