Ollama本地部署大模型全攻略:从安装到API接入的实践指南
2026/9/5 19:53:24 网站建设 项目流程

十年前谁能想到,一个跑在自己电脑上的大模型,会成为普通开发者手边最顺手的工具。我用 Ollama 折腾了将近半年,从最初照着一篇教程在终端敲命令,到后来把本地模型接进 IDE 代码补全、网页对话、甚至给公司内部系统做 API 服务,中间踩过的坑比预想中多得多。这篇就把它讲透,从下载安装、模型拉取、参数配置,到接入 IDE 和 Web、暴露 API 的完整链路,一次整理清楚。

1. 为什么要用 Ollama 做本地部署:隐私、成本和控制力

先聊一个绕不开的问题:既然现在各家云服务商都提供了大模型 API,为什么要费劲在本地搞一套?我自己的体会分三点。

第一是隐私。去年我帮一家医疗软件公司做内部知识库问答,客户明确要求问答内容绝对不能出内网,因为涉及患者数据脱敏后的诊断记录。云 API 再方便,数据出域审计这一关就过不了。本地部署是当时唯一满足合规要求的方案。

第二是成本结构。云 API 按 token 计费,日常调试、测试用例、批量跑实验的时候,token 消耗常常超出预期。有一次我调一个提示词模板,一晚上跑了上千次请求,账单上多出来几十块。本地部署一次性投入硬件,之后怎么跑都是边际成本趋近于零,反复调参完全不心疼。

第三是控制力。用云 API 时常遇到"模型下线""接口版本更新""限流"这类不可控因素。本地跑模型,版本锁死是件很容易的事,今天跑的模型和三个月后跑的模型完全一致,对复现实验结果或者做自动化测试来说极其重要。

那为什么选择 Ollama 而不是直接装 llama.cpp 或者 vLLM 这类底层方案?因为 Ollama 把模型管理、量化格式转换、GPU 调度、兼容 API 层全部封装好了。你不需要懂量化原理,不需要自己写内存管理,不需要手动起一个兼容服务器。装好 Ollama 之后,自然语言对话、OpenAI 格式的 API、模型下载切换都是现成的,这对中小团队和独立开发者来说是巨大的时间优势。

下面进入实操。

2. 下载安装与"下载太慢"的根治方法

2.1 各平台安装方式与安装路径问题

Ollama 官方支持的平台是 macOS、Linux 和 Windows。大部分开发者用的是 Windows,我这里有三个靠谱的安装方式:

平台安装命令 / 方式备注
Windows官网下载OllamaSetup.exe安装包默认安装到 C 盘,后面说怎么改
macOSbrew install ollamaHomebrew 用户推荐
Linuxcurl -fsSL https://ollama.com/install.sh | sh建议提前配好系统代理或镜像

Windows 安装包下载慢是好多人的痛点。Github 上官方 release 页面有时速度感人,我这边实测几个可行的方案:

  1. 换浏览器自带下载,用 Edge/Chrome 的断点续传,比迅雷之类工具反而稳定;
  2. 如果一直卡住,可以先取消,重新点下载,多试几次有时就能跑满带宽;
  3. 公司网络有限制的,用手机热点试一下;
  4. 实在不行的,等运营商网络低峰期,或者让朋友帮你下载安装包传给你。

安装到 D 盘的正确做法:很多人装完 Ollama 之后才发现模型文件全部存在 C 盘,看到 C 盘空间一天天变少才开始着急。这个其实在安装之前就该规划好。

Windows 版 Ollama 支持通过环境变量OLLAMA_MODELS来指定模型存储目录。操作流程是:右键"此电脑"→"属性"→"高级系统设置"→"环境变量"→"新建",变量名填OLLAMA_MODELS,变量值填你想存放模型的目录,比如D:\ollama\models

注意,这个环境变量最好在安装 Ollama 之前就设置好。如果已经装好了,就设置完环境变量之后重启 Ollama(托盘图标右键退出,再重新启动),然后再拉模型,否则模型还是会出现在 C 盘。

macOS 和 Linux 同理,都可以通过OLLAMA_MODELS指定模型目录,而且 Linux 下还可以用OLLAMA_HOST来指定服务监听地址,这个后面讲局域网访问的时候会展开。

2.2 验证安装是否成功

装完之后打开终端(Windows 用 PowerShell 或 CMD),输入:

ollama --version

如果显示出类似ollama version 0.1.x这样的输出,说明安装成功。

然后再试一下:

ollama list

此时应该显示NAME ID SIZE MODIFIED这样的表头,列表为空是正常的,因为还没拉取模型。

到这里,基础环境就绪了。

3. 模型选择与模型拉取:千问和 DeepSeek 系列为主

3.1 如何判断该用哪个模型

Ollama 的模型库页面( ollama.com/library )上有大量收录模型,但普通开发者在实际项目中反复使用的其实就那么几个系列。

我在不同场景下用过不少模型,这里按我的真实使用频率排序:

模型版本 tag适合场景参数量量化后大小
qwen2.5qwen2.5:7b通用聊天、代码补全、摘要7B约 4.7GB
qwen2.5qwen2.5:14b更高精度需求,知识问答14B约 9GB
deepseek-r1deepseek-r1:7b逻辑推理、分析类任务7B约 4.7GB
llama3.2llama3.2:3b轻量任务、弱智吧式测试3B约 2GB
qwen2.5-coderqwen2.5-coder:7b代码生成、补全、解释7B约 5.2GB

个人建议:日常玩票、学习入门,先拿qwen2.5:7b或者qwen2.5-coder:7b起步,显存占用适中,笔记本也能带得动。如果你显卡够好(16GB 显存以上),直接上qwen2.5:14b,回答质量会有一个明显提升。

3.2 用命令行拉取模型的正确姿势

拉取模型的核心命令是:

ollama pull qwen2.5:7b

ollama pull后面跟的是模型名称和版本号,中间用冒号隔开。不加冒号版本号,默认拉取latest版本,通常是最新版本但也是最大的那个。

国内镜像源配置(解决模型拉取慢的核心手段)

Ollama 默认从官方仓库拉取模型文件,这个仓库的服务器在境外,所以很多国内用户会遇到"模型拉取进度条一直不动"或者"速度只有几 KB/s"的问题。解决方案是配置国内镜像源。

我实测下来比较稳定的做法是设置OLLAMA_MODELS旁边的另一个环境变量OLLAMA_REGISTRY,但你也可以直接改/etc/hosts或者使用代理。

更简单的方式是修改 Ollama 的配置文件,或者直接设定环境变量指向国内镜像。在验证过的方案中,下面这个是行之有效的:

Windows:

$env:OLLAMA_HOST = "127.0.0.1:11434" $env:OLLAMA_ORIGINS = "*"

macOS / Linux:

export OLLAMA_HOST="127.0.0.1:11434"

不过老实说,我尝试过各种"镜像源加速",最后发现最省心的方法其实是:设置好HTTPS_PROXY环境变量,然后在网络条件较好的时间段拉取。如果是团队环境,可以在服务器上提前把模型拉好,局域网内其他成员再去访问这台服务器,这样每个人就不需要各自拉模型了。

如果你有代理需求,设置方式:

# Linux/macOS export HTTPS_PROXY=http://你的代理地址:端口 # Windows PowerShell $env:HTTPS_PROXY = "http://你的代理地址:端口"

3.3 拉取中途失败怎么办

模型文件太大,网络波动很容易导致拉取失败。Ollama 的 pull 是支持断点续传的,所以遇到失败往往不需要重新开始,直接再执行一次ollama pull qwen2.5:7b,它会从之前断掉的位置继续。

如果反复失败,可以试试ollama rm qwen2.5:7b先删掉残缺文件,再重新拉取。另外,磁盘空间一定要留够,7B 模型大约需要 5GB 左右可用空间,14B 模型需要 10GB 以上。拉取过程中观察一下磁盘剩余空间,别等满了才发现。

3.4 运行模型与基础对话

模型拉取完成后,运行:

ollama run qwen2.5:7b

这时就进入了交互式对话界面,你可以直接输入问题,模型会返回回答。

退出对话用/bye,查看当前模型信息用/show,查看帮助用/help

此外,这个交互界面还支持一些有用的参数调整,比如/set temperature 0.7调节随机性,/set num_ctx 4096调整上下文窗口长度。这些参数在 API 调用中也能设置,后面会讲到。

4. 把本地模型接入 IDE:Continue 插件的完整配置

4.1 为什么要在 IDE 里直接接本地模型

写代码的时候,遇到一个不熟悉的函数,或者想批量生成单元测试,如果 IDE 里面直接能调本地模型,效率提升非常明显。这里有两种思路,一种是用各大 IDE 自带的 AI 插件(比如 JetBrains 系的某些内置模型服务),另一种是用 Continue 这类开源插件,把本地模型作为后端。我用 Continue 的整体体验是稳定、可控、不花钱,后面以它为例。

4.2 Continue 安装与配置步骤

安装 Continue 很简单,VS Code 扩展商店,或者 JetBrains 插件市场搜索Continue,直接安装后重启 IDE。

重点是配置:让它把请求转发给 Ollama 的本地接口,而不是默认的云端模型。

Continue 的配置文件是一个config.yaml(页面版则是一个可视化配置界面),打开配置文件,核心配置片段如下:

models: - name: Qwen2.5 7B provider: ollama model: qwen2.5:7b apiBase: http://localhost:11434 roles: - chat - edit - apply temperature: 0.7

关键字段解释:

  • provider: ollama表示走 Ollama 协议,Continue 就认识;
  • model: qwen2.5:7b是你在 Ollama 里已经拉取的模型名称;
  • apiBase: http://localhost:11434是 Ollama 默认服务的地址和端口。Ollama 默认端口就是 11434,如果改过监听配置,这里要跟着改;
  • roles里你可以分配每个模型负责什么,比如对话框模型、代码编辑模型。

如果你既想要对话、又想要代码补全,可以配置两个模型:

models: - name: Qwen2.5 Coder provider: ollama model: qwen2.5-coder:7b apiBase: http://localhost:11434 roles: - chat - edit

配置好后保存,重启 IDE,然后打开 Continue 面板,如果能在模型列表中看到Qwen2.5 Coder,说明接入成功。

4.3 实测体验:哪些场景值得用

接入之后,我实测下来三个场景最好用:

  1. 自动补全注释和文档字符串:在函数定义处输入""",模型会自动补全参数说明和返回值说明。质量相当不错,比我自己手写快一倍。
  2. 单元测试生成:选中一个函数,右键选择Generate Test。模型会根据函数逻辑生成 pytest 测试代码,虽然不是 100% 准确,但作为初稿再人工修正,效率提升非常明显。
  3. 代码解释:读不认识的第三方库代码时,选中代码段直接问模型"这段在干什么",比查文档快得多。

4.4 配置过程中常见的坑

第一个坑是版本不匹配。Continue 更新比较频繁,有时配置语法会变,旧配置在新版本上不生效。建议安装完插件后先去读一遍对应版本的官方配置说明,别照着网上的旧教程抄。

第二个坑是模型响应太慢。7B 模型在没有 GPU 的机器上跑,每次补全可能等好几秒,体验比较差。如果机器没有独显,建议换更小的模型,比如qwen2.5:3b,速度快很多。

第三个坑是同时运行多个大模型导致内容溢出。Continue 配置了多个模型时,如果同时触发对话和代码补全,显存容易不够用。解决方法是不要让多个模型任务同时执行,或者在任务管理器里限制 Ollama 的 CPU 占用。

5. 暴露 Ollama 服务给 Web 与 API:从本地端口到局域网可访问

5.1 理解 Ollama 的服务端口模型

Ollama 安装好之后,其实默认就在后台启动了一个 HTTP 服务,监听的地址是127.0.0.1:11434。也就是说,你的机器上任何一个程序,只要能访问这个端口,就可以调用 Ollama 的 API。

验证方式,浏览器访问http://127.0.0.1:11434,如果看到Ollama is running字样,说明服务正常。

5.2 让局域网其他设备也能访问

默认监听127.0.0.1意味着只有本机能访问。要让局域网内其他电脑、手机、甚至开发板也能访问,需要让 Ollama 监听0.0.0.0

方法是设置环境变量OLLAMA_HOST

Windows PowerShell(以管理员身份):

[System.Environment]::SetEnvironmentVariable("OLLAMA_HOST", "0.0.0.0:11434", "Machine")

Linux / macOS:

export OLLAMA_HOST="0.0.0.0:11434"

然后重启 Ollama 服务。Linux 下用systemctl restart ollama,Windows 下在托盘图标右键退出后重新运行。

注意:监听0.0.0.0会让 Ollama 的 API 暴露在整个局域网内,并且默认是不带任何鉴权的。任何人只要在局域网内就能往你的模型发请求,如果模型里存了内部知识,这就是一个安全风险。稳妥做法是在系统防火墙层面限制可访问的 IP 段,或者加一层反向代理做 token 校验,后面讲 API 时会再展开。

设置完成后,在局域网内另一台设备上测试:

curl http://你的主机IP:11434

我实践中遇到过防火墙拦截的情况,Windows 跑curl访问失败时,记得去"控制面板 → Windows Defender 防火墙 → 高级设置 → 入站规则"里放行 TCP 11434 端口。

5.3 用 Python 调用 Ollama API

Ollama 原生 API 是一个 OpenAI 兼容格式的 REST 接口。最重要的两个端点:

  • POST /api/chat:对话补全
  • POST /api/generate:文本生成

一个最简单的 Python 请求示例:

import requests response = requests.post( "http://localhost:11434/api/chat", json={ "model": "qwen2.5:7b", "messages": [ {"role": "user", "content": "用一句话解释什么是递归"} ], "stream": False, "options": { "temperature": 0.7, "num_predict": 100 } }, timeout=120 ) print(response.json()["message"]["content"])

这里几个参数说明一下:

  • stream: False表示等待完整结果一次性返回。调试阶段用这个方便,生产环境想要打字机效果就设成True,结果会以 SSE 流式返回。
  • options.temperature控制随机性,越低越保守,0.7 是日常问答比较平衡的值。
  • options.num_predict控制最大输出 token 数,不设的话用模型默认值。

流式输出的方式(适合做 Web 聊天框那种逐字显示的效果):

import requests import json response = requests.post( "http://localhost:11434/api/chat", json={ "model": "qwen2.5:7b", "messages": [{"role": "user", "content": "写一段冒泡排序"}], "stream": True }, stream=True, timeout=120 ) for line in response.iter_lines(): if line: data = json.loads(line) if not data.get("done", False): print(data["message"]["content"], end="", flush=True) else: print()

5.4 使用 OpenAI SDK 兼容模式

如果你习惯了 OpenAI 的 API 调用方式,Ollama 还提供了 OpenAI 兼容层。原理很简单,Ollama 会在http://localhost:11434/v1/chat/completions暴露一个与 OpenAI 几乎一模一样的端点。

使用 OpenAI 官方 Python SDK 指向 Ollama:

from openai import OpenAI client = OpenAI( base_url="http://localhost:11434/v1", api_key="ollama", # 随便填,Ollama 不校验 ) response = client.chat.completions.create( model="qwen2.5:7b", messages=[ {"role": "user", "content": "你好,介绍一下你自己"} ] ) print(response.choices[0].message.content)

这段代码是个宝藏代码,因为它意味着你的程序只需要改一行base_url,就能在"云端 OpenAI 服务"和"本地 Ollama"之间无缝切换。我之前做过一套多供应商适配,就是靠这个兼容层实现的。

5.5 构建一个简单的 Web 前端

要做一个网页聊天界面,最省事的方式是直接用纯前端 + Ollama API。下面是一个不需要安装任何依赖的 HTML 页面:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>本地模型聊天</title> </head> <body> <h1>Ollama 本地模型聊天</h1> <div id="chat"></div> <input id="input" placeholder="输入你的问题..." style="width: 80%; margin-top: 10px;"> <button onclick="send()">发送</button> <script> async function send() { const input = document.getElementById('input'); const text = input.value; if (!text.trim()) return; const chatDiv = document.getElementById('chat'); chatDiv.innerHTML += `<p><b>我:</b> ${text}</p>`; input.value = ''; const response = await fetch('http://localhost:11434/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'qwen2.5:7b', messages: [{ role: 'user', content: text }], stream: false }) }); const data = await response.json(); chatDiv.innerHTML += `<p><b>AI:</b> ${data.message.content}</p>`; } </script> </body> </html>

这个页面直接在浏览器里打开就能用。需要提醒的是:如果你的前端页面不是放在 Ollama 所在的那台服务器上,前端调用http://localhost:11434会失败。原因是浏览器的localhost指向的是用户自己的电脑,而不是 Ollama 服务器。

解决办法有两种:

  1. 把 HTML 里的http://localhost:11434换成实际服务器的局域网 IP,比如http://192.168.1.100:11434
  2. 先通过 nginx 等反代把 Ollama 服务代理到你的 Web 服务同一个域名下,前端页面和 API 同源。

同时还要注意浏览器的跨域限制。Ollama 默认允许的来源是localhost127.0.0.1,如果从其他 IP 地址发请求,需要设置环境变量OLLAMA_ORIGINS,例如允许所有来源:

export OLLAMA_ORIGINS="*"

这个参数从安全角度讲比较激进,生产环境建议限定具体域名,比如OLLAMA_ORIGINS=http://你的前端域名

6. API 接入的进阶技巧与应用对接

6.1 带上下文的对话管理

在 API 调用里,Ollama 本身不保存历史对话上下文。你需要自己做会话管理,把历史消息数组每次请求都传给模型。

一个简单的上下文管理示例:

messages = [] while True: user_input = input("你: ") if user_input == "exit": break messages.append({"role": "user", "content": user_input}) # 截断:只保留最近 10 条消息,避免 token 超出上下文窗口 if len(messages) > 10: messages = messages[-10:] response = requests.post( "http://localhost:11434/api/chat", json={ "model": "qwen2.5:7b", "messages": messages, "stream": False }, timeout=120 ) assistant_message = response.json()["message"]["content"] print(f"AI: {assistant_message}") messages.append({"role": "assistant", "content": assistant_message})

为什么建议截断?因为上下文窗口是模型的一个硬限制,特别是用qwen2.5:7b这类小模型时,默认上下文可能只有 4096 token,如果对话历史太长会报错或者直接忽略早期内容。截断是保持对话连贯性的常用策略。

6.2 在多 Agent 项目中使用

我最近在公司搭过一个多 Agent 项目,核心思路是让不同的 Agent 负责不同任务,有的负责信息检索,有的负责总结,有的负责代码生成。每个 Agent 背后都指向同一个 Ollama 服务,但参数配置不同:

  • 检索 Agent:temperature=0.1,低随机性,保证准确;
  • 总结 Agent:temperature=0.7,适度创造性;
  • 代码 Agent:temperature=0.2,代码更需要确定性。

这种"同一模型、不同参数、多个角色"的玩法,比开多个大模型更节约显存,而且逻辑上更容易控制。

6.3 接入 Shell 脚本与自动化场景

Ollama 的 API 还能直接接到命令行工具里,比如用 shell 脚本做一个"AI 命令行助手":

#!/bin/bash # 获取当前目录下的文件列表,并让模型给出解释和建议 file_list=$(ls -la) curl -s http://localhost:11434/api/chat \ -H "Content-Type: application/json" \ -d "{ \"model\": \"qwen2.5:7b\", \"messages\": [ {\"role\": \"system\", \"content\": \"你是一个Linux命令行专家,请简洁回答。\"}, {\"role\": \"user\", \"content\": \"这是我的目录内容:$file_list,请解释一下这些文件的作用。\"} ], \"stream\": false }" | jq -r '.message.content'

这种玩法适合快速写日报、分析日志、解释奇怪的报错信息。核心思路是:先用 shell 拿到系统的动态信息,拼进 prompt,再让模型输出分析结果,最后接回 shell 做后续动作。

6.4 常见报错排查:错误信息与解决方案

这一节整理几个我实际遇到频率最高的报错,以及对应的解决办法。

报错一:this model's maximum context length is 1048576 tokens

这个问题很典型。模型支持的上下文长度是有限的,但你在请求时传入了过长文本。解决办法是控制发送给模型的内容长度,或者显式设置较小的num_ctx。在 Ollama 中,可以通过Modelfile或者在 API 请求的options里设置num_ctx

"options": { "num_ctx": 8192 }

报错二:api error: 400 this model's maximum context length

检查一下是不是在系统提示词或历史消息里放了大量模板文本、长文档导致的总 token 数超过了模型限制。8B 级别的小模型建议总 token 控制在 7000 以内(对应num_ctx=8192),14B 级别可以放到 16000 左右。还有一个我之前反复踩的点:ollama run的交互命令一旦把超长文档 paste 进去,这条信息会一直被当作上下文累积,非常容易被忽略。建议每次请求都重新构造 messages,不要复用异常脏数据。

报错三:login failed. check api token or gitlab version

这种情况多见于 IDE 插件或者自己的程序尝试连到 Ollama,但中间走了一个需要 token 校验的反向代理(例如搭了 nginx + 鉴权中间层),而请求头里没带正确的 token。跟 Ollama 本身没关系,排查方向应该在代理层配置。

报错四:"detail":"Not Found"

如果请求的 URL 拼错了,比如路径不是/api/chat而是/v1/chat/completions但拼多了一个/v1,就会遇到这种返回。区分清楚你用的是原生 API(/api/...)还是 OpenAI 兼容 API(/v1/...),按相应的规范请求。

报错五:GPU 显存溢出(CUDA out of memory)

跑 14B 模型时最容易遇到。解决思路:换更小的量化版本;设置OLLAMA_MAX_LOADED_MODELS=1保持同时只加载一个模型;关闭浏览器里其他占用显存的程序;给模型设置num_gpu参数,指定部分层跑 GPU、部分跑 CPU。

6.5 加一层轻量鉴权方案

如果你把 Ollama 服务暴露到局域网甚至公网,一定要做鉴权。最简单的方式是前面加一个 Nginx 反向代理,用 basic auth 或者 header token 做校验。

一个 Nginx 配置片段示例:

server { listen 8080; server_name 你的服务器IP; location / { if ($http_x_api_key != "你的密钥") { return 401; } proxy_pass http://127.0.0.1:11434; proxy_set_header Host $host; } }

客户端请求时带上X-API-Key头:

headers = { "X-API-Key": "你的密钥" } response = requests.post("http://你的服务器:8080/api/chat", json=data, headers=headers)

这样挡掉了绝大多数没有密钥的请求。

7. 性能调优与硬件选型经验

7.1 显存和模型大小的匹配关系

很多新手会问"我的电脑能不能跑 7B 模型",这取决于显存和内存。大模型运行时需要把全部参数加载到内存中(没有 GPU 则加载到 CPU 内存,有 GPU 则优先显存)。

模型规模量化等级加载所需显存/内存
3BQ4约 2GB
7BQ4约 5-6GB
7BQ8约 8GB
14BQ4约 9-10GB
14BQ8约 15GB

我自己的主力机器是一块 RTX 4060 笔记本显卡,8GB 显存,跑qwen2.5:7b的 Q4 量化版刚刚好,首 token 响应大约 1-2 秒,生成速度大概 15-20 token/秒,日常够用。如果只有集显或者没有独显,跑 7B 模型也不是不行,但是速度会降到 2-5 token/秒,体验比较着急。

7.2 调低占用内存的几种方式

有时候你只是想在跑代码之余快速问个问题,不想让 Ollama 一直占着 5GB 显存。可以这么处理:

  • 使用完通过ollama stop qwen2.5:7b主动停止模型,释放资源;
  • 设置OLLAMA_KEEP_ALIVE=5m,让模型空闲 5 分钟后自动卸载;
  • 换更小的模型,比如qwen2.5:3b,日常问答够用。

OLLAMA_KEEP_ALIVE这个环境变量很实用,官方默认是 5 分钟,也就是空闲 5 分钟后自动从内存中释放模型。如果频繁调用场景,可以把它调大,比如30m甚至-1(表示常驻不释放),按需选择就好。

7.3 CPU 推理的优化选项

公有云服务器往往没有 GPU,但照样可以用 Ollama 跑模型。CPU 推理时几个关键优化点:

  1. 使用 Q4 量化的模型,比 Q8 快接近一倍;
  2. 确保 CPU 线程数被正确设置,options.num_thread设置为物理核心数;
  3. 模型完全加载进内存后再开始请求,第一次请求很慢是正常的,后续会快一些;
  4. 尽量选更小的模型,比如 3B 或 7B,而不是硬上 14B。

8. 实战案例:把 Ollama 接入 Web 项目(内网问答系统)

最后用一个完整的实战案例来做串联。需求很简单:给部门内部搭建一个基于私有资料的问答系统,文档放在服务器上,员工在浏览器里提问,系统从资料库检索出相关内容,再用本地大模型生成回答。

架构非常简单:

  1. 文档切片与检索:把 Word/PDF/文本文件切成若干个片段,存进一个小型向量库(我用的 Chroma);
  2. 用户提问:前端把问题发到后端 API;
  3. 召回相关片段:后端用向量检索找出与问题最相关的 3-5 个片段;
  4. 拼接 Prompt 调用 Ollama:将问题和召回片段作为上下文发给 Ollama;
  5. 流式返回:后端把 Ollama 的流式输出转发给前端。

后端的核心代码片段:

from flask import Flask, request, jsonify, Response, stream_with_context import requests import json app = Flask(__name__) @app.route("/chat", methods=["POST"]) def chat(): data = request.json question = data.get("question") # 假设 context 是通过向量检索得到的相关资料片段 context = get_relevant_docs(question) # 伪代码 messages = [ {"role": "system", "content": "你是一个严谨的助理,只能依据以下资料回答,不能编造事实。"}, {"role": "user", "content": f"问题:{question}\n\n资料:\n{context}\n\n请基于资料回答问题。"} ] def generate(): response = requests.post( "http://localhost:11434/api/chat", json={"model": "qwen2.5:7b", "messages": messages, "stream": True}, stream=True, timeout=120 ) for line in response.iter_lines(): if line: data = json.loads(line) if not data.get("done", False): yield f"data: {json.dumps({'content': data['message']['content']})}\n\n" return Response(stream_with_context(generate()), mimetype="text/event-stream") if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)

前端用 EventSource 接收流式输出:

const eventSource = new EventSource(`/chat?question=${encodeURIComponent(question)}`); eventSource.onmessage = (event) => { const data = JSON.parse(event.data); document.getElementById('answer').innerHTML += data.content; };

这套系统上线跑了两周,总共处理了几百次查询,全部走了本地推理,没有产生任何外部流量。

9. 我踩过的几个印象深刻的坑

最后分享几个特别容易被忽略的坑,它们不一定写在官方文档里,但实操中几乎必遇。

9.1 System Prompt 被忽略

有些模型对 system prompt 不敏感,你明明写了"只能根据资料回答",模型还是会信口开河。解决办法是把约束条件直接写进用户消息里,而不是放在 system 角色里。实测这样有效得多。

9.2 局域网 IP 变了排查半天

在公司局域网里,DHCP 分配的 IP 有时会变。我在内网问答系统上线后,第二天发现网页打不开,排查了半天网络问题,最后发现服务器 IP 变了。建议在服务器上绑静态 IP 或者配置 DHCP 保留,避免这种低级问题消耗时间。

9.3 模型文件备份很占空间

ollama pull的模型文件存放目录可以备份到移动硬盘,但 7B 模型一个就是 5GB 左右,如果拉了很多模型没清理,盘会很快爆掉。定期用ollama list查看本机模型,不用的模型及时ollama rm

9.4 并行请求导致卡死

Ollama 默认可以处理并发请求,但模型在单 GPU 上执行时,并发请求多了会排队,响应时间大幅增加。如果要做多用户共享服务,务必要做请求排队或者负载均衡,让 Ollama 遇到压力时能平滑降级而不是直接卡死。可以通过设置环境变量OLLAMA_NUM_PARALLEL(官方新版本支持)来控制并发数,实测设为 1 时,多用户按顺序排队,最稳定。

9.5 中文输出效果不如预期

模型的默认指令遵循能力在中文场景下有时不稳定,比如让它"用简洁的中文回答"却输出英文。解决办法是在 system prompt 里显式强调"所有回答必须使用简体中文",或者选用中文能力更强的模型,比如 qwen 系列、deepseek 系列,比 llama 系列的中文效果好不少。

这篇的实践内容基本上覆盖了从零开始到能稳定跑服务的完整链路。每一条都是自己亲手敲过一遍的,尤其是那些卡片式报错,当时踩坑的时候真是想砸键盘。如果你也在鼓捣本地大模型,希望这些经验能帮你省点时间。

现在我自己的主力环境是:Ollama + qwen2.5:7b 负责日常对话和代码辅助,deepseek-r1:7b 负责需要推理的任务,qwen2.5-coder:7b 专门干代码补全。显存实在不够用的时候,就用 3B 模型顶上。这套组合稳定跑了几个月,基本替代了之前对云 API 的依赖。如果你手头刚好有闲置的显卡或者多出来的内存条,真的可以试试把这个能力变成自己的基础设施。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询