资讯动态

Ollama+Llama3本地部署大语言模型:参数、API与RAG实战

发布时间:2026/10/26 13:41:38 来源:尧图企业网站定制
大语言模型 LLM 这两年从论文里掉进了每个人的桌面。真正让它变得可玩的是 Ollama Llama3 这条组合路线前者把模型下载、量化加载、推理服务、API 暴露这几件脏活全包了后者给了一个中英文都能打的开源权重。用一句话概括这套方案在自己机器上本地部署大语言模型不需要显卡集群不需要云账号一条命令就能拉起一个能对话、能被程序调用的推理服务。我前后在三台机器上折腾过这套东西一台 16GB 统一内存的笔记本、一台带 12GB 显存的台式机、一台纯 CPU 的小主机。踩过的坑从「模型拉到一半断了」到「上下文静默截断导致答非所问」基本都经历了一遍。这篇东西就是把这些过程摊开写包括为什么这么选、参数怎么算、坑怎么绕以及一套能直接抄走的落地步骤。适合谁看想在自己电脑上跑个模型试试水的新手想给内部工具接一个私有推理后端但不想付云费用的开发者以及已经装了 Ollama 但一直卡在「能跑但不好用」阶段的同学。如果你只是想知道本地模型能不能替代在线服务结论我先放这儿8B 级别的模型在大多数日常任务上够用但需要你在提示词、上下文长度和量化等级上做取舍。1. 需求拆解与方案选型先想清楚为什么要自己跑1.1 本地跑模型到底图什么很多人第一次听说本地部署大语言模型第一反应是「我又不训练模型跑它干嘛」。这个问题必须先回答清楚否则你会在拉完 5GB 模型、发现回答质量不如在线服务之后立刻放弃。我自己总结下来本地跑模型的价值集中在四件事上。第一是数据不出机器处理合同草稿、内部会议记录、客户名单这类内容时把原文发到外部接口这件事本身就要走一轮审批而本地推理压根没有这个环节。第二是离线可用飞机上、内网环境、断网现场模型照样能跑。第三是成本结构变了云服务按 token 计费用得越多越贵本地部署是买断制电费和硬件折旧是固定成本跑一万次和跑十万次没有边际成本。第四是可改造你可以换系统提示词、改采样参数、接自己的工具链甚至可以针对特定任务做微调这些在托管服务上要么做不到要么要走一堆流程。代价同样明确模型能力上限受硬件约束8B 模型在复杂推理上确实打不过大参数模型响应速度取决于你的显卡首 token 延迟可能到两三秒还有就是运维成本转移到了你自己身上进程挂了得自己重启。所以判断标准很简单任务对数据敏感度要求高、调用频次高、对绝对智能上限要求不那么极致本地部署就是划算的。反过来如果你要的是最强的推理能力和最广的知识面本地 8B 模型会让你失望。1.2 为什么是 Ollama 而不是裸跑 llama.cpp 或上专业推理框架大模型本地推理的底层生态其实分几层最底下是各种推理引擎llama.cpp 这类用 C/C 写的、针对量化权重做了极致优化的实现中间是各种服务封装最上面才是应用。Ollama 的定位是中间那一层它做了三件关键的事。第一件是把模型权重的获取和版本管理标准化了。你不用去各种地方找 GGUF 文件、手动核对量化版本、自己算校验值ollama pull一句话搞定模型存在统一的目录下用名字:标签的方式索引跟用容器镜像的体验几乎一样。第二件是自动做硬件适配和分层卸载。你的显存装不下整个模型时它会自动把一部分层放到内存里GPU 跑一部分、CPU 跑一部分虽然速度会掉但至少能跑起来。这个逻辑如果自己用 llama.cpp 的手动参数去调得反复试-ngl的值很折磨人。第三件是默认就把 HTTP 服务开起来了。装完就在本地 11434 端口监听直接能用 curl 调还额外提供了一套与 OpenAI 接口兼容的端点意味着你手上那些基于 OpenAI SDK 写的代码改一个 base_url 就能跑在本地模型上。这个迁移成本低到可以忽略。那什么情况下不该用 Ollama如果你的场景是高并发生产服务需要做请求排队、批处理、多副本调度专业推理框架的吞吐会明显更好如果你要做底层算子优化或者自己改推理逻辑那得往下走到引擎层。但对于个人使用、内部工具、原型验证这三个场景Ollama 的性价比是最高的因为它把「从零到能调用」的时间压缩到了十分钟以内。1.3 Llama3 版本怎么挑参数量与变体的取舍逻辑Llama3 这个系列不是一个模型而是一个家族。常见的有 8B 和 70B 两个主力尺寸后续版本还补充了小尺寸和更长上下文的变体。挑哪个取决于你的硬件和任务类型不是越大越好。先把数量级摆出来8B 模型的权重在 4bit 量化下大约 4.7 到 5GB70B 在同样量化下要 40GB 以上。这个差距直接决定了硬件门槛。8B 能在 16GB 内存的普通笔记本上跑起来70B 基本要有 48GB 以上显存或者大容量统一内存的机器。能力上的差距要理性看待。8B 模型在文本摘要、格式转换、简单问答、代码补全、翻译这些任务上表现相当可用日常办公场景能覆盖七八成。但涉及多步推理、长文档的跨段逻辑关联、需要严格遵循复杂指令链的任务8B 就容易掉链子表现为「答得挺流畅但没答到点上」。70B 在这些地方明显更稳代价是速度慢一个数量级。还有一个容易被忽略的维度是上下文窗口。基础版 Llama3 的训练上下文是 8K部分后续版本扩展到了 128K。8K 是什么概念大概相当于五六千个汉字一篇中等长度的技术文档塞进去就满了。如果你的任务是处理长文档选版本时必须确认上下文能力不能只看参数量。我的建议是先上 8B把它跑通、把参数调明白、把应用接上去等你确实遇到能力瓶颈了再考虑升级。因为绝大多数人第一次部署的失败原因不是模型太小而是上下文设置错了、提示词写崩了、或者量化等级选得太激进导致输出质量莫名其妙地差。这些和参数量无关换 70B 一样会踩。2. 硬件预算与环境准备把账算在前面2.1 显存和内存的估算方法带算式大部分人在这一步是靠猜的装完发现跑不动再回来删模型。其实有一个很朴素的估算公式算完误差不会太大。模型权重大小 参数量 × 每权重比特数 ÷ 8每权重比特数bits per weight由量化等级决定。业界常用的 Q4_K_M 混合量化平均下来大约 4.8 到 4.9 bpwQ5_K_M 大约 5.7 bpwQ8_0 大约 8.5 bpwFP16 就是 16 bpw。拿 8B 模型举例Q4_K_M80 亿 × 4.85 ÷ 8 ≈ 4.85 GBQ5_K_M80 亿 × 5.7 ÷ 8 ≈ 5.7 GBQ8_080 亿 × 8.5 ÷ 8 ≈ 8.5 GBFP1680 亿 × 16 ÷ 8 16 GB这还只是权重。真正占内存的大头是KV Cache也就是推理过程中缓存的注意力键值。它的体积和上下文长度成正比算法是KV Cache ≈ 2 × 层数 × KV头数 × 头维度 × 上下文长度 × 每元素字节数以 8B 模型为例32 层、8 个 KV 头用了分组查询注意力、头维度 128FP16 存储每个元素 2 字节。单层单 token 的 KV 是 2 × 8 × 128 × 2 4096 字节也就是 4KB。32 层累加每 token 约 128KB。上下文设成 4096 时KV Cache 约 512MB设成 8192 时约 1GB设成 32768 时就要 4GB 了。所以完整的内存需求是权重 KV Cache 运行开销约 1GB。8B 模型在 Q4 量化、8K 上下文下的实际占用大概是 6GB 出头。这个数字解释了一个常见困惑为什么我的 8GB 显存卡跑 8B 模型模型只有 4.9GB 却还是会爆——因为 KV Cache 和计算缓冲区没算进去。注意上下文长度不是免费的。把 num_ctx 从 4096 调到 32768内存占用能翻好几倍在显存紧张的机器上这是最常见的「跑着跑着就崩」的原因。2.2 三档配置清单与实测速度参考我把常见硬件分成三档每档给出能跑什么、大概多快。速度是 token/秒每秒生成的字词片段数受内存带宽、CPU 型号、量化版本影响很大只作数量级参考。档位典型配置可跑模型生成速度参考适用场景入门16GB 统一内存的轻薄本 / 16GB 内存 核显8B Q4上下文 4K10~20 tok/s个人试用、写作辅助、简单问答主流12GB 显存独显 32GB 内存8B Q5/Q8上下文 8K40~60 tok/s日常开发、内部工具后端、文档处理进阶24GB 显存独显 或 64GB 以上统一内存8B 全精度高速跑 / 30B 级 Q480~120 tok/s8B多任务并发、代码助手、RAG 应用几个实测观察在 M 系列统一内存的笔记本上8B Q4 的生成速度大概是 20~30 tok/s首次加载模型要等 5 到 10 秒之后只要进程不退出就一直驻留。在纯 CPU 环境上16 核同样的模型大概 6~10 tok/s能明显感觉到「一个字一个字往外蹦」但用来做批处理任务完全够用。显存足够的独显机器上8B 模型跑到 100 tok/s 以上不稀奇那时候瓶颈已经不在模型而在你的网络传输和前端渲染了。需要强调一点内存带宽比核心数更重要。大模型推理是典型的访存密集型任务每个 token 的生成都要把权重读一遍。这也是为什么统一内存架构的机器在同价位下往往表现更好——它的内存带宽给得比较足。2.3 系统环境检查清单动手之前花五分钟检查这几项能省掉后面一小时的排错。磁盘空间单个 8B 模型占 5GB 左右但 Ollama 在拉取和转换过程中会有临时文件占用建议留出 20GB 以上余量。想同时存几个模型按每个 5~45GB 估。系统版本Windows 端对系统版本有最低要求太老的版本装不上Linux 端基本没有限制macOS 建议较新的版本老版本在统一内存调度上会有问题。端口占用默认用 11434 端口先确认没被别的服务占了。netstat -ano | findstr 11434Windows或lsof -i :11434类 Unix都能查。显卡驱动独显机器把驱动更新到较新版本否则 Ollama 可能识别不到 GPU退化成纯 CPU 推理速度直接掉一个数量级。防火墙只在本机用的话保持监听地址为127.0.0.1最安全。要让局域网内其他设备访问需要显式改成0.0.0.0这时候记得配好访问控制。提示先确认自己的机器是「显存够」还是「内存够」。显存紧的机器把上下文设在 4096 以内会稳很多内存大的机器可以适当放开上下文但要留意系统整体的交换分区使用情况。3. Ollama 安装与 Llama3 拉取实操3.1 三个平台的安装步骤Linux是最省事的官方提供了一行安装脚本它会自动识别架构、下载对应的二进制、注册成系统服务并启动curl -fsSL https://ollama.com/install.sh | sh装完用systemctl status ollama确认服务在跑。如果没有 systemd 环境比如某些容器里也可以直接ollama serve前台启动。macOS有两种方式用包管理器装或者下载安装包。装完之后应用会驻留在菜单栏后台服务自动起。brew install ollamaWindows走安装包最顺双击装完托盘里会出现图标服务自动启动。装完打开一个新的终端窗口输入ollama --version验证。这里有个小坑装完之后必须新开终端老窗口的环境变量是旧的会提示找不到命令。安装完成后的第一件事是验证服务在监听curl http://127.0.0.1:11434/api/tags返回一个 JSON里面models数组是空的说明服务正常但还没拉模型。这个端点后面会经常用到可以记一下。3.2 拉取、运行与验证拉模型和运行是两条命令也可以合并成一条——ollama run发现本地没有这个模型时会自动先拉取。# 显式拉取只下载不运行 ollama pull llama3 # 拉取并进入交互式对话 ollama run llama3 # 指定更小的标签减少下载量 ollama run llama3:8b首次拉取大概 4.7GB取决于网络情况几分钟到十几分钟不等。断点续传是支持的网络抖断了重新执行同一条命令会接着下不会从头来这点比手工下载权重文件省心太多。进入对话之后可以直接打字提问退出用/bye。多行输入用三个双引号包起来第一行 第二行 第三行有几个在交互模式里很实用的斜杠命令/?看全部命令/clear清空当前会话上下文/show info看当前模型的参数配置/set parameter temperature 0.3临时改采样温度。这些命令不用记输入/?就有。非交互的一次性调用也支持适合写进脚本ollama run llama3 用一句话解释什么是量化模型管理相关的几条命令列一下日常高频命令作用ollama list列出本地已有模型及大小ollama ps查看当前加载在内存里的模型和占用比例ollama rm 模型名删除模型释放磁盘ollama cp 源 目标复制一份模型改配置时常用ollama show 模型名查看模型的参数、模板、量化信息ollama ps值得单独说一下它输出里的 PROCESSOR 列会显示100% GPU、100% CPU或者类似30%/70% CPU/GPU的混合比例。这一列是判断「我的显卡到底有没有被用上」最直接的方法。很多人抱怨速度慢一查发现是100% CPU原因是驱动没装好或者显存不够被自动降级了。3.3 用 Modelfile 定制一个自己的模型直接ollama run llama3用的是默认配置系统提示词很朴素上下文长度也是默认值。想让它变成你的专用助手得写 Modelfile。Modelfile 的语法很轻核心就三类指令FROM指定基础模型PARAMETER调采样和运行参数SYSTEM写系统提示词。还可以用TEMPLATE完全自定义对话模板但除非你有特殊需求一般不用动。FROM llama3:8b PARAMETER temperature 0.4 PARAMETER top_p 0.9 PARAMETER repeat_penalty 1.1 PARAMETER num_ctx 8192 PARAMETER stop |eot_id| SYSTEM 你是一名严谨的技术文档助手。回答时遵循以下规则 1. 先给结论再给理由不要铺垫。 2. 涉及数字和参数时必须给出具体值禁止使用一些若干这类模糊表述。 3. 不确定的内容直接说明不确定不要编造。 4. 输出使用简体中文。 几个参数的选择理由值得说清楚temperature 0.4默认值通常是 0.8偏发散。做技术问答、文档处理这类需要确定性的任务压到 0.3 到 0.5 之间输出会稳定很多同一个问题问三遍答案基本一致。如果是创意写作反而要往上调。top_p 0.9和 temperature 配合使用控制候选词的累积概率截断。两个都调低会导致输出过于死板甚至陷入重复所以一般只重点调一个。repeat_penalty 1.1抑制重复用词。小模型在没有这个参数约束时容易出现「这个问题非常重要非常重要非常重要」这种复读现象。num_ctx 8192这是最容易出问题的一个。老版本 Ollama 默认上下文只有 2048新版本提到了 4096但很多任务 4096 根本不够用。显式写出来避免默认值把你的长文档悄悄截断。stop停止符模型生成到这里就停。不同的模型用不同的特殊标记从ollama show 模型名 --template里能看到原始模板用了什么。写完保存成文件比如MyAssistant.Modelfile文件名随意习惯上首字母大写然后创建ollama create my-assistant -f ./MyAssistant.Modelfile创建过程很快因为它只是把基础模型的层引用过来加了一层配置元数据不会复制几个 G 的权重。之后ollama run my-assistant就是你定制后的版本了。想改配置不用重新写文件直接复制再改ollama cp my-assistant my-assistant-v2 ollama show my-assistant --modelfile v2.Modelfile # 编辑 v2.Modelfile 后 ollama create my-assistant-v2 -f ./v2.Modelfile这套流程的好处是配置可版本化。把 Modelfile 提交到代码仓库里换台机器一条命令就能复现一模一样的行为比在界面上点来点去靠谱得多。4. 把模型接进应用API、兼容层与最小 RAG4.1 原生 REST API 的四个核心端点模型跑起来只是第一步真正的价值在于让程序能调用它。Ollama 的 HTTP 接口设计得很直白日常用到的其实就四个。生成接口/api/generate是最简单的单轮调用给一个 prompt返回一段文本curl http://127.0.0.1:11434/api/generate -d { model: llama3, prompt: 用三句话说明什么是向量数据库, stream: false, options: { temperature: 0.3, num_ctx: 4096 } }stream设为 false 时一次性返回完整结果设为 true 会走流式每个 token 推一行 JSON。做聊天界面必须用流式不然用户要干等十几秒。对话接口/api/chat是多轮场景该用的消息按角色组织curl http://127.0.0.1:11434/api/chat -d { model: llama3, messages: [ {role: system, content: 你是一个简洁的技术助手}, {role: user, content: KV cache 是什么}, {role: assistant, content: 它是推理时缓存的注意力键值对。}, {role: user, content: 它和上下文长度什么关系} ], stream: false, options: {num_ctx: 8192} }返回结构里重点看message.content。这里有个实操要点多轮对话的历史需要你自己维护并每次都完整传过去。服务端是无状态的它不会记得上一轮说了什么。这也意味着上下文长度会被历史消息逐渐吃掉聊到后面就开始报错或者截断生产环境里要做历史裁剪或者摘要压缩。嵌入接口/api/embed把文本转成向量是做检索增强的基础。需要先拉一个嵌入模型这类模型很小几百 MBollama pull nomic-embed-text调用时传input字段返回embeddings数组。老版本用的是/api/embeddings端点、prompt字段、返回单个embedding两个版本都存在用新的就行。模型管理接口/api/tags、/api/pull、/api/delete、/api/show分别对应列表、拉取、删除、查看。/api/pull配合stream: true可以做下载进度条/api/show能拿到模型的参数表做前端展示时有用。4.2 OpenAI 兼容接口与既有代码迁移这一块是 Ollama 最讨巧的设计。它在/v1路径下复刻了一套 OpenAI 风格的接口包括/v1/chat/completions和/v1/embeddings。from openai import OpenAI client OpenAI( base_urlhttp://127.0.0.1:11434/v1, api_keyollama, # 本地不需要鉴权随便填个非空值 ) resp client.chat.completions.create( modelllama3, messages[{role: user, content: 写一段 50 字的产品介绍}], temperature0.3, ) print(resp.choices[0].message.content)这段代码和调用云端服务的写法完全一致只改了base_url和api_key。意味着你手上已有的基于 OpenAI SDK 写的项目迁移成本接近零。这个兼容层是我最推荐新手先用起来的入口比自己拼 HTTP 请求省事。需要清楚兼容层的边界。它兼容的是接口形状不是全部能力。函数调用工具调用的支持是后加的不同版本行为不完全一致logprobs、logit_bias这类偏底层的参数可能被忽略response_format里的 JSON 模式支持也有限。遇到这类需求还是走原生/api/chat或者用format: json参数强制结构化输出。4.3 三十行代码搭一个本地文档问答雏形光聊天没意思把模型接到自己的文档上才叫「部署了自己的大模型」。这里给一个不依赖任何第三方库的最小实现只用了标准库和 numpy装个 numpy 就能跑方便你理解每一步在干什么。思路是三段把文档切块、把每块转成向量存起来、提问时按相似度取最相关的几块塞进提示词。import json, urllib.request import numpy as np BASE http://127.0.0.1:11434 def post(path, payload): req urllib.request.Request( BASE path, datajson.dumps(payload).encode(), headers{Content-Type: application/json}, ) with urllib.request.urlopen(req, timeout180) as r: return json.loads(r.read().decode()) def embed(text): r post(/api/embed, {model: nomic-embed-text, input: text}) return np.array(r[embeddings][0], dtypenp.float32) def chunks(text, size300, overlap50): step size - overlap return [text[i:isize] for i in range(0, len(text), step) if text[i:isize].strip()] # 索引阶段 raw open(manual.txt, encodingutf-8).read() pieces chunks(raw) vecs np.stack([embed(p) for p in pieces]) vecs / np.linalg.norm(vecs, axis1, keepdimsTrue) # 查询阶段 def ask(question, top_k3): q embed(question) q / np.linalg.norm(q) idx np.argsort(vecs q)[-top_k:][::-1] context \n\n.join(pieces[i] for i in idx) prompt ( 只根据下面的资料回答问题。资料中没有的信息直接回答“资料中未提及”。\n\n f资料\n{context}\n\n问题{question} ) r post(/api/chat, { model: llama3, messages: [{role: user, content: prompt}], stream: False, options: {temperature: 0.2, num_ctx: 8192}, }) return r[message][content] print(ask(设备出现 E05 报错该怎么处理))几个设计上的取舍说明一下。切块大小 300 字、重叠 50 字这个组合是经验值切太小会丢上下文切太大会让噪声变多重叠是为了避免关键句正好被切断在两块之间。相似度用余弦因为嵌入向量已经归一化了直接点积就等价于余弦省一次除法。提示词里明确写「资料中没有就说未提及」这一句能显著降低编造率我实测过加上之后胡编的比例能降一半以上。这套东西能跑但它不是生产级方案。缺的是持久化索引每次启动重算太慢、更细的切分策略按标题层级切比按字数切好、以及重排序环节。不过作为理解 RAG 骨架的起点这三十来行足够了。注意嵌入模型和对话模型是两个独立的模型都要提前 pull 下来。用对话模型去做嵌入是行不通的输出的向量维度对不上语义空间也不对。4.4 后台常驻与开机自启开发时前台跑没问题真要当服务用就得做常驻。Linux 下 Ollama 安装脚本默认就注册了 systemd 服务改配置不要直接编辑主 unit 文件升级会被覆盖用 override 的方式sudo mkdir -p /etc/systemd/system/ollama.service.d sudo tee /etc/systemd/system/ollama.service.d/override.conf EOF [Service] EnvironmentOLLAMA_HOST0.0.0.0:11434 EnvironmentOLLAMA_MODELS/data/ollama/models EnvironmentOLLAMA_KEEP_ALIVE-1 EnvironmentOLLAMA_NUM_PARALLEL2 EOF sudo systemctl daemon-reload sudo systemctl restart ollama这几个环境变量的作用分别是OLLAMA_HOST控制监听地址OLLAMA_MODELS把模型目录挪到大容量磁盘上默认在家目录很容易被撑爆OLLAMA_KEEP_ALIVE-1让模型常驻内存不自动卸载默认 5 分钟无请求就卸载下次请求又要重新加载首字延迟会很难看OLLAMA_NUM_PARALLEL控制并发处理数。OLLAMA_KEEP_ALIVE是个双刃剑。设成 -1 之后响应快但内存会一直被占着在内存紧张的机器上会导致其他程序卡顿。我一般设成30m这种折中值。排查服务问题看日志journalctl -u ollama -fmacOS 的日志在~/.ollama/logs/server.logWindows 在用户目录下的AppData\Local\Ollama\server.log。模型加载失败、显存分配失败这类问题日志里都有明确原因。5. 性能调优量化等级与关键参数5.1 量化等级怎么选精度、体积与速度的三角量化就是把权重从高精度浮点数压缩成低位整数用一点点精度损失换大幅度的体积缩减。同一个人模型不同量化版本的质量差距可能比参数量的差距还明显所以这一步不能随便选。常见的等级从低到高大致是 Q2_K、Q3_K_S/M、Q4_0、Q4_K_S/M、Q5_K_M、Q6_K、Q8_0最后是 FP16 原始精度。名字里的 K 表示用了分块的混合量化策略S/M/L 表示块大小M 是均衡档。量化等级每权重比特8B 模型体积质量表现建议Q2_K~2.6~2.7GB明显退化长句容易崩只在极端受限时用Q3_K_M~3.9~4.0GB有可见损失不推荐Q4_04.5~4.7GB可用偶有错字兼容性最好Q4_K_M~4.85~4.9GB损失很小性价比最高首选Q5_K_M~5.7~5.7GB接近原始内存有余量时用Q8_0~8.5~8.5GB几乎无损显存充足时用FP1616~16GB基准一般没必要我的经验是默认选 Q4_K_M这是质量和体积的甜点。如果显存还剩 2GB 以上余量升到 Q5_K_M 能感觉到输出更稳长句的语法错误更少。Q8_0 在大多数任务上和 Q4_K_M 的差距小到需要仔细对比才能发现除非你在做评测或者对精度极度敏感否则多占的那几个 G 显存不划算。有一个反直觉的现象值得提醒量化损失是非线性的。从 Q8 降到 Q5几乎察觉不到变化从 Q5 降到 Q4仔细看能发现从 Q4 降到 Q3会突然出现明显的「变傻」——主要表现为指令遵循能力下降、开始忽略提示词里的格式要求。所以别为了省 1GB 显存去试 Q3得不偿失。5.2 num_ctx、num_gpu、num_thread、temperature 四个旋钮Ollama 的参数有二十多个但真正影响体验的其实就四个。num_ctx上下文长度是最容易踩坑的一个。它决定模型一次能「看见」多少 token。设小了长文档被静默截断模型只看到后半段回答自然驴唇不对马嘴而且不报错这是最坑的地方。我在处理一份两万字的技术手册时被这个问题折磨了半天一直以为是模型能力不行最后发现是上下文只有 2048。设定原则先估算你的输入长度。中文一个字大概 1.5 到 2 个 token一篇 5000 字的中文文档大概 8000 到 10000 token加上输出预留num_ctx 至少要 12K 才够。但同时要记住 KV Cache 随上下文线性增长8K 上下文下 8B 模型的 KV 约占 1GB32K 就要 4GB显存会爆。在显存和需求之间找平衡点不要无脑拉满。num_gpu卸载到 GPU 的层数决定多少层放在显存里跑。默认会自动判断但自动判断有时候偏保守。手动指定时可以从小往大试找到一个不爆显存的最大值。ollama ps里显示的 CPU/GPU 比例就是它的直接结果。理想状态是 100% GPU一旦出现混合比例速度会掉得比较明显因为每层都在做数据搬运。num_threadCPU 线程数只在 CPU 推理时起作用。经验值是设成物理核心数不要设成逻辑核心数超线程在这里没有收益反而有调度开销。8 核 16 线程的机器设 8 比设 16 快。temperature采样温度前面提过补充一点它和 top_p、top_k 是联动的。调三种参数都能改变输出的随机性同时压低会导致输出进入死循环。稳妥的做法是 temperature 为主0.2 到 0.8 之间top_p 保持 0.9top_k 保持默认 40。参数可以在三个层面设置优先级从高到低单次请求的options字段 Modelfile 里的PARAMETER 系统默认。调参时建议先用请求级参数快速试找到合适的值再固化进 Modelfile。5.3 显存不够时的分层卸载策略这是本地部署最常见的困境模型很想跑显存差一点。有几种应对思路可以组合使用。第一种是降量化等级从 Q5 降到 Q4省下 1GB 左右。这是损失最小的方案优先考虑。第二种是缩上下文把 num_ctx 从 32K 压到 8KKV Cache 能省下 3GB 左右。如果你的任务主要是短问答这个调整几乎无感。第三种是接受分层卸载让 Ollama 自动把一部分层放到内存GPU 跑一部分 CPU 跑一部分。速度会掉到纯 GPU 的三分之一到一半但至少能跑。判断依据看ollama ps的 PROCESSOR 列比如24%/76% CPU/GPU表示大部分在 CPU 上这时候可以手动把 num_gpu 调低一点让分配更均衡反而可能更快——因为减少来回搬运的次数比多放几层在显存里更重要。第四种是换更小的模型。8B 跑不动就上 3B 级别的很多任务上 3B 的表现比「8B 但上下文被砍到 2K」要好。这个取舍很多人不愿意做但实际效果往往更好。还有一个容易被忽略的点关闭其他占显存的程序。浏览器开着几十个标签页、设计软件在后台渲染都能吃掉 1 到 2GB 显存。跑模型前把它们关掉有时候比调参数更有效。6. 常见问题与排查实录6.1 报错速查表下面这些是我实际遇到过、或者在社区里被反复问到的。表格里给的是排查方向不是绝对答案因为同一个现象可能有好几种原因。现象最可能的原因处理方式model requires more system memory权重 KV Cache 超出可用内存降量化等级、缩 num_ctx、关掉占内存的程序服务起不来端口报错11434 被占用或前一个实例没退干净查端口占用杀掉旧进程或改 OLLAMA_HOST 换端口速度极慢ollama ps显示 100% CPUGPU 未被识别驱动问题或显存不足被降级更新驱动确认显存够检查是否有集成显卡抢占拉模型卡在某个百分比网络中断或目标磁盘空间不足重新执行 pull支持续传先清理磁盘回答答非所问、只答后半段num_ctx 太小输入被静默截断显式设置 num_ctx 到覆盖输入长度输出重复同一句话temperature 太低 repeat_penalty 未设temperature 提到 0.4 以上repeat_penalty 设 1.1中文输出夹杂英文或乱码模型本身中文能力弱或提示词语言混用系统提示词明确要求中文输出换中文优化更好的模型首次请求等很久之后正常模型未常驻每次都要重新加载设 OLLAMA_KEEP_ALIVE保持进程不退出多用户同时访问时排队默认并发为 1设 OLLAMA_NUM_PARALLEL但要注意内存按并发数翻倍修改环境变量后不生效改错了地方或没重载服务systemd 用 override 文件改完 daemon-reload6.2 输出质量类问题的排查思路性能问题有明确报错质量问题是隐性的更费时间。我总结了一个从外到内的排查顺序按这个顺序走能省不少事。第一步确认上下文够不够。这是最高频的原因占了质量问题的一大半。做法很简单先看你的输入大概多少 token再对比 num_ctx 设置。有个偷懒的估算方法把输入文本的字数乘以 1.8大概就是 token 数。如果接近或超过 num_ctx先加大再说。第二步看系统提示词有没有被遵守。小模型对系统提示词的敏感度不如大模型写得太抽象等于没写。「请专业地回答」这种指令基本无效要写成可执行的具体规则比如「先给结论再给理由」「涉及数字必须给具体值」「不确定就说不确定」。规则条目控制在五条以内太多了模型会顾此失彼。第三步降温度。默认 0.8 的温度在技术任务上太发散同一个问题每次答案都不一样看起来就像「不稳定」。压到 0.3 到 0.5输出会稳定很多。第四步检查量化等级。如果你用的是 Q3 或更低的量化质量下降是正常的不是模型的问题。换 Q4_K_M 再测一遍。第五步才是考虑换模型。前面四步都排查完还是不行说明任务确实超出了这个尺寸模型的能力边界。这时候上更大的模型或者在提示词里加几个示例少样本提示往往比换模型见效更快。提示调试阶段建议固定住 temperature 和 seed让输出可复现。同一个输入跑两遍结果不一样会给排查带来很大干扰。6.3 几条踩坑心得关于模型目录的位置。默认模型存在用户家目录下Linux 服务器上家目录往往挂的是小容量系统盘几个模型下去就红了。我现在的习惯是装完第一件事就把OLLAMA_MODELS指到大容量数据盘上注意改完要重新拉模型或者手动把旧的 models 目录整个拷过去改之前拉的模型不会自动迁移。关于「装了但感觉没用上」。判断有没有用上 GPU别靠感觉看ollama ps的 PROCESSOR 列。曾经在一台机器上折腾了两小时以为速度就是这样的最后发现是驱动版本太老导致完全走的 CPU更新驱动之后速度翻了六倍。这是最值得优先检查的一项。关于流式输出的必要性。不管做什么前端只要涉及对话一定要开 stream。哪怕总耗时一样流式让用户在第一秒就看到字往外冒心理感受差别巨大。实现上注意处理 SSE 的分行解析每行是一个独立的 JSON可能被网络切成半行要做缓冲区拼接。关于提示词里的中文标点。这一条有点玄学但确实有效如果要求模型输出结构化内容比如 JSON 或表格提示词里的示例不要用中文全角标点模型有概率把全角引号带进 JSON 里导致解析失败。示例统一用半角输出格式的稳定性会好很多。关于模型的「记忆」。服务端完全无状态历史必须自己存、自己传、自己裁剪。我一开始没意识到这点以为 Ollama 会记住对话结果接了 API 之后发现模型对上一轮一无所知白排查了半天。多轮场景的完整方案是自己维护一个消息数组超过上下文预算时把最早的几轮丢掉或者做摘要压缩。我个人在实际操作中的体会这套东西搭起来其实不难难的是「跑起来」和「用起来」之间的那段路。真正决定体验的不是模型多大、显卡多好而是三个看起来很小的地方上下文长度有没有设对、模型有没有常驻在内存里、提示词写得够不够具体。这三个调好了一台普通笔记本上的 8B 模型就足以应付日常的文档处理、代码辅助和知识问答调不好就算堆上顶配显卡也只会有「这模型怎么这么蠢」的挫败感。下一步想继续玩的话可以往两个方向延伸一是把嵌入模型和向量库接上做一个真正能查内部资料的问答系统从先跑通检索召回开始再慢慢加切分策略和重排序二是试试用 Modelfile 把你的固定任务固化成专属模型比如代码评审助手或者会议纪要整理助手把提示词、参数、停止符都封装进去以后换机器一条命令就能复现。这两个方向的门槛都不高但带来的实际收益比单纯升级硬件明显得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑