LLM端侧部署系列 | 如何将阿里千问大模型Qwen部署到手机上?实战演示(下篇)

news2025/1/16 12:55:57
  • 引言

  • 简介

  • 编译Android可用的模型

    • 转换权重

    • 生成配置文件

    • 模型编译

  • 编译apk

    • 修改配置文件

    • 绑定android library

    • 配置gradle

    • 编译apk

  • 手机上运行

    • 安装 APK

    • 植入模型

    • 效果实测

0. 引言

清明时节雨纷纷,路上行人欲断魂。

小伙伴们好,我是《小窗幽记机器学习》的小编:卖青团的小女孩,紧接前文LLM系列。今天这篇小作文主要介绍如何将阿里巴巴的千问大模型Qwen 1.8B部署到手机端,实现离线、断网条件下使用大模型。主要包括以下几个步骤:

  1. 编译Android手机可以使用的Qwen模型

  2. 编译打包APK,为Qwen在Android手机上运行提供用户交互界面

  3. 安装APK和效果实测

如需与小编进一步交流,可以在《小窗幽记机器学习》上添加小编好友。

1. 简介

为将Qwen大模型部署到手机,实现断网下Qwen模型正常使用,本文选择MLC-LLM框架。

MLC LLM(机器学习编译大型语言模型,Machine Learning Compilation for Large Language Models) 是一种高性能的通用部署解决方案,将任何语言模型本地化部署在各种硬件后端和本机应用程序上,并为每个人提供一个高效的框架,以进一步优化自己模型性能。该项目的使命是使每个人都能够使用ML编译技术在各种设备上本机开发、优化和部署AI模型。

以下将以Qwen1.5-1.8B-Chat为例,详细说明如何利用mlc-llm将该模型部署到Android手机上,最终实现每秒约20个token的生成速度。以下命令执行都在mlc-llm的目类下执行。囿于篇幅,将在后文,以上篇名义补充介绍对应的环境安装和配置等工作。

2. 编译Android可用模型

MODEL_NAME=Qwen1.5-1.8B-Chat
QUANTIZATION=q4f16_1

2.1 权重转换

# convert weights
mlc_llm convert_weight /share_model_zoo/LLM/Qwen/$MODEL_NAME/ --quantization $QUANTIZATION -o dist/$MODEL_NAME-$QUANTIZATION-MLC/

通过上述命令,将hf格式的Qwen模型转为mlc-llm支持的模型格式,结果文件存于:dist/Qwen1.5-1.8B-Chat-q4f16_1-MLC

2.2 生成配置文件

# 生成配置文件

mlc_llm gen_config /share_model_zoo/LLM/Qwen/$MODEL_NAME/ --quantization $QUANTIZATION --model-type qwen2 --conv-template chatml --context-window-size 4096 -o dist/${MODEL_NAME}-${QUANTIZATION}-MLC/

此时生成的配置文件dist/Qwen1.5-1.8B-Chat-q4f16_1-MLC/mlc-chat-config.json信息:

{
  "model_type": "qwen2",
  "quantization": "q4f16_1",
  "model_config": {
    "hidden_act": "silu",
    "hidden_size": 2048,
    "intermediate_size": 5504,
    "num_attention_heads": 16,
    "num_hidden_layers": 24,
    "num_key_value_heads": 16,
    "rms_norm_eps": 1e-06,
    "rope_theta": 1000000.0,
    "vocab_size": 151936,
    "context_window_size": 4096,
    "prefill_chunk_size": 4096,
    "tensor_parallel_shards": 1,
    "head_dim": 128,
    "dtype": "float32"
  },
  "vocab_size": 151936,
  "context_window_size": 4096,
  "sliding_window_size": -1,
  "prefill_chunk_size": 4096,
  "attention_sink_size": -1,
  "tensor_parallel_shards": 1,
  "mean_gen_len": 128,
  "max_gen_len": 512,
  "shift_fill_factor": 0.3,
  "temperature": 0.7,
  "presence_penalty": 0.0,
  "frequency_penalty": 0.0,
  "repetition_penalty": 1.1,
  "top_p": 0.8,
  "conv_template": {
    "name": "chatml",
    "system_template": "<|im_start|>system\n{system_message}",
    "system_message": "A conversation between a user and an LLM-based AI assistant. The assistant gives helpful and honest answers.",
    "add_role_after_system_message": true,
    "roles": {
      "user": "<|im_start|>user",
      "assistant": "<|im_start|>assistant"
    },
    "role_templates": {
      "user": "{user_message}",
      "assistant": "{assistant_message}",
      "tool": "{tool_message}"
    },
    "messages": [],
    "seps": [
      "<|im_end|>\n"
    ],
    "role_content_sep": "\n",
    "role_empty_sep": "\n",
    "stop_str": [
      "<|im_end|>"
    ],
    "stop_token_ids": [
      2
    ],
    "function_string": "",
    "use_function_calling": false
  },
  "pad_token_id": 151643,
  "bos_token_id": 151643,
  "eos_token_id": [
    151645,
    151643
  ],
  "tokenizer_files": [
    "tokenizer.json",
    "vocab.json",
    "merges.txt",
    "tokenizer_config.json"
  ],
  "version": "0.1.0"
}

2.3 模型编译

# 进行模型编译:

# 2. compile: compile model library with specification in mlc-chat-config.json

mkdir dist/libs

mlc_llm compile ./dist/${MODEL_NAME}-${QUANTIZATION}-MLC/mlc-chat-config.json --device android -o ./dist/libs/${MODEL_NAME}-${QUANTIZATION}-android.tar

生成dist/libs/Qwen1.5-1.8B-Chat-q4f16_1-android.tar文件。

3. 编译apk

3.1 修改配置文件

# Configure list of models
vim ./android/library/src/main/assets/app-config.json

./android/library/src/main/assets/app-config.json改为:

{
  "model_list": [
    {
      "model_url": "https://huggingface.co/Qwen/Qwen1.5-1.8B-Chat",
      "model_lib": "qwen2_q4f16_1",
      "estimated_vram_bytes": 4348727787,
      "model_id": "Qwen1.5-1.8B-Chat-q4f16_1"  # 手机上模型目录要跟这个一致,不然无法加载
    }
  ],
  "model_lib_path_for_prepare_libs": {
    "qwen2_q4f16_1": "libs/Qwen1.5-1.8B-Chat-q4f16_1-android.tar"
  }
}

3.2 绑定android library

需要查看以下系统变量:

echo $ANDROID_NDK   # Android NDK toolchain
echo $TVM_NDK_CC   # Android NDK clang
echo $JAVA_HOME    # Java
export TVM_HOME=/share/Repository/mlc-llm/3rdparty/tvm # mlc-llm 中的 tvm 目类
echo $TVM_HOME     # TVM Unity runtime

是否符合预期。

# Bundle model library
cd ./android/library
./prepare_libs.sh

上述脚本会基于rustup安装aarch64-linux-android,如果比较慢,可以进行如下配置:

export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup
export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup

再执行上述脚本。

3.3 配置gradle

修改android/gradle/wrapper/gradle-wrapper.properties, 将原始的内容:

#Thu Jan 25 10:19:50 EST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

可以看出,gradle-8.5-bin.zip的路径是:android/gradle/wrapper/dist/gradle-8.5-bin.zip

这里需要注意,wrapper/dists的完整路径其实是/root/.gradle/wrapper/dists修改为:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=dist/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

需要注意,distributionUrl 这个的base目录其实是mlc-llm目录下的android/gradle/wrapper

3.4 编译apk

# Build android app
cd .. && ./gradlew assembleDebug

编译生成的Android apk 文件位于:app/build/outputs/apk/debug/app-debug.apk

4. 手机实测

4.1 安装 APK

将手机设置成debug模式,数据线连接手机,正常连接之后在电脑执行以下命令,将上面编译出的apk安装到Android手机上:

adb install app-debug.apk

PS: 需要预先在本机电脑上安装 adb 命令。

4.2 植入模型

# 改名,从而适配之前的配置信息
mv Qwen1.5-1.8B-Chat-q4f16_1-MLC Qwen1.5-1.8B-Chat-q4f16_1

# 将模型文件推送到手机的 /data/local/tmp/ 目类
adb push Qwen1.5-1.8B-Chat-q4f16_1 /data/local/tmp/

adb shell "mkdir -p /storage/emulated/0/Android/data/ai.mlc.mlcchat/files/"

adb shell "mv /data/local/tmp/Qwen1.5-1.8B-Chat-q4f16_1 /storage/emulated/0/Android/data/ai.mlc.mlcchat/files/"

4.3 聊天实测

实测大约1s可以生成20个token。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1569506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS-App:App Store新的审核政策,在应用隐私清单中声明和解释使用特定API的原因

App Store新的审核政策&#xff0c;在应用隐私清单中声明和解释使用特定API的原因 设备/引擎&#xff1a;Mac&#xff08;11.6&#xff09;/Mac Mini 开发工具&#xff1a;终端 开发需求&#xff1a;苹果官方邮件通知&#xff0c; App Store新的审核政策&#xff0c;在应用隐…

Transformer学习: Transformer小模块学习--位置编码,多头自注意力,掩码矩阵

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Transformer学习 1 位置编码模块1.1 PE代码1.2 测试PE1.3 原文代码 2 多头自注意力模块2.1 多头自注意力代码2.2 测试多头注意力 3 未来序列掩码矩阵3.1 代码3.2 测试掩码 1 …

绿联 安装halo博客,使用MySQL数据库

绿联 安装halo博客&#xff0c;使用MySQL数据库 1、镜像 halohub/halo:2 halo2系列已支持halohub/halo:2直接拉取最新版本&#xff0c;因此更新容器可以使用相同镜像重新编辑的方式进行升级。 安装前准备&#xff1a; 绿联 安装Mysql 5.7版本数据库 绿联 安装phpmyadmin管理M…

基本线段树以及相关例题

1.线段树的概念 线段树是一种二叉树&#xff0c;也就是对于一个线段&#xff0c;我们会用一个二叉树来表示。 这个其实就是一个线段树&#xff0c;我们会将其每次从中间分开&#xff0c;其左孩子就是左边的集合的和&#xff0c;其右孩子就是右边集合的和&#xff1b; 我们可以…

VSCode常用修改默认设置(settings.json)

❓ 问题1 我现在在vscode中鼠标选中某个单词&#xff0c;相同的单词都会自动出现一个高亮背景色&#xff0c;我需要怎么关闭这个功能呢&#xff1f; ⚠️ 注意 selectionHighlight 这个是鼠标双击后的高亮匹配&#xff0c;可以保留默认开启的配置&#xff0c;不用去改它。 …

力扣每日一题:LCR112--矩阵中的最长递增路径

题目 给定一个 m x n 整数矩阵 matrix &#xff0c;找出其中 最长递增路径 的长度。 对于每个单元格&#xff0c;你可以往上&#xff0c;下&#xff0c;左&#xff0c;右四个方向移动。 不能 在 对角线 方向上移动或移动到 边界外&#xff08;即不允许环绕&#xff09;。 示例…

前端入门系列-HTML-HTML结构

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” HTML基础 HTML结构 认识HTML标签 HTML代码是由“标签”构成的。 形如 <body>hello </body> 标签名&#xff08;body&#xff09;放到<>中大部分标签成对…

见证历史:Quantinuum与微软取得突破性进展,开启了可靠量子计算的新时代!

Quantinuum与微软的合作取得了重大突破&#xff0c;将可靠量子计算带入了新的时代。他们结合了Quantinuum的System Model H2量子计算机和微软创新的量子比特虚拟化系统&#xff0c;在逻辑量子比特领域取得了800倍于物理电路错误率的突破。这一创新不仅影响深远&#xff0c;加速…

C#仿OutLook的特色窗体设计

目录 1. 资源图片准备 2. 设计流程&#xff1a; &#xff08;1&#xff09;用MenuStrip控件设计菜单栏 &#xff08;2&#xff09;用ToolStrip控件设计工具栏 &#xff08;3&#xff09;用StatusStrip控件设计状态栏 &#xff08;4&#xff09;ImageList组件装载树节点图…

【ORB-SLAM3】Ubuntu20.04 使用 RealSense D435i 运行 ORB-SLAM3 时遇到的一些 Bug

【ORB-SLAM3】使用 RealSense D435i 跑 ORB-SLAM3 时遇到的一些 Bug 1 hwmon command 0x80( 5 0 0 0 ) failed (response -7 HW not ready)2 No rule to make target /opt/ros/noetic/lib/x86_64-linux-gnu/librealsense2.so, needed by ../lib/libORB_SLAM3.so 1 hwmon comman…

微信小程序 python+django口腔牙科问诊系统 springboot设计与实现_1171u

口腔助手”小程序主要有管理员&#xff0c;医生和用户三个功能模块。以下将对这三个功能的作用进行详细的剖析。 本文通过采用B/S架构&#xff0c;uniapp框架、MySQL数据库&#xff0c;结合国内“口腔助手”管理现状&#xff0c;开发了一个基于微信小程序的“口腔助手”小程序。…

基于ArrayList实现简单洗牌

前言 在之前的那篇文章中&#xff0c;我们已经认识了顺序表—>http://t.csdnimg.cn/2I3fE 基于此&#xff0c;便好理解ArrayList和后面的洗牌游戏了。 什么是ArrayList? ArrayList底层是一段连续的空间&#xff0c;并且可以动态扩容&#xff0c;是一个动态类型的顺序表&…

二、企业级架构之Nginx

一、Nginx的重装与升级 1、为什么需要重装与升级&#xff1a; 在实际业务场景中&#xff0c;需要使用软件新版本的功能、特性&#xff0c;就需要对原有软件进行升级或者重装操作。 Nginx&#xff1a;1.12版本 → 1.16版本 2、Nginx重装&#xff1a; 第一步&#xff1a;停止…

linux操作系统的进程状态

这个博客只是为了自己复习用的&#xff01;&#xff01;&#xff01; 冯诺依曼体系结构 计算机是由一个一个硬件组成的 输入设备&#xff1a;键盘&#xff0c;鼠标&#xff0c;扫描仪&#xff0c;写板等等 中央处理器&#xff08;CPU&#xff09;:含有运算器和控制器等 输出单…

Vue-05

v-model 应用于其他表单元素 常见的表单元素都可以用v-model绑定关联 → 快速获取或设置表单元素的值 它会根据控件类型自动选取正确的方法来更新元素 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name…

树莓派部署yolov5实现目标检测(ubuntu22.04.3)

最近两天搞了一下树莓派部署yolov5&#xff0c;有点难搞&#xff08;这个东西有点老&#xff0c;版本冲突有些包废弃了等等&#xff09; 最后换到ubuntu系统弄了&#xff0c;下面是我的整体步骤&#xff08;建议先使能一下ssh&#xff08;最下面有&#xff09;&#xff0c;结合…

Macbook文件清理软件 Mac电脑清理垃圾文件怎么清理

为了维护Macbook电脑的系统健康&#xff0c;我们需要定期给电脑进行全面清理&#xff0c;清除系统垃圾文件、软件缓存和系统内存。那么好用的Macbook文件清理软件有哪些呢&#xff1f;今天就给大家介绍几款好用的电脑清理软件并介绍Mac电脑清理垃圾文件怎么清理。 一、Macbook…

RPA自动化小红书自动化写文以及发文!

1、视频演示 RPA自动化小红书自动写作发文 2、核心功能点 采集笔记&#xff1a;采集小红书上点赞量大于1000的爆款笔记 下载素材&#xff1a;下载爆款笔记的主图 爆款改写&#xff1a;根据爆款笔记的标题仿写新的标题以及新的文案 自动发布&#xff1a;将爆款笔记发布到小红…

Django之REST Client插件

一、接口测试工具介绍 在开发前后端分离项目时,无论是开发后端,还是前端,基本都是需要测试API接口的内容,而目前我们需要开发遵循RESTFul规范的项目,也是必然的(自己不开发前端页面)。 在网上有很多这样的工具,常用的postman,但还是需要下载安装。在这我们介绍一个VSCod…

【GEE实践应用】GEE下载遥感数据以及下载后在ArcGIS中的常见显示问题处理(以下载哨兵2号数据为例)

本期内容我们使用GEE进行遥感数据的下载&#xff0c;使用的相关代码如下所示&#xff0c;其中table是我们提前导入的下载遥感数据的研究区域的矢量边界数据。 var district table;var dsize district.size(); print(dsize);var district_geometry district.geometry();Map.…