﻿# 介紹好用工具：Ollama 快速在本地啟動並執行大型語言模型

我最近在嘗試多套 LLM 大語言模型，原本都採用 [LM Studio](https://lmstudio.ai/) 來實驗，但後來發現 [Ollama](https://ollama.com/) 還蠻符合我需求的，而且非常容易上手，所以這篇文章我打算來分享一下 Ollama 的使用方式。

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/4c5381dfc66f13758aef-5772464c-303c-40f5-a075-212bf25931b9.webp)

### 啟動 Ollama 容器

上個月 Ollama 推出了 Windows 版本，但目前還在 Preview 階段，可能會不太穩定，所以我並沒有特別跑去嘗試。而且我個人不是非常喜歡在電腦裝太多程式，如果可以，我還是比較傾向使用 Docker 容器來跑，所以我通常都會使用 Docker 容器來啟動 Ollama。

```bash
docker run --name ollama -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 ollama/ollama
```

啟動之後，Ollama 會自動在本機監聽一個 Port `11434` 來提供服務，他提供跟 OpenAI Platform [相容的 API 介面](https://github.com/ollama/ollama/blob/main/docs/api/openai-compatibility.mdx)，要在本機整合這些 LLM 來用，真的相當方便！

你可以連接 [http://localhost:11434/](http://localhost:11434/) 看看是否顯示 `Ollama is running` 字樣，如果有的話，就代表 Ollama 已經成功啟動了。

透過 `curl` 也可以非常輕鬆的呼叫 Ollama 內建的 [REST APIs](https://github.com/ollama/ollama/blob/main/docs/api.md)：

```bash
curl http://localhost:11434/api/tags
```

### 執行 Ollama 並載入模型

你可以從 [Ollama Library](https://ollama.com/library) 找到所有已經上架的 Models (模型)，然後透過一個簡單的 `docker exec` 命令，就可以自動下載並啟動一個 CLI 介面，讓你可以快速進行推論，直接跟該模型聊天！

我們以最近很夯的 [`gemma`](https://ollama.com/library/gemma) 模型為例，這是一套由 Google DeepMind 推出的開源免費的 LLM 模型，你可以透過以下命令來啟動，這個命令預設會啟動 [gemma-7b](https://huggingface.co/google/gemma-7b) 模型，第一次執行會自動從 [google/gemma-7b · Hugging Face](https://huggingface.co/google/gemma-7b) 下載模型：

```bash
docker exec -it ollama ollama run gemma
```

> 上述命令 `docker exec -it ollama` 是指定要在 `ollama` 容器執行，而 `ollama run gemma` 才是我們要在容器中執行的命令。

![docker exec -it ollama ollama run gemma](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/24a0f9a03f2631a6af96-7a3b6ef6-412c-48d3-b769-81dde3685428.jpg)

由於不同的 LLM 模型有多種不同的規格大小，目前 Ollama Library 有提供 `2b` 與 `7b` 的版本，所以你也可以這樣啟動：

```bash
docker exec -it ollama ollama run gemma:2b
```

```bash
docker exec -it ollama ollama run gemma:7b
```

不過，你若進入 [`gemma`](https://ollama.com/library/gemma) 模型的 [Tags](https://ollama.com/library/gemma/tags) 頁面，可以看到更多種標籤，例如各種不同量化位元的版本，像是 `7b-instruct-q5_K_M` 模型，你可以可以非常輕易的下載回來玩：

```bash
docker exec -it ollama ollama run gemma:7b-instruct-q5_K_M
```

你可以用以下命令列出目前已經安裝的模型：

```bash
docker exec -it ollama ollama list
```

```
NAME                      ID               SIZE    MODIFIED
gemma:7b-instruct-q5_K_M  556abeb39bfd     5.2 GB  37 minutes ago
gemma:latest              430ed3535049     5.2 GB  41 minutes ago
```

### 使用 Ollama CLI 進行推論

當你啟動了 `ollama run` 之後，你就可以直接跟模型進行對話，你可以用 `/?` 命令查詢幾個簡單的命令，幫助你管理這個 Ollama CLI 介面，也可以幫助你設定聊天的環境。

1.  查詢命令用法
    
    ```
    >>> /?
    Available Commands:
      /set            Set session variables
      /show           Show model information
      /load <model>   Load a session or model
      /save <model>   Save your current session
      /bye            Exit
      /?, /help       Help for a command
      /? shortcuts    Help for keyboard shortcuts
    
    Use """ to begin a multi-line message.
    
    >>> /show
    Available Commands:
      /show info         Show details for this model
      /show license      Show model license
      /show modelfile    Show Modelfile for this model
      /show parameters   Show parameters for this model
      /show system       Show system message
      /show template     Show prompt template
    ```
    
2.  設定與顯示系統提示
    
    ```
    /set system "You are a helpful English to Traditional Chinese translator. You are not a coder. You are good at Traditional Chinese, avoid using Simplified Chinese characters. Provide no explanation. No welcome message. No pleasantries. No small talk in front. Be concise. Just translate the text."
    ```
    
    ```
    /show system
    ```
    
3.  設定回應模式 ( JSON mode )
    
    ```
    /set format json
    ```
    
4.  設定 `temperature` 超參數
    
    ```
    /set parameter temperature 0.5
    ```
    
5.  測試翻譯功能
    
    在 Ollama CLI 介面中，你如果要輸入多行文字，一定要先複製文字下來，然後直接貼上到 CLI 介面中，然後按下 `Enter` 鍵，這樣才能正確的輸入多行文字。
    
    ```
    Translate the text to English and output the result in JSON format with a property: translation
    """
    最近在嘗試把一些 LLM 應用程式跑在 Docker 容器中，但是發現 Docker Desktop for Windows 預設是不支援 NVIDIA CUDA 的，需要特別設定一下才能使用。
    """
    ```
    
    > 另一中輸入「多行」的方法，就是先輸入三個雙引號 `"""`，然後就可以輸入多行了，最後輸入三個雙引號 `"""` 結束，按下 Enter 即可送出。
    
6.  儲存聊天記錄為一個新模型
    
    這個功能我覺得蠻酷的，他可以把我的聊天記錄全部儲存下來，然後儲存成一個新的模型：
    
    ```
    /save translator
    ```
    
    下次你只要輸入以下命令，就可以把上述命令儲存的 `translator` 模型重新載入，他會載入所有之前的聊天記錄：
    
    ```
    docker exec -it ollama ollama run translator
    ```
    
    如果要將模型刪除，可以用 `ollama rm` 命令，相當直覺：
    
    ```
    docker exec -it ollama ollama rm translator
    ```
    
7.  如何清空 Ollama CLI 介面中的歷史紀錄
    
    由於你在 Ollama CLI 載入模型後，他會記錄你的所有對話紀錄，而且前面的聊天記錄都會保存著，這可能會導致你的對話的時候被前面的提示訊息所影響。如果你想要清空這些紀錄，有兩種方法：
    
    第一種：直接輸入 `/bye` 命令或按 `Ctrl+D` 快速鍵退出，然後再重新執行一次
    
    第二種：直接重新載入模型，這樣就會清空所有的歷史紀錄：
    
    ```
    /load MODEL_NAME
    ```
    
    例如：
    
    ```
    /load gemma
    ```
    
8.  退出 Ollama CLI 介面
    
    ```
    /bye
    ```
    

### 使用 Ollama API 進行推論

你可以透過 `curl` 來呼叫 Ollama 提供的 API 服務，無論你用什麼程式語言，都可以輕鬆的在本機整合這些大語言模型。

重點是 Ollama 提供的 API 服務大多都是跟 OpenAI Platform 相容的，例如 `/api/chat` API 就是跟 OpenAI 的 Chat Completions API 相容，`/api/generate` API 就是跟 OpenAI 的 Completions API 相容。你可以透過以下命令來呼叫 `generate` API：

```bash
curl http://localhost:11434/api/generate -d '{
  "model": "gemma",
  "prompt":"Why is the sky blue?"
}'
```

上面這個命令預設會回傳 Streaming 的版本，他會一個字一個字回傳，每一行都是一個 JSON，又稱 [Newline Delimited JSON](https://en.wikipedia.org/wiki/JSON_streaming#Newline-delimited_JSON) (`NDJSON`) 格式，HTTP 回應內容類型為 `application/x-ndjson`，這是一種專門用來實現 JSON streaming 的一種特殊格式，方便你在得到完整內容之前，就可以先處理部分內容！👍

```
{"model":"gemma","created_at":"2024-03-04T14:59:36.98871865Z","response":"The","done":false}
{"model":"gemma","created_at":"2024-03-04T14:59:37.146659434Z","response":" sky","done":false}
{"model":"gemma","created_at":"2024-03-04T14:59:37.307918086Z","response":" appears","done":false}
{"model":"gemma","created_at":"2024-03-04T14:59:37.468489644Z","response":" blue","done":false}
{"model":"gemma","created_at":"2024-03-04T14:59:37.626642242Z","response":" due","done":false}
{"model":"gemma","created_at":"2024-03-04T14:59:37.786657308Z","response":" to","done":false}
...
```

如果你不想要 Streaming 的版本，你可以在 Request Body 中加上 `stream: false`，這樣就會一次回傳完整的結果，但你有可能會等很久才能得到結果：

```bash
curl http://localhost:11434/api/generate -d '{
  "model": "gemma",
  "prompt":"Why is the sky blue?",
  "stream": false
}'
```

完整的 API 說明請見 [API documentation](https://github.com/ollama/ollama/blob/main/docs/api.md)。

如果你想要用 .NET 串接 Ollama 的話，可以考慮 [OllamaSharp](https://github.com/awaescher/OllamaSharp) 套件！👍

### 相關連結

-   [Ollama](https://ollama.com/)
    -   [Blog · Ollama](https://ollama.com/blog)
-   GitHub
    -   [ollama/ollama](https://github.com/ollama/ollama): Get up and running with Llama 2, Mistral, Gemma, and other large language models.
        -   [API](https://github.com/ollama/ollama/blob/main/docs/api.md)
        -   [OpenAI compatibility](https://github.com/ollama/ollama/blob/main/docs/api/openai-compatibility.mdx)
    -   [OllamaSharp](https://github.com/awaescher/OllamaSharp)
