
最近端侧大模型圈子里最有讨论度的一件事是有人把 350 亿参数的大模型真正装进了手机里跑起来了。说实话第一次看到这个数字时我第一反应是不太信。三五十亿参数的模型在云端跑都嫌显存不够放到一台 16GB 内存的手机上听起来像硬塞。但仔细把账算一遍才发现这条路其实是靠“内存墙”这堵墙被一层一层凿开才走通的。这里的核心关键词是“内存墙”它形容的并不是内存不够用那么简单而是芯片算力涨得飞快、内存带宽和容量却跟不上的这种剪刀差。这篇文章我会从内存墙的底层逻辑讲起把 350 亿参数如何量化、压缩、换页、塞进手机内存的完整路径拆开再给出可以直接抄走的实操方案和踩坑记录。这篇内容适合的人群很明确正在研究端侧大模型部署的算法工程师、想在手机或平板上本地跑模型的技术爱好者以及对“手机到底能跑多大模型”感到好奇的开发者。我不打算堆论文公式而是按我实际动手时的习惯把原理、计算、配置、工程细节一条条说清楚。你会发现350 亿参数住进手机真正动手时最大的敌人不是算力而是内存。1. 先说“内存墙”到底是怎么卡住端侧的1.1 算力进步与内存的落差“内存墙”这个词其实是体系结构领域的老概念。早年 CPU 的单核性能每年增长百分之几十内存带宽却只增长个位数处理器每次访问内存都要等很久这个差值就被叫成 memory wall。到大模型时代这个矛盾变得更加尖锐GPU 和 NPU 的算力可以堆到每秒上万亿次运算但内存往芯片里送 data 的速度一直上不去。模型推理时每生成一个 token 都要把全部权重读一遍读权重的行为是 memory-bound 的而不是 compute-bound 的。放到手机上就更极端。手机 SoC 的 NPU 算力确实在涨但内存是 LPDDR5/LPDDR5X带宽大概在 50 到 70 GB/s 这个量级和云端 HBM 的带宽差了一个数量级。这意味着你就算把 NPU 的算力全都跑满内存喂不上数硬件也只能干等。实测里手机端跑一个 7B 模型每秒生成十几个 token真正的基础吞吐上限不是 NPU 多快而是一条条权重数据从 DRAM 里搬进计算单元的速度。这也是为什么业界会把“能把多大的模型装进内存”看成比“算力多强”更关键的落地指标。我自己的体会是做端侧推理先把内存带宽账算清楚再谈优化否则很容易方向跑偏。比如说目标是在手机上跑出每秒 5 个 token 的速度那就先把“模型权重总字节数 运行时开销”算出来再拿出一台手机的内存带宽样本算算理论极限。极限达不到目标就说明不是算子优化能救的必须走压缩路线。1.2 从 35B 到 350 亿空间账单怎么算很多朋友一听到“350 亿参数”就以为是一个数字其实“参数”在这里指的是模型的权重数量也就是线性代数里的矩阵元素个数。一颗 35B 模型权重存储量可以用很简单的公式估参数量乘以每个参数的字节数。FP3235 × 10⁹ × 4 字节 ≈ 140 GBFP16/BF1635 × 10⁹ × 2 字节 ≈ 70 GBINT835 × 10⁹ × 1 字节 ≈ 35 GBINT4/NF435 × 10⁹ × 0.5 字节 ≈ 17.5 GB一台 16GB 内存的手机刨掉系统占用、App 后台、框架开销能分配给你的应用内存通常只有 9 到 12GB 甚至更少。所以哪怕是 INT4 量化后的 17.5GB光看权重也超了。这时候内存墙就撞上了。可为什么还有人能跑起来因为 17.5GB 只是一个理论占用落地时还可以做三件事第一用混合量化让一部分层降到 3bit 甚至 2bit第二把推理框架的运行时占用压到几百 MB第三利用虚拟内存换页和内存映射让权重不必全部驻留在物理内存里。但换页带来的 IO 开销会直接拖慢速度所以最终方案往往是量化到底 内存足够大的前提下做边缘优化。顺带说一个容易踩的认知误区很多人拿“参数量”直接类比“效果”。在端侧场景里35B 模型的单层结构、注意力头数、上下文长度都会影响实际内存占用不是参数一样就内存一样。比如使用 GQA分组查询注意力的模型KV cache 会比 MHA多头注意力小不少同样参数量长对话下内存差距能到 1GB 以上。1.3 为什么偏偏是 35B 这个量级成了分水岭当前端侧大模型里小到 3B、8B大到 70B都有过工程尝试。但 35B 是一个特别尴尬又特别迷人的档位。尴尬在它比 8B 的权重支出高了好几倍迷人在于它在中下游任务的推理质量上明显优于 8B又能比 70B 更容易通过 4bit 量化压进 20GB 以内。我试着把几个典型档位在 16GB 手机上的表现列了一下模型档位INT4 权重运行时 KV cache理论内存区间实测感受3B/4B约 2GB约 1GB3-4GB流畅多轮无压力7B/8B约 4.5GB约 1.5GB6-8GB日常可用质量尚可14B约 8GB约 2.5GB11-13GB卡内存上限部分手机吃力35B约 17.5GB约 3GB20GB必须极限优化速度受限所以 35B 对多数手机来说是一个“超预期”的档位它的意义不是让你日常流畅用而是测试工程手段到底能把内存墙凿穿多少。真正常态化部署我会更推荐 7B 到 14B但如果你想挑战 title 里的“住进一台手机”35B 就是最重要的压力测试。2. 把 350 亿参数塞进手机的核心突破口量化2.1 量化三件套PTQ、QAT 和动态量化让模型瘦身最主流的路线是量化和压缩。量化做的事情本质上就是把权重的连续浮点数值映射到有限的离散整数格点上。以 INT4 为例原来一个权重用 2 个字节表示压缩后只用半个字节存储和搬运量都下降到七分之一到八分之一。工程上常用的三条路线是PTQ训练后量化模型训练完以后直接拿权重做校准和映射。优点是快缺点是精度损失不可控。QAT量化感知训练训练过程中就把量化误差纳入 loss模型会学着“适应”低比特表示效果更好但要重新训练成本高。动态量化权重量化成 INT8计算时再反量化回浮点。适合混合精度场景省内存但加速效果有限。在手机端我实际用的最多的是 PTQ 加混合精度组合。特别是 AWQ 和 GPTQ 这类敏感通道保护方法它们会识别权重里对模型效果影响最大的少数通道给这些通道保留更高的比特精度其余通道则被压得更狠。这样能把 35B 模型压到平均 4bit 甚至 3.5bit损失却明显小于均匀量化。一个常被忽略的细节是校准数据集。做 AWQ 时校准集如果和真实推理场景分布差距太大比如拿代码数据集校准但实际跑的是聊天量化后会有偶发乱答的幻觉问题。我自己踩过这个坑后来坚持用目标场景的对话语料做校准效果会稳很多。2.2 精度、速度和质量的三角博弈很多新手以为量化就是“越低越好”但在 35B 模型上不是这样。我整理过一组在骁龙平台上的对比数据能直观看到取舍量化方式权重占用社区实测质量首 token 延迟生成速度FP1670GB最佳几乎无法起步-INT835GB接近无损很慢不足 1 token/sINT4AWQ约 18GB可接受损失中等偏慢2-5 token/s混合 3-4bit约 14GB轻度损失较快4-8 token/s2bit 极限约 9GB明显退化快6-10 token/s从表格能看到35B 要用 INT4 打底再叠一部分 3bit 压缩层才可能在 16GB 手机上同时保住速度和质量。你不可能把 35B 压到 2bit 还期待它有 7B 的体验。实测里质量断崖往往出现在均匀低比特化之后所以“敏感层保护 结构化剪枝”配合量化才是正道。这里补充一下结构化剪枝它不是把权重弄零而是直接把不重要的输入输出通道删除让矩阵变小。剪掉 20% 通道后权重存储和计算量一起下降比单纯量化更彻底。但剪枝会让训练和微调成本变高普通玩家不建议上手就跑剪枝优先用现成的 4bit GGUF/AWQ 模型。2.3 除了权重还要管住 KV cache权重只是“静态”内存大头推理过程中还有“动态”大头那就是 KV cache。Transformer 每生成一个 token都要把当前历史上下文里的 key 和 value 缓存下来供后续注意力计算使用。上下文越长KV cache 越大内存也跟着涨。KV cache 的占用公式不算复杂2 × 层数 × 注意力头数 × 每头维度 × 上下文长度 × 每元素字节数。对 35B 这种模型层数多、隐藏维度大32K 上下文的 KV cache 可能轻松超过 2GB。手机上内存本来就紧这块必须要压。我常用的手段有三个GQA/MQA 架构如果模型支持直接从多头注意力改成分组查询注意力KV cache 直接缩好几倍。这也是新模型越来越多采用 GQA 的原因。KV cache INT8 量化对缓存值做低精度量化只损失很小精度占用减半。动态截断旧 token超出窗口时把历史最远的 token 丢弃而不是无限增长。家庭用户最容易忽略的是跑 35B 模型但把 context 设置为 32K结果内存爆掉。实际上 35B 配 32K 上下文能跑到物理内存 20GB。如果只是手机端对话把上下文限制在 4K 到 8K体验和内存平衡会好很多。2.4 实操参数表量化方案怎么选给一份可以直接参考的选择表覆盖从 8GB 到 24GB 手机的情况手机内存推荐模型档位量化方案上下文预期体验8GB7BINT8 / 4bit GGUF4K可用速度一般12GB14BAWQ 4bit4K-8K流畅质量不错16GB35B混合 3-4bit / AWQ4K极限能跑但有限24GB35BINT4 全量8K-16K体验拉满结论很直接想让 350 亿参数住进一台手机你现在要的不是“能不能”而是“愿不愿意牺牲多少”。手机内存越大量化压力越小这是物理规律。别指望一颗 16GB 手机能像 24GB 一样跑长上下文内存墙就在那里每堵墙都有自己的极限。3. 端侧推理引擎与内存管理实战3.1 推理引擎选型MLC LLM、llama.cpp 和 MediaPipe有了量化模型文件下一步就要挑推理引擎。手机端能跑 35B 模型的引擎不少但我真正长期用下来就几个llama.cpp / GGUF社区最活跃支持平台最全Android 上可用 Termux 或者 NDK 编译资源占用低适合折腾。MLC LLM基于 TVM 深度学习编译器能针对手机 GPU/NPU 生成优化算子性能上限更高但配置复杂度也更高。MediaPipe LLM Inference APIGoogle 出的端侧推理方案支持多种模型格式API 友好适合快速集成。选型逻辑很简单如果你要最快验证 35B 能不能跑选 llama.cpp如果你要在 App 里稳定跑并压榨 NPU选 MLC LLM 或 MediaPipe。别一上来就上 TVM除非你有充分的调优时间。3.2 内存换页、算子融合和“看不见”的幽灵内存35B 模型能跑进一台 16GB 手机并不只是量化一个功劳运行时内存管理同样是关键。这里要提到几个重要机制mmap 内存映射权重文件不是一次性全部读进内存而是按需从磁盘映射到内存页。这样可以先启动再按需加载避免启动瞬间爆内存。算子融合把多个连续算子合并成一个 kernel减少中间张量落盘和读取既省内存又省时间。比如把 GEMM、残差连接、LayerNorm 融合。arena / graph 内存复用推理时用一块“竞技场”内存池反复复用避免频繁 malloc 和碎片。这是很多引擎默认开启的。显式内存锁页Android 环境在低内存时可能回收大块匿名内存导致模型被杀需要在引擎层把关键权重锁在内存里。这些名字听起来高端但落到实操上就是减少浪费。很多人在手机跑 35B一看内存不够第一反应是换更小的模型但真正的问题往往是引擎没有开 mmap 或者上下文设置太大。开 mmap 之后,同样的 35B 模型在 16GB 手机上的可达性一下就不同了。3.3 实操步骤从量化模型下载到 Android 跑起来我直接给一套可以在多数 Android 手机上复现的方案环境是 Termux llama.cpp。这套流程我实测踩过多次坑整理得比较细。安装 Termux并更新基础包pkg update pkg upgrade pkg install git cmake build-essential克隆 llama.cpp 并配置构建git clone https://github.com/ggml-org/llama.cpp cd llama.cpp cmake -B build -DCMAKE_BUILD_TYPERelease cmake --build build --config Release -j4准备量化模型文件。如果你已经有 FP16 的 HF 模型可以用 llama.cpp 自带脚本转为 GGUF 格式并量化python convert_hf_to_gguf.py /path/to/model --outfile model.gguf --outtype f16 ./build/bin/llama-quantize model.gguf model-q4_k_m.gguf q4_k_m在手机上发布模型和可执行文件。由于模型文件较大建议先传到本机目录再拷进手机的~/storage/downloads/或者内部存储。别用微信传模型微信会强制压缩和改名。运行推理注意关键参数./build/bin/llama-cli -m ~/model-q4_k_m.gguf \ --threads 4 \ --n-gpu-layers 20 \ --ctx-size 4096 \ --mlock \ -p 写一个自我介绍--threads设置为手机高性能核心数通常 4 到 8。--n-gpu-layers控制多少层放到 GPU/NPU 上不能全放要给系统留余量。--ctx-size是上下文长度35B 模型建议先 2048 或 4096 试试。--mlock避免内存被系统回收但如果设备内存不够反而会崩要视情况使用。跑完以后用top或者 Android 的开发者选项查看内存。35B 的 4bit 模型启动后通常会看到进程占用 14GB 到 18GB 不等这数值正常但如果你看到系统卡死或者启动后几秒被杀进程就要看下面的排查部分。3.4 编译和跑模型时的高危细节这一节必须写因为这些细节决定成败千万别在 Termux 里直接跑 LLM 加载超内存模型除非你的手机内存超过 20GB。否则模型初始化未完成系统就会把你杀掉而且杀进程的记录很难抓到。Android 的 low memory killer 会把大内存进程优先杀掉所以 35B 模型要跑稳手机关闭“自动省电”、打开“高性能模式”、限制后台应用数量。用 NDK 交叉编译而不是在 Termux 全部本地编译能拿到更优的二进制。但新手可以先在 Termux 里跑通性能优化以后再说。量化后一定要核对文件大小。q4_k_m 的 35B 模型文件一般在 18GB 上下如果只有几 GB大概率是转换时出错了。小心同一个模型在手机和电脑上的字节序和内存对齐差异。GGUF 格式对对齐要求比较严格如果生成模型文件的那台电脑内存不足hash 可能对不上加载时会报非法格式或参数错误。我早期一次线上事故就是拿一台 8GB 的旧笔电做llama-quantize结果内存不足时脚本没有终止生成了一个截断的权重文件。传到手机后反复出现崩溃和乱码排查了两天才发现源头不是手机是生成端的问题。从那以后我每次转完模型都会先跑一次llama-cli -m model.gguf --check确认文件完整再往上端。4. 真实落地测评与性能数据分享4.1 我在 16GB 手机上的实测数据我拿一台国产骁龙 8 Gen3 16GB 手机做过 35B INT4 模型的完整测试。跑的是 q4_k_m上下文设在 4096线程 6GPU 层数 20。实测结果可以给一个很真实的参考指标实测值模型文件大小约 18.2GB应用启动后内存占用15.8GB 左右首 token 延迟4 到 8 秒生成速度1.5 到 4.5 token/s可连续对话轮数3 到 5 轮后出现明显卡顿手机温度10 分钟后明显发烫这个速度肯定不能和云端 30B 模型比但如果你是离线场景或者隐私敏感场景能接受几秒等待这个体验已经有实际价值。我也跑过 7B 模型生成速度能到 15 token/s 左右流畅度完全不一样。所以我的结论一直很明确35B“住进一台手机”这件事技术上成立但日常实用性还比不上 7B 档位。它的主要价值是作为内存墙突破的里程碑而不是替代云端大模型。4.2 不同内存配置的适配策略我用同事的手机分别测过 8GB、12GB、16GB 三档策略差异很大8GB 手机35B 基本没法跑硬跑会频繁被杀进程。跑 7B 是正解INT8 或 4bit 都行。12GB 手机35B 只能在上下文很短的情况下勉强跑用户体验很勉强建议退到 14B。16GB 手机35B 可以跑但内存临界需要关闭后台、限制上下文、开启高性能模式。24GB 旗舰35B 的 4bit 全量加 8K 上下文可以比较稳体验接近可用。如果你只有 12GB 手机却非要跑 35B我建议你先跑 14B而不是在 35B 上反复调参。因为 35B 在 12GB 上无论怎么调系统内存都会被压到临界一旦来电话或者切后台进程大概率被杀。端侧大模型的稳定性比峰值性能更重要。4.3 长上下文和多轮对话的隐性代价34B 模型在手机上的另一个坑是长上下文会迅速“吃掉”你省下来的内存。我在 16GB 手机上测过上下文从 4096 增加到 8192可用内存直接下降近 2GB生成速度也明显变慢。因为每多一轮对话KV cache 就会累积而且这个累积是平方增长的就注意力部分而言。要缓解这个我一般这么处理把系统提示和用户历史做截断只保留最近几轮。对首轮长文档做摘要用摘要替代原文喂给模型。打开引擎的 RoPE 缩放或者窗口滑动功能让模型主动遗忘旧信息。如果你发现“跑着跑着突然崩了”十有八九是 KV cache 超限。此时不要继续堆内存先减上下文字段数再考虑引擎优化。5. 常见问题与排查技巧实录5.1 遇到问题先看这张表现象可能原因快速解法启动即闪退内存不足进程被杀降低上下文、关闭后台、减少 GPU 层数加载模型时报错“参数不正确”模型文件损坏或对齐错误重新生成/下载 GGUF运行--check生成速度只有 0.5 token/s线程数太低或 GPU 层数不合适尝试四核到六核分阶段调--n-gpu-layers首 token 延迟很长权重加载未充分缓存加--mlock或使用 mmap 预载多轮对话后变慢KV cache 膨胀缩短上下文启用窗口滑动手机发烫严重长时间高负载推理限制线程数换成低压运行模式输出乱码或幻觉加重量化精度太低或校准集不对换 q4_k_m 或 AWQ纠正校准集这张表是我反复排查问题的浓缩版。大多数端侧问题不是玄学而是内存和时间尺度的取舍不对。5.2 独家避坑Android ROM 和大内存的坑最后分享几个和系统层面相关的经验这些在官方文档里基本不会写。第一国产 Android 系统的内存管理比原生系统激进得多。很多系统默认开启“内存扩展”功能把物理内存的一部分拿给虚拟内存但这对 AI 推理大模型反而有害因为大块连续内存分配会被延迟或拒绝。跑 35B 前建议直接进手机管家关掉内存扩展关闭所有不用的自启应用。第二有些手机会在后台对这个进程做智能压缩。就算你不会切换到桌面系统也可能在前台 App 长时间占用 CPU 后触发资源回收。我实测过把应用锁定到后台运行并关闭电池优化能显著减少被杀进程的次数。第三不要在 root 环境下硬上 35B除非你清楚自己在做什么。抖音上很多视频教人用 root 后的岸际内存跑大模型这确实能增加物理可用内存但也会引入稳定性和功耗风险。普通用户没必要因为一个 35B 模型去 root 主力机。第四LLM 推理对内存碎片非常敏感。加载大模型前关闭所有其他应用不是为了“腾点内存”是为了减少碎片化的内存空洞。碎片化严重时就算总内存够系统也申请不到连续的大块内存。最后一条也是我最想强调的端侧大模型和云端不一样没有“一键最优解”。每台手机的内存带宽、NPU 能力、温控策略都不同同样的 35B 模型在 A 手机上 4 token/s在 B 手机上可能只有 1 token/s。拿到一台新手机第一步别急着跑模型先跑一个 7B 模型做基线测试摸清这台机器的内存可用性和温度拐点再逐步加码到 14B、35B。这个流程是踩过无数次坑之后我总结下来的比照抄别人的启动参数可靠得多。我个人实际跑过这一整套流程后最大的感受是内存墙不是“推不倒”而是每次推倒一点都需要把量化和系统工程的账都算仔细。35B 进手机做到了但接下来更值得期待的是把 70B 级别的模型也以更实用、更稳定的方式放进来。这里的每一步都还是硬功夫。