边缘 AI 部署——移动端和嵌入式设备的大模型
边缘 AI 部署——移动端和嵌入式设备的大模型
适读人群:对端侧 AI 感兴趣的工程师 | 阅读时长:约13分钟 | 核心价值:搞清楚边缘 AI 的真实能力边界,不被宣传忽悠
前几个月我买了一块树莓派 5,想自己试试本地跑模型是什么感觉。网上各种帖子说"树莓派可以跑大模型",我半信半疑。
实际跑下来,我的感受是:能跑,但你得先搞清楚"能跑"和"好用"是两回事。
这篇文章是我实际折腾之后的观察,加上我对 iOS/Android 端侧推理的调研。不会只讲好的,也不会劝退,就说真实情况。
先说树莓派 5 跑 llama.cpp
树莓派 5 的配置:Cortex-A76 四核 CPU,4GB 或 8GB RAM,没有 GPU。
跑模型用 llama.cpp,这是目前在 CPU 上跑 LLM 最成熟的方案。
安装和基础使用:
# 在树莓派上编译 llama.cpp
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make -j4 # 树莓派 5 有4核,用上
# 下载一个小模型测试,用 Q4_K_M 量化版本
# Qwen2.5-0.5B-Instruct GGUF 文件大约 400MB
wget https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct-GGUF/resolve/main/qwen2.5-0.5b-instruct-q4_k_m.gguf
# 运行推理
./llama-cli \
-m ./qwen2.5-0.5b-instruct-q4_k_m.gguf \
-p "你好,给我讲一个笑话" \
-n 200 \
--temp 0.7 \
-t 4 # 使用4个线程我的实测速度数据(树莓派 5,8GB 版本):
模型 大小 量化 速度(token/s)
----------------------------------------------------------------------
Qwen2.5-0.5B-Instruct ~400MB Q4_K_M 约 8-10 t/s
Qwen2.5-1.5B-Instruct ~1.1GB Q4_K_M 约 3-4 t/s
Phi-3.5-mini-instruct ~2.4GB Q4_K_M 约 1.5-2 t/s
Llama-3.2-3B-Instruct ~2.0GB Q4_K_M 约 1-1.5 t/s
7B 量级的模型(如 Qwen2.5-7B) ~4.5GB Q4_K_M 内存不够,跑不起来树莓派 5 的 8GB 内存能装下 4GB 左右的模型(系统和其他程序也要占用内存)。跑 0.5B 的小模型,速度勉强能接受,跑 3B 的模型,1-2 token/s,体验比较差。
说个直观的比较:人正常说话速度大约是每秒 3-4 个汉字,1 token/s 的速度大概是正常对话速度的 1/3,会有明显的等待感。
量化对效果的影响
量化是边缘 AI 的核心技术,用低位数表示模型权重,换来更小的体积和更快的速度。
常见量化格式对比:
量化格式 位数 体积比例 质量损失 说明
Q8_0 8bit ~100% 极小 接近原始精度
Q6_K 6bit ~75% 很小 平衡方案
Q4_K_M 4bit ~50% 小-中 最常用
Q4_0 4bit ~50% 中 比 Q4_K_M 略差
Q3_K_M 3bit ~37% 明显 小模型不建议
Q2_K 2bit ~25% 大 通常不可接受实际跑下来,Q4_K_M 是甜蜜点。对于 1.5B 以上的模型,Q4_K_M 相比 Q8_0 的质量差距在日常对话任务上基本感知不到,但体积能省一半。
对于 0.5B 这种小模型,量化的副作用更明显——本来模型容量就有限,再用低精度表示,质量下降会更明显。0.5B 模型建议用 Q6_K 或 Q8_0,别贪图更小的量化格式。
可以用这个命令测试不同量化格式的速度:
# 跑一个性能基准测试
./llama-bench \
-m ./model.gguf \
-p 512 \ # prompt 长度
-n 128 \ # 生成 token 数
-t 4 \ # 线程数
-r 3 # 重复3次取平均iOS 端侧推理:Core ML
苹果的 Neural Engine 是目前消费级设备里边缘 AI 能力最强的。A17 Pro 的 Neural Engine 理论算力达到 35 TOPS,M 系列芯片更强。
iOS 上跑端侧模型主要有两条路:
方案一:Core ML + Apple Intelligence 框架
苹果官方推荐路线,模型需要转成 Core ML 格式(.mlpackage):
# 把 HuggingFace 模型转成 Core ML(在 Mac 上做转换)
import coremltools as ct
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
# 加载模型(小模型,比如 Phi-3-mini)
model_id = "microsoft/Phi-3-mini-4k-instruct"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.float16)
# 转换为 Core ML
# 注意:直接转换 LLM 比较复杂,实际项目建议用 apple/corenet 或 mlx-lm
# 这里展示概念,实际使用更推荐 mlx-lm 框架实际项目里,我更推荐用苹果的 mlx-lm 框架(在 Apple Silicon Mac 上)或直接用已经转好的 Core ML 模型:
// iOS 端调用 Core ML 模型示例
import CoreML
import NaturalLanguage
class LocalLLMService {
private var model: MLModel?
func loadModel() async throws {
let config = MLModelConfiguration()
config.computeUnits = .cpuAndNeuralEngine // 优先用 Neural Engine
// 加载已转换的 .mlpackage
guard let modelURL = Bundle.main.url(
forResource: "Phi3Mini", withExtension: "mlpackage"
) else {
throw ModelError.notFound
}
model = try await MLModel.load(contentsOf: modelURL, configuration: config)
}
func generate(prompt: String) async throws -> String {
// 实际推理逻辑依赖具体模型的输入输出格式
// 这里是伪代码示意
guard let model = model else { throw ModelError.notLoaded }
let input = try MLDictionaryFeatureProvider(dictionary: [
"input_ids": MLMultiArray(/* tokenized input */)
])
let output = try await model.prediction(from: input)
// 解码输出...
return ""
}
}方案二:llama.cpp 的 iOS 版本
有人把 llama.cpp 编译成了 iOS 库,可以直接在 iOS app 里用:
// 使用 LLM Farm 或自编译的 llama.cpp iOS 版本
// GitHub: guinmoon/LLMFarm 是一个封装好的开源 iOS app 可以参考
// 核心是把 llama.cpp 的 C/C++ 代码通过 Xcode 编译进 iOS 项目
// 然后用 Swift 包装调用iPhone 15 Pro 跑 Q4_K_M 量化的 Phi-3-mini(3.8B)的实测速度大约在 15-20 token/s,已经是可以流畅对话的速度。
Android 端侧推理:NNAPI 和 MediaPipe
Android 的端侧 AI 生态比 iOS 更分散,因为硬件差异太大。
主流方案是 Android 的 NNAPI(Neural Networks API),硬件厂商通过驱动实现加速:
// 使用 LiteRT(原 TensorFlow Lite)+ NNAPI 加速
import org.tensorflow.lite.Interpreter
import org.tensorflow.lite.gpu.GpuDelegate
import org.tensorflow.lite.nnapi.NnApiDelegate
class LocalModelInference(private val context: Context) {
private var interpreter: Interpreter? = null
fun initialize(modelPath: String) {
val options = Interpreter.Options().apply {
// 优先尝试 NNAPI 加速
try {
val nnApiDelegate = NnApiDelegate()
addDelegate(nnApiDelegate)
} catch (e: Exception) {
// NNAPI 不可用时降级到 GPU
try {
val gpuDelegate = GpuDelegate()
addDelegate(gpuDelegate)
} catch (e2: Exception) {
// 最终降级到 CPU
setNumThreads(4)
}
}
}
val modelBuffer = loadModelFile(modelPath)
interpreter = Interpreter(modelBuffer, options)
}
private fun loadModelFile(path: String): ByteBuffer {
val assetManager = context.assets
val fileDescriptor = assetManager.openFd(path)
val inputStream = FileInputStream(fileDescriptor.fileDescriptor)
val fileChannel = inputStream.channel
return fileChannel.map(
FileChannel.MapMode.READ_ONLY,
fileDescriptor.startOffset,
fileDescriptor.declaredLength
)
}
}Google 的 MediaPipe LLM Inference API 是另一个选择,封装得更高,直接支持 Gemma 等模型:
// MediaPipe LLM Inference(Gemma 2B 端侧版本)
import com.google.mediapipe.tasks.genai.llminference.LlmInference
val options = LlmInference.LlmInferenceOptions.builder()
.setModelPath("/path/to/gemma-2b-it-cpu-int4.bin")
.setMaxTokens(1024)
.setTopK(40)
.setTemperature(0.8f)
.setRandomSeed(101)
.build()
val llmInference = LlmInference.createFromOptions(context, options)
val result = llmInference.generateResponse("请用一句话介绍你自己")边缘 AI 的真实应用场景
说完技术,说说什么场景真的适合用边缘 AI,什么不适合。
适合的场景:
隐私敏感的本地处理:医疗记录摘要、日记分析、私人文档问答。数据不出设备,隐私保护最强。
离线可用需求:工业设备检测、农业场景(网络差的地方)、飞行模式下的辅助功能。
低延迟要求 + 请求量大:语音唤醒词检测、实时图像分类。这些本来就用小模型,边缘完全够用。
成本敏感的高频小任务:如果你有个 App 每天要处理几十万次简单的文本分类,全部走 API 成本很高,边缘可以扛住大部分请求。
不适合的场景:
复杂推理任务:边缘设备跑的模型通常是 1-3B 量级,复杂的多步推理、代码生成、长文档理解效果差很多。
需要最新知识的任务:端侧模型训练数据有截止,没法实时更新。
追求最佳效果的对话产品:如果你的产品核心竞争力是 AI 对话质量,用云端的大模型,别在端侧凑合。
现实期望
我理解一些同学对边缘 AI 很兴奋,觉得"以后不用交 API 费用了"。这个想法我不完全认同。
边缘 AI 的优势是隐私、离线、低延迟、零 API 成本。劣势是效果受限、部署麻烦、设备要求高。
它不是云端大模型的替代品,是补充。两者解决不同的问题。
树莓派跑 0.5B 的模型,能做一个不用联网的智能家居控制器,能做语音命令解析,这些场景它完全够用。但让它做一个高质量的技术问答助手,别为难它了。
边缘 AI 是个值得关注的方向,但要根据你的实际需求判断值不值得投入,而不是因为概念热就跟风。
