---
# System prepended metadata

title: Ollama 使用過程紀錄

---

# **Ollama 使用過程紀錄**
感謝筆者李維的教學[https://hackmd.io/@Livy5x/H1vqda_Yye](https://)

## 安裝所需內容
1.   [Python安裝](https://www.python.org/)
>  個人習慣使用Python3.10但理論上來說3.11跟3.12也行
2.   [Ollama安裝](https://ollama.com/download) 
## Ollama模型列表
[網址](https://ollama.com/search)
## Ollama常用指令
1. 下載模型
```
ollama pull <model-name>
```
使用範例
```
ollama pull mistral
```
2. 查看已安裝的模型
```
ollama list
```
3. 刪除模型
```
ollama remove <model-name>
```
使用範例
```
ollama remove llama2
```

## 開始下載與設定
1. 下載 mistral 模型
> 預設為C:\Users\\*(你的使用者名字)*\\.ollama
> 如果要更改模型下載位置請<font color="#f00">**最後再執行下面的指令**</font>
 ```
 ollama pull mistral
 ```
> ### 修改模型下載位置
> > 感謝Git上面的[教學](https://github.com/datawhalechina/handy-ollama/blob/main/docs/C2/2.%20Ollama%20%E5%9C%A8%20Windows%20%E4%B8%8B%E7%9A%84%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE.md)
> 1. 進入windows設定，搜尋進階系統設定
> ![image](https://hackmd.io/_uploads/BJNrnNRhkg.png)
> 
> 2. 在進階的選項點選環境變數
>  ![image](https://hackmd.io/_uploads/SkmEMBR2Jg.png)
> 
> 3. 在系統變數(或使用者變數)下新增變數並設定變數值為自己想要塞入的資料夾
> ```
> OLLAMA_MODELS
> ```
> ![image](https://hackmd.io/_uploads/SJKRGrAh1x.png)
> 4. 套用後確定並檢查，在CMD內輸入
> ```
> echo %OLLAMA_MODELS%
> ```
> 確認是否為自己想要的資料夾
> 5.重啟電腦
> > 筆者自己使用時沒有重開一直將模型檔案載入到C:\Users\\*(你的使用者名字)*\\.ollama

2.下載套件
```
pip install ollama numpy
```
> 個人習慣有自己做版控，指令跟正常人不太一樣
> ```python310 -m pip install ollama numpy```
>正常來說照著上面跑或建立[虛擬環境](https://pythonbook.cc/chapters/basic/install-python)就好了
## 實作
1. 建立空資料夾並切換到該資料夾內(在CMD內下指令)
```
cd (自己資料夾的絕對路徑)
```
2. 在自己的建立py檔
3. 程式碼與說明
### 完整的Code
```
import ollama
import json
import os
from numpy import linalg, dot

def parse_paragraph(filename):
    with open(filename, encoding="utf-8") as f:
        return [line.strip() for line in f if line.strip()]

def calc_embeddings(paragraphs):
    return [
        ollama.embeddings(model="mistral", prompt=data)["embedding"]
        for data in paragraphs
    ]
def cache_embeddings(filename, paragraphs):
    embedding_file = f"cache/{filename}.json"

    if os.path.isfile(embedding_file):
        with open(embedding_file) as f:
            return json.load(f)

    os.makedirs("cache", exist_ok=True)

    embeddings = calc_embeddings(paragraphs)

    with open(embedding_file, "w") as f:
        json.dump(embeddings, f)

    return embeddings

def calc_similar_vectors(v, vectors):
    v_norm = linalg.norm(v)
    scores = [dot(v, item) / (v_norm * linalg.norm(item)) for item in vectors]
    return sorted(enumerate(scores), reverse=True, key=lambda x: x[1])

if __name__ == "__main__":
    doc = "prompt.txt"
    paragraphs = parse_paragraph(doc)
    embeddings = cache_embeddings(doc, paragraphs)

    prompt = input("請問你想問什麼問題？\n>>> ")

    while prompt.lower() != "bye":
        prompt_embedding = ollama.embeddings(model="mistral", prompt=prompt)[
            "embedding"
        ]
        #取出前3高分數的段落
        similar_vectors = calc_similar_vectors(prompt_embedding, embeddings)[:3]

        system_prompt = (
            "現在開始使用我提供的情境來回答，只能使用繁體中文，不要有簡體中文字。如果你不確定答案，就說不知道。情境如下："
            + "\n".join(paragraphs[vector[0]] for vector in similar_vectors)
        )

        response = ollama.chat(
            model="mistral",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": prompt},
            ],
        )

        print(response["message"]["content"])
        prompt = input(">>> ")
```
### 程式碼重點解析
這一段程式碼將提示字串切成一行一行
```
def parse_paragraph(filename):
    with open(filename, encoding="utf-8") as f:
        return [line.strip() for line in f if line.strip()]
```
> 原作者是沒有encoding的，但我的電腦被我搞成了預設編碼為cp932(日本編碼):sweat_smile:
> UnicodeDecodeError: 'cp932' codec can't decode byte 0x84 in position 26: illegal multibyte sequence

這一段程式碼將提示字串轉換成向量
```
def calc_embedings(paragraphs):
    return [
        ollama.embeddings(model="mistral", prompt=data)["embedding"]
        for data in paragraphs
    ]
```
> 範例:
> cat → [0.8, 0.1, 0.3]
> dog → [0.9, 0.2, 0.4]
> apple → [0.1, 0.8, 0.9]


下方第1區塊將輸入內容轉換成向量
下方第2區塊similar_vectors[:3] 是用來從 calc_similar_vectors 的結果中取出前三個最相似的向量。

```
prompt = input("請問你想問什麼問題？\n>>> ")
prompt_embedding = ollama.embeddings(model="mistral", prompt=prompt)[
            "embedding"
        ]
```
```
similar_vectors = calc_similar_vectors(prompt_embedding, embeddings)[:3]

        system_prompt = (
            "現在開始使用我提供的情境來回答，只能使用繁體中文，不要有簡體中文字。如果你不確定答案，就說不知道。情境如下："
            + "\n".join(paragraphs[vector[0]] for vector in similar_vectors)
        )
```
如果只取 similar_vectors[0]，那麼生成的 system_prompt 只會基於單一段落（[paragraphs[vector[0]]])，可能導致回答過於狹隘，無法涵蓋更廣泛的情境。


使用similar_vectors[:3]的情況
![image](https://hackmd.io/_uploads/ByUl6dR3Je.png)

使用similar_vectors[:1]的情況
![image](https://hackmd.io/_uploads/r1gLFaOCnJx.png)

使用的提示
```
流螢是米哈遊開發的電子遊戲《崩壞：星穹鐵道》中的虛構角色，她是遊戲中虛構組織「星核獵手」的成員，化名為薩姆，常以機甲形態出現。
「薩姆」之名最初在遊戲1.0版本（2023年）中提及，而流螢形象則於遊戲2.0版本（2024年）亮相。
在遊戲劇情中，流螢在以夢境聞名的虛構星球匹諾康尼中體驗了三次死亡，與主角在生死與夢境交錯的冒險中結下深厚情誼。

在角色設定中，流螢來自覆滅的虛構跨星球國家格拉默共和國，是其量產的基因改造戰士。失去故國的她飽受名為「失熵症」的慢性病的困擾。
在加入虛構組織星核獵手之後，她踏上了尋找生命意義的旅途。流螢的日語和英語配音員皆因與角色相似的慢性病經歷而倍感共鳴，為表現流螢的人格魅力做出努力。

流螢「機甲美少女」的人物設定和「鄰家女孩」的服飾風格都獲得評論員的正面評價。
評論員表揚了流螢的劇情塑造，認為在情感烘托上極具戲劇性，且給人以情感的寄託，在人物的成長弧光中傳達了對「死亡」和「命運」的深刻理解。
```



##  使用GPU執行模型
[教學網站](https://github.com/datawhalechina/handy-ollama/blob/main/docs/C3/3.%20%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9C%A8%20GPU%20%E4%B8%AD%E8%BF%90%E8%A1%8C.md)
<font color="#f00">to be continue...</font>














