【小白笔记】 MNN 移动端大模型部署
最近尝试用 MNN 框架在我的 Android 手机上跑一个大模型。这篇笔记记录了我从零开始,克服重重困难,最终成功配置好开发环境的心路历程。
https://github.com/alibaba/MNN/blob/master/apps/Android/MnnLlmChat/README_CN.md
1. 核心操作:克隆代码库
我的第一步是获取 MNN 的代码。我以为这很简单,但却在这里遇到了第一个大难题,并学到了很多重要的底层知识。
-
第一次尝试:HTTPS 克隆
我简单地复制了仓库地址,使用git clone https://...
命令。没想到,克隆速度非常慢,只有几十 KB/s。我尝试用Ctrl + C
中断操作,发现这会留下一个不完整的文件夹。- 中断操作:我学到,在命令行里,如果想停止一个正在运行的命令,只需要按下
Ctrl + C
。中断后,Git 会留下一个不完整的文件夹,所以我每次重新开始前,都得先用rm -rf MNN
把旧的文件夹删掉,才能重新克隆。 - 学到的知识点:
HTTPS
(Hypertext Transfer Protocol Secure,即超文本传输安全协议)是我们平时上网最常用的协议,它通过用户名和密码来验证身份。用它来克隆代码库操作简单,但传输效率有时不如其他协议,特别是当代码库很大时。
- 中断操作:我学到,在命令行里,如果想停止一个正在运行的命令,只需要按下
-
第二次尝试:SSH 协议克隆
因为 HTTPS 太慢,我决定尝试SSH
(Secure Shell,即安全外壳协议)。我听说它更快、更安全。我尝试用git clone git@github.com:alibaba/MNN.git
命令,结果终端报错:Permission denied (publickey)
。- 我的第一个坑:我以为我配置过 SSH 密钥,但实际上我的电脑没有有效的密钥,或者 GitHub 账户里没有我的公钥。
- 我的解决:我按照教程,一步步生成了密钥对,并将公钥上传到了 GitHub。
- 生成密钥:我运行了
ssh-keygen -t ed25519 -C "我的邮箱"
。 - 理解“口令”:程序提示我输入 passphrase(口令),这是为我的私钥设置的一个额外密码。我选择了留空,以方便后续操作。
- 我的第二个坑:我重新命名了密钥文件,但没有指定完整路径,结果文件被保存到了我当前所在的文件夹(
/g/down
)。这导致我用默认路径~/.ssh/id_ed25519.pub
去查看公钥时,终端报错No such file or directory
。 - 我的解决:我明白了,命令行的相对路径是相对于我当前所在的文件夹。我找到了我新命名的文件,并将其移动到了正确的
.ssh
目录下。
- 生成密钥:我运行了
- 学到的知识点:
- SSH 密钥对:SSH 不用密码,而是通过“公钥”(public key)和“私钥”(private key)来验证身份。我的私钥是我的“钥匙”,它只存在于我自己的电脑上,绝不能泄露。公钥是我的“锁”,我可以把它放到任何我想连接的服务器上(比如 GitHub)。当我的电脑用私钥“开锁”时,服务器会用公钥来验证,如果匹配,就代表身份验证通过。
- SSH 命令:
git clone git@github.com:alibaba/MNN.git
中的git@github.com
是 SSH 协议的地址,它告诉 Git 使用 SSH 来连接 GitHub。alibaba/MNN.git
指向了具体的代码库。
-
第三次尝试:浅克隆
即使配置了 SSH,克隆速度依然不理想。我了解到,这是因为 MNN 是一个非常大的代码库。最终,我选择了浅克隆(Shallow Clone),只克隆最新的代码,而不是完整的历史记录。这个方法极大地减少了下载的数据量。- 我的命令:
git clone --depth 1 git@github.com:alibaba/MNN.git
- 学到的知识点:
--depth 1
参数就是“浅克隆”的关键,它告诉 Git 只获取最新版本。对于我这种只关心最新代码、不需要查看项目历史的初学者来说,这是一种非常高效的方法。
- 我的命令:
-
第四次尝试:镜像站点与代理
浅克隆依然很慢,我无法忍受等待,于是用Ctrl + C
主动中断了操作。我意识到,我的网络连接可能不稳定,需要一个更稳定的加速服务。我尝试了多个 GitHub 镜像站点和代理服务,但都失败了。- 我的错误尝试:
- 尝试
https://github.com.cnpmjs.org/
,提示Could not resolve host
(无法解析主机),这意味着这个镜像站点可能已失效。 - 尝试
https://hub.fastgit.org/
,依然提示Could not resolve host
,确认问题不在于镜像站点的选择,而是我本地的网络或 DNS 设置。 - 尝试
https://gitclone.com/
,提示Could not read from remote repository
,这说明代理服务本身有问题,无法从 GitHub 获取数据。
- 尝试
- 学到的知识点:这些加速服务有时并不稳定,它们本身也可能成为连接失败的原因。当所有代理都失败时,问题很可能出在本地。
- 我的错误尝试:
-
我的最终解决方案:回到官方,解决本地网络问题
最终,我使用官方地址,配合浅克隆,成功地获取了代码。
2. 核心操作:构建 MNN 库
在成功克隆代码后,我进入了下一个阶段:构建 MNN 库。在这里,我遇到了比克隆更复杂的问题,因为我的电脑缺少构建所需的工具。
-
我的第一次构建尝试:缺少工具
我尝试运行构建命令,但很快就遇到了错误。终端提示我找不到cmake
和ninja
命令。我意识到,我的电脑缺少将源码编译成库文件的“翻译官”和“建造者”。 -
我的解决:配置环境变量
我并没有单独去下载这些工具,而是利用了我已有的资源。- CMake:我知道我的 Android Studio SDK 里已经有 CMake 了(路径是
D:\sdk\cmake\3.22.1
)。我直接将D:\sdk\cmake\3.22.1\bin
这个路径手动添加到了系统的Path
环境变量中。 - Ninja:我从 GitHub 下载了
ninja.exe
,然后把它所在的文件夹路径手动添加到了Path
环境变量中。 - 学到的知识点:环境变量
Path
就像是电脑的“指令搜索路径”。当我输入一个命令时,电脑会去Path
里列出的所有文件夹里找对应的可执行文件。如果找不到,就会报错“command not found”。通过手动添加路径,我让电脑“知道”这些工具在哪里了。 - 我犯的错误:在添加
ninja
的路径时,我一开始犯了个错误,把路径写成了G:\down\ninja-win\ninja.exe
,包含了.exe
本身。结果还是失败了。我这才明白,Path
变量里应该只放文件夹路径,电脑会自动在这些文件夹里找可执行文件。 - 一个重要的发现:我发现,即使我添加了正确的路径,我的 Git Bash 终端还是找不到命令。后来我才知道,修改环境变量后,必须完全关闭并重新打开终端,新的配置才会生效。
- CMake:我知道我的 Android Studio SDK 里已经有 CMake 了(路径是
-
理解用户变量和系统变量
在配置环境变量时,我还学到了一个重要的概念:- 用户变量:只对当前登录的 Windows 用户生效。
- 系统变量:对所有用户都生效。
一般来说,如果这个工具只给自己用,就放在用户变量里;如果是所有用户都可能用到的工具,就放在系统变量里。