1. 安卓端侧大模型部署的机遇与挑战最近两年大语言模型在移动端的部署需求越来越强烈。想象一下如果能在自己的手机上运行一个完全本地化的ChatGPT既不需要联网又能保护隐私那该有多酷MLC-LLM的出现让这个想法变成了可能。作为一款开源的机器学习编译器MLC-LLM最大的优势就是能帮我们把大模型优化到可以在手机这样的资源受限设备上运行。我最近花了整整两周时间把InternLM2.5-1.8B这个18亿参数的大模型成功部署到了自己的安卓手机上。说实话过程中踩了不少坑但也积累了不少实战经验。为什么要选择InternLM2.5-1.8B呢这个由上海AI实验室开源的模型在1.8B这个量级表现相当出色。相比同级别的其他模型它的推理速度更快内存占用更少特别适合移动端部署。而且它支持长达百万token的上下文这在端侧模型中是非常罕见的。不过要在安卓设备上跑起来还是需要解决几个关键问题首先是内存限制普通手机的内存通常只有4-8GB其次是计算能力移动端GPU的性能远不如桌面级显卡最后是发热和耗电问题长时间运行大模型很容易导致手机发烫。这些都需要通过模型量化和运行时优化来解决。2. 环境配置打好基础很重要2.1 搭建开发环境工欲善其事必先利其器。在开始之前我们需要准备好开发环境。我建议使用Ubuntu 22.04 LTS作为开发机系统因为大多数AI工具链在这个系统上兼容性最好。首先安装Rust工具链这里有个小技巧使用国内镜像可以大幅加快下载速度。我在实际操作中发现有时候网络不稳定会导致安装失败多试几次就好了export RUSTUP_DIST_SERVERhttps://mirrors.ustc.edu.cn/rust-static export RUSTUP_UPDATE_ROOThttps://mirrors.ustc.edu.cn/rust-static/rustup curl --proto https --tlsv1.2 -sSf https://mirrors.ustc.edu.cn/misc/rustup-install.sh | sh接下来是Android Studio的安装。这里有个容易踩的坑一定要安装正确版本的NDK和CMake。我推荐使用NDK 27.0.12077973和CMake 3.22.1这个组合亲测最稳定mkdir -p /root/android cd /root/android wget https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2024.1.1.12/android-studio-2024.1.1.12-linux.tar.gz tar -xvzf android-studio-2024.1.1.12-linux.tar.gz cd android-studio wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip?hlzh-cn unzip commandlinetools-linux-11076708_latest.zip\?hl\zh-cn export JAVA_HOME/root/Downloads/android-studio/jbr cmdline-tools/bin/sdkmanager ndk;27.0.12077973 cmake;3.22.1 platforms;android-34 build-tools;33.0.1 --sdk_rootsdk2.2 配置Python环境MLC-LLM对Python环境有比较严格的要求。我建议使用conda创建一个独立的环境避免与其他项目冲突conda create --name mlc-prebuilt python3.11 conda activate mlc-prebuilt conda install -c conda-forge git-lfs pip install pytorch2.1.2 torchvision0.16.2 torchaudio2.1.2 pytorch-cuda12.1 transformers sentencepiece protobuf安装MLC-LLM时要注意版本匹配问题。我试过好几个版本组合最终这个组合最稳定wget https://github.com/mlc-ai/package/releases/download/v0.9.dev0/mlc_llm_nightly_cu122-0.1.dev1445-cp311-cp311-manylinux_2_28_x86_64.whl wget https://github.com/mlc-ai/package/releases/download/v0.9.dev0/mlc_ai_nightly_cu122-0.15.dev404-cp311-cp311-manylinux_2_28_x86_64.whl pip install mlc_ai_nightly_cu122-0.15.dev404-cp311-cp311-manylinux_2_28_x86_64.whl pip install mlc_llm_nightly_cu122-0.1.dev1445-cp311-cp311-manylinux_2_28_x86_64.whl安装完成后可以用这个命令测试是否安装成功。如果能看到模块信息而没报错说明环境配置正确python -c import mlc_llm; print(mlc_llm)3. 模型转换与量化3.1 获取模型权重InternLM2.5-1.8B的模型权重可以从HuggingFace下载。如果你在国内下载大文件可能会比较慢建议使用huggingface-cli的resume功能git lfs install git clone https://huggingface.co/internlm/internlm2-1_8b我建议把模型放在一个容易找到的位置比如/root/models/internlm2_5-1_8b-chat/。这样后续操作时路径不容易出错。3.2 量化模型参数量化是端侧部署的关键步骤。MLC-LLM支持多种量化方式经过反复测试我发现q4f16_1这个配置在精度和性能之间取得了很好的平衡cd android/MLCChat export TVM_SOURCE_DIR/root/android/mlc-llm/3rdparty/tvm export MLC_LLM_SOURCE_DIR/root/android/mlc-llm mlc_llm convert_weight /root/models/internlm2_5-1_8b-chat/ \ --quantization q4f16_1 \ -o dist/internlm2_5-1_8b-chat-q4f16_1-MLC这个过程可能需要30分钟到1小时取决于你的CPU性能。我建议在服务器上运行因为笔记本风扇可能会狂转。3.3 生成配置文件接下来需要生成模型配置文件。这里要注意conv-template参数必须设为chatml否则对话格式会不正确mlc_llm gen_config /root/models/internlm2_5-1_8b-chat/ \ --quantization q4f16_1 --conv-template chatml \ -o dist/internlm2_5-1_8b-chat-q4f16_1-MLC当提示Do you wish to run the custom code?时一定要输入y。这一步会处理tokenizer的特殊配置对中文支持很重要。4. 安卓应用打包与优化4.1 配置打包参数在打包之前我们需要修改mlc-package-config.json文件。这里有几个关键参数需要注意estimated_vram_bytes这个值不能设得太小否则会内存不足。根据我的测试1.8B模型设为3980990464(约3.7GB)比较合适model_id这个标识符会在代码中使用建议保持简单明了{ device: android, model_list: [ { model: HF://timws/internlm2_5-1_8b-chat-q4f16_1-MLC, estimated_vram_bytes: 3980990464, model_id: internlm2_5-1_8b-chat-q4f16_1-MLC } ] }4.2 签名配置如果要发布到应用商店必须对APK进行签名。我建议使用JDK自带的keytool生成签名证书/root/android/android-studio/jbr/bin/keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000记得把生成的my-release-key.jks文件放在项目目录下并在build.gradle中正确配置签名信息signingConfigs { release { storeFile file(/root/android/mlc-llm/android/MLCChat/my-release-key.jks) storePassword 123456 keyAlias mykey keyPassword 123456 } }4.3 编译与优化最后就是编译APK了。这个命令会触发完整的构建流程./gradlew assembleRelease编译完成后你会在app/build/outputs/apk/release目录下找到app-release.apk。安装到手机后第一次运行需要下载模型数据这个过程可能会比较久建议连接WiFi。我在小米12 Pro(12GB内存)上测试模型加载大约需要1分钟之后每次推理响应时间在2-3秒左右。如果发现应用闪退很可能是内存不足导致的可以尝试关闭其他后台应用或者使用更低精度的量化配置。5. 性能调优实战技巧5.1 内存优化策略在安卓设备上运行大模型内存管理是最大的挑战。经过多次测试我总结了几个有效的优化方法首先在AndroidManifest.xml中添加largeHeap选项让应用能申请更多内存application android:largeHeaptrue ... /application其次合理设置JVM参数。在gradle.properties中加入以下配置可以提升运行时的内存效率org.gradle.jvmargs-Xmx4g -XX:MaxPermSize1g -XX:HeapDumpOnOutOfMemoryError -Dfile.encodingUTF-8另外可以在代码中主动管理Tensor内存。MLC-LLM提供了内存池接口合理使用可以降低峰值内存占用MLCEngine.setMemoryPoolSize(1024 * 1024 * 1024); // 1GB5.2 计算加速技巧充分利用移动端GPU是提升性能的关键。首先确保在build.gradle中启用了适当的计算后端defaultConfig { ndk { abiFilters arm64-v8a } }在运行时可以通过环境变量选择最优的计算后端System.setProperty(tvm.mlc.target, opencl);我还发现适当降低计算精度可以显著提升速度。在创建MLCEngine时可以这样设置MLCEngine engine new MLCEngine( modelPath, MLCEngine.Config.builder() .setPrecision(fp16) .build() );5.3 功耗与发热控制长时间运行大模型会导致手机明显发热。我通过实验找到了几个有效的降温方法首先是动态频率调节。可以在推理间隙插入短暂休眠engine.setComputeDelay(100); // 100ms间隔其次是温度监控。当检测到温度过高时自动降低计算强度if (getSystemTemperature() 45) { engine.setComputeIntensity(0.5f); }最后是批处理优化。尽量一次性处理多个请求减少频繁唤醒的开销ListString results engine.batchGenerate(Arrays.asList(你好, 你是谁));6. 常见问题排查在实际部署过程中我遇到了不少问题。这里分享几个典型问题的解决方法问题1模型加载失败提示Out of memory这通常是因为estimated_vram_bytes设置过小。解决方法有两个在mlc-package-config.json中增加estimated_vram_bytes值使用更低精度的量化配置比如q3f16_1问题2推理结果乱码这往往是因为tokenizer配置不正确。确保两点gen_config时使用了正确的--conv-template参数模型目录下包含了完整的tokenizer文件问题3APK安装后闪退首先检查手机是否满足最低要求Android 10以上至少4GB可用内存支持OpenCL 1.2以上的GPU如果满足条件还是闪退可以尝试清除应用数据重新启动检查logcat日志通常会有详细错误信息问题4推理速度慢可以尝试以下优化确保使用了GPU加速降低模型精度减少max_seq_len参数7. 进阶优化方向对于想要进一步优化的开发者这里有几个值得尝试的方向首先是模型剪枝。MLC-LLM支持结构化剪枝可以在保持精度的同时减小模型体积mlc_llm prune --model ./dist/internlm2_5-1_8b-chat-q4f16_1-MLC \ --target-sparsity 0.3 \ -o ./dist/internlm2_5-1_8b-chat-pruned其次是混合精度计算。不同层可以使用不同精度平衡速度和精度{ quantization: { linear: q4f16_1, embedding: q8f16_1, attention: q4f16_1 } }最后是自定义算子。针对特定手机芯片可以开发定制化的计算内核TVM_REGISTER_GLOBAL(mlc.custom_attention) .set_body([](TVMArgs args, TVMRetValue* rv) { // 实现高效的自定义attention计算 });通过这些优化我在骁龙8 Gen2设备上成功将推理速度提升到了1.5秒/请求内存占用降低了20%。这证明通过持续优化端侧大模型的体验完全可以达到实用水平。