欢迎光临
我们一直在努力

我把一个 30B 的大模型,跑在了几百块钱的开发板上

上周有个朋友问我:边缘设备能不能跑 30B? 我说:能,但你先接受一个事实——它比你的内存大。 然后我把 Qwen3-30B-A3B(权重文件 17.66 GB)跑在了一块 16 GB 内存的 RK3588 开发板上,并且让它的服务进程峰值内存停在了 1.11 GB。 这不是“理论上可以”,是板端实测,日志和数字我全放在下面,你可以照着复现。

一、故事的起点:一块塞不进去的模型

先说清楚矛盾有多大:

  • 模型:Qwen3-30B-A3B,MoE 结构,q4 量化后权重文件 17.66 GB;
  • 板子:Orange Pi 5 Plus(RK3588,8 核,eMMC),MemTotal 15,647,860 kB ≈ 15.6 GB。

17.66 > 15.6,这是小学算术题。全层常驻的做法下,它连“把权重放进去”这一步都很勉强——实测服务峰值 14.23 GB,几乎吃掉整块内存,KV 缓存和系统进程只能捡剩下的。所以问题不是“怎么优化”,而是:能不能不把权重全放进去?

二、三个数字,讲完整个故事

我不想堆术语,先把三个数字放这儿:

数字一:1.11 GB。开启逐层推理(VLLM_VQF_STREAM=1)后,同一个 30B 模型的服务峰值内存是 1.11 GB,对比全层档的 14.23 GB——省 12.8 倍。权重常驻部分从 11.73 GB 降到 0.51 GB。

数字二:620 秒 → 23 秒。省钱不等于好用。基线条件下,30B 处理一轮 300 token 的上下文要 620 秒(对,十分钟)。在组合①(L3 驱逐 × 前缀复用)之上再叠 MoE 组合⑤(VLLM_ACTQ=1 VLLM_MOE_BATCH=1)之后,第一轮降到 23 秒,tpot 从 2,240 ms 降到 504 ms。

数字三:4.7 秒 / 3.2 秒。这是第二轮、第三轮追问的 prefill 时间——对比基线同样是 722 秒 / 822 秒。也就是说,多轮对话里的追问,从“泡杯咖啡”变成了“眨个眼”。

三、怎么做到的(人话版)

1)权重不搬进内存,而是“挂在文件上”

我们的权重格式(自研 VQF v2)在转换阶段就把量化、布局、对齐全干完了。加载时只做一件事:mmap。进程刚起来时它占多少内存?988 kB。不到 1 MB。因为那会儿它只映射了地址,一页物理内存都还没读。

2)用完一层,就把那层的内存还给系统

逐层推理模式下的每一层:

第 N 层要算了 → 触碰它的文件页(内核从存储读进内存)→ 算完
→ MADV_DONTNEED 立刻丢弃这些页 → 下一层

只保留 keep=1 层常驻。板端启动日志就是这么写的:

[VQF-STREAM] enabled keep=1 nl=48 segs=11 per-layer=334.1MB data=16847.2MB resident~808.4MB rss=988kB

data=16847.2MB(模型总权重)与 resident~808.4MB(实际常驻)摆在一起,就是“解耦”两个字。

为什么丢弃是免费的? 因为这些页是“干净”的——只读映射,没被改写过,内核不需要回写磁盘,直接扔掉就行,下次从文件重新读。

3)KV 缓存也得会过日子

权重的问题解决了,KV 缓存还在涨。v1.0 的 KV v2 改成惰性分配:底座随用随长,而不是一上来按 max_seq 预分配一大块 F32。

4)MoE 模型还有额外红利

30B-A3B 是 MoE(激活约 3B)。组合⑤ 打开专家激活量化 + 专家批量后,同样的 prefill 计算量下速度直接跳一个档:第一轮 620 s → 23 s,追问轮 822 s → 3.2 s。

省内存和跑得快,这两件事没有互相排斥。

四、完整数据(可以直接拿去对线)

多轮追问实测(300 token 上文 + 32 token 生成,组合⑧为基线,组合①是 L3 驱逐 × 前缀复用):

模型驻留配置第 2 轮 prefill第 3 轮 prefill相对基线
2B 逐层 ⑧ 基线 6,057 ms 6,706 ms —
2B 逐层 ① P3 1,189 ms 1,130 ms −80.4% / −83.1%
8B 逐层 ⑧ 基线 19,579 ms 21,545 ms —
8B 逐层 ① P3 2,048 ms 2,203 ms −89.5% / −89.8%
30B-A3B 全层 ⑧ 基线 722,394 ms 822,409 ms —
30B-A3B 全层 ① P3 28,633 ms 32,140 ms −96.0% / −96.1%
30B-A3B 全层 ①+⑤ P3+MoE 4,727 ms 3,157 ms −99.3% / −99.6%
30B-A3B 逐层 ⑧ 基线 724,367 ms 824,535 ms —
30B-A3B 逐层 ① P3 29,368 ms 32,820 ms −95.9% / −96.0%
30B-A3B 逐层 ①+⑤ P3+MoE 5,269 ms 3,695 ms −99.3% / −99.6%

注意最后两行:逐层档 + 组合① + 组合⑤ 同时开,省 12.8 倍内存的同时,追问轮 prefill 只要 3.7 ~ 5.3 秒。这就是我说“省内存和快不矛盾”的依据。

内存对照(服务口径,含 KV):

模型(权重体积)全层峰值逐层峰值省
2B(4.16 GB) 2,968,920 kB 854,476 kB 3.5×
8B(6.60 GB) 4,523,240 kB 914,448 kB 4.9×
30B-A3B(17.66 GB) 14,228,868 kB 1,112,500 kB 12.8×

五、自己跑一遍

git clone https://gitee.com/pei-xiaoguang/kestrel-llm.git && cd kestrel-llm
./build_rk3588.sh
转换一次(v1 只认自研 VQF v2 格式)
cd vqf_convert && ./build.sh
./vqf_conv –model <safetensors-dir> –convert-vqf <out.vqf> –wmode q4 && cd ..
省内存 + 多轮加速 一起上
VLLM_VQF_STREAM=1 VLLM_L3_PREFIX_REUSE=1 VLLM_ACTQ=1 VLLM_MOE_BATCH=1

./vllm_kestrel –serve –port 8080 –model <模型目录> –auto-load –wmode q4

–sparse-attn –sparse-k 32 –l3-evict –l3-ratio 0.75 –l3-min-seq 128

日志里你应该能看到逐层生效的那一行,以及多轮对话时 [KV-PREFIX] reuse … 的前缀复用记录。

六、丑话说在前面

  • 30B 在这块板上的绝对速度依然很低。基线 0.45 tok/s,优化后好很多,但别指望它做实时对话机器人——它的正确姿势是“归档式推理”“批量摘要”“离线问答”这类能容忍秒级延迟的活。
  • 逐层只支持明文权重。加密或签名的 VQF 会被显式拒绝(必须全层驻留)——安全和省内存目前二选一。
  • 只适配 Qwen3 系(Qwen3-VL 2B/8B、Qwen3-MoE)。其他架构没验证过,别拿 Llama 来试然后骂人。
  • 代价是真实存在的:逐层档热态 tpot 会涨 18% ~ 39%,模型越大、存储越慢,这笔“利息”越高。

七、最后一句

把 17.66 GB 塞进 15.6 GB,靠的不是压缩算法,是换了个前提:“权重必须同时待在内存里”——这个前提,在 mmap + 按层建页 + 用完就还的模型下,本来就不成立。

Kestrel(vllm_kestrel)已完全开放:https://gitee.com/pei-xiaoguang/kestrel-llm

双许可协议:学习与学术研究完全免费,商业与产品化部署请先取得商业授权。跑出不一样的数据,欢迎来 Issues 砸场子。

附:配图清单与提示词

位置图意生成提示词(文生图)
封面 大模型方块 vs 小开发板的视觉冲突,“17.66 GB / 15.6 GB” 字样 split composition: left a huge dense blue data cube labeled 17.66 GB, right a small green ARM board labeled 15.6 GB, dark studio background, cinematic, photorealistic, 16:9
§二 数字一 14.23 GB → 1.11 GB 的横条对比 建议脚本绘制:两条横条 + 12.8× 标注
§三 第 2 点 逐层“建页 → 算完 → DONTNEED”循环图 circular technical diagram: map page, compute layer, release page with MADV_DONTNEED, isometric style, blue/orange, white background, 16:9
§四 表 三模型 × 全层/逐层 峰值柱状图 建议脚本绘制:6 根柱,逐层用高亮色
赞(0)
未经允许不得转载:171主机测评 » 我把一个 30B 的大模型,跑在了几百块钱的开发板上
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址