开源模型 vs 闭源模型
这个问题的讨论经常在两句话之间来回横跳:"闭源的效果就是好"和"开源才不会被卡脖子"。但真要落到决策上,它其实不取决于立场,取决于两个可以算的数:你每月用掉多少 Token,以及你的机器能不能被跑满。 这篇把这两句口号换成一张账单。
本文的关系图:
一个问题:自建,还是调 API?
↓ 三个变量决定答案
每月用多少 Token × 一台机器能产多少 × API 什么价
↓
分水岭:每月约 2 亿 Token
↓
但真正的胜负手不是用量,是「能不能批处理」
↓
而钱以外,还有五件算不进账单的事
一、先掰正一个词:多数"开源",其实是"开放权重"
先说一件容易扫兴的事。
当你看到"开源大模型"时,绝大多数情况下,实际公开的只有一样东西:权重文件------也就是那些训练好的数字。
而"开源"这个词在软件世界的标准含义,是源代码公开,任何人都能读、能改、能重新编译。对照一下大模型的实际情况:
| 传统开源软件 | 多数"开源大模型" | |
|---|---|---|
| 成品(权重 / 二进制) | 公开 | 公开 |
| 源代码(架构实现) | 公开 | 通常公开 |
| 训练数据 | ------ | 基本不公开 |
| 训练代码 / 全部流程 | ------ | 基本不公开 |
| 能否从零复现 | 能 | 不能 |
你拿到的是"成品",不是"菜谱"。 你可以用、可以改、可以微调,但你没法自己从零再造一个------因为最关键的那份配方(数据配比和处理流程)不在你手里。
所以更准确的叫法是 "开放权重"(open weights)。
这个区别不是文字游戏,它直接影响你的权利。 权重文件的许可证五花八门,绝不是"随便用":
- 真宽松的:Apache 2.0、MIT 这类,商用、修改、再分发基本都行;
- 社区许可证 :允许商用,但常常带附加条款------比如月活用户超过某个数要单独申请 ,或者你基于它训练的新模型必须改名;
- 非商用许可:研究可以,商用不行;
- 禁止蒸馏:某些闭源模型的服务条款明确禁止"用它的输出训练自己的模型"。
所以下载之前先读许可证,别只看"开源"两个字就下手。 一个模型技术再好,许可证不允许你的用法,等于不能用。
二、成本那笔账:别猜,算
现在进入正题。下面这段代码把"自建还是调 API"算成一笔月账单------纯算术,可以照着改参数。
python
"""开源 vs 闭源:把「自建还是调 API」算成一笔账。
下面所有价格都是【假设值】,只为演示算法本身,不代表任何厂商的真实报价。
请把你自己的实际报价代进去------结论会随行情变,但算账的方法不变。
"""
import math
# ── 自建:一台机器的成本 ───────────────────────────
GPU = 15000 # 一张 24GB 消费级显卡(元)
HOST = 8000 # 主机其余部分:CPU / 主板 / 内存 / 电源(元)
MONTHS = 36 # 折旧年限
WATT = 600 # 整机满载功耗(瓦)
ELEC = 0.6 # 电价(元/度)
HOURS = 24 * 30 # 每月运行小时数
# ── 吞吐:决定这台机器值不值 ───────────────────────
SINGLE = 30 # 单并发生成速度(token / 秒)
BATCH = 50 # 批处理并发数(vLLM 这类框架的连续批处理)
# ── 闭源 API ──────────────────────────────────────
PRICE_IN = 2.0 # 元 / 百万 token(输入)
PRICE_OUT = 8.0 # 元 / 百万 token(输出)
CELL = 20
def disp_width(s):
"""显示宽度:中日韩字符占 2 格,用来对齐表格。"""
return sum(2 if ord(c) > 0x2E80 else 1 for c in s)
def pad(s, n, right=False):
fill = " " * max(0, n - disp_width(s))
return fill + s if right else s + fill
def row(cells, widths):
return "".join(pad(c, w, right=(i > 0)) for i, (c, w) in enumerate(zip(cells, widths)))
amort = (GPU + HOST) / MONTHS
power = WATT / 1000 * HOURS * ELEC
fixed = amort + power
cap_single = SINGLE * HOURS * 3600 / 1e6 # 百万 token / 月
cap_batch = SINGLE * BATCH * HOURS * 3600 / 1e6
api_avg = (PRICE_IN + PRICE_OUT) / 2
def self_host(monthly_m, cap):
"""要几台机器才够,以及每月总成本。"""
machines = max(1, math.ceil(monthly_m / cap))
return machines * fixed, machines
# ── ① 一台机器的月成本 ─────────────────────────────
W = (26, 16)
print("① 一台自建机器的月成本")
print(row([" 显卡(24GB 消费级)", f"¥{GPU:,}"], W))
print(row([" 主机其余部分", f"¥{HOST:,}"], W))
print(row([f" 合计(按 {MONTHS} 个月折旧)", f"¥{amort:,.0f} / 月"], W))
print(row([f" 电费 {WATT}W × {HOURS}h × {ELEC} 元", f"¥{power:,.0f} / 月"], W))
print(row([" ------------------------------------------", "------------------------------------"], W))
print(row([" 每月固定成本", f"¥{fixed:,.0f}"], W))
print(f" 拆开看:折旧占 {amort/fixed:.0%},电费占 {power/fixed:.0%}------真正贵的是硬件,不是电")
print()
# ── ② 产能 ────────────────────────────────────────
print("② 这台机器一个月最多产出多少 Token")
print(row([" 单并发", f"{SINGLE} token/s"], W))
print(row([" → 月产能", f"{cap_single:,.2f} 百万 token"], W))
print(row([" 批处理", f"{SINGLE} × {BATCH} 并发"], W))
print(row([" → 月产能", f"{cap_batch:,.2f} 百万 token"], W))
print(f" 批处理把吞吐拉高 {BATCH} 倍------这是自建成败的那个关键变量")
print()
# ── ③ 单位成本 ────────────────────────────────────
print("③ 单位成本(元 / 百万 token)")
print(row([f" 闭源 API(输入输出 1:1,均价 ¥{api_avg:g})", f"{api_avg:.2f}"], W))
print(row([" 自建 · 单并发", f"{fixed/cap_single:.2f}"], W))
print(row([" 自建 · 批处理", f"{fixed/cap_batch:.2f}"], W))
print()
# ── ④ 盈亏平衡点 ──────────────────────────────────
print("④ 盈亏平衡点:每月用掉多少才划算")
breakeven = fixed / api_avg
print(row([" API 单价", f"¥{api_avg:.2f} / 百万"], W))
print(row([" 一台机器月成本", f"¥{fixed:,.0f}"], W))
print(row([" → 平衡点", f"{breakeven:,.1f} 百万 token / 月"], W))
print()
print(f" 但一台机器单并发一个月只能产 {cap_single:,.1f} 百万,够不着这个点。")
print(" → 单并发自建,永远到不了盈亏平衡。")
print(f" 批处理产能 {cap_batch:,.1f} 百万 ≫ {breakeven:,.1f} 百万 → 轻松越过,且越用越便宜。")
print()
# ── ⑤ 不同规模下的账单 ────────────────────────────
print("⑤ 不同规模下的实际月账单(元)")
W2 = (20, 16, 26, 26)
print(row([" 月 Token 量", "闭源 API", "自建·单并发", "自建·批处理"], W2))
print(" " + "-" * 84)
for m in (1, 10, 100, 1000, 10000):
cs, ms = self_host(m, cap_single)
cb, mb = self_host(m, cap_batch)
print(row([f" {m:,} 百万",
f"¥{m*api_avg:,.0f}",
f"¥{cs:,.0f} ({ms} 台)",
f"¥{cb:,.0f} ({mb} 台)"], W2))
print()
print(f" 结论:每月 {breakeven:,.0f} 百万 token 是分水岭。低于它,API 几乎总是更便宜;")
print(" 高于它,把机器跑满(批处理)能便宜一个数量级。")
真实运行结果 (本机实测,完整脚本见 code/07-open-vs-closed-demo.py):
① 一台自建机器的月成本
显卡(24GB 消费级) ¥15,000
主机其余部分 ¥8,000
合计(按 36 个月折旧) ¥639 / 月
电费 600W × 720h × 0.6 元 ¥259 / 月
------------------------------------------ ------------------------------------
每月固定成本 ¥898
拆开看:折旧占 71%,电费占 29%------真正贵的是硬件,不是电
② 这台机器一个月最多产出多少 Token
单并发 30 token/s
→ 月产能 77.76 百万 token
批处理 30 × 50 并发
→ 月产能 3,888.00 百万 token
批处理把吞吐拉高 50 倍------这是自建成败的那个关键变量
③ 单位成本(元 / 百万 token)
闭源 API(输入输出 1:1,均价 ¥5) 5.00
自建 · 单并发 11.55
自建 · 批处理 0.23
④ 盈亏平衡点:每月用掉多少才划算
API 单价 ¥5.00 / 百万
一台机器月成本 ¥898
→ 平衡点 179.6 百万 token / 月
但一台机器单并发一个月只能产 77.8 百万,够不着这个点。
→ 单并发自建,永远到不了盈亏平衡。
批处理产能 3,888.0 百万 ≫ 179.6 百万 → 轻松越过,且越用越便宜。
⑤ 不同规模下的实际月账单(元)
月 Token 量 闭源 API 自建·单并发 自建·批处理
------------------------------------------------------------------------------------
1 百万 ¥5 ¥898 (1 台) ¥898 (1 台)
10 百万 ¥50 ¥898 (1 台) ¥898 (1 台)
100 百万 ¥500 ¥1,796 (2 台) ¥898 (1 台)
1,000 百万 ¥5,000 ¥11,675 (13 台) ¥898 (1 台)
10,000 百万 ¥50,000 ¥115,853 (129 台) ¥2,694 (3 台)
结论:每月 180 百万 token 是分水岭。低于它,API 几乎总是更便宜;
高于它,把机器跑满(批处理)能便宜一个数量级。
这张表里有三个反直觉的结论,一个比一个重要。
第一个:电费根本不是成本,硬件折旧才是。
折旧占 71%,电费只占 29%。所以"自建省电费"这种想法完全跑偏了------自建省下来的从来不是电,是你对"硬件已经买了"这件事的摊销。
第二个,也是最反直觉的:单并发自建,永远算不过账。
一台机器单并发一个月只能产 77.8 百万 Token,但盈亏平衡点在 179.6 百万。够不着。
意思是:如果你把这张卡插在自己电脑上,一次只服务一个人------那你的单位成本是 ¥11.55 / 百万,比 API 的 ¥5 贵一倍多。 你买了一台机器,然后以两倍于市场价的价格给自己供货。
第三个:批处理一开,形势立刻反转。
同样的机器,允许它一次处理 50 个请求,月产能从 77.8 百万跳到 3,888 百万,单位成本从 ¥11.55 砸到 ¥0.23------是 API 的二十分之一。
看 ⑤ 最后一行就更清楚了:每月 100 亿 Token 时,API 要 ¥50,000,而自建只要 ¥2,694。
所以"自建还是 API"这个问题的真正答案,不是看你有没有钱,是看你有没有量、以及你会不会把机器跑满。
三个必须补上的实话:
- 上面没算人力。 自建意味着你要管模型部署、显存调优、版本升级、故障排查。如果每月为此投入两小时,按 ¥200/小时算就是 ¥400------这一项直接吃掉小规模下所有的价格优势。 对一个月只用 100 万 Token 的团队,API 是压倒性的选择。
- 批处理不是免费的午餐。 它拉高吞吐的代价是延迟 ------一个请求要等别人的一起凑批。交互式场景(比如陪你聊天)感受得到,后台批处理场景(比如跑一批文档)感受不到。 这也是为什么"能不能批处理"取决于你的业务形态,而不只是技术。
- API 那边的价格是动的。 这几年 API 单价一直在降。今天算出来的分水岭,明年可能就挪到别处了。 所以别把这张表当结论,把这段代码当工具。
三、钱以外的五件事
如果只看价格,那大多数个人和小团队就该用 API。但现实里,很多公司宁可多花钱也要私有化部署------因为他们算的不是同一笔账。
第一,数据出不出内网。
这是唯一一个"给多少钱都不能让步"的约束。金融、医疗、政务、法务这类场景,数据就不允许离开自己的机房 ,API 这条路从合规上直接堵死。对这类场景,讨论"哪个更便宜"根本没有意义。
第二,锁定效应。
用 API 意味着你把自己接在了一根随时会变的管子上:
- 涨价------你只能接受,或者重写;
- 改行为------某天它悄悄更新了版本,你精心调过的提示词开始失灵;
- 下线------用了两年的模型宣布停服,你只有几周时间迁移。
开放权重最大的价值,恰恰在这里:你手里的那个文件,不会因为任何人做决定而改变。 三年后它还躺在你的硬盘上,行为和你今天测的一模一样。对要长期维护的系统,这个"不变"本身就很值钱。
第三,你能改多深。
API 给你的是一个黑盒接口,你能调的只有提示词和几个参数。而拿到权重,你可以:
- 微调------用你自己的数据把领域能力练上去;
- 改推理参数------采样策略、logit 处理、约束解码,全都是开放的;
- 蒸馏------把大模型的能力压进一个小模型,顺便压成本;
- 拆开看------注意力在关注什么、哪一层出了错,你可以真的去看。
第四,能力上限。
诚实地说:目前最强的通用模型,基本都不公开权重。 如果你做的是"什么难题都要碰一碰"的通用任务,闭源那边的天花板确实更高。
但这不等于开源就一定弱------在垂直领域,一个用你自己的数据微调过的小模型,打赢通用大模型是常见现象。 因为通用大模型要兼顾所有人,而你可以只服务一件事。
第五,出问题找谁。
用 API,你有服务条款、有 SLA、有工单可以提。自建,半夜服务挂了是你自己的事。 对一个没有专职算法工程师的团队,这一条的分量往往被低估。
四、其实没人真的二选一
把上面这些摆开,你会发现最理性的答案通常不是"选一个",而是分工:
姿势一:主力走 API,敏感数据走本地。
通用任务、可以外发的数据交给闭源 API;涉及客户隐私、合同、病历的部分,交给本地部署的小模型。成本和合规各让一步,各拿一半。
姿势二:先用 API 验证,跑量之后再迁。
产品早期用量小、方向还在变------这时候任何自建都是浪费 。等业务跑通、用量越过那条分水岭,再把稳定的那部分迁到自建。这是最省钱的路径,因为你在最不确定的时候保持了最大的灵活性。
姿势三:开源做垂直,闭源做难题。
日常高频、模式固定的任务(分类、抽取、格式化输出)交给你微调过的小模型,便宜且快;真的遇到硬骨头,再转发给最强的那一个。 这叫模型路由,是现在很主流的一种做法。
共同点是什么? 三种姿势都要求你别把自己焊死在某一个模型上:
- 代码里加一层抽象,别把某家的 SDK 调用散落在业务各处;
- 自己维护一套评测集------这是你唯一能判断"换个模型到底行不行"的依据;
- 把提示词和模型版本绑定管理,别让上游的静默更新悄悄改变你的行为。
"可切换"本身就是一种能力。 大多数团队真正的风险,不是选错了模型,而是选错之后改不动了。
五、四个常见误区
误区一:以为开源 = 免费。
权重不要钱,但硬件、电费、运维、人力全都要钱 。上面那张表算得很清楚:小规模下自建的单价反而是 API 的两倍多。"免费"只免掉了最便宜的那一部分。
误区二:以为开源 = 更安全。
不一定。开放权重意味着任何人都能把它重新训练、移除掉所有安全对齐 ------已经有很多被"去审查"的版本在流传。同时,你自己部署也意味着安全责任全落到你头上:模型会不会泄露提示词里的敏感信息、要不要做输入输出过滤,都得你自己做。
唯一的例外场景是数据主权 ------如果你要的是"数据不出门",那本地部署确实更安全。但这两件事是两回事,别混着说。
误区三:以为闭源 = 效果一定更好。
在通用能力排行榜上通常如此,但在你的具体任务上未必 。一个拿你两万条业务数据微调过的小模型,在你那个场景里打赢通用大模型一点都不稀奇。排行榜衡量的是"平均能力",而你只需要在"一件事"上表现好。
误区四:以为这是永久的选择。
两边都在动。API 在降价,开放权重在变强,"开放权重"的许可证也在松动。所以正确的姿势不是今天选一个然后一辈子不变,而是保持随时能换的能力。
六、把这件事放回地图上
把大模型的概念按依赖关系从下往上摞成几层------最底下是算力和数据,往上依次是文字的表示、模型结构、训练、调用,最顶上才是增强和智能体:
L6 智能体层 Agent / Function Calling / ReAct / 记忆 / MCP
L5 增强层 RAG / 向量检索 / Rerank / GraphRAG / 微调
L4 调用层 Prompt / Few-shot / CoT / 温度 / Top-p
L3 训练层 预训练 / SFT / RLHF / DPO / LoRA / Scaling Law
L2 结构层 Transformer / 注意力 / 参数量 / 上下文窗口 / ★ 开源闭源 ★ ← 本篇在这里
L1 表示层 Token / 分词 / 词表 / Embedding
L0 底座 算力 / 数据 / 成本
这一层里,"开源还是闭源"是唯一一个不是技术结构、而是发布方式的词。
它不决定模型内部长什么样,但它决定了你能碰到这个模型的哪一部分------是只能通过一根水管接水,还是能拿到整口井自己打。
而且它是往下贯通的一层:
- 它决定了 L0 那笔账由谁来付------是别人的电费,还是你的;
- 它决定了 L3 的哪些手段你能用------不能微调,很多训练层的方法就跟你无关;
- 它决定了 L5 / L6 的天花板------你搭的整条检索链和智能体,全都建在某个具体模型的行为之上。
所以"选模型"这个动作,从来不只是选效果,也是在选你的成本结构、合规边界和长期自主程度。 三个标准答案是没有的,但有一件事是确定的:任何让你"换不了"的选择,都要多想一想。
- "开源"要打引号 ------多数情况公开的只是权重,不是数据、不是训练过程。下载前先读许可证。
- 成本的分水岭在用量上 :小规模 API 完胜;大规模自建能便宜一个数量级------但前提是你的机器能被批处理跑满,而单并发自建几乎永远算不过账。
- 钱只决定一半。数据主权、锁定风险、可定制深度、能力上限、责任归属------这五件事排在价格前面的场景,比你想的多。
《大模型概念地图》专栏 · 第 7 篇