书生大模型实战(从入门到进阶)L3-彩蛋岛-InternLM 1.8B 模型 Android 端侧部署实践
目录
1 环境准备
1.1 安装rust
1.2 安装Android Studio
1.3 设置环境变量
2 转换模型
2.1 安装mlc-llm
2.2 (可选)转换参数
2.3 (可选)生成配置
2.4 (可选)上传到huggingface
2.5 (可选) 测试转换的模型
3 打包运行
3.1 修改配置文件
3.2 运行打包命令
3.3 创建签名
3.4 修改gradle配置
3.5 命令行编译
3.6 运行体验
本文是对书生大模型L3-彩蛋岛-InternLM 1.8B 模型 Android 端侧部署实践部分的学习和实现,学习地址如下:
学习地址:学员闯关手册 - 飞书云文档 (feishu.cn)
1 环境准备
1.1 安装rust
参考: Other Installation Methods - Rust Forge。
使用了国内的镜像,出现选项直接Enter:
export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static
export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup
curl --proto '=https' --tlsv1.2 -sSf https://mirrors.ustc.edu.cn/misc/rustup-install.sh | sh
1.2 安装Android Studio
参考 :https://developer.android.com/studio。
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?hl=zh-cn
unzip commandlinetools-linux-11076708_latest.zip\?hl\=zh-cn
export JAVA_HOME=/root/android/android-studio/jbr
cmdline-tools/bin/sdkmanager "ndk;27.0.12077973" "cmake;3.22.1" "platforms;android-34" "build-tools;33.0.1" --sdk_root='sdk'
1.3 设置环境变量
. "$HOME/.cargo/env"
export ANDROID_NDK=/root/android/android-studio/sdk/ndk/27.0.12077973
export TVM_NDK_CC=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang
export JAVA_HOME=/root/android/android-studio/jbr
export ANDROID_HOME=/root/android/android-studio/sdk
export PATH=/usr/local/cuda-12/bin:$PATH
export PATH=/root/android/android-studio/sdk/cmake/3.22.1/bin:$PATH
2 转换模型
2.1 安装mlc-llm
参考:https://llm.mlc.ai/docs/install/mlc_llm.html,安装mlc-llm
可能需要代理。
安装pytorch
部分也可以使用其他包含torch
的conda
环境。
conda create --name mlc-prebuilt python=3.11
conda activate mlc-prebuilt
conda install -c conda-forge git-lfs
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
python -m pip install --pre -U -f https://mlc.ai/wheels mlc-llm-nightly-cu122 mlc-ai-nightly-cu122
测试如下输出说明安装正确:
python -c "import mlc_llm; print(mlc_llm)"
克隆项目:
git clone https://github.com/mlc-ai/mlc-llm.git
cd mlc-llm
git submodule update --init --recursive
2.2 (可选)转换参数
(如果不想上传到huggingface可以跳过这一步,有公开上传的)
使用 mlc_llm
的 convert_weight
对模型参数进行转换和量化,转换后的参数可以跨平台使用。
mkdir -p /root/models/
ln -s /share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat /root/models/internlm2_5-1_8b-chat
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
2.3 (可选)生成配置
(如果不想上传到huggingface可以跳过这一步,有公开上传的)
使用 mlc_llm
的 gen_config
生成 mlc-chat-config.json
并处理 tokenizer。
出现提示时输入y。
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/N] y
2.4 (可选)上传到huggingface
上传这一步需要能访问huggingface,可能需要部署代理并耗费一定流量。
具体方法可以参考网上的大量教程,如果不想上传到huggingface可以跳过这一步,直接在接下来的配置中使用如下链接的模型(和文档中的转换方法一样) https://huggingface.co/timws/internlm2_5-1_8b-chat-q4f16_1-MLC。
2.5 (可选) 测试转换的模型
在打包之前可以测试模型效果,需要编译成二进制文件。
在个人电脑上运行测试代码正常,InternStudio上暂未成功。
mlc_llm compile ./dist/internlm2_5-1_8b-chat-q4f16_1-MLC/mlc-chat-config.json \--device cuda -o dist/libs/internlm2_5-1_8b-chat-q4f16_1-MLC-cuda.so
测试编译的模型是否符合预期,手机端运行的效果和测试效果接近:
from mlc_llm import MLCEngine# Create engine
engine = MLCEngine(model="./dist/internlm2_5-1_8b-chat-q4f16_1-MLC", model_lib="./dist/libs/internlm2_5-1_8b-chat-q4f16_1-MLC-cuda.so")# Run chat completion in OpenAI API.
print(engine)
for response in engine.chat.completions.create(messages=[{"role": "user", "content": "你是谁?"}],stream=True
):for choice in response.choices:print(choice.delta.content, end="", flush=True)
print("\n")
engine.terminate()
3 打包运行
3.1 修改配置文件
修改mlc-package-config.json
参考如下:
{"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"},{"model": "HF://mlc-ai/gemma-2b-it-q4f16_1-MLC","model_id": "gemma-2b-q4f16_1-MLC","estimated_vram_bytes": 3980990464}]
}
3.2 运行打包命令
这一步需要能访问huggingface,可能需要部署代理:
mlc_llm package
3.3 创建签名
cd /root/android/mlc-llm/android/MLCChat
/root/android/android-studio/jbr/bin/keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000
Enter keystore password:
Re-enter new password:
What is your first and last name?[Unknown]: Any
What is the name of your organizational unit?[Unknown]: Any
What is the name of your organization?[Unknown]: Any
What is the name of your City or Locality?[Unknown]: Any
What is the name of your State or Province?[Unknown]: Any
What is the two-letter country code for this unit?[Unknown]: CN
Is CN=Any, OU=Any, O=Any, L=Any, ST=Any, C=CN correct?[no]: yesGenerating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 10,000 daysfor: CN=Any, OU=Any, O=Any, L=Any, ST=Any, C=CN
[Storing my-release-key.jks]
3.4 修改gradle配置
如果是本地可以WIFI或USB调试不用签名,在服务器构建需要签名 修改app/build.gradle
为如下内容,主要是增加了签名部分,注意确认签名文件的位置:
plugins {id 'com.android.application'id 'org.jetbrains.kotlin.android'
}android {namespace 'ai.mlc.mlcchat'compileSdk 34defaultConfig {applicationId "ai.mlc.mlcchat"minSdk 26targetSdk 33versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"vectorDrawables {useSupportLibrary true}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = '1.8'}buildFeatures {compose true}composeOptions {kotlinCompilerExtensionVersion '1.4.3'}packagingOptions {resources {excludes += '/META-INF/{AL2.0,LGPL2.1}'}}signingConfigs {release {storeFile file("/root/android/mlc-llm/android/MLCChat/my-release-key.jks")storePassword "123456"keyAlias "mykey"keyPassword "123456"}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'signingConfig signingConfigs.release}}
}dependencies {implementation project(":mlc4j")implementation 'androidx.core:core-ktx:1.10.1'implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'implementation 'androidx.activity:activity-compose:1.7.1'implementation platform('androidx.compose:compose-bom:2022.10.00')implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1'implementation 'androidx.compose.ui:ui'implementation 'androidx.compose.ui:ui-graphics'implementation 'androidx.compose.ui:ui-tooling-preview'implementation 'androidx.compose.material3:material3:1.1.0'implementation 'androidx.compose.material:material-icons-extended'implementation 'androidx.appcompat:appcompat:1.6.1'implementation 'androidx.navigation:navigation-compose:2.5.3'implementation 'com.google.code.gson:gson:2.10.1'implementation fileTree(dir: 'src/main/libs', include: ['*.aar', '*.jar'], exclude: [])testImplementation 'junit:junit:4.13.2'androidTestImplementation 'androidx.test.ext:junit:1.1.5'androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00')androidTestImplementation 'androidx.compose.ui:ui-test-junit4'debugImplementation 'androidx.compose.ui:ui-tooling'debugImplementation 'androidx.compose.ui:ui-test-manifest'}
3.5 命令行编译
运行编译命令,完成后在app/build/outputs/apk/release
生成app-release.apk
安装包,下载到手机上运行 运行App需要能访问huggingface下载模型(参考文档中的bundle方法需要ADB刷入模型数据):
./gradlew assembleRelease
3.6 运行体验
- 运行App需要能访问huggingface下载模型
- 需要大概4G运行内存
- 如果运行闪退,和可能是下载不完整可以删除重新下载
相关文章:
书生大模型实战(从入门到进阶)L3-彩蛋岛-InternLM 1.8B 模型 Android 端侧部署实践
目录 1 环境准备 1.1 安装rust 1.2 安装Android Studio 1.3 设置环境变量 2 转换模型 2.1 安装mlc-llm 2.2 (可选)转换参数 2.3 (可选)生成配置 2.4 (可选)上传到huggingface 2.5 (可选) 测试转换的模型 3 打包运行 3.1 修改配置文件 3.2 运行打包命令 3.3 创建签…...
setState是同步更新还是异步更新
setState是同步更新还是异步更新 先说结论setState为什么设计为异步react18之前为什么不确定是同步还是异步呢react18之后setState有哪些改动 先说结论 React18之前:使用了ReactDOM.render,setState在React调度流程中是异步更新,在原生事件和…...
TCP 流量控制 - 滑动窗口和拥塞控制算法解析
滑动窗口主要管理数据流动的速率,对单个连接较好,拥塞控制则防止网络出现过载,对提高整体的网络通畅较好。下面详细解析两者的原理和作用。 1. TCP 滑动窗口算法 TCP 使用滑动窗口机制来控制数据的发送和接收,以实现流量控制&…...
MongoDB聚合操作及索引底层原理
目录 链接:https://note.youdao.com/ynoteshare/index.html?id=50fdb657a9b06950fa255a82555b44a6&type=note&_time=1727951783296 本节课的内容: 聚合操作: 聚合管道操作: 编辑 $match 进行文档筛选 编辑 将筛选和投影结合使用: 编辑 多条件匹配: …...
C++ | Leetcode C++题解之第454题四数相加II
题目: 题解: class Solution { public:int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {unordered_map<int, int> countAB;for (int u: A) {for (int v: B) {count…...
【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】
目录 stm32cubemx配置芯片选择工程配置stm32基础配置SPI的配置定时器的配置ADC的配置中断优先级的配置生成工程 工程代码编写FOC代码结构搭建电机编码器角度读取PWM产生FOC开环代码编写确定电机正负旋转方向电机旋转速度计算多圈逻辑角度电流采样极对数转子角度确定 闭环控制控…...
谷歌收录查询工具,谷歌收录查询工具的使用指南
谷歌收录查询工具是网站管理员和SEO专业人士用于检查网站是否被谷歌搜索引擎收录及其收录情况的重要辅助手段。以下是一些常用的谷歌收录查询工具及其详细使用指南: 一、Google Search Console(谷歌搜索控制台) 简介: Google Sea…...
vue3 拖拽插件(drag)
前端vue项目中,经常会有弹框拖拽的需求,下面介绍常用方法: 1.如果你使用的是elementPlus插件的el-dialog组件,只需要增加draggable属性即可,代码如下: <el-dialogv-model"showDiloag"width"500&quo…...
数据结构--线性表(顺序结构)
1.线性表的定义和基本操作 1.1线性表以及基本逻辑 1.1.1线性表 (1)n(>0)个数据元素的有限序列,记作(a1,a2,...an),其中ai是线性表中的数据元素,n是表的长度。 (2)…...
面试准备111
Java基础 反射 集合 多线程 Synchronized/volatile 线程池 cas atomic 网络 tcp 三次握手/四次挥手 流量控制 拥塞控制 数据结构 算法 Spring 循环依赖 Mybatis 如何防止sql注入 Mysql 索引 索引分类 索引设计原则 事务 四种隔离级别 MVCC 日志 Binlog…...
Spring 的 IOC 和 AOP 是什么,有哪些优点?解密 Spring两大核心概念:IOC与AOP的魅力所在
在现代Java开发中,Spring框架几乎是不可或缺的存在。它不仅简化了开发过程,还提高了软件的灵活性和可维护性。今天,我们要深入探讨Spring中的两个核心概念:IOC(控制反转)和AOP(面向切面编程&…...
第二百六十四节 JPA教程 - JPA查询日期参数示例
JPA教程 - JPA查询日期参数示例 我们可以在查询中使用日期类型值。 以下代码使用EntityManager创建具有两个参数的查询。 然后它传递两个日期类型值。 em.createQuery("SELECT e " "FROM Professor e " "WHERE e.startDate BETWEEN :start AND :en…...
Spring MVC的运行流程详解
Spring MVC作为一个广泛使用的框架,提供了灵活且强大的MVC架构支持。尤其在业务系统中,Spring MVC能够有效地处理大量并发请求,提供良好的用户体验。本文将详细讲解Spring MVC的运行流程,以电商交易系统为案例,帮助读者…...
判断有向图是否为单连通图的算法
判断有向图是否为单连通图的算法 算法描述伪代码C语言实现解释在图论中,单连通图(singly connected graph)是指对于图中的任意两个顶点 m 和 v,如果存在从 m 到 v 的路径,则该路径是唯一的。为了判断一个有向图是否为单连通图,我们需要确保从任意顶点出发,到任意其他顶点…...
php与python建站的区别有哪些
php与Python建站的区别: 1、语言层面Python的特性比php好,更加规范。 2、Python的性能比php高。 3、有只需要启动服务的时候执行一次的代码,在php里每个请求都会被执行一次,Python不需要。虽然php可以通过缓存缩短这方面的差距…...
模型评估与验证:确保模型在未知数据上的表现----示例:使用K折交叉验证评估分类模型、房价预测问题使用K折交叉验证来评估一个线性回归模型的性能
模型评估与验证是机器学习流程中的关键步骤,它帮助我们了解模型在未见过的数据上的泛化能力。交叉验证(Cross-Validation, CV)是一种常用的技术,通过将数据集划分为多个子集并进行多次训练和测试来估计模型的性能。此外࿰…...
awd基础学习
一、常用防御手段 1、改ssh密码 passwd [user] 2、改数据库密码 进入数据库 mysql -uroot -proot 改密码 update mysql.user set passwordpassword(新密码) where userroot; 查看用户信息密码 select host,user,password from mysql.user; 改配置文件 (否则会宕机…...
C#基于SkiaSharp实现印章管理(10)
向PDF文件插入印章图片比之前实现的向图片文件插入印章麻烦得多。 最初的想法是使用PDF浏览控件在线打开PDF文件,然后在控件中实现鼠标移动时动态显示印章,点击鼠标时向当前PDF页面的鼠标点击位置插入图片。由于是.net 8的Winform项目,选…...
通过栈实现字符串中查找是否有指定字符串的存在
题目示例: 分析 由与没有给出字符串的长度,所以只能通过getline一次性处理,而在输入后恰好能倒序处理字符串,以标点符号为分界点,将数字当成字符放到栈里,遇到下一个标点符号时执行查找操作,…...
MongoDB伪分布式部署(mac M2)
1. 序言 本博客是上一博客的进阶版:mac M2安装单机版 MongoDB 7.x,上一博客可以看做是单机、单节点部署MongoDB本博客将介绍单机、多服务部署MongoDB,实际就是伪分布式部署 2. 副本集(Replica Set)方式部署 2.1 什么是副本集? …...
Golang | Leetcode Golang题解之第454题四数相加II
题目: 题解: func fourSumCount(a, b, c, d []int) (ans int) {countAB : map[int]int{}for _, v : range a {for _, w : range b {countAB[vw]}}for _, v : range c {for _, w : range d {ans countAB[-v-w]}}return }...
[ComfyUI]Flux:超美3D微观山水禅意,经典中文元素AI重现,佛陀楼阁山水画卷
在数字艺术和创意领域,[ComfyUI]Flux以其独特的虚实结合技术,已经成为艺术家和设计师们手中的利器。今天,我们激动地宣布,[ComfyUI]Flux带来了一款超美的3D微观山水禅意作品,经典中文元素通过AI技术重现,包…...
Linux 系统 nvm 管理node无法使用
文章目录 一、报错说明二、报错原因三、解决办法四、验证 一、报错说明 centos7服务器使用nvm安装的node之后,只要使用npm或者node,均会出现以下问题。 npm -v node: /lib64/libm.so.6: version GLIBC_2.27 not found (required by node) node: /lib64…...
信号处理快速傅里叶变换(FFT)的学习
FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。另外,FFT可以将一个信号的频谱提取出来&am…...
vue3项目el-table表格行内编辑加输入框校验
核心点 1. el-form的model属性需要跟el-form-item的prop要对应 2. el-form的model属性绑定tableData 3. el-form-item的prop绑定字符串:scope.index.列名(注意有个点) 4. el-form-item需要单独设置rules属性 代码示例 <el-form :mod…...
【Node.js】内置模块FileSystem的保姆级入门讲解
作者:CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境:Vscode 本文代码都经由博主PleaSure乐事实操后得出,可以放心使用。 1.FileSystem介绍 Node.js 的 fs(filesystem)模块是一个核心模块,…...
问:LINUXWINDOWS线程CPU时间如何排序?
Linux 在Linux上,你可以使用ps命令结合sort命令来查看和排序进程或线程的CPU使用时间。 查看进程的CPU使用时间并按时间排序 使用ps命令的-o选项可以自定义输出格式,-e选项表示显示所有进程,--sort选项用于排序。 ps -e -o pid,tid,comm,…...
postgresql-重复执行相同语句,试试 prepare!
文章目录 每次你向 PostgreSQL 发送 SQL 语句时,数据库都必须对其进行解析(parse)。解析虽然很快,但如果同样的语句被解析一千次,这种操作累积起来可能会占用大量时间,而这些时间本可以用于处理其他事务。为避免这种情况ÿ…...
wpf加载带材料的3D模型(下载的3D预览一样有纹理)
背景:最近真的是忙啊,累出汁水了 整体效果: 放大可以看清砖头: 1、需要自己准备好3D模型,比如我这里是下载的这里的3D Warehouse,下载Collada File格式文件 2、解压可以看到一个model.dae和材料的文件夹&…...
【k8s之深入理解调度】调度框架扩展点理解
参考自 K8s 调度框架设计与 scheduler plugins 开发部署示例(2024) 调度插件扩展点 等待调度阶段PreEnqueuePod 处于 ready for scheduling 的阶段。 内部工作原理:sig-scheduling/scheduler_queues.md。在 Pod 被放入调度队列之前执行的插…...
专业做公司宣传网站/cnzz数据统计
在工作中可能会用协同工作的场景,而nfs这项技术服务就能很好满足这一场景。 接下来就直接安装配置 nfs服务的安装配置 1.检查是否有 NFS 和 RPC rpm -qa nfs-utils bind-utils2.安装NFS 和 RPC(两个都有就跳过) yum -y install nfs-utils…...
网站是用什么程序做的/平面设计主要做什么
本文将要为您介绍的是Internet worm(Java网络爬虫-虎牙篇),具体操作方法:jsoup虎牙篇IDE:Idea:package InternetWorm.huyaData;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elemen…...
天元建设集团有限公司文件/seo长沙
题目 5 :密码锁 使用单片机实现简易密码锁,通过输入密码,实现门锁的开启(控制继电器)。 具体要求如下: (1)当输入正确密码后,继电器开启。 (2)当三…...
做网站运营用什么软件/百度蜘蛛池自动收录seo
甲骨文公司正计划将安全方面的一大棘手难题对象序列化功能从Java当中剔除出去。这项功能亦被称为Java对象序列化,主要用于将对象编码为字节流形式。除了用于轻量化持久性与通过套接字或Java RMI进行通信之外,序列化功能还支持从字节流中重构对象图。\\甲…...
免费申请网站永久域名/淘宝运营培训班
ItemsControl是一个基础类型,控件本身没有内置滚动条。如果不喜欢ListBox默认的复制样式,只是需要一个简单的可滚动Items Control,可以给ItemsControl的Template加一个ScrollViewer: <ItemsControl.Template> …...
wordpress页面图片插件/bing搜索引擎国际版
12月1日23时11分,嫦娥五号探测器成功着陆在月球。嫦娥五号的顺利登陆也预示着我国航天工作又跨进了一大步。从另一个角度来看“嫦娥五号”也是一种机器人,肩负着“挖土”使命,飞向太空。这也恰恰是科技改变未来的一种预兆。随着智能机器人技术…...