1. 手机跑大模型这件事到底靠不靠谱先说结论能跑但别指望它替代云端服务。我前后在骁龙8 Gen 2的Android机和iPhone 15 Pro上折腾了差不多两个月从最初的“这玩意儿真能跑”到后来把本地模型接进自己的笔记工作流中间踩的坑比想象中多得多。这篇文章就把整个路径完整拆一遍包括模型怎么选、量化怎么做、推理框架怎么挑、内存怎么省以及那些文档里不会写的坑。所谓“手机本地部署LLM”本质是把一个已经训练好的大语言模型经过压缩和格式转换后塞进手机的运行内存里用手机芯片做推理计算。它解决的核心问题是在没有网络、不想把数据传到云端、或者单纯想省API费用的场景下依然能用到语言模型的能力。适合谁来参考三类人一是对隐私敏感、希望数据不出设备的开发者二是想学习端侧推理原理的技术爱好者三是需要在离线环境下做文本处理比如摘要、翻译、分类的工程人员。但这里有个前提认知必须先建立手机端能跑的模型参数量通常在0.5B到7B之间而且必须经过量化压缩。一个7B模型在FP16精度下大约需要14GB内存手机根本扛不住。量化到4-bit之后体积能压到3.5GB到4GB左右这才勉强进入旗舰机的可运行范围。所以你在手机上跑的那个“大模型”和云端动辄几百B参数的模型完全不是一个量级的东西。它的定位更像是一个随身携带的离线小助手而不是全能型AI。我实测下来Android端的生态明显比iOS端成熟。原因也简单Android允许侧载应用、允许直接访问文件系统、允许后台长时间运行计算任务而iOS对这些限制严格得多。所以如果你是第一次尝试我建议从Android开始成功率会高很多。iOS不是不能做但路径更窄后面会详细说。2. 模型选型与量化不是越小越好也不是越大越强2.1 手机端模型的参数甜点区在哪里很多人一上来就想跑7B模型觉得参数越大效果越好。理论上没错但手机端有个硬约束内存带宽和散热。我做过一组对比测试在同一台骁龙8 Gen 2设备上分别跑Qwen2.5-0.5B、Qwen2.5-1.5B、Llama-3.2-3B和Mistral-7B的4-bit量化版本结果如下模型量化精度模型体积加载时间生成速度tokens/s手机发热情况Qwen2.5-0.5BQ4_K_M约400MB1-2秒25-35几乎不热Qwen2.5-1.5BQ4_K_M约1GB2-4秒15-22轻微温热Llama-3.2-3BQ4_K_M约2GB4-8秒8-14明显发热Mistral-7BQ4_K_M约4GB10-20秒3-6烫手会降频从这张表能看出来1.5B到3B是手机端的甜点区。0.5B虽然快但理解能力有限复杂一点的指令就开始胡言乱语7B虽然效果最好但生成速度慢到你会失去耐心而且手机很快就会因为过热而降频速度进一步下降。我个人的建议是中文场景优先选Qwen2.5-1.5B或Qwen2.5-3B的量化版英文场景可以考虑Llama-3.2-3B或者Phi-3.5-mini。这些模型在各自参数量级上的表现都比较均衡不会出现某个能力特别短板的情况。2.2 量化到底在做什么为什么必须做量化这个词听起来很专业但用生活化的方式解释就很好理解。假设你原来用一把精确到毫米的尺子量东西每个数据都要存成16位浮点数量化相当于换了一把精确到厘米的尺子每个数据只存4位整数。精度损失了一些但存储空间和计算量都大幅下降。具体到技术层面常见的量化方法有GPTQ、AWQ、GGUF等格式。手机端最常用的是GGUF格式配合Q4_K_M量化原因是GGUF是llama.cpp生态的标准格式支持CPU推理对硬件要求最低而且Q4_K_M在精度和体积之间取得了很好的平衡。注意不要盲目追求Q2或Q3级别的极致压缩。我试过Q2_K量化的7B模型体积确实压到了2.5GB左右但输出质量下降非常明显经常出现重复、断句错误、逻辑混乱的问题。省下来的那点内存不值得用效果来换。量化的具体操作通常在电脑上完成需要用到llama.cpp提供的量化工具。流程是先下载原始模型通常是HuggingFace上的safetensors格式转换成GGUF格式然后再做量化。这个过程我在后面实操章节会详细展开。2.3 模型来源与格式选择模型下载渠道主要是HuggingFace和ModelScope。国内访问HuggingFace有时候不太顺畅ModelScope上的模型镜像比较全速度也快建议优先考虑。格式方面手机端基本就认GGUF这一种。如果你看到的是safetensors或者PyTorch的.bin文件都需要先转换。有些模型作者会直接提供已经量化好的GGUF文件省去自己转换的步骤优先选这种。选模型的时候还要注意对话模板的问题。不同模型用的对话格式不一样比如Qwen用的是ChatML格式Llama用的是自己的特殊token格式。如果模板搞错了模型会把用户输入当成普通文本续写而不是当成指令来执行输出结果会非常奇怪。好在现在主流的推理框架都内置了常见模型的模板选对模型名称一般就能自动匹配。3. Android端部署实操从零到跑通3.1 推理框架怎么选llama.cpp还是MLC-LLMAndroid端目前主流的本地推理方案有两个llama.cpp和MLC-LLM。两者思路不同适用场景也不一样。llama.cpp是纯C实现的推理引擎核心优势是CPU推理效率高、依赖少、移植简单。它不需要特定的GPU加速在骁龙芯片上通过NEON指令集优化就能跑出不错的速度。缺点是纯CPU推理时功耗较高长时间运行发热明显。MLC-LLM则是基于TVM编译器的方案支持GPU加速Android上通过OpenCL或Vulkan理论上有更好的能效比。但它的部署流程更复杂需要针对特定设备编译而且对模型格式有额外要求。我两个方案都试过最后长期用的是llama.cpp。原因很实际MLC-LLM的编译环节太容易出错了不同手机芯片的兼容性差异很大有时候编译通过了跑起来也会崩。llama.cpp虽然速度不是最快的但胜在稳定基本上只要模型文件没问题就能跑起来。如果你只是想快速体验不想折腾编译环境可以直接用现成的App。比如ChatterUI、LM Playground、PocketPal这几个都内置了llama.cpp的推理能力下载模型文件导入就能用。但如果你想自己控制推理参数、集成到自己的应用里那就需要自己编译llama.cpp的Android版本。3.2 编译llama.cpp的Android版本编译环境准备是第一步。你需要Android Studio最新稳定版即可主要用于获取NDK和CMakeAndroid NDK建议用r26或r27版本CMake 3.22以上Git具体编译命令如下这是我在Ubuntu环境下实测通过的流程# 克隆仓库 git clone https://github.com/ggerganov/llama.cpp cd llama.cpp # 创建构建目录 mkdir build-android cd build-android # 配置CMake注意替换NDK路径 cmake .. \ -DCMAKE_TOOLCHAIN_FILE$ANDROID_NDK/build/cmake/android.toolchain.cmake \ -DANDROID_ABIarm64-v8a \ -DANDROID_PLATFORMandroid-28 \ -DCMAKE_BUILD_TYPERelease \ -DLLAMA_CURLOFF # 编译 make -j$(nproc)编译完成后你会得到libllama.so、libggml.so等动态库文件以及llama-cli和llama-server两个可执行文件。把这些文件推到手机上就可以通过adb shell运行了。实操心得-DANDROID_PLATFORM建议设成android-28或更高。我试过设成android-24编译能过但运行时会报缺少某些系统符号。另外-DLLAMA_CURLOFF是关掉网络请求功能手机端本地推理用不到关掉能减少依赖。3.3 把模型跑起来完整命令行操作编译产物推送到手机adb push build-android/bin/llama-cli /data/local/tmp/ adb push build-android/lib/*.so /data/local/tmp/ adb push qwen2.5-1.5b-instruct-q4_k_m.gguf /data/local/tmp/ adb shell chmod x /data/local/tmp/llama-cli然后进入手机shell运行adb shell cd /data/local/tmp LD_LIBRARY_PATH. ./llama-cli \ -m qwen2.5-1.5b-instruct-q4_k_m.gguf \ -n 512 \ -t 6 \ -c 2048 \ --temp 0.7 \ -p 你好请用一句话介绍你自己参数解释一下-n 512是最大生成token数-t 6是使用6个线程骁龙8 Gen 2有1个X核4个性能核3个能效核设成6比较均衡-c 2048是上下文窗口大小--temp 0.7是温度参数控制随机性。实测在骁龙8 Gen 2上Qwen2.5-1.5B Q4_K_M的生成速度大约在18-22 tokens/s首token延迟在1秒左右。这个速度用来做文本摘要、翻译、简单问答是完全够用的。3.4 集成到Android应用的关键点如果你想在自己的App里集成核心是通过JNI调用llama.cpp的C接口。主要涉及几个步骤第一在CMakeLists里链接编译好的动态库。第二写JNI桥接层把Java/Kotlin的字符串传成C的char指针。第三管理模型加载和推理的生命周期避免内存泄漏。这里有个容易忽略的点模型加载应该在后台线程做而且要做好内存回收。一个1.5B的Q4模型加载后大约占用1.2GB到1.5GB内存如果Activity销毁时没有正确释放下次加载就会OOM。我的做法是把模型实例放在Application级别的单例里全局只加载一次所有页面共享。另外Android 12以上对后台进程限制更严如果推理时间较长建议用Foreground Service加通知的方式保活否则系统可能在推理过程中把进程杀掉。4. iOS端部署限制更多但并非不可能4.1 iOS端的特殊约束iOS端做本地LLM部署最大的障碍不是硬件性能——A17 Pro的神经网络引擎其实很强——而是系统限制。iOS不允许JIT编译不允许动态加载未签名的可执行代码后台运行时间也严格受限。这意味着llama.cpp那种“编译一个可执行文件直接跑”的路子在iOS上行不通。iOS上可行的方案主要有两个一是用Core ML把模型转换成Apple自己的格式利用Neural Engine加速二是用MLX框架这是Apple专门为自家芯片做的机器学习框架支持统一内存架构推理效率不错。Core ML的优点是能吃到Neural Engine的加速功耗低缺点是转换流程复杂对模型结构有要求不是所有LLM都能顺利转。MLX的优点是灵活支持动态图转换相对简单缺点是生态还在建设中文档不够完善。4.2 用MLX跑通第一个模型MLX的安装需要Python环境建议用conda创建一个独立环境pip install mlx mlx-lm然后直接从HuggingFace拉取MLX格式的模型mlx_lm.generate \ --model mlx-community/Qwen2.5-1.5B-Instruct-4bit \ --prompt 请用一句话解释什么是量化 \ --max-tokens 200这个命令在Mac上就能跑验证模型没问题后再考虑往iOS设备上部署。iOS端需要把MLX的推理代码集成到App里通过Swift调用。Apple官方有一个MLX Swift的示例项目可以作为起点。注意iOS端跑模型对设备内存要求很高。1.5B的4-bit模型大约需要1GB左右的内存iPhone 15 Pro的8GB内存勉强够用但如果是iPhone 14或更早的6GB机型跑起来会比较吃力系统可能会因为内存压力杀掉App。4.3 iOS端的替代思路用快捷指令调用本地服务如果你不想折腾App开发还有一个取巧的办法在电脑上跑一个本地推理服务比如用Ollama然后手机通过局域网访问。这样手机端只负责发送请求和展示结果计算全在电脑上完成。这个方案的好处是手机端零负担模型可以随便选大的缺点是必须和电脑在同一个网络下失去了“随时随地离线使用”的意义。但如果你主要在家里或办公室用这个方案其实很实用。具体做法是在电脑上启动Ollama服务然后iPhone上用快捷指令的“获取URL内容”功能向电脑的IP地址发送POST请求。请求体是JSON格式包含prompt和参数。返回的结果解析后展示出来就行。5. 性能调优与省电策略5.1 线程数怎么设才合理线程数不是越多越好。手机芯片通常是大小核架构比如骁龙8 Gen 2是143天玑9300是44。如果把线程数设成8系统会把任务分配到所有核心上包括能效核。但能效核的主频低参与计算反而会拖慢整体速度因为推理是同步的最慢的那个核心决定了整体速度。我的经验是线程数设成性能核的数量。骁龙8 Gen 2设61个X核4个性能核1个能效核做调度天玑9300设84个X44个A720A17 Pro设6。这样能保证所有计算都落在高性能核心上避免被能效核拖后腿。你可以通过adb shell cat /proc/cpuinfo查看CPU核心信息然后根据实际情况调整。5.2 上下文长度与内存的权衡上下文窗口context window直接决定了模型能“记住”多少内容。设得越大内存占用越高。以Qwen2.5-1.5B Q4_K_M为例2048上下文大约占1.2GB内存4096上下文就要1.5GB左右。手机端我建议上下文不要超过4096。一方面内存吃不消另一方面上下文越长首token延迟越高因为模型需要处理更多的输入token。如果你只是做短文本处理2048完全够用。如果确实需要处理长文档可以采用分块处理的策略把长文档切成若干段每段单独送给模型处理最后把结果拼接起来。虽然会损失一些跨段落的上下文关联但内存压力小很多。5.3 散热与持续性能手机跑LLM最大的敌人是散热。我实测过骁龙8 Gen 2在连续推理10分钟后机身温度会升到42度左右然后系统开始降频生成速度从20 tokens/s降到12 tokens/s左右。如果继续跑温度会稳定在45度上下速度维持在10-12 tokens/s。缓解办法有几个一是限制单次生成的最大token数比如设成256生成完就停让手机有时间散热二是避免边充电边推理充电本身就在发热叠加推理的热量会加速降频三是如果条件允许摘掉手机壳裸机散热会好一些。实操心得如果你需要长时间批量处理文本建议把任务拆成小批次每批之间间隔30秒到1分钟让芯片有时间降温。我试过连续跑1小时不做间隔的话后半段速度只有前半段的一半。6. 常见问题与排查技巧实录6.1 模型加载失败或崩溃这是最常见的问题原因通常有三个模型文件损坏、内存不足、格式不兼容。排查步骤先用md5sum校验模型文件的完整性对比下载页面提供的哈希值。如果文件没问题检查手机剩余内存是否足够1.5B的Q4模型至少需要1.5GB可用内存。如果内存也够那可能是GGUF版本和推理框架版本不匹配尝试更新llama.cpp到最新版重新编译。6.2 输出乱码或重复这种情况通常是对话模板不匹配导致的。模型没有正确识别指令格式把用户输入当成了普通文本续写。解决办法是在推理时指定正确的chat templatellama.cpp用--chat-template参数比如--chat-template chatml对应Qwen系列。另一个可能的原因是温度参数设得太低或太高。温度太低比如0.1会导致输出过于确定容易陷入重复循环温度太高比如1.5会导致输出过于随机出现乱码。建议设在0.6到0.8之间。6.3 速度突然变慢如果之前跑得好好的突然速度掉了一半大概率是手机降频了。检查手机温度如果背面明显发烫那就是散热问题。停一会儿等温度降下来再跑。另一个可能是后台有其他应用在抢资源。Android的后台管理比较宽松有些应用会在后台偷偷跑计算任务。建议推理前清理一下后台或者开飞行模式减少网络相关的后台活动。6.4 常见问题速查表问题现象可能原因排查方法解决方案加载模型时崩溃内存不足查看logcat中的OOM信息换更小的模型或更低的量化精度输出乱码对话模板错误检查模型文档确认模板格式指定正确的chat template输出重复温度参数不当尝试调整温度值温度设在0.6-0.8之间速度突然下降芯片降频检查手机温度暂停推理等待降温首token延迟高上下文过长查看context设置减小上下文窗口推理中途中断后台被杀查看系统日志使用Foreground Service7. 开源项目推荐与选型建议7.1 推理框架类llama.cpp是目前最成熟的端侧推理框架社区活跃更新频繁支持几乎所有主流模型架构。缺点是纯CPU推理功耗较高但胜在稳定可靠。MLC-LLM支持GPU加速理论能效比更好但编译部署门槛高适合有编译经验的开发者。MLX是Apple生态的专属方案在iPhone和Mac上表现优秀但只支持Apple设备跨平台性差。Ollama虽然主要是桌面端方案但它的API设计很简洁可以作为手机端App的后端服务手机通过局域网调用。7.2 现成App类ChatterUI是我用得最多的Android端App界面简洁支持导入GGUF模型可以调整推理参数还支持多轮对话历史管理。PocketPal的UI更现代一些内置了模型下载功能不需要自己找模型文件适合新手快速体验。LM Playground偏向开发者向可以实时看到推理速度、内存占用等指标方便调优。iOS端的话MLX Chat是一个不错的起点基于MLX框架支持在iPhone上直接跑量化模型。7.3 模型资源类ModelScope上的模型镜像比较全国内下载速度快推荐优先使用。HuggingFace上的模型更新更及时但国内访问可能不稳定可以作为备选。选模型的时候注意看模型卡片上的说明确认是否支持GGUF格式、是否有现成的量化版本、对话模板是什么格式。这些信息决定了你能不能顺利跑起来。8. 我踩过的几个坑和最后的小建议第一个坑是盲目追求大参数。一开始我非要跑7B模型结果加载慢、生成慢、手机烫体验极差。后来换成1.5B速度上来了日常用完全够。模型大小和体验之间要平衡不是越大越好。第二个坑是忽略了对话模板。有次跑一个Llama模型输出全是重复的“好的好的好的”查了半天才发现是模板没设对。现在养成了习惯拿到新模型先看文档确认模板格式。第三个坑是没做内存回收。在App里反复加载模型测试结果跑了十几次之后OOM崩溃。后来改成全局单例只加载一次问题就解决了。如果你刚开始折腾我的建议是先用现成App跑通流程再考虑自己编译集成。ChatterUI加一个Qwen2.5-1.5B的GGUF文件十分钟就能体验到手机跑大模型的效果。有了直观感受之后再决定要不要深入折腾编译和集成。另外手机端LLM目前的定位是“离线小助手”适合做文本摘要、翻译、简单分类、格式转换这类任务。别指望它写长文、做复杂推理、或者替代云端大模型。把它当成一个随身携带的、不联网也能用的文本处理工具心态就对了。最后分享一个实用技巧如果你经常需要处理同类任务可以给模型写一个固定的系统提示词system prompt把任务要求、输出格式、注意事项都写进去。这样每次只需要输入待处理的内容模型就会按照预设的格式输出省去了重复描述需求的麻烦。我在做文本分类的时候就是这么干的效率提升很明显。
阅读完成 · 觉得有帮助?