本地部署 PLaMo,llama.cpp 完整教程,不用显卡

本地部署 PLaMo,llama.cpp 完整教程,不用显卡

结论先行:一台 2016 年的 4 核 Celeron 小主机,没有显卡,能跑通一个 0.8B 的翻译模型,4 线程 decode 跑到 7.59 tok/s

这句判断来自一次实测量出来的数:同一个 546.6 MiB 的 GGUF 文件,我在两台无显卡机器上各跑了一遍:单线程 2.01 对 14.68,差 7.3 倍。

环境、命令、量出来的数都在下面,可以直接照着重跑。

今天本来该写「怎么部署」。但昨晚取材那一步锁的命题是「能不能跑」,我就按这个写------顺手把这堆命令一起给你,因为纯 CPU 场景下这两个问题其实是同一件事:你装不起来,就没法知道跑不跑得动。

① 五步命令,从零到出译文

整条链路我照这个顺序走的,每一步都能复现。

第一步,拿官方 GGUF,pin 到具体文件。

PLaMo 3 Translate 是 PFN 11-05 放出的开放权重,官方直接在 Hugging Face 给了 GGUF 预量化,四档尺寸都有。0.8B 这一档的四个量化版本,真实字节是:

量化档 字节 折合
Q2_K 410,177,946 B 391.1 MiB
Q3_K_M 486,286,394 B 463.8 MiB
Q4_0 547,565,978 B 522.2 MiB
Q4_K_M 573,116,288 B 546.6 MiB

我拿的是 Q4_K_M。这里有个小坑:很多地方说「模型多大」用的是 MiB,下载工具显示的是 MB,同一个文件你会看到 546.6 和 573.1 两种说法,别以为下错了。

第二步,验两个东西:字节数和 GGUF 魔数。

bash 复制代码
ls -l plamo-3-translate-0.8b-Q4_K_M.gguf
head -c 4 plamo-3-translate-0.8b-Q4_K_M.gguf

第一条要输出 573116288。第二条要输出 GGUF 四个字符------不是这四个字符,文件就是下废了,后面所有报错都是这一个原因。

第三步,用 llama-bench 扫线程,别看单次结果。

bash 复制代码
llama-bench -m plamo-3-translate-0.8b-Q4_K_M.gguf -p 128 -n 64 -t 8 -r 3

-p 128 是 prefill 长度,-n 64 是生成长度,-t 8 是线程数,-r 3 跑三次取均值。-t 必须从 1 开始一档一档往上加------这是整篇最值钱的一步,下一节给原因。

第四步,跑一件真活,不是跑分。

bash 复制代码
llama-cli -m plamo-3-translate-0.8b-Q4_K_M.gguf -st --jinja -t 8 --temp 0 \
  -p "Translate into Chinese: The unified memory architecture lets the CPU and GPU share one physical memory pool, but it does not remove the bandwidth ceiling."

-st 是单轮,--jinja 走官方 chat 模板,--temp 0 关掉随机性。测翻译必须关------不关的话同一个输入每次结果不一样,你没法判断好坏。

第五步,要长期用就起 server。

bash 复制代码
llama-server -m plamo-3-translate-0.8b-Q4_K_M.gguf -t 8 -c 2048

默认 8080 端口,-c 2048 是上下文长度。-c 别贪大 :KV 缓存按 -c 线性涨,纯 CPU 上多一千上下文就是多一份内存读,直接吃掉 decode 速度。

② 三台机器一条曲线

先给机器,因为后面的数离开机器就没意义。

机器 CPU 核心 / 线程 指令集 llama.cpp 选的后端
fn02 Xeon E5-2673 v4 @ 2.30GHz 2×20C / 80T,双 NUMA AVX2 libggml-cpu-haswell.so
lianxiang Celeron J3455 @ 1.50GHz< place_holder_mm_span_0442 > 4C / 4T

两台都没有显卡。注意最后一列:同一个二进制在不同 CPU 上走的是两条不同的代码路径,所以跨机比较不是比谁的主频高。

Xeon 那台我绑了单 NUMA 节点(taskset -c 0-19,40-59),每档 3 轮:

线程 prefill 128 (t/s) decode 64 (t/s)
1 49.43 14.68
2 98.37 24.42
4 180.61 36.56
8 343.24 40.64
16 616.58 42.04
20 701.39 41.72

J3455 只有 4 核,扫到 4 就完了:

线程 prefill 64 (t/s) decode 32 (t/s)
1 3.16 2.01
2 6.06 3.86
4 12.09 7.59

把两台的 decode 摆在一起:

  • 单线程:14.68 对 2.01,差 7.3 倍
  • 4 线程:36.56 对 7.59,差 4.8 倍
  • 4 线程相对单线程的扩展比:Xeon 2.49 倍 ,J3455 3.78 倍

最后一行最反直觉。便宜的老机器,加核效率反而更高。 因为它没有跨 NUMA 的远程内存访问,也没有超线程在抢同一份执行单元------4 个物理核就是 4 份真算力。Xeon 那 2.49 倍是被自己的拓扑吃掉的。

这条对买机器的人有意义:如果你只是要跑 0.5B 到 2B 这种小模型,一台 4 核老机器把核用满是划算的,你不需要 80 线程。

③ 同一份文件,为什么你那台可能跑不出这个数

上面两台机器用的是同一个 llama.cpp 二进制,但加载的后端库不一样:

bash 复制代码
fn02     (AVX2)  →  libggml-cpu-haswell.so
lianxiang(SSE4.2)→  libggml-cpu-sse42.so

llama.cpp 启动时会自己探测 CPU 指令集,然后挑一个最匹配的 ggml 后端。这件事不报错,不提示,你从输出里也看不出来------除非你主动去找那一行。

查法很简单,启动时把日志留下来,然后 grep:

bash 复制代码
llama-bench -m plamo-3-translate-0.8b-Q4_K_M.gguf -p 128 -n 64 -t 8 -r 1 2>&1 | grep -i "ggml-cpu"

看到 haswell、sandybridge、zen4 这类名字,说明走了 AVX2 或更新的路径;看到 sse42、neon,说明被降级了。

差距有多大?J3455 是 2016 年的 Apollo Lake,只有 SSE4.2,没有 AVX。它在 4 线程跑 7.59 tok/s 已经是把 4 个物理核榨干的结果------降级不是说它偷懒,是它只能用 SSE4.2 那套指令做矩阵乘法,一次处理的数就是比 AVX2 少一半。

所以「我 CPU 主频 2.3GHz,他 1.5GHz,我该比他快吧」这个推理不成立。指令集是乘数,主频只是其中一项。

判据一句话:先看后端名字,再看主频。 后端被降级到 SSE4.2 的机器,主频再高也补不回来。

④ 线程加到哪一档停:三条判据

这是纯 CPU 部署里最容易做错的一步。很多人一次就试 -t 16 或者干脆不传,然后用那个数当结论。

我的做法是扫一遍,然后看三件事:

判据一:decode 不再涨的那一档,就是你要的线程数。

Xeon 那台的 decode 是 14.68 → 24.42 → 36.56 → 40.64 → 42.04 → 41.72。8 线程往后基本平了,第 8 档就是答案。加到 20 线程只多 2.7%,但你多付出了 12 个线程的调度开销和内存争抢。

判据二:prefill 还在涨,说明那不是你的瓶颈。

同一台机器 prefill 从 343 一路涨到 701。如果你的活是「一次喂一大段文档、只让模型回答一句话」,那 prefill 才是主要耗时,你应该按 prefill 的曲线选线程,能开到 20。 反过来,如果你的活是「问答式、一个 token 一个 token 往外吐」,就按 decode 的曲线选。

同一台机器,两种活,两个答案。「该开几线程」这个问题,不问清楚干什么活就答不了。

判据三:跨 NUMA 会倒扣。 那台 Xeon 是双路,两个 NUMA 节点。我这次全程用 taskset 绑在 node0 上(0-19,40-59)。不绑的话,线程会被调度到另一个节点,访问的是远程内存,延迟高一截。双路机器上如果不绑核,你测出来的数会比绑核低,而且低多少每次都不一样。

这条不是理论。同一个模型,绑单节点和不绑的差别,我在 10-30 那篇里量过------跨 NUMA 同 8 线程慢 19%,80 线程全开比 8 线程慢 2.66 倍。 那次是 Qwen3-0.6B,这次是 PLaMo 0.8B,机型相同,结论一致。

所以双路机器上跑纯 CPU 推理,第一步不是调线程,是 taskset 或者 numactl 把进程钉死在一个节点上。钉完再谈线程数。

⑤ 为什么 8 线程就到顶:瓶颈是带宽,不是算力

Xeon 那张表里最该被记住的是这两行:8 线程 40.64,20 线程 41.72。多了 12 个线程,只换来 2.7%。

同时在涨的是 prefill:8 线程 343,20 线程 701,翻了一倍。

同一个进程里两件事走向相反,说明它们不是同一种活。prefill 是把整段提示词一次性算完,能吃满所有核的算力;decode 是每生成一个字,把整个权重文件从内存里重读一遍------它卡在内存带宽上,你加多少核都在排队等同一根内存条。

我用同机两个不同体积的模型验了这条:

模型 体积 decode (t/s) 每 token 有效带宽
PLaMo 0.8B Q4_K_M 0.573 GB 40.64 23.29 GB/s
Qwen2.5-1.5B Q4_K_M 1.117 GB 23.87 26.67 GB/s

体积比是 1.95,速度比是 1.70。两个比只差 14.5%。 也就是说「每生成一个字要读多少字节」基本是常数,速度就由体积倒数决定。

所以那条经验公式是对的,但只能当趋势用:

bash 复制代码
decode 速度 ≈ 可用内存带宽 ÷ 模型体积

我试过拿 0.8B 的结果去推 2B:算出 12.89 tok/s,实测 17.27,误差 25.4% 。原因是不同模型的层数和专家结构不一样,每个 token 实际读的量不等于文件体积一刀切。外推可以,别当精确值报给老板。

实测的内存带宽我也列一下,但只有一半能用:

线程 内存 copy 带宽
1 14.71 GB/s
4 54.83 GB/s
8 74.90 GB/s
16 185.94 GB/s ⚠️
20 219.60 GB/s ⚠️

后两行是废数据。E5-2673 v4 是 4 通道 DDR4-2400,理论带宽约 76.8 GB/s,测出 219 是不可能的------那个测法在多线程下被 CPU cache 命中污染了。可信区间只有 1 到 8 线程。

这个坑值得单独说一句:如果一篇稿子只贴了「实测 219 GB/s」,读者会觉得这台机器内存快得离谱,实际上是我的测法错了。 我把它留在这里标成废数据,比删掉更有用。

⑥ 对号入座:你的机器在哪一档

这是全篇我唯一想让你截图发出去的东西。判据是 decode 速度,不是核数、不是主频。

decode 速度 是什么体验 什么机器
2 tok/s 以下 看不了。一句话等半分钟 老 ARM 盒子、4 核无 AVX 单线程
2 到 7 tok/s 能看,但难受。1000 字译文要等 2 分钟以上 4 核无 AVX 全核跑
7 到 15 tok/s 能用了。接近人阅读速度 4 核老机器全核、Xeon 单线程
15 tok/s 以上 顺手 8 线程以上的服务器

2 tok/s 是「能不能看」的线,7 tok/s 是「能不能用」的线。 这两条线比任何跑分都好用,因为它们直接对应你的等待时间。

换成钱更直观。如果你每月的翻译活按 200 万 token 算:

  • 走云端 API,按公开报价每百万输入 0.83 美元、输出 2.50 美元估,翻译这种任务输入输出差不多对半,一个月大约 3.3 美元,23 块左右
  • 自己跑:J3455 那台整机 TDP 10W 级别,一天跑 4 小时,一个月电费 不到 2 块钱

结论不好听:一个月 23 块的事,不值得为它买机器。 纯 CPU 跑本地的价值不在省钱,在「离线」和「数据不出门」这两件事上------飞行模式、断网环境、不能上传的文档,这些场景云端 API 根本给不了你。为省钱买机器是算不过来的。

这条判断我敢直接说:你要是只为了省翻译费,别装,直接用 API。 装上它的理由只有一个:这份文档不能出你的内网。

⑦ 边界:我测到什么,没测到什么

四件事得说清,否则上面那些数会被用错。

第一,0.8B 不听语种指令。 我给的指令是翻成中文,它输出了日文:

原文:The unified memory architecture lets the CPU and GPU share one<|place_holder_mm_span_0442|> pool, but it does not remove the bandwidth ceiling. 输出:統合メモリアーキテクチャにより、CPUとGPUが単一の物理メモリプールを共有できますが、帯域幅の上限は解消されません。

内容翻译是准的,语种没听。这是 0.8B 的真实局限,不是我参数写错--------temp 0 已经关了随机性。能跑不等于能替代,0.8B 能干活,但你得盯着。

第二,尺寸曲线只画了三个点。 0.8B、1.5B、2B,8B 和 31B 没测。8B 的 Q4_K_M 是 5035.8 MiB,下载要 27 分钟,昨晚时间盒不够;31B 官方只给 14 分片 safetensors,得自己转 GGUF。所以别拿上面那条公式去推 8B 的速度。

第三,真实任务只跑了两条。 英译中 4.18 秒整轮、48.0 tok/s,中译日 4.42 秒,就这两条。没有做批量译文质量打分,也没跟云端同类服务同题对照------PFN 官方说 0.8B 的质量超过谷歌和腾讯的同类模型,这是他们自评,我没验证,你别当结论。

第四,功耗是标称值不是实测。 J3455 TDP 10W、E5-2673 v4 TDP 135W,都是官方标称。整机实际功耗我没测,所以上面那个「一个月不到 2 块」只能当量级看。

还有一条:Q4 的其他档位(Q2_K / Q3_K_M / Q4_0)字节数我拿到了,但没真跑。「量化到多低还能用」这个问题本文没有答案。

验证等级:L1 | 两台无显卡机器同文件同参数各扫 4--6 档线程,Xeon 每档 3 轮取均值;跨机结论(7.3 倍 / 4.8 倍)由两机独立实测直接相比,未做第三台复现

参考来源

  • 模型与字节:PFN 官方 pfnet/plamo-3-translate-{0.8b,2b,8b}-GGUF,经 hf-mirror API 逐文件取真实字节;0.8B Q4_K_M 本机下载校验 573,116,288 B,GGUF 魔数通过,llama.cpp 报 890.34 M 参数
  • 线程扫描:2026-11-06 00:20--00:43 实测。fn02(Xeon E5-2673 v4,taskset -c 0-19,40-59 绑单 NUMA)p128/n64/r3;lianxiang(Celeron J3455)p64/n32/r2
  • 同机体积对照:qwen2.5-1.5b-instruct-q4_k_m.gguf 实测 1,117,320,736 B,与上表同机同参数
  • 真实翻译:llama-cli -st --jinja -t 8 --temp 0,英译中 / 中译日各一条
  • 内存带宽:每线程独立 256 MB buffer 并行 copy,读写双计;T≥16 因超理论带宽判为 cache 污染,本文作废并标注
  • 2 tok/s / 7 tok/s 两条线、23 块与 2 块电费、每月 200 万 token 的量级换算均为按上表实测值与公开报价换算,非独立计时;TDP 为官方标称值不是实测

声明

本文所有 tok/s、字节数、带宽数值来自两台无显卡机器的真机实测,CPU 型号、指令集、后端库、线程绑定方式、采样轮数已在文中标明。未测到的部分(8B / 31B 尺寸、批量译文质量、与云端服务的同题对照、Q4 其他量化档位、整机实际功耗、多机并发)已逐条写为未测。T≥16 的内存带宽读数因超出硬件理论值判为测法污染,已作废并保留原文以便复核。PFN 关于 0.8B 质量超过同类服务的说法属其自评口径,本文未验证,不作为结论。不同 CPU、不同指令集、不同量化档位下绝对值都会变,判断方法不变。


本文所有数字均为本机实测,非引用。环境与脚本版本见文末参考来源。 作者:丘山录 · 记录本地部署与算力实测

相关推荐
播播资源12 分钟前
同账户实测 11 个多模态模型:图像 0.03 元起、竖屏视频 8 元一条,最贵和最便宜差 267 倍
大数据·人工智能·深度学习
Linye16 分钟前
AI 越跑越偏?从 500 行臃肿规则到 80 行核心约束:多 Agent 项目中的「规则瘦身与防腐」四步排查法
人工智能·架构
Eyfcom19 分钟前
〖AI物流落地 06〗AI Copilot 在 TMS 调度系统中的应用:Text-to-SQL、意图拆解与自动调参
人工智能·物流系统·快递系统·跨境物流快递系统·ai物流落地
域限奇点访客19 分钟前
怎么让AI稳定输出可解析的问卷结构?schema约束、失败重试与降级策略
人工智能
探索前端22 分钟前
把带贴图的 OBJ / glTF 转成 3D Tiles:我写了个 mesh-to-tiles
人工智能
nicksxs23 分钟前
把 LLM 判断拆成 Choice / Score / Noul:Jev SDK 六条实测
人工智能
AICoder码农王25 分钟前
AgentScope Java v2 Lab-1,审批只走有门的腿
人工智能
AI前端工程狮26 分钟前
1 秒超时,3 秒才写完:MCP 写操作的重复提交实测
人工智能·程序员