很多人想在自己机器上跑个开源模型,搜到两个名字:Ollama 和 llama.cpp,装完发现一个像 App、一个像工具库,就懵了——到底该用哪个。这篇不站队,把两者的定位、可控点、维护成本摊开对照,再给一套按场景选型的判断顺序,让你在动手前就知道自己会卡在哪一步。
很多人想在自己机器上跑个开源模型,搜到两个名字:Ollama 和 llama.cpp。装完发现一个像 App、一个像工具库,界面、命令、文档风格全不一样,就懵了——到底该用哪个。这篇不站队,把两者的定位、可控点、维护成本摊开对照,再给一套按场景选型的判断顺序,让你在动手前就知道自己大概会卡在哪一步。
先把结论的反面说清楚:这两个东西底层解决的是同一件事,就是在本地把权重跑起来出 token,所以搜索结果高度重叠、社区回答经常混着讲。真正的差别不在功能多少,而在抽象层级——一个偏交付成品,一个偏可嵌入的推理引擎。层级一确定,后面所有取舍基本都是它的衍生结果。
为什么这两个名字总被放在一起比
它们被放一起,不是因为谁替代谁,而是因为搜索「本地跑模型」时两条路径都会跳出来。你搜的是需求,引擎和成品都满足这个需求,于是看起来像竞品。判断的第一步不是比功能,而是先给自己贴个标签:你是「用户」,还是「集成方」。
| 你的身份 | 主要诉求 | 优先考虑 |
|---|---|---|
| 用户 | 今天就想跑通、能对话 | 上手路径短的那个 |
| 集成方 | 把推理塞进自己的程序 | 可编程、可编译、可嵌的那个 |
| 两者之间 | 先验证效果再决定 | 先用顺手的跑通,再按瓶颈下沉 |
| 运维统一者 | 跟团队现有规范一致 | 团队已定的那套,不单开分支 |
身份不同,答案可能反过来。比如一个做产品的团队,即便成员个人更习惯点开就能用的界面,真到接进服务时仍要看引擎侧的接口与并发能力;反过来,只是想拿模型整理本地文档的人,纠结编译选项属于给自己加戏。
定位差异:一个是成品,一个是引擎
Ollama 把模型拉取、运行、常驻服务、对外接口打包在一起,装完就能聊,适合不想碰编译和链接的人。它的价值在于把一堆琐碎步骤收进一个入口,代价是部分底层选项被默认值挡住,你想改某个细节时得先确认它有没有暴露出来。
llama.cpp 更接近底层实现,你能拿到更细的开关与构建选项,也意味着模型转换、参数拼接、服务封装这些事要自己接。它的价值在于自由度,代价是排查时你得知道每个参数在干什么,出问题不能只靠重启解决。
- 成品式路径
- 把常用流程收进统一入口,少配置、快见效,细节改动受暴露程度限制
- 引擎式路径
- 把推理能力交给你自己组装,自由度高,但每一步都要自己负责
- 判断法
- 需要「今天就想跑通」倾向前者;要把推理塞进自己的程序,倾向后者
可控点对比:哪些开关你摸得到
量化档位、上下文长度、线程与显存卸载策略,两边都能调,但暴露方式和粒度不同。Ollama 走配置与服务参数,改动集中、上手快;llama.cpp 走启动参数与编译选项,更细但更散。这不是谁强谁弱,而是你愿意把复杂度放在哪一层。
| 可调项 | 成品式路径的摸法 | 引擎式路径的摸法 |
|---|---|---|
| 量化档位 | 换标签或换文件 | 选对应量化文件并配参数 |
| 上下文长度 | 改服务配置项 | 启动参数里显式指定 |
| 显存卸载 | 依赖默认策略 | 逐层指定卸载层数 |
| 线程数 | 配置里给一个值 | 启动参数里按核数调 |
实操建议:不管走哪条,先把当前设置记成一张小表——模型、量化、上下文、并发各是多少。发现效果不对时,一次只改一项,改完用同一段输入对比输出。想省事,就直接拿站内的基线数据当参照,到 /tools/speed-test 量一遍当前延迟,别凭感觉判断快慢。
硬件适配:老卡、核显、纯 CPU 谁更省心
只有 CPU 或显存很小的机器,优先看谁能把层卸载到内存并稳定跑起来,而不是看谁功能多。功能列表再长,跑两轮就爆显存也白搭。先确认瓶颈在显存、内存带宽还是 CPU 单核,再决定装哪个。
- 先认硬件名词把「显存」「统一内存」「内存带宽」这些词对上号,到 /ai-dict/category/hardware 看释义,避免把显存和系统内存混着算。
- 再算部署可行性按你要跑的模型规模与量化档,到 /models/deploy 估一遍占用,看落在哪一档。
- 最后验证稳定性跑一段长输入,观察是否掉速或中断;能连续跑完才算适配,能启动不算。
多卡、异构卡、非主流加速卡场景,往往要看构建选项与后端支持,这类问题成品式路径给不了太多空间。如果你的机器属于这一类,基本可以先把引擎式路径列为首选,再去比细节。具体某张卡的适配情况,到 /ai-dict/category/hardware 对照当时的说明确认。
长期维护成本:升级、换模型、多人共用
当成日常服务长期挂着的,重点看版本升级会不会破坏原有调用、有没有守护进程和统一入口。只是偶尔试玩、跑完就关的,维护成本几乎可以忽略,选顺手的那个就行。把使用频率想清楚,比比较功能更重要。
- 长期常驻:优先看升级兼容性与进程管理方式,别让一次升级把调用全打断
- 偶尔试玩:谁装得快用谁,不值得为参数花时间
- 多人共用:提前定好端口、并发上限和显存占用怎么隔离,别等冲突了再改
- 换模型频繁:看换模型要不要重做转换和配置,步骤越少越省事
- 无人值守:要有日志和重启策略,否则半夜挂了没人知道
多人共用同一台机器是个容易被低估的坑。两个人各自起服务、都以为显存够用,结果同时跑就互相挤。做法是固定一个统一入口,把并发数写进配置,谁要用先申请。端口和模型目录也统一约定,避免各拉一份权重占满磁盘。
先选错也别慌:两者之间的迁移成本
模型权重文件本身是通用的,真正要重做的是启动参数、服务封装和调用地址。所以「选错」通常没你想的那么贵,贵的是一开始就把调用地址写死在业务代码里,换个引擎要改几十处。
- 记录现状把当前用的量化档、上下文长度、并发设置抄下来,做成一张对照表。
- 做一层薄封装让业务只认自己的接口,引擎细节收在封装里,后面换只改这一层。
- 逐个对齐换过去后按对照表一项一项调,别一次全改,否则出问题说不清是哪项引起的。
- 量基线再比换之前用 /tools/speed-test 量一遍延迟基线,换完用同一段输入对比,别凭感觉说快了慢了。
迁移时最容易忽略的是默认值差异。同样一段输入,两边默认的上下文长度、采样参数可能不一样,输出自然不同。先固定一组参数再比效果,否则你会误判是引擎的问题,其实是配置没对齐。
选型清单:按这五个问题走一遍
| 问题 | 答是 | 答否 |
|---|---|---|
| 要嵌进自己的产品吗 | 偏引擎式路径 | 偏成品式路径 |
| 机器有可用独显吗 | 两条路都可行,看其余问题 | 先按 CPU 场景筛 |
| 要长期常驻服务吗 | 重看维护与升级兼容 | 选顺手的即可 |
| 愿意为参数翻文档吗 | 倾向引擎式路径 | 倾向成品式路径 |
| 能接受的排查时间短吗 | 倾向上手快的那条 | 可接受下沉调参 |
五问里「嵌进产品」和「愿意调参」都答是,倾向引擎式路径;都答否,倾向成品式路径。介于中间的情况,先用上手快的把流程跑通,再按实际瓶颈决定要不要下沉。别在还没跑通之前就先纠结终极方案。
- 先跑通再优化,不要第一步就追求最优配置
- 记录基线,没有对比数据就别说哪条路更快
- 一次只改一个变量,改完立刻验证
- 把调用层做薄,给自己留后路
- 硬件适配拿不准就去站内对照,别靠猜
什么情况下这套判断不适用
要拼高并发和吞吐的场景,这两个都不是首选,去看 /inference 里的服务化方案对比。那类场景关心的是批处理、调度和多实例编排,本地单机跑通的经验搬不过去。硬套这份清单,只会让你在错误的方向上多花时间。
团队已经统一了某套部署规范时,个人偏好让位于运维一致性,别为此单开一条路。纯粹想验证模型效果、不打算长期跑的,随便选一个能最快出结果的即可,纠结半小时的选型成本比省下的调试时间还高。
下一步与其继续在两条路之间反复横跳,不如先拿手头的机器量一份基线,再去对照站内的部署与硬件资料,结论会比空想清楚得多。→常见问题
Ollama 是不是就是 llama.cpp 套了个壳?
底层确实共用同一套推理实现思路,但把 Ollama 理解成「壳」会误导判断。它额外提供了模型管理、常驻服务和接口层,这些才是日常使用中真正省事或受限的地方。要不要用,取决于你需不需要这层管理。
我只想在自己电脑上试着跑一个开源模型,该装哪个?
先装上手指令少的那一个,把模型跑通、看看速度和效果是否可接受。等确认要长期用、或者发现某个参数调不动时,再去换另一个。上来就折腾编译和参数,容易卡在环境上而不是模型上。
两者跑同一个模型,输出结果会不一样吗?
同样的权重和同样的量化档,生成质量理论上接近,差异主要来自采样参数默认值、上下文长度限制和停止条件这些设置。如果对比结果差很多,先检查这几项是否对齐,别急着归因到工具本身。
机器只有 CPU、没有独立显卡,还有必要折腾吗?
能跑,但速度和能跑的模型规模都受限,适合验证流程和做小任务。要不要继续投入,取决于你能否接受当前的出字速度,先用 /tools/speed-test 量一遍再决定更稳妥。
以后想换到别的方式部署,现在的工作会白做吗?
模型权重和量化文件通常可以复用,白做的主要是服务配置和调用封装。把接口调用写成单独一层,换引擎时只改这一层,之前的投入就还能留下大部分。