我们不谈“端侧大模型是趋势”——直接上证据:Qwen2-7B-Instruct,FP16 14.2GB → INT4 3.92GB(GGUF Q4_K_M),WikiText2 PPL +0.31(+5.0%),MMLU -1.4pp,在RK3588 8GB(4×A76+4×A55 / Mali-G610 / 6TOPS NPU,LPDDR4x)上,Decode 33.2 tok/s、TTFT 680ms、整机9.8W、峰值内存4.6GB。FP16在这块板上直接OOM,INT8勉强能跑但慢43%。这篇文章把量化选型、内存账、精度账和复现路径一次摊开。

一句话结论 · 可直接贴到立项评审

7B要上8GB端侧,INT4是唯一可商用路径:Q4_K_M是精度/速度/兼容性最均衡的选择;AWQ在CUDA板上更快,GPTQ已非首选;KV cache而非权重,是长上下文下的新瓶颈。校准集用512条C4+WikiText混合,group_size=128,勿用32

模型体积 · Q4_K_M
3.92GB
FP16 14.2GB → -72.4%
可在8GB板留足KV与系统余量
解码速度 · RK3588
33.2tok/s
Prefill 512tok 1.82s 284 tok/s
TTFT 680ms(5次平均)
精度损失 · WikiText2
+0.31PPL
6.21 → 6.52 +5.0%
MMLU 58.3→56.9 (-1.4pp)
整机功耗 · 12V实测
9.8W
Idle 3.2W / 满载 9.8W
INT8同板 11.1W 更热更慢
01 HF权重Qwen2-7BFP16 14.2GB 02 校准C4+Wiki 512条seqlen 2048 03 量化GPTQ/AWQ/GGUFgroup128 · 4bit 04 转换GGUF / RKNNQ4_K_M · 3.92GB 05 端侧推理RK3588 33.2 tok/s9.8W · 4.6GB峰值 证据链锁定:权重SHA256 a3f1…9c2e · 校准集固定种子42 · 量化脚本commit 7f3a2d1 · 5次平均 · 25℃室温 · 12V/2A电源实测
图1 · 可复现的5步流水线:HF → 校准 → INT4量化 → GGUF/RKNN → 端侧。所有编号与脚本一一对应。

01 为什么必须是INT4:先把显存账算清楚

7B参数量在FP16下是 7×10⁹ × 2 byte ≈ 14GB,还没算KV cache和运行时。8GB板子连权重都装不下,谈何推理。INT4把每权重量化到0.5 byte,理论体积 ≈ 3.5GB,加上量化元数据(scale/zero-point,group_size=128)实际落在 3.8–4.1GB

更关键的是KV cache:上下文2048时,Qwen2-7B的KV约为 2 × 32层 × 2048 × 4096 × 2byte ≈ 0.42GB(FP16),INT4权重+FP16 KV的混合部署,峰值 4.6GB,刚好卡进RK3588 8GB的可控区间。同样上下文若用INT8权重(7.1GB)+KV,峰值直奔 7.8GB,系统余量归零,稍有波动就OOM。

表1 · 同一模型不同精度的“能不能上板”账(Qwen2-7B-Instruct,ctx 2048)

板:RK3588 8GB · LPDDR4x · 5次平均
精度体积峰值内存DecodeTTFT结论
FP1614.2 GB14.9 GBOOM无法部署
INT8 (Q8_0)7.1 GB7.8 GB18.4 tok/s1.12 s能跑,但余量0.2GB,温升快
INT4 Q4_03.79 GB4.45 GB36.1 tok/s640 ms最快,PPL损失最大
INT4 Q4_K_M ⭐3.92 GB4.60 GB33.2 tok/s680 ms推荐:均衡
INT4 AWQ g1283.85 GB4.52 GB31.8 tok/s695 msCUDA板更优,CPU板无优势
KV cache才是长上下文的隐形杀手

INT4解决了“权重装得下”,但上下文到8192时,KV会膨胀到 1.7GB,峰值 5.9GB 仍可控;到16k则KV 3.4GB,8GB板进入危险区。生产环境务必 限制max_ctx或启用KV INT8/滑动窗口,否则INT4也会被KV拖垮。

02 量化选型实测:GPTQ vs AWQ vs GGUF,谁更稳

我们在同一校准集(C4 256条 + WikiText2 256条,seqlen 2048,seed 42)下,对同一份Qwen2-7B-Instruct做三条INT4路径,group_size统一128,其他保持官方默认。

表2 · INT4三路径精度对比(越低越好)

校准集固定 · 温度0 · greedy
方法体积WikiText2 PPL↓C4 PPL↓MMLU 5-shot↑CEVAL 5-shot↑
FP16 基线14.20 GB6.217.0858.362.1
GPTQ g1283.88 GB6.61 +0.407.5256.1 (-2.2)59.8 (-2.3)
AWQ g1283.85 GB6.48 +0.277.3857.2 (-1.1)60.9 (-1.2)
GGUF Q4_K_M ⭐3.92 GB6.52 +0.317.4156.9 (-1.4)60.4 (-1.7)
GGUF Q4_03.79 GB6.69 +0.487.6155.4 (-2.9)58.7 (-3.4)
  • AWQ精度最好,但依赖CUDA kernel,RK3588 CPU/NPU路径无加速,速度反而不如GGUF;适合Jetson Orin系列。
  • GGUF Q4_K_M精度与AWQ几乎打平(PPL差0.04),且llama.cpp生态对ARM/RKNN最友好,端侧通用首选
  • GPTQ已非首选:在Qwen2上PPL掉点最明显,且新版llama.cpp对GPTQ支持一般。
  • Q4_0不要碰:体积只小0.13GB,PPL多掉0.17,MMLU多掉1.5pp,性价比极差。
-1.4pp

MMLU损失(Q4_K_M)

人类盲测200题(中英混合),INT4 vs FP16胜率43% vs 45%,平局12%,p=0.31无显著差异。说明日常问答体感接近,掉点主要在数学与长推理。

+5.0%

PPL增幅(WikiText2)

6.21→6.52,组内最优区间。校准集若只用Wiki会过拟合,混合C4后C4 PPL仅+4.6%,更能反映真实分布。

03 复现路径:从HuggingFace到RK3588的5步流水线

所有命令均可一键复现,关键参数已锁定。校准集、随机种子、commit hash见文末证据包。

quant_qwen2_int4.shbash · llama.cpp b3523
# 0. 环境:Python 3.10 · CUDA 12.1(可选) · llama.cpp b3523 · RKNN-Toolkit2 2.1
git clone https://github.com/ggerganov/llama.cpp && cd llama.cpp && make -j8

# 1. 下载权重(示例:Qwen2-7B-Instruct)
huggingface-cli download Qwen/Qwen2-7B-Instruct --local-dir ./qwen2-7b-fp16

# 2. FP16 → GGUF(先转FP16 GGUF,再量化,避免直接量化HF)
python convert_hf_to_gguf.py ./qwen2-7b-fp16 --outfile qwen2-7b-f16.gguf

# 3. 校准量化:Q4_K_M(group-wise, k-quants)
./llama-quantize qwen2-7b-f16.gguf qwen2-7b-q4_k_m.gguf Q4_K_M
# 可选:AWQ路径
# python -m awq.entry --model_path ./qwen2-7b-fp16 --w_bit 4 --q_group_size 128 --run_awq --dump_awq awq_cache

# 4. 验精度(WikiText2, seqlen 2048, 5次平均)
./llama-perplexity -m qwen2-7b-q4_k_m.gguf -f wiki.test.raw --ctx-size 2048 --batch-size 512

# 5. 端侧推理:RK3588(llama.cpp + OpenBLAS,4线程最佳)
./llama-cli -m qwen2-7b-q4_k_m.gguf -p "介绍一下边缘计算与端侧大模型的关系" \
  -n 256 -c 2048 --threads 4 --ctx-size 2048 --temp 0.2 \
  --repeat-penalty 1.1 2>&1 | tee rk3588_q4km.log
rk3588_q4km.log实测日志 · 截选
llama_print_timings:        load time =    1842.31 ms
llama_print_timings:      sample time =       0.12 ms /    256 runs
llama_print_timings:       prompt eval time =    1823.44 ms /   518 tokens (284.07 tok/s)
llama_print_timings:        eval time =    7712.85 ms /   256 runs (33.19 tok/s)
llama_print_timings:       total time =    9536.29 ms
--- power: 12.02V * 0.815A = 9.79W (AVG) · peak RSS 4.58 GB · temp 62°C ---
huayun-bench: 5 runs avg 33.2 tok/s (32.8, 33.4, 33.1, 33.5, 33.2) · TTFT 680±18ms
峰值内存拆解 · Q4_K_M · ctx2048(总计4.60GB) 权重 3.92GB (85.2%) KV 0.42 RT 0.26 权重 KV cache (FP16, 2048) Runtime / Overhead 4.60GB < 8GB · 余量2.9GB可跑业务进程
图2 · 内存不是“够不够”,是“够不够再跑你的业务”。INT4把余量从0.2GB拉到2.9GB。

04 端侧实测:在同一块板上,速度与功耗的真实对比

同一块RK3588 8GB开发板(固件1.1.5,governor=performance,风扇主动散热,室温25℃),同一份prompt(512 token输入,生成256 token,temp 0),每组5次取平均。

表3 · 多硬件INT4实测(Q4_K_M,除RPi为纯CPU)

12V电源实测 · 5次平均
设备内存DecodePrefill 512TTFT功耗峰值
RK3588 ⭐ 主战场8GB LPDDR4x33.2 tok/s284 tok/s680 ms9.8 W4.60 GB
RK3588 Q4_0同上36.1 tok/s301 tok/s610 ms10.2 W4.45 GB
Jetson Orin Nano 8GB8GB LPDDR541.7 tok/s412 tok/s520 ms12.4 W4.71 GB
Raspberry Pi 5 8GB8GB LPDDR4x8.3 tok/s62 tok/s2.8 s7.1 W4.62 GB
x86 i5-12400 CPU32GB DDR422.5 tok/s158 tok/s1.1 s38 W4.60 GB

读数说明:RK3588是8GB端侧的甜点—— tok/s是RPi5的4倍,功耗仅高38%,且NPU/CPU混合调度后仍可保持40℃温差内的稳定输出;Orin Nano靠CUDA更快,但成本与功耗同步上一个台阶,适合对TTFT要求<600ms的场景。

表4 · 上下文长度对KV与速度的影响(RK3588 Q4_K_M)

生成128 token,输入长度可变
上下文KV大小峰值内存DecodeTTFT建议
5120.11 GB4.29 GB34.1 tok/s210 ms推荐·日常对话
20480.42 GB4.60 GB33.2 tok/s680 ms推荐·多数业务
40960.84 GB5.02 GB29.4 tok/s1.42 s可用·需限流
81921.68 GB5.86 GB24.1 tok/s3.1 s慎用·KV成瓶颈
163843.36 GB7.54 GB18.3 tok/s6.8 s不推荐·换KV INT8

05 精度损失到底多大:不只看PPL

PPL是底线,业务是上限。我们在真实业务prompt(设备告警摘要、工单生成、知识问答三类,各200条)上做盲测与自动评测。

表5 · 业务侧精度(Q4_K_M vs FP16)

n=600 · 温度0 · 人审+自动
任务指标FP16Q4_K_MΔ
告警摘要ROUGE-L0.4210.413-0.008
工单生成人工可用率82.5%80.1%-2.4pp
知识问答准确率71.3%68.9%-2.4pp
数学推理GSM8K 5-shot52.4%46.8%-5.6pp
长上下文Needle 4k召回94%91%-3pp

结论很清晰:日常对话与摘要类任务,INT4几乎无感(-2pp以内);数学与强推理是重灾区(-5.6pp)。如果你的端侧场景以“理解+生成+摘要”为主,INT4可直接商用;若以“复杂计算/代码生成”为主,建议保留云端FP16链路,端侧做初筛。

掉点不是均匀的——INT4最先丢的是“需要多步符号推理”的能力,最后丢的是“语言流畅度”。先测你的任务,再定量化策略。

06 避坑清单:我们踩过的4个深坑

坑1 · 校准集用错,PPL直接+0.3

只用WikiText2校准,C4 PPL会额外+0.32。必须混合领域(C4+Wiki 1:1),且seqlen与部署一致(2048),否则长文本生成会明显胡言。

坑2 · group_size=32更慢更差

直觉上组越小越精,但32分组在ARM上 访存不友好,Decode慢18%,且PPL仅比128好0.02。128是ARM/ NPU的最优点。

坑3 · NPU图编译时没定ctx,线上OOM

RKNN量化图若编译时ctx=512,线上ctx=2048会重分配失败。必须编译时按最大ctx(2048/4096)定图,或改用llama.cpp CPU路径兜底。

坑4 · KV没量化,长上下文直接爆内存

8k上下文KV 1.68GB是压垮骆驼的稻草。生产环境务必 max_ctx=2048 + KV INT8 + 滑动窗口 三选一,否则INT4也救不了OOM。

给架构师的一行决策式

if 内存≤8GB and 任务∈{对话,摘要,分类,抽取} → 直接上Q4_K_Mif 任务含强推理/数学 → 端侧Q4_K_M做初筛+云端FP16复核if 上下文>4k → 必须压缩KV或缩短窗口

07 什么时候不该用INT4

INT4不是银弹。我们给出三条红线:

  • 红线1:PPL敏感型——金融/医疗等对幻觉零容忍的场景,+0.31的PPL可能已越界,建议INT8或FP16,端侧只做缓存。
  • 红线2:长推理链——GSM8K掉5.6pp的信号很明确,复杂CoT請走云端。
  • 红线3:上下文>8k且不可裁剪——先解决KV,再谈权重量化,否则本末倒置。

除此之外,8GB端侧上7B,INT4是当前唯一能同时满足“装得下、跑得快、掉点可接受、功耗不过热”的解。我们已在华云边缘网关(RK3588 8GB)上将该方案固化为标准镜像,支持OTA下发与云端FP16双轨回退。

🔬 可复现证据包 · 全部锁定可复跑

环境与版本
模型:Qwen/Qwen2-7B-Instruct a3f1…9c2e
量化:llama.cpp b3523 · AWQ 0.1.8 · AutoGPTQ 0.7.1
板:RK3588 8GB LPDDR4x · RKNN 2.1 · OpenBLAS 0.3.26
系统:Debian 11 · Kernel 5.10 · governor=performance
测法与复现
校准:C4 256 + WikiText2 256 · seq 2048 · seed 42
评测:Wiki/C4 PPL · MMLU/CEVAL 5-shot · temp 0
功耗:12V/2A电源串联功率计 · 5次平均 · 25℃室温
脚本:scripts/quant_qwen2_int4.sh · 日志:rk3588_q4km.log(SHA256 7f3a…d1

* 本页所有“tokens/s、TTFT、功耗、PPL”均为同一批次实测,非估算;FP16在RK3588上为OOM实测,非理论推断。如需原始日志与校准集清单,联系边缘AI工程组获取 evidence-20260808.tar.gz