跟著這篇走完,你會在本機把 Qwen3 跑起來:先用命令行聊一輪,再用 HTTP 接口發起一次帶上下文的多輪會話。整個過程 5 步,每步都有一條命令能驗證自己做對了沒有。文中出現的 localhost:11434 是 Ollama 的預設監聽地址,模型固定用 qwen3:8b;如果你換了端口或換了 tag,把示例值替換掉即可。
前置條件
| 項 | 要求 | 說明 |
|---|---|---|
| Ollama | 0.34.4 或更高 | 本文按 0.34.4 寫,它是 2026-09 的最新穩定版;0.40.0 仍是預發佈版,不要用 |
| 磁盤 | 6 GB 以上空閒 | qwen3:8b 的權重文件 5.2 GB,另需一點空間放運行時文件 |
| 記憶體 | 8 GB 以上 | 8B 模型按預設 Q4_K_M 量化後約 5 GB 常駐,統一記憶體或顯存都能兜住 |
| 網絡 | 能訪問 ollama.com | 只在首次拉模型時需要下載 5.2 GB,之後可以完全離線運行 |
裝完或升級後先跑這條確認版本。
ollama --version
看到 ollama version is 0.34.4 就是對的。Windows 上有些版本只回顯一行版本號字符串,內容一致即可;命令直接報 command not found 說明沒裝成功,回到第一步。版本低於 0.34 時 ollama ps 和 thinking 相關參數的行為會和本文不一致,建議先升級再往下走。
第一步:安裝並啟動 Ollama
macOS 和 Linux 用同一條安裝腳本,Windows 用 PowerShell 的對應版本。不想跑腳本的話,官方下載頁 上有各平臺的圖形安裝包,裝出來是同一個東西。
# macOS / Linux
curl -fsSL https://ollama.com/install.sh | sh
# Windows(PowerShell)
irm https://ollama.com/install.ps1 | iex
裝完之後 macOS 和 Windows 上 Ollama 會常駐選單欄並自動拉起服務,Linux 上安裝腳本會註冊 systemd 服務並立即啟動。這一步不需要手動執行 ollama serve,只有 Docker 或純命令行環境才需要自己起進程。
驗證服務是否已經在監聽預設端口。
curl http://localhost:11434/api/version
返回 {"version":"0.34.4"} 說明服務在跑,可以直接進入下一步。返回 curl: (7) Failed to connect to localhost port 11434 是服務沒起或沒綁在這個地址上,先看 Ollama 進程在不在,再看是不是被 OLLAMA_HOST 改到了別的地址。
第二步:拉取 qwen3:8b
Ollama 的模型不會隨安裝包一起下發,要單獨 pull 到本地。qwen3 是倉庫名,8b 是規格 tag,寫全了才能避開歧義。
ollama pull qwen3:8b
下載 5.2 GB,速度取決於網絡。qwen3 倉庫裡還有更小和更大的規格,按機器記憶體挑一檔(完整 tag 列表見 qwen3 模型庫頁):
| tag | 下載體積 | 上下文 | 適合 |
|---|---|---|---|
qwen3:1.7b |
1.4 GB | 40K | 只驗證鏈路,不追求效果 |
qwen3:4b |
2.5 GB | 256K | 8 GB 記憶體以下的機器 |
qwen3:8b |
5.2 GB | 40K | 本文用的檔位,16 GB 記憶體機器跑得舒服 |
qwen3:14b |
9.3 GB | 40K | 32 GB 記憶體以上 |
驗證模型是否真的落到本地。
ollama list
輸出裡出現一行 qwen3:8b、SIZE 列顯示 5.2 GB,就算拉好了。列表裡沒有它,說明前面的 pull 中途失敗,重跑一次 ollama pull qwen3:8b 會斷點續傳。
第三步:用命令行完成一次會話
ollama run 會拉起模型並進入交互提示符,這是最快確認「模型到底能不能答」的方式。
ollama run qwen3:8b
首次執行需要把權重加載進記憶體,會等幾秒到幾十秒。加載完出現 >>> 提示符,直接敲問題回車即可。Qwen3 預設開啟 thinking,你會先看到一段推理過程,再看到正式回答。聊完輸入 /bye 退出。
會話變長以後如果發現模型開始忘掉前面的內容,是預設上下文只有 4096 token 被塞滿了。可以在會話裡臨時抬高。
>>> /set parameter num_ctx 8192
這個設置只對當前會話生效。想改所有會話的預設值,用環境變數起服務:OLLAMA_CONTEXT_LENGTH=8192 ollama serve。
驗證。
在 >>> 下輸入 用一句话解释什么是栈溢出,能看到先出一段 thinking 再給出答案;輸入 /bye 能幹淨退出回到 shell,這一步就算成了。如果一直停在 pulling manifest,那是網絡沒通,不是模型問題。
第四步:用 REST API 發一次請求
Ollama 服務同時暴露了一套 HTTP 接口,端口就是剛才驗證過的 11434。先發一條單輪請求確認接口通不通。
curl http://localhost:11434/api/chat -d '{
"model": "qwen3:8b",
"messages": [
{ "role": "user", "content": "用一句话说明 /api/chat 和 /api/generate 的区别" }
],
"stream": false
}'
stream 預設是 true,會把響應切成一行一個 JSON 分片推回來。這裡顯式寫成 false,一次拿到完整 JSON,便於確認鏈路。想看流式效果就把它打開,同時給 curl 加上 -N 關掉輸出緩衝。
curl -N http://localhost:11434/api/chat -d '{
"model": "qwen3:8b",
"messages": [{ "role": "user", "content": "从 1 数到 5" }],
"stream": true
}'
驗證。
拿第一個請求的返回體,同時滿足三條就算通了:"done": true、message.content 非空、eval_count 大於 0。eval_count 是這次實際生成的 token 數,它是 0 就說明模型沒產出內容,通常是模型名寫錯或顯存不夠導致加載失敗。total_duration 和 eval_duration 單位都是納秒,順手除一下能得到每秒 token 數。
第五步:把會話接下去
/api/chat 是無狀態的,它不記得你上一次請求過什麼。所謂多輪會話,就是每輪都把歷史消息按順序拼進 messages 再發一遍。下面這條把第一輪的問和答都帶了進去。
curl http://localhost:11434/api/chat -d '{
"model": "qwen3:8b",
"messages": [
{ "role": "user", "content": "我叫阿禾,在做支付网关的限流。" },
{ "role": "assistant", "content": "<上一轮真实的回答原文>" },
{ "role": "user", "content": "我刚才说我在做什么?" }
],
"stream": false
}'
第二條 assistant 消息要填上一輪返回的 message.content 原文,不能自己編一句。這一段就是你以後寫客戶端時要維護的會話狀態:一個按 role 和 content 累積的陣列,越聊越長,直到撞上 num_ctx 上限再考慮截斷或摘要。
驗證。
返回的 message.content 裡出現「支付網關」或「限流」,說明上下文真的被帶進去了。如果答非所問,先檢查 messages 陣列裡有沒有漏掉 assistant 那一條——只塞 user 消息等於把上一輪的答案抹掉,模型自然接不上話。
核心概念
| 概念 | 是什麼 | 類比 |
|---|---|---|
| Ollama | 把權重文件、運行參數和推理引擎(llama.cpp / MLX)打包成本地常駐服務的運行時 | 像本地的數據庫服務,裝好就有一個進程守在 11434 端口 |
| 模型 tag | 仓库名:规格 形式的模型標識,如 qwen3:8b、qwen3:4b |
像鏡像 tag,同一個倉庫下不同規格 |
| 量化 | 把權重壓到 4 bit 左右再存,預設 Q4_K_M,體積能小到三分之一上下 | 像給圖片降碼率,體積大降、質量損失有限 |
| num_ctx | 一次請求能看到的 token 上限,預設 4096,超出的歷史會被截掉 | 相當於工作臺面積,放不下的材料只能推到地上 |
/api/chat |
無狀態的對話接口,歷史會話完全由調用方自己拼 | 和 HTTP 一樣天然無狀態,服務端不替你記 session |
常見問題
curl: (7) Failed to connect to localhost port 11434
現象:命令行 curl 或客戶端都連不上 11434,報 Connection refused,不是超時。
原因:Ollama 服務沒起來,或者只綁在別的地址上(容器裡最常見,容器內的 localhost 不是宿主機)。
model "qwen3:9b" not found, try pulling it first
現象:請求發出去了,Ollama 回一句 model not found 並讓你先 pull。
原因:服務是通的,只是本地庫裡沒有這個名字——tag 寫錯、規格不存在,或者壓根沒拉過。
多輪對話到後面報 400,或者模型開始忘掉開頭的內容
現象:前幾輪正常,聊長了以後要麼被服務端拒絕,要麼回答裡丟掉早先的設定。
原因:歷史消息越堆越長,撞上了 num_ctx;預設 4096,條數沒超但 token 早就爆了。
Java 客戶端裡模型名寫錯,拋的是 NullPointerException
現象:服務端明明只是「沒這個模型」,客戶端棧裡卻是 NPE,連模型名都不提。
原因:Ollama 對不存在的模型返回 404、響應體為空,客戶端解析空響應體時炸在 HTTP 層。
