☰
35B大模型端侧部署实战:量化、内存墙与手机推理优化
2026/10/2 10:00:40 网站建设 项目流程

这标题很唬人,但拆开看就一句话:我们能不能把 350 亿参数的大模型,从数据中心的GPU机房,搬到普通人裤兜里的那台手机上。这不是把模型文件拷进手机就完事,而是要让它跑得动、跑得稳、跑得省电,还要真的能聊。老实说,放在两年前这是个近乎疯狂的想法,因为 350 亿参数如果用 FP16 精度存下来,光权重就要 70GB,绝大多数电脑都背不动,更别说手机。但最近这半年,一批模型的量化方案和端侧推理引擎成熟得很快,32B、34B、35B 这个量级的模型已经开始在 16GB、24GB 内存的旗舰机上出字了。这篇文章我就用自己折腾过的过程和踩过的坑,把“内存墙”这件事掰开揉碎,说清楚怎么把一个 35B 级模型真正塞进手机里跑起来。

1. 内存墙是什么:为什么 350 亿参数这么难搞

1.1 容量账:先算算模型到底占多少地方

我习惯先算一笔硬账。350 亿个参数,也就是 35B,每个参数用不同精度存储,体积差距非常大:

精度单个参数占位权重总大小
FP324 字节约 140 GB
FP162 字节约 70 GB
INT81 字节约 35 GB
INT40.5 字节约 17.5 GB

一台主流旗舰手机,标称 16GB 或 24GB 内存,看着不少,但系统本身要吃掉五六GB,相机后台、桌面进程、各种常驻App又要占一截,真正能分给大模型的内存通常不到一半。FP16 想都不用想,INT8 也得掂量掂量,唯独 INT4 量化之后 17.5GB 的体积勉强能挤进一台 24GB 内存的机器,16GB 机型就得靠各种内存压缩和换页技巧硬撑。

这里有个容易忽略的细节:权重只是模型运行时占用的“大头”,不是全部。模型在生成过程中还要维护 KV Cache,也就是历史上所有已生成 token 的键值缓存,用于注意力计算。假设上下文窗口是 2048 token,层数假设 64 层,每层 32B 模型的 KV 通道数不小,KV Cache 随输入长度线性膨胀,几百MB 到 1GB 都是正常的。所以大家在部署时看的是“权重 + KV Cache + 激活值 + 运行时开销”的总和,不是孤零零一个 GGUF 文件的大小。

1.2 带宽账:算得快不如搬书搬得快

容量的问题只是“装不装得下”,真正卡住大多数人的是内存带宽。大模型做自回归推理时,每生成一个 token,都要把全部权重从内存里读一遍送到计算单元。这就好比一个人去图书馆查资料,他读题只要一秒钟,但每查一个字都得跑回书架搬一整排书回来,搬书时间远远超过读题时间。

拿手机上的 LPDDR5X 内存举例,理论带宽几十GB每秒,我们按比较乐观的 50GB/s 算。一个 INT4 量化后的 35B 模型,权重 17.5GB,生成一个 token 至少要把这些字节都过一遍:17.5GB / 50GB/s = 0.35 秒。换算成速度就是大约 2.8 token/s。实际项目里还有注意力计算、激活值读写、调度开销,所以端侧 35B 模型跑到每秒两三个 token 是很正常的。这就是“内存墙”的直观含义:墙上写的不是算力不够,而是内存搬数据的速度不够。

这个结论对所有端侧推理都成立。7B 模型 INT4 量化后只有 4GB 左右,在同样的带宽下,理论速度能到每秒十几二十个 token,体验就完全不一样。所以不是大家不想上更大的模型,而是带宽这堵墙先把你按住了。

1.3 设备现状:手机处理器天梯图上真正的关键指标

翻手机处理器天梯图,很多人只看 CPU 跑分和 GPU 性能,但做端侧大模型部署,我最关心的其实是内存带宽和可持续算力。手机 SoC 天梯图上那些旗舰芯,比如各家最新的 8 系和 A 系芯片,NPU 的 TOPS 数字看着吓人,但 NPU 往往只擅长跑卷积和特定结构的算子,Transformer 里的复杂注意力逻辑未必能完全扔给它。真正决定大模型生成速度的,还是 CPU/GPU 对内存的读取带宽,以及算子和算子之间能不能高效衔接。

实话说,现在的手机内存带宽已经比几年前强了很多。LPDDR5X 在多通道加持下能摸到 60GB/s 上下,部分机型甚至配置了更大的内存通道位宽。可这个数字和数据中心里 HBM 内存动辄 TB/s 的带宽差了几十倍,即使算上功耗差异,端侧模型也注定只能在“更小的模型 + 更低的精度”里找平衡。这就是为什么我们讨论的从来不是“手机上跑 350 亿全精度模型”,而是在“量化、蒸馏、MoE、KV Cache 优化”这一整套组合拳下,让 35B 模型能在一个资源极度受限的环境里活下来。

2. 把 350 亿参数塞进手机的关键路径

2.1 量化:最直接的内存缩减手术

量化是所有方案里最流行也最见效的。它的思路很简单,把参数从 FP16 的 16 位浮点映射到 INT8 甚至 INT4 的整数范围。但“映射”两个字背后学问很大,不是简单截断就行。模型权重里有明显的异常值,少数维度数值极大,如果直接均匀量化,这些小但重要的维度可能被压成噪声,模型就废了。

GPTQ 的思路是逐层量化后,用剩余未量化的权重做误差补偿,尽量让输出层的结果误差最小。AWQ 则是先观察哪些通道对激活值影响最大,对重要通道保留更高精度,不重要通道分得更粗。SmoothQuant 干脆换个思路:把激活值里的异常“抹平”,让模型整体更容易量化。这些方法背后都绕不开一个数据集,叫“校准集”。用少量有代表性的文本跑一遍模型,统计每层激活值的分布,再确定量化参数。这本质上就是参数校准,和传统模型里的参数校准思路很像,复杂的金融模型拿历史数据校准参数,语言模型拿校准集确定量化比例,都是同一个逻辑。

做端侧部署,我不太自己从头训练量化模型,通常直接用社区验证过的量化方案,但同样会把校准集换到自己目标场景的数据上试一遍。量化参数里有一个很关键的组大小(group size),比如 32、64、128。组越小,量化越精细,但体积更大,速度和内存占用也会略增;组越大,模型更省内存,但精度可能下滑。我自己实测下来,35B 模型用 group size 128,4bit 精度,是端侧性价比最高的档位,几乎成了社区共识。

2.2 模型结构侧的手术:剪枝、蒸馏与MoE

量化是“改存储精度”,还有一条路是“改模型结构”,从源头减少要搬的参数。

第一个思路是剪枝。把注意力头、FFN 层中间维度里对输出贡献很小的部分删掉。35B 模型剪掉 30% 参数后,如果微调得当,能力损失可能比想象中小,但剪枝之后还需要重新微调,对个人开发者来说成本偏高,更适合有训练资源的团队。

第二个思路是蒸馏。用 35B 大模型当教师,教一个小模型怎么回答问题。蒸馏出来的 7B 模型可能保留大模型八成以上的风格和知识密度,体积却只有原来的五分之一。这个方案在手机上非常稳,很多“端侧小钢炮”模型就是这么来的。不过它有一个天然上限:小模型的知识容量有限,不可能完全复刻 35B 的广度。

第三个思路是 MoE,也就是混合专家结构。一个大模型内部拆成若干专家子网络,每次只激活其中两三个专家。350 亿参数里,真正为每个 token 工作的可能只有几十亿参数。这样内存里还是得装下全部专家,但计算和带宽消耗只聚焦在激活的子集上,推理速度接近一个十几B的模型。近两年很多高效开源模型都验证了这条路的可行性,也是我看好的端侧方向。

2.3 推理引擎的内存调度艺术

模型本身已经压缩到 17GB 左右了,如何在有限内存里跑起来,就得看推理引擎的调度本事。我用的比较多的是 llama.cpp 和基于 TVM 的 MLC-LLM,它们的底层优化方向极其相似,核心就几个层面。

第一是算子融合。一个简单的计算图里,Norm、线性变换、残差相加、激活函数,如果每个算子都单独把中间结果写回内存,下一算子再读出来,会白白浪费大量带宽。把相邻算子融合成一个大的内核函数,中间结果留在片上寄存器或高速缓存里,能省掉健康数量的内存访问。

第二是 KV Cache 优化。前面说过 KV Cache 会随序列增长占用大量内存,所以现在的引擎普遍支持量化 KV Cache,用 8bit 或 4bit 存储缓存。对长对话场景,这个优化能让可用上下文多出一大截。

第三是投机解码。小模型先草拟若干候选 token,大模型一次性校验多个 token,校验通过就一次吐出好几个,相当于把生成速度提升一倍甚至更多,代价是多一点点小模型的计算开销。在 “生成速度只有 2-3 token/s” 的场景,这个技术非常值钱。

第四是内存池和零拷贝加载。权重只加载一次,常驻内存,不随对话增长而被系统回收;激活值则在上下层之间复用同一块缓冲区,避免频繁分配释放。这些看似不起眼的工程细节,跑 7B 模型时感觉不明显,跑 35B 时就决定你是“刚加载就闪退”还是“稳定输出好几轮对话”。

3. 实操记录:端到端跑通一个 35B 级模型

3.1 准备:目标和环境确认

我这次选的目标是 35B 量级的开源指令模型,量化后 INT4 权重约 17.5GB,加上 KV Cache 和运行时开销,理论峰值内存需求接近 19GB。所以我准备了一台 24GB 内存的安卓旗舰机做主力测试,同时在 16GB 的次旗舰上做对比。安装了 Termux 作为 Linux 环境,整个流程和电脑上几乎一样,这个方案在安卓上最通用,也最适合排查问题。

先说结论:24GB 内存机型跑 35B INT4 属于“将将够用”,16GB 机型在长对话下确实会触发系统杀进程或者加载缓慢。如果你的目标是长期稳定使用,我建议至少 24GB 内存,16GB 还是留给 14B 模型或者对上下文长度严格要求的情况吧。

3.2 离线量化:把 HF 模型转成 GGUF 并压到 4bit

我习惯先在电脑上完成模型格式转换和量化,再把量化好的文件传到手机,让手机只做推理,不碰训练相关的重活。先用 llama.cpp 仓库里的转换脚本,把 Hugging Face 格式的原始模型转成 FP16 的 GGUF 文件,再用 llama-quantize 压到目标精度。

git clone https://github.com/ggml-org/llama.cpp cd llama.cpp cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j$(nproc) python3 convert_hf_to_gguf.py /path/to/your-35b-hf-model \ --outfile model-f16.gguf \ --outtype f16 ./build/bin/llama-quantize model-f16.gguf model-q4_K_M.gguf q4_K_M

我重点说说量化格式。llama.cpp 的量化类型五花八门,Q4_0、Q4_1、Q4_K_M、Q5_K_M、Q6_K…… 刚接触的人很容易眼花缭乱。我的经验是:K 系列(K-quant)是现在的主流选择,Q4_K_M 在体积和精度之间非常均衡,Q5_K_M 会相对更稳一点,体积大约多 1GB 左右,但端侧速度差异不大。极端情况下可以试 Q3_K_M,但 35B 模型压到 3bit 之后,角色的口吻和逻辑一致性明显下滑,我个人不建议为了省那 2GB 牺牲体验。

量化完成后,建议跑一遍内置的困惑度测试,或者用同一批问题量化前后模型对比,确认回答没有明显劣化。这一步很多人跳过,结果部署到手机才发现某个专业场景的回答完全跑偏,那个时候再排查就麻烦了。

3.3 手机端部署:Termux 环境与运行参数

把量化好的 GGUF 文件用数据线或者局域网传到手机后,在 Termux 里准备编译环境。如果你的手机支持,可以直接下载社区预编译的 llama.cpp 二进制,省掉编译时间。我因为老喜欢改参数,选择自己编译一次,主要是为了开 OpenMP 和多线程优化。

pkg update pkg install build-essential cmake git git clone https://github.com/ggml-org/llama.cpp cd llama.cpp cmake -B build -DGGML_OPENMP=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j$(nproc)

运行时的命令我很固定:

./build/bin/llama-cli -m model-q4_K_M.gguf \ -c 2048 \ -t 6 \ --temp 0.6 \ --repeat-penalty 1.1 \ --top-p 0.9

逐项解释几个关键参数:-c 是上下文长度,2048 足够日常问答,再大会让 KV Cache 占用暴涨;-t 是线程数,为了让出系统调度,我一般设物理核心数附近,全拉满反而可能因为调度开销变慢;--temp 控制随机性,--top-p 做核采样限制候选范围,--repeat-penalty 防止重复。这些采样相关参数,就是大家常说的超参数,同一个模型换一套超参数,回答风格可以从“老实念书”变成“放飞自我”,调试的时候很有意思。

跑起来之后,真正看到光标一格一格往外蹦字,心里还是很有成就感的。不过要提醒一句:手机散热是硬伤。持续推理时 CPU/GPU 长时间高负载,手机会开始降频,速度会从每秒两三个 token 掉到一两秒一秒,这是物理限制,只能靠主动散热或者控制对话长度缓解。

3.4 性能评估:tokens/s 与结果参数解释

部署完不能只看“能跑”就完事,还得看数据。我习惯用几个固定指标来评估端侧推理质量。最直观的是生成速度,单位 tokens/s,实测方法很简单:生成一个固定长度比如 256 token 的回答,记录耗时。llama.cpp 的日志会直接打印平均速度,不用自己算。

第二个指标是困惑度。困惑度衡量模型对文本的预测不确定性,越低代表模型越“懂”文本。量化和推理参数改动后,我会在测试集上对比困惑度变化。如果困惑度上升很大,说明量化损伤已经影响到底层能力,得换更高精度。

第三个是实际任务的人工评测。我在量化前后分别让模型写一段技术说明、编一个故事、总结一段对话,然后按逻辑、细节、语气三个维度打分。说实话,机器指标再漂亮,都不如这个来得直接。35B 级的模型在端侧经常给我惊喜:对长文理解、复杂指令的把握,明显比 7B 模型高一个档次,但偶尔也会冒出小模型身上的毛病,比如过度引用废话、偶尔逻辑跳脱。这些结果参数不用太紧张,多半是采样超参数的问题,调低 --temp 就能压住。

4. 常见问题与排查技巧实录

4.1 明明有内存,却提示内存不足

我第一次跑的时候,加载模型到一半直接被杀进程,手机弹“内存不足”,但系统设置里明明还剩十几个 GB。查了半天发现两个原因:一是 Android 对单个应用的内存有上限,Termux 这个进程默认无法吃掉全部物理内存,得靠设置里的“强制启用可调整大小缓冲区”之类选项或者修改一些系统权限来放开;二是随着上下文增长,KV Cache 会突然膨胀,系统在内存压力大的时候会优先回收后台进程,而 Termux 本身没有高优先级保护。

解决办法也很务实:降低 -c 到 1024,换 Q4_K_M 这种更省内存的量化格式,或者干脆用 16GB 机型跑 14B。另外一个容易踩的坑是别开太多后台 App,大模型推理本来就吃内存,再挂几个微信和相机进程,系统很容易误杀。

4.2 生成速度慢到没法用

35B 模型端侧每秒两三个 token,这是内存带宽决定的物理上限,不是你的错,也不完全是手机的错。但如果你明显感觉到比同配置的别人慢,先检查运行日志,确认是否真的加载了量化文件,会不会量化失败退回 FP16 了。再检查线程数,有些默认配置没开 OpenMP,或者用的是没有优化的预编译包,移动端二进制需要针对 ARM 平台启用对应指令集和核心数量。

还有一个隐蔽问题是散热。手机跑 35B 模型时热量来得比预想快,温度一上来,系统直接锁 CPU/GPU 频率,速度直接腰斩。给我的教训是:保持通风,不要边充电边跑,或者把手机壳摘掉,能让持续速度稳定不少。

4.3 量化后回答离谱,甚至报非法参数异常

如果模型能加载但回答混乱、乱码、重复,先怀疑量化精度。Q3 甚至更低档位在 35B 模型上容易出现这种问题,我建议至少用 Q4_K_M。再一个原因是量化校准集跟你场景偏差太大,比如用新闻数据校准的模型,硬要用到代码生成上,权重分布不匹配,只能重新用目标领域数据做量化。

运行时里偶发“非法参数异常”,也就是 invalid argument 这类报错,多数情况是采样参数和引擎版本不匹配。比如 --repeat-penalty 设成负数,或者 top-p 超过 1,引擎直接拒绝。这类问题只要回看命令行参数,基本能定位到原因。我在调试时给自己定了一条规则:改参数一次只改一个,记录当前 tokens/s 和输出样例,不然多个变量混在一起,永远搞不清是谁在捣乱。

4.4 端侧部署常见问题速查表

现象首要原因快速解法
加载即被杀进程单进程内存上限/可用 RAM 不足降低上下文、换 Q4_K_M、换 24GB 机型
速度只有零点几个 token/s降频/线程配置不佳/未用 ARM 优化改善散热、调整 -t、检查预编译包
输出乱码重复量化太低或校准集不匹配升级 Q5/Q6 量化,换校准集重建
对话稍微变长就开始变慢KV Cache 膨胀开启 KV Cache 量化,降低 -c
报 invalid argument采样超参数越界/命令行错误检查参数范围,逐个复位

这些坑看着小,但每一个都能让你在凌晨两点抓狂。我建议任何人在正式用之前,先在电脑上用同样的 GGUF 文件跑一遍基线,手机上有问题时跟电脑行为对比,很快就能锁定是模型文件的问题还是运行环境的问题。

5. 个人心得与后续还能怎么玩

5.1 不是所有场景都适合端侧 35B

折腾完这一圈,我的体会是:能跑,但不意味着所有场景都应该跑。35B 模型在端侧的优势是本地私有、不需要联网、数据不出手机,这对处理隐私内容、离线知识问答有天然价值。但每秒两三个 token 的速度注定了它不适合实时聊天或者长篇幅内容创作。更适合的场景是“我问一句,你等几秒,然后给一段完整回答”这种模式,比如会议纪要总结、写邮件草稿、本地资料问答。

我后来把它做成了一个小助手,主要在飞行模式和断网状态下用。速度慢一点反而让对话节奏更从容,模型因为没有网络延迟,回答完整度比云端的抽风式临时应答稳得多。

5.2 从参数压缩到参数校准的思维

干硬件的人对 lm317 三端稳压器的参数调校门儿清:一个电阻值变了,输出电压就飘了,必须按负载重新校准。ML 模型部署也一样,模型的量化参数、采样超参数、上下文长度,不是越大越好,也不是默认值就万能,而是要和你的实际使用负载匹配。我见过有人在端侧模型里硬套数据中心那套 prompt 和采样配置,结果效果奇差,不是模型不行,是参数没有校准到当前场景。

这种“抱着算账思维做部署”的习惯,让我少走了很多弯路。每次换模型,我都会先跑一轮量化精度对比,再根据目标场景调采样的那一组超参数,最后才丢到手机上做真机测试。流程很土,但稳定。

5.3 下一步可以玩的扩展方向

如果有精力,可以往前再走几步。一是给手机模型接上本地 RAG,把个人文档切片后建索引,模型回答时检索相关内容做参考,35B 模型的语言理解能力配合检索,能把本地知识库玩出花来。二是多模型协作,用不到 1GB 的小模型做意图识别,把复杂问题转发给 35B 大模型,轻量任务直接小模型回答,兼顾速度与容量。三是把 KV Cache 进一步压到 4bit,配合更大的上下文窗口,让长对话的体验更稳定。

这些方向不需要云端算力,只需要持续优化推理管线和合理控制超参数,每一台 24GB 内存的手机都能变成随身带着的个人模型工作站。内存墙还在,但墙已经被凿出了不少洞,能钻过去的路越来越多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询