
在 Hacker News 上每隔一段时间就会有人重新发起同一个问题How is everyone using Local LLMs? 这个标题看起来只是普通的经验交流但它背后隐藏的真实状态是——本地模型部署已经不是难事了难的是部署完之后怎么把它放进真正的工作流里。很多人跑通了一个模型问了两句话发现回答质量不如云端 API然后就卸载了。这个结论下得太早了。本地 LLM 的价值不在于替代 ChatGPT而在于它改变了 AI 计算的生产关系模型权重在你自己机器上数据不出本机调用不按 token 计费离线也能运行。它更像是一台“私有的 AI 计算单元”而不是“免费的 GPT 替代品”。这篇文章会围绕大家实际用本地 LLM 做了什么来展开先讲清楚核心概念和选型再给出三个可以直接跑通的最小示例最后讨论常见问题和工程建议。如果你已经装好了 Ollama 或 LM Studio但不知道下一步该做什么这篇文章可以直接当作实践路线图来用。1. 这篇文章真正要解决的问题先给结论本地 LLM 真正降低的是隐私、成本和定制化这三座大山的门槛。先解释隐私。很多企业内部资料、用户数据、医疗记录、代码仓库是不能随便传到外部 API 的。过去要做 AI 功能只能走私有化部署大模型成本极高。现在通过开源模型加量化技术一台普通开发机甚至一台 MacBook 就能跑起一个 7B 或 14B 模型数据全程留在本地。这个变化让不少中小团队第一次有了“在合规前提下尝试 AI”的机会。再说成本。云端模型按 token 计费如果是高频调用比如日志分析、文本分类、批量信息抽取一个月下来账单不小。本地模型跑起来之后电费几乎可以忽略不计尤其是用个人电脑或内部服务器做离线批处理时边际成本接近零。这也是为什么很多开发者宁可牺牲一点回答质量也要把高频小任务放到本地。最后是定制化。云端模型你只能通过 Prompt 调教但本地模型可以换权重、调采样参数、做 LoRA 微调甚至改造推理服务。对于研究型开发者来说这种自由度是云端 API 给不了的。不过也要说清楚边界。本地 LLM 不适合所有人。如果你的核心诉求是通用写作、复杂推理、多语言高质量输出那顶级云端模型仍然更稳。本地模型的能力上限摆在那里7B 模型再折腾也达不到 GPT-4 级别。这篇文章的服务对象是那些有数据隐私顾虑、有高频自动化需求、想深入研究模型机制或者单纯想在离线环境里拥有一套 AI 能力的开发者。2. 本地 LLM 的核心概念与原理2.1 本地 LLM 到底是什么本地 LLM 是指在自有设备上运行推理的开源大语言模型。与 ChatGPT 这类云端服务不同本地模型的所有计算都在你的 CPU、GPU 或 NPU 上完成。你下载的是模型权重文件运行的是一个推理引擎输入输出都不经过第三方服务器。这带来一个直接好处只要模型装进内存断网也能用。另一个好处是可控性你可以随时换模型、换量化等级、改推理参数。但也带来一个代价硬件资源完全由你承担。2.2 参数量与显存内存估算模型文件大小主要由参数量和精度决定。参数量的单位是 BBillion十亿。7B 就是 70 亿参数。每个参数需要一定字节数来存储FP324 字节精度最高体积最大。FP16 / BF162 字节推理常用体积适中。INT81 字节量化后精度损失较小。INT4 / Q4_K_M约 0.5 字节体积小是本地部署最常见的格式。以 7B 模型为例粗算权重占用精度7B 模型权重大小FP32约 28GBFP16 / BF16约 14GBINT8约 7GBQ4_K_M约 4GB这还只是模型权重实际运行时还有 KV Cache、上下文窗口和推理引擎开销所以内存需求要再上浮 20% 到 50%。如果你只有 16GB 内存跑 14B 的 Q4 量化模型已经比较紧张如果只有 8GB 内存7B Q4 是相对稳妥的选择。2.3 为什么本地 LLM 慢很多人第一次用本地模型时最不习惯的就是速度。云端模型生成 50 token/s 很平常本地 7B 模型在 CPU 上可能只有 5 到 15 token/s。原因很简单大模型推理是内存带宽密集型任务每生成一个 token 都要把整个模型权重读一遍。内存带宽越高生成速度越快。这也是为什么 Apple Silicon 的 Mac 跑本地模型体验不错——统一内存架构给了 CPU 和 GPU 共享高带宽内存跑 7B 到 32B 模型都有实用速度。NVIDIA 显卡因为显存带宽高同样是很好的推理硬件。纯 CPU 老机器也能跑但只能处理小模型或者忍耐较慢的速度。2.4 几个容易混淆的概念Embedding 模型和生成模型是两类不同的模型。Embedding 模型把文本转成向量用于计算相似度、做检索生成模型负责生成文字。RAG检索增强生成就是把这两者结合起来先用 Embedding 从知识库中找回相关片段再把片段拼进 Prompt交给生成模型作答。Function Calling 是让模型输出结构化工具调用请求的能力。模型本身不会真正调用外部函数它只负责说“我想调用 fetch_webpage 这个工具参数是 xxx”。真正执行工具的是外部框架。MCPModel Context Protocol是 Anthropic 提出的开放协议用来统一大模型与外部工具的连接方式。过去每接一个工具就要写一套集成MCP 把工具封装成标准服务模型可以通过统一的协议去发现和调用工具。Agent 则是在多轮对话中自主决定调用哪些工具、按什么顺序调用的系统。LLM 负责决策编排框架负责执行、重试和状态管理。3. 大家实际都在用本地 LLM 做什么从社区讨论和实际项目看本地 LLM 的主流用法越来越清晰。它不是被当成聊天机器人用而是被嵌入到各种工作流里。3.1 离线编程辅助这是最常见的用途之一。很多开发者把本地模型接到 VS Code 或终端里用于代码补全、生成注释、解释报错信息、写测试用例。尤其是网络受限环境或者想避免代码片段上传到云端时本地模型成了唯一选项。7B 模型写简单脚本和工具函数是够用的但复杂架构设计还是会露怯。更合理的姿势是把本地模型当成一个熟悉多种语言的“结对同事”让它帮你写正则、写 Shell 脚本、做代码 review而不是让它直接设计整个系统。3.2 私有知识库问答RAG企业里最常见的需求是“让 AI 帮我们读文档”。合同条款、产品手册、内部 Wiki、历史工单这些内容往往不适合上传到外部服务。本地 RAG 方案的思路是先用 Embedding 模型把文档向量化用户提问时检索相关片段再交给本地生成模型回答。这套架构不需要微调模型也不需要 GPU 集群一台 16GB 内存的机器就能跑出一个可用的私有问答系统。真正要花心思的是文档切分、检索排序和 Prompt 设计模型反而是最容易替换的部分。3.3 文本结构化与数据提取本地模型很适合做信息抽取。比如从非结构化文本中提取合同里的金额、日期、甲乙双方信息从工单里提取问题分类从日志里提取异常类型。这类任务不需要很强的创作能力只需要稳定的指令遵循能力7B 到 14B 模型完全可以胜任。实践中可以写一个简单脚本把待处理文本批量发给本地模型让模型输出 JSON再落库。相比写正则表达式这种方式的泛化能力强很多相比调用云端模型成本低很多。3.4 个人写作与内容总结很多人把本地模型当写作助手。比如总结会议纪要、润色邮件、把零散想法扩写成文章大纲、翻译技术文档。这类任务不需要太多实时性模型慢一点也可以接受。Karpathy 曾经提到过一个很有意思的范式让 LLM 帮你整理个人知识库把聊天记录里的内容沉淀成 Wiki 卡片再放到 Obsidian 这类笔记工具里管理。核心不是模型多聪明而是把模型的输出变成可复用的结构化资产。这个思路对本地模型特别适合因为笔记内容往往涉及个人隐私放在本地处理更安心。3.5 本地自动化 Agent把本地模型和自动化脚本结合可以做出很多实用工具。比如定时收集 RSS 并总结成日报监听某个目录的新文件并自动分类抓取网页内容后提炼要点甚至控制智能家居。这类 Agent 通常不追求复杂的多轮推理而是把“理解指令”和“执行动作”拆开LLM 负责前者脚本负责后者。当任务变得复杂后就需要编排框架了。LLM 本身只负责“下一步做什么”而框架负责“怎么做、做错了怎么重试、上下文怎么管理”。这也是 LangChain、Spring AI 这类框架存在的意义。3.6 教育与模型研究对于想学习大模型原理的人来说本地部署是最好的实验环境。你可以直接观察模型在不同采样参数下的输出差异可以测试量化的质量损失可以尝试 LoRA 微调甚至可以研究 KV Cache 对上下文长度的影响。这些实验在云端 API 上几乎做不了或者说成本太高。3.7 隐私敏感场景医疗、金融、法律、政务这类行业的数据合规要求很高。即便不考虑技术难度数据能不能出境本身就是政治和法律问题。本地模型在这里的核心价值不是能力而是信任边界模型和数据都在你手里审计和管控变得简单。4. 选型模型、量化与推理引擎4.1 模型选择不同任务适合不同模型不要指望一个模型通吃所有场景。从当前开源生态看中文场景下通义千问系列Qwen2.5是综合表现比较稳的选择0.5B 到 72B 都有覆盖低端机到高性能服务器。英文场景可以看 Llama 系列和 Mistral 系列辅助编程工具场景可以看专门训练的代码模型例如 Qwen2.5-Coder。Embedding 模型方面BGE-M3 是常用的多语言向量模型支持中文和英文检索效果不错。它对硬件要求很低CPU 也能跑。4.2 量化选择量化等级直接决定你能不能跑起来。对于 7B 模型Q4_K_M 是内存和质量的平衡点如果内存充裕Q6_K 或 Q8 质量更好。14B 模型一般建议 Q4_K_M 起步32B 模型则需要大内存或者多卡才能跑 Q8。需要说明的是量化并不是越小越好。Q2 量化后的模型经常出现明显质量下降尤其是中文写作和复杂推理不建议在生产场景使用。FP16、BF16、INT8、INT4 这些精度选择本质上是质量、速度、内存三者的取舍。4.3 推理引擎对比推理引擎平台特点适合人群OllamaWindows / macOS / Linux安装简单、命令友好、提供 OpenAI 兼容 API绝大多数开发者LM StudioWindows / macOS / Linux图形界面、模型管理直观、内置聊天窗口Mac 用户、可视化操作偏好者llama.cpp跨平台底层 C 实现、可编译定制、资源占用低嵌入式设备、深度折腾玩家vLLMLinux NVIDIA GPU高吞吐、支持连续批处理、生产级服务需要对外提供服务的团队对于普通开发者和个人用户Ollama 是上手最快、社区生态最好的选择。它自带模型仓库一条命令就能完成安装、下载、启动还提供 OpenAI 兼容接口意味着很多本来适配 GPT 的开源项目可以直接改 base_url 接到本地模型上。5. 基础环境准备与安装5.1 硬件建议最低门槛8GB 内存可以跑 1.5B 到 3B 模型体验较差。实用门槛16GB 内存可以流畅跑 7B Q4 模型。舒适区32GB 统一内存或 16GB 显存以上可以跑 14B 到 32B 模型。需要说明的是本地 LLM 不一定和业务应用跑在同一台电脑上。它通过 HTTP 服务暴露ComfyUI、IDE、Agent 程序都通过 API 访问模型同机部署不是必须的。局域网里的配置也可以很灵活一台大内存的旧服务器专门跑 Ollama开发机通过网络调用。5.2 安装 OllamaOllama 的安装命令很简单# macOS 或 Linux curl -fsSL https://ollama.com/install.sh | sh # Windows 用户直接下载安装包 # https://ollama.com/download安装完成后启动服务并拉取一个模型# 拉取 Qwen2.5 7B 模型约 4GB 左右 ollama pull qwen2.5:7b # 拉取 BGE-M3 Embedding 模型后面 RAG 示例会用到 ollama pull bge-m3 # 查看本地已有模型 ollama listOllama 默认监听 11434 端口。验证服务是否正常curl http://localhost:11434/v1/models如果返回一个 JSON 列表说明服务已经跑起来了。这里有一个常见坑Ollama 安装后可能在后台运行也可能只在前台运行。如果你改了环境变量或者端口配置需要重启服务才能生效。5.3 LM Studio 作为替代LM Studio 更适合不喜欢命令行的用户。安装后图形界面里可以直接搜索模型、下载、配置上下文长度、调整量化等级、启动本地 OpenAI 兼容服务。Mac 用户的体验尤其顺滑因为它充分利用了 Metal 加速和统一内存。如果你主要是想快速体验不同模型不关心命令行LM Studio 可能比 Ollama 更合适。它的本地服务路径是http://localhost:1234/v1用法和 OpenAI 接口基本一致。6. 实操示例从 API 调用到 RAG 再到 MCP这一部分给出三个可以直接跑通的示例。第一个是基础 API 调用第二个是最小 RAG 知识库第三个是 MCP 工具服务。建议按顺序执行先跑通基础环境再逐步增加复杂度。6.1 示例一OpenAI 兼容 API 调用Ollama 提供了 OpenAI 兼容接口这是它最实用的设计之一。任何原本对接 OpenAI 的程序只要把base_url改成http://localhost:11434/v1模型名改成本地模型名就能切换到本地推理。先用 curl 测试一次对话curl http://localhost:11434/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen2.5:7b, messages: [ {role: user, content: 用三句话解释什么是 RAG} ], stream: false }正常返回会包含choices[0].message.content字段。用 Python 调用更接近工程场景# 文件路径ollama_chat.py # 依赖pip install requests import requests OLLAMA_URL http://localhost:11434 def chat(prompt: str, model: str qwen2.5:7b) - str: resp requests.post( f{OLLAMA_URL}/v1/chat/completions, json{ model: model, messages: [{role: user, content: prompt}], stream: False, }, timeout300, ) resp.raise_for_status() data resp.json() return data[choices][0][message][content] if __name__ __main__: answer chat(用三句话解释什么是 RAG) print(answer)这段代码的核心是把 HTTP 请求封装成一个函数传入 Prompt返回模型生成的文本。timeout300是因为本地模型生成速度可能慢尤其是 CPU 推理超时设置得太短会导致请求中断。6.2 示例二最小 RAG 知识库RAG 是本地 LLM 最有价值的落地场景之一。下面这个示例不依赖重型框架只用 requests 和标准库实现一个完整的“文档切分 - 向量化 - 检索 - 生成”流程。# 文件路径local_rag_demo.py # 依赖pip install requests # 前置ollama pull qwen2.5:7b ollama pull bge-m3 import math import requests OLLAMA_URL http://localhost:11434 def embed(text: str): resp requests.post( f{OLLAMA_URL}/v1/embeddings, json{model: bge-m3, input: text}, timeout60, ) resp.raise_for_status() return resp.json()[data][0][embedding] def cosine_similarity(vec_a, vec_b): dot sum(x * y for x, y in zip(vec_a, vec_b)) norm_a math.sqrt(sum(x * x for x in vec_a)) norm_b math.sqrt(sum(x * x for x in vec_b)) return dot / (norm_a * norm_b) def split_text(text: str, chunk_size: int 200): # 简单按句号切分真实项目中建议用更完善的分块策略 sentences text.replace(\n, ).split(。) chunks [] current for sentence in sentences: if len(current) len(sentence) chunk_size and current: chunks.append(current.strip()) current sentence 。 else: current sentence 。 if current.strip(): chunks.append(current.strip()) return chunks def build_index(documents): index [] for doc in documents: for chunk in split_text(doc): index.append({content: chunk, vector: embed(chunk)}) return index def search(query, index, top_k2): query_vec embed(query) scored [] for item in index: score cosine_similarity(query_vec, item[vector]) scored.append((score, item[content])) scored.sort(reverseTrue, keylambda x: x[0]) return [content for _, content in scored[:top_k]] if __name__ __main__: docs [ 本地大模型可以在无网络环境下运行模型权重和数据都保留在自有设备中。, RAG 检索增强生成的核心思路是先召回相关片段再交给大模型生成答案。, MCP 是一个开放协议统一了大模型调用外部工具的方式。, Ollama 是最简单的本地大模型部署工具之一安装后可通过 HTTP API 调用模型。, ] index build_index(docs) query 我想用本地大模型做一个知识库问答系统应该怎么做 contexts search(query, index) prompt ( 请根据下面提供的参考资料回答用户问题。\n f参考资料\n \n.join(contexts) \n\n f用户问题{query} ) resp requests.post( f{OLLAMA_URL}/v1/chat/completions, json{ model: qwen2.5:7b, messages: [ {role: system, content: 你是知识库助手请只根据参考资料回答不要编造。}, {role: user, content: prompt}, ], stream: False, }, timeout300, ) resp.raise_for_status() answer resp.json()[choices][0][message][content] print(召回片段) for c in contexts: print(-, c) print(\n生成答案) print(answer)这段代码的核心逻辑值得拆开解释。embed函数调用本地 Embedding 模型把文本转为向量。BGE-M3 的向量维度是 1024但调用方不需要关心维度直接交给余弦相似度计算即可。build_index函数把文档切分后向量化。这里用的切分逻辑是“按句号累积超过阈值就断开”非常简单演示够用。真实项目里还要考虑段落边界、标题层级、句子完整性甚至用递归切分器。search函数把用户问题向量化和所有文档片段计算余弦相似度取分数最高的前两个片段作为上下文。这里没有用向量数据库。一旦文档量超过几百个片段内存遍历就会变慢届时再引入 ChromaDB、LanceDB 或 Qdrant 这类向量数据库不迟。最后一步把检索到的片段拼进 Prompt让生成模型基于参考资料回答。System Prompt 里强调“只根据参考资料回答不要编造”这是 RAG 工程里必须坚持的约束否则模型会凭训练记忆自由发挥失去 RAG 的意义。6.3 示例三通过 MCP 暴露本地工具MCP 的价值在于统一工具接入。下面用 MCP Python SDK 写一个最简单的工具服务暴露一个fetch_webpage函数让支持 MCP 的客户端可以调用这个工具来抓取网页并返回文本。# 文件路径mcp_server.py # 依赖pip install mcp requests from mcp.server.fastmcp import FastMCP import requests mcp FastMCP(web-tools) mcp.tool() def fetch_webpage(url: str) - str: 抓取指定网页的文本内容返回前 2000 个字符。 resp requests.get(url, timeout10) resp.encoding resp.apparent_encoding return resp.text[:2000] if __name__ __main__: mcp.run