跳到正文
返回博客
·约 2 分钟读完

用 MLX 在 Mac 上运行 Hugging Face 模型

在 Python 虚拟环境里安装 mlx-lm,在 Apple 芯片上运行 mlx-community 的模型,按内存选 4 位还是 8 位,并自己转换模型,附 M4 上实测的速度和内存。

创建一个 Python 虚拟环境,运行 pip install mlx-lm,然后执行 mlx_lm.generate --model mlx-community/<模型名> --prompt "..."。第一次运行会从 Hugging Face 下载模型,之后直接用本地副本。MLX 是 Apple 为 Apple 芯片上的机器学习做的数组框架,Hugging Face 上的 mlx-community 组织里有数千个已经转换好的模型。内存紧张时选 4 位的文件,想要更高质量的余量时选 8 位。下面所有内容都在一台 Apple M4、16 GB 内存的 Mac 上运行(sysctl 返回 Apple M4 和 17179869184 字节),系统是 macOS 27.0.1,文中的数字就是工具打印出来的结果。

MLX 和 mlx-lm 是什么

MLX 的 README 把它描述为“an array framework for machine learning on Apple silicon, brought to you by Apple machine learning research”。这里有两点最重要:它的 Python API 紧贴 NumPy,另外还有 C++、C 和 Swift API;数组放在共享内存里,所以运算可以在 CPU 或 GPU 上进行,不需要在两者之间拷贝数据。

mlx-lm 是基于 MLX 的另一个 Python 包。它的 README 说用途是在 Apple 芯片上用 MLX“生成文本并微调大语言模型”,支持接入 Hugging Face Hub,也支持量化和上传模型。下面用到的三个命令行工具都来自它:mlx_lm.generate、mlx_lm.chat 和 mlx_lm.convert。

在虚拟环境里安装

虚拟环境能让这些包不进入系统的 Python。我用的是 Homebrew 的 Python 3.14.7(这台 Mac 的系统 Python 是 3.9.6,我没有试过):

python3.14 -m venv mlx-venv
./mlx-venv/bin/pip install mlx-lm
./mlx-venv/bin/pip list | grep -i -E "^(mlx|mlx-lm|transformers|huggingface)"

安装后的版本如下:

huggingface_hub   2.4.0
mlx               0.32.4
mlx-lm            0.32.2
mlx-metal         0.32.4
transformers      5.22.1

下载的模型默认放在 Hugging Face 缓存,也就是 ~/.cache/huggingface。想让一次试验自成一体,就把 HF_HOME 设成一个之后可以删掉的文件夹;我就是这么做的,模型文件落在了这个文件夹里,没有进入主目录:

export HF_HOME="$PWD/hf-home"

用 mlx-community 的模型生成文本

--model 参数接受本地文件夹或 Hugging Face 仓库名。按 mlx-lm 的 README 和 --help,不写这个参数时默认用 mlx-community/Llama-3.2-3B-Instruct-4bit。为了下载得快,我用了一个很小的模型。写之前我在 Hugging Face 的模型列表里确认过 mlx-community/Qwen2.5-0.5B-Instruct-4bit 和 -8bit 都存在(Qwen2.5-0.5B-Instruct 的模型卡标注的是 Apache 2.0 许可;你要发布的模型请自己读它的模型卡):

./mlx-venv/bin/mlx_lm.generate \
  --model mlx-community/Qwen2.5-0.5B-Instruct-4bit \
  --prompt "Explain in two sentences what an Apple silicon Mac is." \
  --max-tokens 100 --seed 0

打印结果(节选):

==========
An Apple silicon Mac is a powerful and versatile computer that combines the best features of Apple hardware with the latest software and software development tools to create a cutting-edge computing experience. It's a powerful and versatile computer ...
==========
Prompt: 41 tokens, 435.835 tokens-per-sec
Generation: 66 tokens, 225.996 tokens-per-sec
Peak memory: 0.361 GB

最有用的是最后三行:提示词处理速度、生成速度和峰值内存。这么小的模型会重复自己的话,很正常。想要对话式使用,mlx_lm.chat 会在运行期间保留对话上下文:

./mlx-venv/bin/mlx_lm.chat --model mlx-community/Qwen2.5-0.5B-Instruct-4bit --max-tokens 60

我给它输入了一个问题,它以每秒 224.9 个 token 的速度回答,峰值 0.35 GB。但答错了:问“What is MLX?”,这个 0.5B 的模型讲的是 MLflow 和 TensorFlow。极小的模型适合检查环境和速度,不适合问事实,所以请用你真正打算用的规模来测试。mlx_lm.generate -h 会列出其余选项,包括 --temp、--top-p 等采样参数。

按 Mac 的内存选 4 位还是 8 位

量化是用更少的位数保存每个权重,所以文件和所需内存都会变小。mlx-lm 的 README 在“能不能放下”这件事上只说了两点:相对内存太大的模型会很慢;如果看到警告“Generating with a model that requires ...”,可以用 sudo sysctl iogpu.wired_limit_mb=N 提高系统的 wired 内存上限,N 要大于模型的大小(单位 MB)且小于机器的内存大小。这个 wired 内存功能需要 macOS 15 或更新。README 没有给出“哪种模型适合哪种 Mac”的表,所以请自己测,如下。

同一个提示词、同一个种子、同一台 Mac(Apple M4,16 GB),每个各跑两次;两次的峰值内存相同,速度接近:

模型权重文件峰值内存生成速度
Qwen2.5-0.5B-Instruct 原版(bf16)942 MB未测未测
mlx-community/Qwen2.5-0.5B-Instruct-8bit501 MB0.609 GB每秒 147 至 153 个 token
mlx-community/Qwen2.5-0.5B-Instruct-4bit265 MB0.361 GB每秒 226 至 240 个 token

在这台 Mac 和这个模型上,4 位比 8 位的峰值内存少约 40%,生成也更快。这只是对一个 0.5B 模型的测量,不能直接推到别的规模。8 位和 4 位两次停止时生成的 token 数也不同(36 和 66),所以速度只能大致比较。实际做法:

  • 先看模型在 Hugging Face 页面上的文件大小。我的测试里峰值内存比权重文件大(265 MB 的文件对应 0.361 GB),所以要留出比文件更多的空间。
  • 先用 4 位,用你自己的提示词检查输出质量,只有 4 位不够好再升到 8 位。
  • 别忘了系统其他部分也要内存。模型几乎占满内存,正是 README 警告会很慢的情况。

用 mlx_lm.convert 自己转换模型

如果某个模型没有 MLX 版本,就自己转换。README 给出了用 mlx_lm.convert --model <仓库> -q 在命令行里量化,用 --upload-repo 把结果上传到 Hugging Face。我转换的是原版 Qwen/Qwen2.5-0.5B-Instruct,并用 --mlx-path 指定了保存的文件夹:

./mlx-venv/bin/mlx_lm.convert \
  --hf-path Qwen/Qwen2.5-0.5B-Instruct \
  -q \
  --mlx-path ./qwen-4bit-mine

它打印了 Using dtype: bfloat16、Quantizing 和 Quantized model with 4.502 bits per weight.。文件夹里有一个 278,065,225 字节的 model.safetensors(整个文件夹 290 MB),还有配置和分词器文件。每个权重 4.502 位而不是 4 位,是因为量化还要保存每一组的缩放值。按路径运行的方式相同:

./mlx-venv/bin/mlx_lm.generate --model ./qwen-4bit-mine --prompt "Say hello in five words." --max-tokens 30 --seed 0

它回答了 Hello, how may I assist you today?,速度每秒 182.8 个 token,峰值 0.350 GB。mlx_lm.convert --help 还列出了 --q-bits 和 --q-group-size,我没有改动它们。转换后的文件要连同原模型的许可证一起保留,因为转换结果是衍生副本。

MLX Swift 在 App 里的位置

mlx-lm 是 Python,适合在你的 Mac 和脚本里用,不适合放进要上架的 iOS 或 macOS App。做 App 要用 Swift:MLX 的 README 列出了 Swift API,MLX Swift 的 README 称它是“a Swift API for MLX”。在 Xcode 或 SwiftPM 里把 https://github.com/ml-explore/mlx-swift.git 加为包依赖即可。README 提醒,命令行的 SwiftPM 编译不了 Metal 着色器,最终构建要通过 Xcode 完成。

语言模型的代码在另一个包里。mlx-swift-examples 的 README 说,MLXLMCommon、MLXLLM、MLXVLM 和 MLXEmbedders 已经移到 mlx-swift-lm,它自称是用于构建大语言模型和视觉语言模型工具与应用的 Swift 包。它的 README 给出了 Package.swift 的依赖写法和要链接的产品(MLXLLM、MLXLMCommon、MLXHuggingFace,以及两个 Hugging Face 包里的 HuggingFace 和 Tokenizers)。示例仓库里有一个能在 iOS 和 macOS 上运行、并从 Hugging Face 下载模型的 App(LLMEval),还有一个小型聊天 App(MLXChatExample)。这些我都没有为本文构建过,所以复制依赖写法之前请先看当前的 README 版本。想看 Core ML 这条路,见在 iOS App 中使用 Hugging Face 模型。

清理

试验很容易清理。我只删除了我的临时目录下的文件夹:hf-home 缓存(原版加两个量化版的 Qwen 文件共 1.7 GB)、转换出来的文件夹,以及虚拟环境(474 MB)。~/.cache 里什么都没留下。如果你没有设置 HF_HOME,模型在 ~/.cache/huggingface/hub。想找更多模型来试,可以看模型页面。

来源

均于 2026 年 11 月 2 日阅读,文中每条命令都在开头所述的那台 Mac 上运行过。

作者

独立开发者,在 Obelisk Club 做本地优先的 Mac 与 iOS 效率应用。 关于作者 →