快轉到主要內容

五分鐘上手 Ollama - 在本機跑 LLM 語言模型

Ollama 可以在自己的電腦跑大型語言模型!無論是有名的像 Llama3, Phi-3 等等,或是別人的 GGUF 模型都可

我以 Macbook Air M1 為例,介紹「安裝」、「跑法」和「API 互動」。 下一篇文章將會有下載台灣繁體 LLM: TAIDE, 做 Modelfile, 並用 Ollama 在筆電上執行!

安裝 #

https://ollama.com/ 點 “Download” 按鈕,選擇你的作業系統,會有不同安裝方式

The download page of Ollama.  Different OS, different way
下載/安裝頁面。Apple Silicon 可用

如果是 Mac, 下載後解開執行,簡單照著指示放到應用程式即可。雖然是應用程式,不過實際要跑模型的時候是用命令列

文件 #

文件的連結在右下有個很小的 “Docs”, 目前是直接連到 github

跑法 #

打開終端機,在命令列輸入文字 ollama run <模型名稱>,就會先把模型下載到本機,然後執行模型

例如想要玩個微軟出的「小」模型 phi3:

$ ollama run phi3
  • 也可以 ollama pull <名字> 只下載模型不跑
  • ollama list 可顯示本機下載了哪些模型
  • ollama rm <名字> 可刪除下載的模型
  • 模型儲存在 ~/.ollama/models/ ; log 也在 ~/.ollama/logs/server.log

不過要怎麼知道模型的名稱呢?

支援的模型 #

Ollama 也是個 Hub, 點右上角的 “Models” 以後,中間會出現一些「有名的」模型

點進去某個模型會有其資訊、版本、以及 ollama run 的名稱

llama 3 model card
Ollama 的 model card

Ollama 模型頁面的 “template” 在 本篇後半部會解釋。“params” 會在 下一篇解釋

普羅大眾也能上傳模型到 Ollama 網站,讓大家 pull/run (目前是 early alpha),不過普通人的模型目前不會在 Models 那頁出現,要用右上角的搜尋框

The initial cli interface of ollama run

而 Ollama 也可以跑 GGUF 檔,我將會在 下一篇文章介紹

聊天介面 #

ollama run 下載完模型後會出現「文字模式」的互動,可以在裡面正常聊天,在同個執行內會記得前面聊什麼。按 ctrl-d 或輸入 /bye 離開

ollama run chat has context

一開始輸入三個引號 “"",就可以放心 enter 輸入多行的文字

Enter multi-lines in ollama run

不想這麼陽春?官方有列出 超 多 實用的圖形介面整合,例如 Ollama WebUI

怎麼關掉 Ollama #

「這什麼蠢問題?不是 ctrl-c 或是 ctrl-d 就好了嗎?」

其實 ollama run 「結束」以後,服務還在 port 照 bind,可以 ps 看到。雖然一段時間沒跑模型以後,模型就會從記憶體裡卸載,但如果有潔癖的話,可以在 Mac menu bar 右上角看到 Ollama 的圖示,點下去 Quit 就行

Ollama icon in Mac menu bar; quit from there
右上角有羊駝圖示,用來關掉 Ollama

(Linux 我沒試過,不過聽說用 systemctl 可以關掉 ollama)

API 介面 #

所謂 API 就是

  • 讓 Ollama 變成服務;不需要他的聊天介面
  • 透過寫程式跟 Ollama 溝通

接下來介紹用 python 或 HTTP API 去溝通;想開發自己的 RAG / Agent 時很有幫助

啟動 Ollama 服務 #

ollama serve 不要指定模型名稱,只要是已經下載的都可以呼叫執行

$ ollama serve

如果出現下列錯誤訊息,通常是因為 ollama 已經啟動、正在服務,只是之前沒關乾淨

$ ollama serve
Error: listen tcp 127.0.0.1:11434: bind: address already in use

不用擔心,直接看下一段怎麼用 python 跟模型溝通吧!

Python SDK #

Ollama 有 python 函式庫pip install ollama 安裝就可使用

最主要有兩個 function: chatgenerate

  • Chat : 一來一往的對話,有人類 (user) 跟機器人 (assistant) 兩種角色
  • Generate : 語言模型最基本的運作:文字接龍。給單一長串文字,去生成接下來的文字

在呼叫的時候要當場指定模型。下面是 chat 的例子

import ollama

question_1 = "What is 2+2?"

ans_1 = "2 + 2 equals 4. This is a basic arithmetic operation where you are " \
        "adding the number 2 to another number 2, resulting in 4."

question_2 = "Add 3 onto the last answer. What is it now?"

response = ollama.chat(
    model="phi3",
    messages=[
        {"role": "user", "content": question_1},
        {"role": "assistant", "content": ans_1},
        {"role": "user", "content": question_2}
    ]
)

print(response["message"]["role"])
print(response["message"]["content"])
  • .chat(model=,) 指定用哪一個模型
  • messages 是訊息一來一往、多次來回對話:是一個 list,而且由 user 與 assistant 兩種角色 (role) 交錯
  • 如果要讓聊天有「記憶」,就要把之前的對話一起傳入。例如例子中的第二個問題(第三個訊息),只說了把 3 加上「上次的答案」。然而,因為有第一句問題與第二句回答,所以模型知道「上次的答案」是什麼
  • 詳細的文件在 ollama-python 的 github

generate 呢?

import ollama

question_1 = "What is 2+2?"

ans_1 = "2 + 2 equals 4. This is a basic arithmetic operation where you are " \
        "adding the number 2 to another number 2, resulting in 4."

question_2 = "Add 3 onto the last answer. What is it now?"

prompt = f"""<|user|>
{question_1}<|end|>
<|assistant|>
{ans_1}<|end|>
<|user|>
{question_2}<|end|>
<|assistant|>
"""

response = ollama.generate(
    model="phi3",
    prompt=prompt
)

print(response["response"])

看例子的最後幾行:generate 跟 chat 最大分別是,generate 只有給模型一串很長的文字 – 單純就是做文字接龍而已,不一定代表對話

不過,如果要用 generate 代表多輪的對話,但只能傳一串,要怎麼分辨誰問誰答?看例子的中段,我用特殊的 token <|user|>, <|assistant|> 之類的隔開,把多輪對話組成一整串文字

不同模型有不同 token、不同隔開的格式,我怎麼知道 phi3 模型是這樣組合?總算要講到 model template

模型 template #

The model template in a model card

在模型那一頁會有 template,代表怎麼用一個 prompt 代表多角色的對話,通常是:

  1. {{ .System }}: 可有可無的「系統」資訊(告訴這模型做什麼樣子的行為或角色扮演)在最前面
  2. {{ .Prompt }}: 然後是「使用者」的輸入,例如問題或敘述
  3. {{ .Response }}: 然後是「機器人」也就是模型的回答

所以例如 phi3,我就根據他的 template,把對話用 <|user|>...<|end|><|assistant|>...<|end|>... 的形式傳給他

一個模型的 template ,是當初在「訓練」的時候餵給他資料的模式。因此不同模型可能會有不同的模式

如果你是訓練模型或包模型下一篇解釋),那 template 就很重要,需要寫好給使用模型的人

但如果你是使用模型的人,其實是可以用 chat 來進行「對話」,不一定要用 generate 自己塞成一串字

HTTP API / REST API #

上述的 python 函式庫其實只是呼叫 Ollama 的 HTTP API,所以也可以用下面的方法得到模型 output

curl http://localhost:11434/api/chat -d '{
  "model": "phi3",
  "messages": [
    { "role": "user", "content": "What is 2+2?" }
  ]
}'

不過如果真的執行,會得到下面的結果

Ollama HTTP API is streaming by default

那是因為和 Python SDK 不一樣,HTTP API 預設的 streaming 是開的,也就是一有結果就會馬上輸出,所以看到的結果是分段一個字一個字的

如果希望 ollama 一口氣把結果完成以後才輸出,要主動加 "stream": false

curl http://localhost:11434/api/chat -d '{
  "model": "phi3",
  "messages": [
    { "role": "user", "content": "What is 2+2?" }
  ],
  "stream": false
}'

和之前講的一樣,除了 /api/chat 這種一來一往有角色的對話以外,也可以回歸本質用文字接龍的 /api/generate 。詳細的文件在 Ollama 的 github


下一篇將會下載台灣的繁體模型: TAIDE, 做 Modelfile, 並用 Ollama 在筆電上執行,以及分享記憶體不夠的慘痛經驗!

若您覺得有趣, 請 追蹤我的Facebook 或  Linkedin, 讓你獲得更多資訊!