当前位置: 首页 > news >正文

移动端调用大模型详解

🌟 大家好,我是“没事学AI”!
🤖 在AI的星辰大海里,我是那个执着的航海者,带着对智能的好奇不断探索。
📚 每一篇技术解析都是我打磨的罗盘,每一次模型实操都是我扬起的风帆。
💻 每一行代码演示都是我的航线记录,每一个案例拆解都是我的藏宝图绘制。
🚀 在人工智能的浪潮中,我既是领航员也是同行者。让我们一起,在AI学习的航程里,解锁更多AI的奥秘与可能——别忘了点赞、关注、收藏,跟上我的脚步,让“没事学AI”陪你从入门到精通!

目录

      • 一、端侧调用大模型支持的格式(iOS与安卓对比)
      • 二、格式的应用场景与核心区别
        • 1. `.onnx`格式(开放神经网络交换格式)
        • 2. `.tflite`格式(TensorFlow Lite专用格式)
        • 3. `.mlmodel/.mlpackage`格式(Core ML专用格式)
        • 4. `.mnn`格式(阿里MNN框架格式)
      • 三、技术实现(端侧本地调用)
        • (一)安卓端实现
          • 1. `.onnx`格式(基于ONNX Runtime)
          • 2. `.mnn`格式(基于MNN框架)
        • (二)iOS端实现
          • 1. `.mlmodel`格式(基于Core ML)
          • 2. `.onnx`格式(基于ONNX Runtime for iOS)

一、端侧调用大模型支持的格式(iOS与安卓对比)

移动端端侧调用大模型需依赖模型格式与硬件架构的兼容性,iOS和安卓支持的核心格式及对应框架如下:

模型格式安卓支持框架iOS支持框架核心依赖硬件加速
.onnxONNX RuntimeONNX Runtime安卓:ARM CPU/GPU(Vulkan);iOS:Metal GPU
.tfliteTensorFlow LiteTensorFlow Lite安卓:NNAPI;iOS:Core ML Delegate(间接调用ANE)
.mlmodel/.mlpackageCore MLiOS:ANE(苹果神经网络引擎)
.mnnMNN(阿里)安卓:ARM NEON/Vulkan

二、格式的应用场景与核心区别

1. .onnx格式(开放神经网络交换格式)
  • 应用场景
    中大型模型(7B-13B参数,量化后),如本地文档问答、代码补全、多轮对话。适合需要跨平台(安卓/iOS)部署、模型精度要求较高的场景(如医疗辅助诊断的本地推理)。
  • 核心优势
    跨框架兼容(支持PyTorch/TensorFlow模型转换),支持INT4/INT8量化,推理速度均衡,适合对兼容性要求高的复杂任务。
  • 局限性
    模型体积较大(7B参数INT4量化后约4GB),对移动端内存要求高(需6GB以上运存)。
2. .tflite格式(TensorFlow Lite专用格式)
  • 应用场景
    轻量级模型(<1B参数),如输入法智能补全、实时语音转文本、简单问答机器人(如儿童教育APP的离线互动)。
  • 核心优势
    体积小(1B参数INT8量化后约250MB),推理速度快(<300ms),适合资源受限的移动端,支持安卓/iOS跨平台。
  • 局限性
    复杂任务精度较低,中大型模型转换后性能损耗明显。
3. .mlmodel/.mlpackage格式(Core ML专用格式)
  • 应用场景
    苹果生态专属场景,如iPhone/iPad本地语音助手、照片内容生成(如相册智能分类+文案生成)、离线翻译。适合依赖低功耗、高性能的场景(如续航敏感的移动设备)。
  • 核心优势
    深度优化苹果硬件(ANE加速),推理延迟低(<200ms),功耗比其他格式低30%-50%。
  • 局限性
    仅支持iOS,需专门转换,兼容性差。
4. .mnn格式(阿里MNN框架格式)
  • 应用场景
    安卓高性能场景,如实时图像生成(如电商APP的虚拟试衣间)、多模态推理(图文结合的商品推荐)。
  • 核心优势
    针对ARM架构深度优化,推理速度比ONNX Runtime快10%-20%,支持动态shape输入。
  • 局限性
    仅支持安卓,生态较封闭,模型转换工具链较少。

三、技术实现(端侧本地调用)

(一)安卓端实现
1. .onnx格式(基于ONNX Runtime)

步骤

  1. 模型转换(PC端):用optimum将Hugging Face模型转为ONNX并量化(如Llama 3-8B→INT4)。
  2. 安卓集成:通过ONNX Runtime加载模型,实现推理。

代码实现

// 1. 依赖配置(app/build.gradle)
dependencies {implementation 'com.microsoft.onnxruntime:onnxruntime-android:1.16.3'implementation 'androidx.appcompat:appcompat:1.6.1'
}// 2. 模型管理类
import ai.onnxruntime.OrtEnvironment;
import ai.onnxruntime.OrtException;
import ai.onnxruntime.OrtSession;
import android.content.Context;
import java.io.File;
import java.util.Collections;public class ONNXModelRunner {private OrtEnvironment env;private OrtSession session;private Tokenizer tokenizer;// 初始化模型(从手机本地加载)public void init(Context context) throws OrtException, IOException {// 模型路径(假设已复制到/files目录)File modelFile = new File(context.getFilesDir(), "llama3-8b-int4.onnx");env = OrtEnvironment.getEnvironment();OrtSession.SessionOptions options = new OrtSession.SessionOptions();options.setIntraOpNumThreads(4); // 启用4线程options.enableVulkanAcceleration(); // 启用GPU加速(需设备支持)session = env.createSession(modelFile.getAbsolutePath(), options);// 初始化分词器(加载vocab.txt)tokenizer = new Tokenizer(new File(context.getFilesDir(), "vocab.txt"));}// 文本生成推理public String generate(String input) throws OrtException {// 分词:文本→token IDlong[] inputTokens = tokenizer.encode(input);// 构建输入TensorOrtSession.Result result = session.run(Collections.singletonMap("input_ids", ai.onnxruntime.Tensor.createTensor(env, inputTokens, new long[]{1, inputTokens.length})));// 解码:token ID→文本long[] outputTokens = (long[]) result.get("output_ids").getValue();return tokenizer.decode(outputTokens);}// 释放资源public void close() throws OrtException {session.close();env.close();}
}// 3. 分词器实现(核心逻辑)
class Tokenizer {private Map<String, Long> vocab;private Map<Long, String> reverseVocab;public Tokenizer(File vocabFile) throws IOException {// 加载词表(格式:"词 编号")vocab = new HashMap<>();List<String> lines = Files.readAllLines(vocabFile.toPath(), StandardCharsets.UTF_8);for (String line : lines) {String[] parts = line.split(" ");vocab.put(parts[0], Long.parseLong(parts[1]));}// 构建反向映射reverseVocab = vocab.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));}public long[] encode(String text) {// 简化实现:按空格分割(实际需用Hugging Face分词逻辑)String[] words = text.split(" ");long[] tokens = new long[words.length + 2];tokens[0] = 1; // 起始符<s>for (int i = 0; i < words.length; i++) {tokens[i + 1] = vocab.getOrDefault(words[i], 0L); // 未知词用0}tokens[tokens.length - 1] = 2; // 结束符</s>return tokens;}public String decode(long[] tokens) {StringBuilder sb = new StringBuilder();for (long token : tokens) {if (token == 1 || token == 2) continue; // 跳过特殊符sb.append(reverseVocab.getOrDefault(token, "[UNK]")).append(" ");}return sb.toString().trim();}
}// 4. 调用示例(Activity)
public class ONNXActivity extends AppCompatActivity {private ONNXModelRunner runner;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_onnx);// 复制模型到本地(首次运行)copyAssetsToFiles("llama3-8b-int4.onnx", "vocab.txt");// 初始化并推理try {runner = new ONNXModelRunner();runner.init(this);String result = runner.generate("请介绍ONNX格式的优势");Log.d("ONNX Result", result);} catch (Exception e) {e.printStackTrace();}}// 复制assets文件到/files目录private void copyAssetsToFiles(String... filenames) {new Thread(() -> {try {for (String filename : filenames) {InputStream in = getAssets().open(filename);File outFile = new File(getFilesDir(), filename);OutputStream out = new FileOutputStream(outFile);byte[] buffer = new byte[1024];int len;while ((len = in.read(buffer)) > 0) out.write(buffer, 0, len);in.close();out.close();}} catch (IOException e) {e.printStackTrace();}}).start();}@Overrideprotected void onDestroy() {super.onDestroy();try {runner.close();} catch (OrtException e) {e.printStackTrace();}}
}
2. .mnn格式(基于MNN框架)

代码实现

// 1. 依赖配置
dependencies {implementation 'com.aliyun.mnn:mnn:1.3.0'
}// 2. 模型管理类
import com.aliyun.mnn.MNNNetInstance;
import com.aliyun.mnn.Tensor;
import com.aliyun.mnn.MNNForwardType;public class MNNModelRunner {private MNNNetInstance instance;private MNNNetInstance.Session session;private Tokenizer tokenizer;public void init(Context context) {// 加载模型(启用GPU加速)String modelPath = new File(context.getFilesDir(), "multimodal-model.mnn").getAbsolutePath();MNNNetInstance.Config config = new MNNNetInstance.Config();config.forwardType = MNNForwardType.FORWARD_VULKAN; // Vulkan GPU加速instance = MNNNetInstance.createFromFile(modelPath, config);MNNNetInstance.SessionConfig sessionConfig = new MNNNetInstance.SessionConfig();sessionConfig.numThread = 4;session = instance.createSession(sessionConfig);// 初始化分词器tokenizer = new Tokenizer(new File(context.getFilesDir(), "vocab.txt"));}// 多模态推理(输入文本,输出文本)public String generate(String input) {int[] inputTokens = tokenizer.encodeInt(input); // 转为int型token// 输入Tensor配置Tensor inputTensor = Tensor.create(new int[]{1, inputTokens.length}, Tensor.DataType.INT32, session);inputTensor.copyFrom(inputTokens);session.input("input_ids", inputTensor);// 推理session.run();// 输出TensorTensor outputTensor = session.getOutput("output_ids");int[] outputTokens = outputTensor.getIntData();// 释放资源inputTensor.release();outputTensor.release();return tokenizer.decodeInt(outputTokens);}
}
(二)iOS端实现
1. .mlmodel格式(基于Core ML)

步骤

  1. 模型转换(PC端):用coremltools将Hugging Face模型转为.mlmodel(如Llama 3-8B→INT8)。
  2. iOS集成:Xcode导入模型,通过Core ML API调用。

代码实现(Swift)

// 1. 导入模型(拖入Xcode,自动生成Llama3_8b类)
import CoreML// 2. 模型管理类
class CoreMLModelRunner {private let model: Llama3_8bprivate let tokenizer: Tokenizerinit() throws {// 初始化模型guard let model = try? Llama3_8b(configuration: .init()) else {throw NSError(domain: "ModelError", code: 0)}self.model = model// 初始化分词器(加载vocab.txt)guard let vocabURL = Bundle.main.url(forResource: "vocab", withExtension: "txt") else {throw NSError(domain: "TokenizerError", code: 0)}tokenizer = try Tokenizer(vocabURL: vocabURL)}// 异步推理func generate(text: String) async throws -> String {// 1. 分词let inputTokens = try tokenizer.encode(text: text)// 2. 构建输入(Core ML要求MLMultiArray)let inputShape = [1, inputTokens.count] as [NSNumber]guard let inputArray = try? MLMultiArray(shape: inputShape, dataType: .int32) else {throw NSError(domain: "InputError", code: 0)}// 填充输入数据for (index, token) in inputTokens.enumerated() {inputArray[index] = token as NSNumber}let modelInput = Llama3_8bInput(input_ids: inputArray)// 3. 推理(利用ANE加速)let output = try await model.prediction(input: modelInput)// 4. 解码let outputTokens = output.output_ids as! [Int32]return try tokenizer.decode(tokens: outputTokens)}
}// 3. 分词器实现(Swift)
class Tokenizer {private var vocab: [String: Int32] = [:]private var reverseVocab: [Int32: String] = [:]init(vocabURL: URL) throws {let content = try String(contentsOf: vocabURL, encoding: .utf8)let lines = content.components(separatedBy: .newlines)for line in lines {let parts = line.components(separatedBy: .whitespaces)if parts.count == 2, let id = Int32(parts[1]) {vocab[parts[0]] = idreverseVocab[id] = parts[0]}}}func encode(text: String) throws -> [Int32] {let words = text.components(separatedBy: .whitespaces)var tokens: [Int32] = [1] // 起始符for word in words {tokens.append(vocab[word] ?? 0)}tokens.append(2) // 结束符return tokens}func decode(tokens: [Int32]) throws -> String {var text = ""for token in tokens {guard token != 1, token != 2 else { continue }text += reverseVocab[token] ?? "[UNK]"text += " "}return text.trimmingCharacters(in: .whitespaces)}
}// 4. 调用示例(ViewController)
class CoreMLViewController: UIViewController {private var runner: CoreMLModelRunner!override func viewDidLoad() {super.viewDidLoad()do {runner = try CoreMLModelRunner()Task {let result = try await runner.generate(text: "介绍Core ML的优势")print("Core ML Result: \(result)")}} catch {print("Error: \(error)")}}
}
2. .onnx格式(基于ONNX Runtime for iOS)

代码实现(Swift)

// 1. 依赖配置(Podfile)
// pod 'ONNXRuntime'import ONNXRuntimeclass ONNXiOSRunner {private let env: ORTEnvironmentprivate let session: ORTSessionprivate let tokenizer: Tokenizerinit(modelName: String) throws {env = try ORTEnvironment(loggingLevel: .error)// 加载模型(从bundle)guard let modelURL = Bundle.main.url(forResource: modelName, withExtension: "onnx") else {throw NSError(domain: "ModelError", code: 0)}let options = ORTSessionOptions()try options.setIntraOpNumThreads(4)try options.enableMetalAcceleration() // GPU加速session = try ORTSession(environment: env, modelPath: modelURL.path, options: options)// 初始化分词器guard let vocabURL = Bundle.main.url(forResource: "vocab", withExtension: "txt") else {throw NSError(domain: "TokenizerError", code: 0)}tokenizer = try Tokenizer(vocabURL: vocabURL)}func generate(text: String) throws -> String {let inputTokens = try tokenizer.encode(text: text)let inputShape: [NSNumber] = [1, NSNumber(value: inputTokens.count)]let inputTensor = try ORTTensor(data: inputTokens,shape: inputShape,elementType: .int64,environment: env)> 🌈 我是“没事学AI”!要是这篇文章让你学 AI 的路上有了点收获:
👁️ 【关注】跟我一起挖 AI 的各种门道,看看它还有多少新奇玩法等着咱们发现
👍 【点赞】为这些有用的 AI 知识鼓鼓掌,让更多人知道学 AI 也能这么轻松
🔖 【收藏】把这些 AI 小技巧存起来,啥时候想练手了,翻出来就能用
💬 【评论】说说你学 AI 时的想法和疑问,让大家的思路碰出更多火花
学 AI 的路还长,咱们结伴同行,在 AI 的世界里找到属于自己的乐趣和成就!
http://www.dtcms.com/a/327115.html

相关文章:

  • 【运维进阶】Ansible 自动化
  • 西门子 S7-200 与 S7-1200 借 PPI 以太网模块通讯,赋能食品行业进步
  • 【pxe】通过pxe批量安装centos系统(传统Legacy启动+uefi启动)
  • Neo4j Cypher语句
  • 淘宝API列表:高效获取商品详情图主图商品视频参数item_get
  • 微前端 + Docker + Kubernetes 运作机制
  • 【51单片机定时器流水灯】2022-10-28
  • Docker使用----(安装_Windows版)
  • Go语言实战案例:使用Gin框架构建Hello API
  • windows单机单卡+CIFAR-10数据集+Docker模拟训练
  • 快速了解自然语言处理
  • 《Redis慢查询日志操作:SLOWLOG GET/CONFIG等命令的分析方法》
  • 计算机视觉(4)-相机基础知识恶补
  • 前端css学习笔记3:伪类选择器与伪元素选择器
  • 【shell脚本编程】-4 shell脚本编写冒泡排序
  • Redis命令大全
  • 新型Windows RPC攻击可劫持服务并完全攻陷Active Directory,PoC已公开
  • C++——模板初阶
  • 企业培训笔记:宠物信息管理--实现宠物信息的添加
  • 计算机毕设不知道选什么题目?基于Spark的糖尿病数据分析系统【Hadoop+Spark+python】
  • 多语言与隐形攻击:LLM安全防线为何被频频突破?
  • 雪花算法snowflake分布式id生成原理详解,以及对解决时钟回拨问题几种方案讨论
  • 跨设备开发不再难:HarmonyOS 分布式任务管理应用全解析
  • 【web站点安全开发】任务2:HTML5核心特性与元素详解
  • 树:数据结构中的层次架构
  • 【后端】Spring @Resource和@Autowired的用法和区别
  • 一键生成 Android 适配不同分辨率尺寸的图片
  • [GESP202309 六级] 2023年9月GESP C++六级上机题题解,附带讲解视频!
  • Airtable 入门指南:从创建项目到基础数据分析与可视化
  • 修复图像、视频和3D场景的AI工具–Inpaint Anything