iOS Swift SDK
MLC LLM iOS 应用程序可以通过两种方式安装:通过预构建的包或从源代码构建。如果您是希望尝试模型的 iOS 用户,推荐使用预构建的包。如果您是开发者,希望将新功能集成到包中,则需要从源代码构建 iOS 包。
使用预构建的 iOS 应用程序
MLC Chat 应用程序现已免费登陆 App Store。您只需点击下方按钮即可下载并探索其功能:
从源代码构建 iOS 应用程序
本节展示了如何从源代码构建应用程序。
第一步:安装构建依赖项
首先,请克隆 MLC LLM GitHub 仓库。克隆完成后,进入 ios/
目录。
git clone https://github.com/mlc-ai/mlc-llm.git
cd mlc-llm
git submodule update --init --recursive
cd ./ios
请按照 安装 MLC LLM Python 包 的说明获取 mlc_llm 包的二进制构建版本。请注意,这与用于 iOS 包构建的上述源代码是独立的。您无需为主机环境构建 mlc_llm,我们可以直接使用预构建的包来实现这一目的。
还需要具备以下构建依赖项:
CMake >= 3.24,
Git and Git-LFS,
Rust 和 Cargo,这是 Hugging Face 分词器所必需的。
第二步:构建运行时和模型库
为 iOS 应用程序构建的模型在 MLCChat/mlc-package-config.json
文件中指定,具体位于 model_list
部分:
model
指向包含预转换模型权重的 Hugging Face 仓库。iOS 应用程序将从该 Hugging Face URL 下载模型权重。model_id
是模型的唯一标识符。estimated_vram_bytes
是对模型在运行时占用的 vRAM 的估计。"bundle_weight": true
表示在构建时,模型的权重将被捆绑到应用程序中。overrides
指定了一些模型配置参数的覆盖值。
有一行命令可以构建并准备所有模型库:
cd /path/to/MLCChat # e.g., "ios/MLCChat"
export MLC_LLM_SOURCE_DIR=/path/to/mlc-llm # e.g., "../.."
mlc_llm package
该命令主要执行以下两个步骤:
编译模型。 将
MLCChat/mlc-package-config.json
中model_list
的每个模型编译成二进制模型库。构建运行时和分词器。 除了模型本身外,还需要轻量级的运行时和分词器来实际运行大语言模型。
该命令会创建包含运行时和模型构建输出的 ./dist/
目录。请确保 dist/
遵循以下结构(除可选的模型权重外):
dist
├── bundle # The directory for mlc-app-config.json (and optionally model weights)
│ │ # that will be bundled into the iOS app.
│ ├── mlc-app-config.json # The app config JSON file.
│ └── [optional model weights]
└── lib
├── libmlc_llm.a # A lightweight interface to interact with LLM, tokenizer, and TVM Unity runtime.
├── libmodel_iphone.a # The compiled model lib.
├── libsentencepiece.a # SentencePiece tokenizer
├── libtokenizers_cpp.a # Huggingface tokenizer.
└── libtvm_runtime.a # TVM Unity runtime.
备注
利用本地 JIT 缓存来避免重复编译相同的输入。然而,有时当我们有新的编译器更新或缓存库出现问题时,强制重新构建是有帮助的。您可以通过设置环境变量 MLC_JIT_POLICY=REDO
来实现这一点。
MLC_JIT_POLICY=REDO mlc_llm package
步骤 3. (可选)将模型权重打包到应用程序中
默认情况下,在运行应用程序时会从 Hugging Face 下载模型权重。作为可选方案,可以将模型权重打包到应用程序中:在 MLCChat/mlc-package-config.json
中,为您希望打包权重的模型设置 "bundle_weight": true
,然后再次运行 mlc_llm package
。以下是示例:
{
"device": "iphone",
"model_list": [
{
"model": "HF://mlc-ai/gemma-2b-it-q4f16_1-MLC",
"model_id": "gemma-2b-q4f16_1",
"estimated_vram_bytes": 3000000000,
"overrides": {
"prefill_chunk_size": 128
},
"bundle_weight": true
}
]
}
运行 mlc_llm package
的结果应如下所示:
dist
├── bundle
│ ├── gemma-2b-q4f16_1 # The model weights that will be bundled into the app.
│ └── mlc-app-config.json
└── ...
步骤 4. 构建 iOS 应用程序
使用 Xcode 打开 ./ios/MLCChat/MLCChat.xcodeproj
。请注意,您需要 Apple 开发者账户才能使用 Xcode,系统可能会提示您使用自己的开发者团队凭证和产品包标识符。
确保 Xcode 项目中所有必要的依赖项和配置均已正确设置。
完成必要的更改后,使用 Xcode 构建 iOS 应用程序。如果您使用的是 Apple Silicon Mac,可以选择目标“我的 Mac(专为 iPad 设计)”以在 Mac 上运行。您也可以直接在 iPad 或 iPhone 上运行。
自定义 App
可以通过自定义 MLCChat/mlc-package-config.json 来定制 iOS 应用程序中构建的模型。以下我们将介绍该 JSON 文件的每个字段。
JSON 文件的 "model_list"
中的每个条目包含以下字段:
model
(必填)要构建到应用程序中的 MLC 转换模型的路径。
它可以是 Hugging Face URL(例如
"model": "HF://mlc-ai/phi-2-q4f16_1-MLC"
),也可以是包含转换后模型权重的本地模型目录路径(例如"model": "../dist/gemma-2b-q4f16_1"
)。如果您希望将本地模型构建到应用程序中,请查看 转换模型权重。注意:本地路径(如果是相对路径)是相对于
ios/
目录的。model_id
(必需)用于标识模型的唯一本地标识符。它可以是任意值。
estimated_vram_bytes
(必需)运行模型所需的 vRAM 估计值。
bundle_weight
(可选)布尔标志,指示是否将模型权重打包到应用程序中。请参阅 步骤 3. (可选)将模型权重打包到应用程序中。
overrides
(可选)字典,用于覆盖默认的模型上下文窗口大小(以限制 KV 缓存大小)和预填充块大小(以限制模型的临时执行内存)。例如:
{ "device": "iphone", "model_list": [ { "model": "HF://mlc-ai/RedPajama-INCITE-Chat-3B-v1-q4f16_1-MLC", "model_id": "RedPajama-INCITE-Chat-3B-v1-q4f16_1", "estimated_vram_bytes": 2960000000, "overrides": { "context_window_size": 512, "prefill_chunk_size": 128 } } ] }
model_lib
(可选)字符串,指定用于模型的系统库前缀。通常,当您希望将具有相同架构的多个模型变体构建到应用程序中时,会使用此字段。此字段不会影响任何应用程序功能。 下面介绍的
"model_lib_path_for_prepare_libs"
也与此相关。例如:{ "device": "iphone", "model_list": [ { "model": "HF://mlc-ai/RedPajama-INCITE-Chat-3B-v1-q4f16_1-MLC", "model_id": "RedPajama-INCITE-Chat-3B-v1-q4f16_1", "estimated_vram_bytes": 2960000000, "model_lib": "gpt_neox_q4f16_1" } ] }
除了 MLCChat/mlc-package-config.json
中的 model_list
外,您还可以 选择性地 指定 "model_lib_path_for_prepare_libs"
字典,如果您希望使用手动编译的模型库。此字典的键应为模型列表中指定的 model_lib
,而字典的值是手动编译的模型库的路径(绝对路径或相对路径)。在运行 mlc_llm package
时,"model_lib_path_for_prepare_libs"
中指定的模型库将被构建到应用程序中。例如:
{
"device": "iphone",
"model_list": [
{
"model": "HF://mlc-ai/RedPajama-INCITE-Chat-3B-v1-q4f16_1-MLC",
"model_id": "RedPajama-INCITE-Chat-3B-v1-q4f16_1",
"estimated_vram_bytes": 2960000000,
"model_lib": "gpt_neox_q4f16_1"
}
],
"model_lib_path_for_prepare_libs": {
"gpt_neox_q4f16_1": "../../dist/lib/RedPajama-INCITE-Chat-3B-v1-q4f16_1-iphone.tar"
}
}
引入您自己的模型
本节介绍如何将您自己的模型构建到 iOS 应用程序中。以 NeuralHermes 模型为例,它是 Mistral 模型的变体。
备注
本节大部分内容复制自 转换模型权重。请参阅该页面以获取更多详细信息。请注意,权重在 MLC 中跨所有平台共享。
第一步:从 HF 克隆并转换权重
您可以在 mlc-llm 仓库下,或您自己的工作目录中。请注意,所有平台可以共享相同的编译/量化权重。有关 convert_weight
的规范,请参阅 编译命令规范。
# Create directory
mkdir -p dist/models && cd dist/models
# Clone HF weights
git lfs install
git clone https://huggingface.co/mlabonne/NeuralHermes-2.5-Mistral-7B
cd ../..
# Convert weight
mlc_llm convert_weight ./dist/models/NeuralHermes-2.5-Mistral-7B/ \
--quantization q4f16_1 \
-o dist/NeuralHermes-2.5-Mistral-7B-q3f16_1-MLC
步骤 2. 生成 MLC Chat 配置文件
使用 mlc_llm gen_config
生成 mlc-chat-config.json
并处理分词器。有关 gen_config
的规范,请参阅 编译命令规范。
mlc_llm gen_config ./dist/models/NeuralHermes-2.5-Mistral-7B/ \
--quantization q3f16_1 --conv-template neural_hermes_mistral \
-o dist/NeuralHermes-2.5-Mistral-7B-q3f16_1-MLC
对于 conv-template
,conversation_template.py 包含了 MLC 提供的完整对话模板列表。
如果您添加的模型需要新的对话模板,您需要自行添加。请参考 此 PR 作为示例。通过 mlc-chat-config.json
中的 conv_template
字段查找要使用的模板。
更多详情,请参阅 自定义 MLC Chat 配置。
步骤 3. 将权重上传至 HF
# First, please create a repository on Hugging Face.
# With the repository created, run
git lfs install
git clone https://huggingface.co/my-huggingface-account/my-mistral-weight-huggingface-repo
cd my-mistral-weight-huggingface-repo
cp path/to/mlc-llm/dist/NeuralHermes-2.5-Mistral-7B-q3f16_1-MLC/* .
git add . && git commit -m "Add mistral model weights"
git push origin main
成功完成所有步骤后,您应该会得到类似于 NeuralHermes-2.5-Mistral-7B-q3f16_1-MLC 的 Huggingface 仓库,其中包含转换/量化后的权重、mlc-chat-config.json
配置文件以及分词器文件。
步骤 4. 在模型列表中注册
最后,将模型添加到 MLCChat/mlc-package-config.json 的 model_list
中,通过指定 Hugging Face 链接作为 model
:
{
"device": "iphone",
"model_list": [
{
"model": "HF://mlc-ai/NeuralHermes-2.5-Mistral-7B-q3f16_1-MLC",
"model_id": "Mistral-7B-Instruct-v0.2-q3f16_1",
"estimated_vram_bytes": 3316000000,
}
]
}
现在,再次按照 第二步:构建运行时和模型库 和 步骤 4. 构建 iOS 应用程序 的步骤操作。应用程序将使用您刚刚添加的 NeuralHermes-Mistral
模型。
使用 MLC Swift API 构建应用程序
还提供了 Swift 包,您可以使用它来构建自己的应用程序。该包位于 ios/MLCSwift
目录下。
首先,在您的项目文件夹中创建
mlc-package-config.json
。您可以通过复制 MLCChat 文件夹中的文件来完成此操作。然后运行mlc_llm package
。这将在/path/to/project/dist
下生成必要的库。在“构建阶段”下,添加
/path/to/project/dist/bundle
,这将把此文件夹复制到您的应用程序中,以包含捆绑的权重和配置。在 Xcode 中,将
ios/MLCSwift
包添加到您的应用程序中。在“框架、库和嵌入内容”下,点击添加包依赖项,并添加指向ios/MLCSwift
的本地包。最后,需要添加库依赖项。在构建设置下:
添加库搜索路径
/path/to/project/dist/lib
。将以下项目添加到“其他链接器标志”中。
-Wl,-all_load -lmodel_iphone -lmlc_llm -ltvm_runtime -ltokenizers_cpp -lsentencepiece -ltokenizers_c
然后,您可以将 MLCSwift 包导入到您的应用程序中。以下代码展示了如何使用聊天模块的示例。
import MLCSwift
func runExample() async {
let engine = MLCEngine()
let modelPath = "/path/to/model/weights"
let modelLib = "model-lib-name"
await engine.reload(modelPath: modelPath, modelLib: modelLib)
// run chat completion as in OpenAI API style
for await res in await engine.chat.completions.create(
messages: [
ChatCompletionMessage(
role: .user,
content: "What is the meaning of life?"
)
]
) {
print(res.choices[0].delta.content!.asText())
}
}
查看 MLCEngineExample 以获取最小的入门示例。