如何在 Apple Silicon 上做机器学习:MLX 新手实战指南
【免费下载链接】mlxMLX: An array framework for Apple silicon项目地址: https://gitcode.com/GitHub_Trending/ml/mlx
MLX 是 Apple 机器学习研究团队推出的、面向 Apple silicon 的数组框架(array framework)。它的 Python API 与 NumPy 高度相似,内置延迟计算、统一内存模型和可组合的函数变换(自动微分、向量化),可以在 Mac 上直接训练和推理模型。如果你熟悉 PyTorch 的写法、想把代码搬到 Apple Silicon 设备,或者想在 MacBook 上跑本地模型,这个项目值得花一小时上手。
安装命令怎么选:三种场景
根据你的运行环境,三选一即可:
pip install mlx # Apple Silicon Mac(需 macOS >= 14.0、原生 Python >= 3.10) pip install mlx[cuda12] # Linux + NVIDIA GPU(SM 7.5 及以上架构) pip install mlx[cpu] # Linux 纯 CPU 版本在 Mac 上如果pip找不到匹配版本,多半是 Python 不是原生的 arm 版本:运行python -c "import platform; print(platform.processor())",输出应为arm,如果是i386请换成原生 Python(比如通过 Conda 安装)。
5 分钟跑通第一个数组:先理解延迟计算
下面这段代码演示了 MLX 最核心的行为——操作先记录、后执行:
import mlx.core as mx a = mx.array([1, 2, 3, 4]) b = mx.array([1.0, 2.0, 3.0, 4.0]) c = a + b # 此时 c 只是计算图上的一个"配方",尚未真正计算 mx.eval(c) # 显式触发计算 print(c) # array([2, 4, 6, 8], dtype=float32)你会发现c = a + b之后并没有立即产生数值,MLX 只是在记录一张动态计算图;只有在mx.eval、打印数组、调用.item()或转成 numpy 时才会真正落盘计算。这个设计的直接好处是:图可以在执行前被变换(求导、向量化),而且最终没被使用的输出不会白算。更多细节可以看仓库里的说明:docs/src/usage/lazy_evaluation.rst
统一内存:在操作时指定设备,而不是搬移数组
Apple Silicon 的 CPU 和 GPU 直接共享同一个内存池,MLX 完全利用了这一点:创建数组时不指定位置,而是在调用操作时通过stream参数指定设备:
a = mx.random.normal((100,)) b = mx.random.normal((100,)) mx.add(a, b, stream=mx.cpu) # 让 CPU 算 mx.add(a, b, stream=mx.gpu) # 让 GPU 算,与上一条并行执行这两个操作互不依赖,MLX 会并行调度;如果第二条依赖第一条的结果,调度器会自动在两个 stream 之间插入依赖,不需要你手动同步。官方文档里有个实测例子(M1 Max):矩阵乘法放 GPU、几百次小的exp放 CPU,总耗时约 1.4ms,比全部堆在 GPU 上(2.8ms)快一倍。
可组合的函数变换:求导和向量化各一行
MLX 提供了mx.grad、mx.vmap、mx.jvp、mx.vjp、mx.value_and_grad等变换,并且可以任意嵌套组合。比如求二阶导就是mx.grad(mx.grad(mx.sin))(x),mx.grad(mx.vmap(mx.grad(fn)))这样的组合也是合法的。两个最常用的模式:
- 训练时用
mx.value_and_grad(fn)一次拿到函数值和梯度,避免重复计算前向图; - 批量推理时给模型外层套一个
mx.vmap(model),自动沿新维度向量化。
保存与加载模型:4 种序列化格式
mx.load会根据文件扩展名自动识别格式,支持.npy(单数组)、.npz(多数组)、.safetensors和.gguf(后两者也常用于交换模型权重):
a, b = mx.array([1.0]), mx.array([2.0]) mx.savez("arrays", a, b=b) # 存为 arrays.npz mx.save_safetensors("arrays", {"a": a, "b": b}) # 存为 safetensors state = mx.load("arrays.npz") # 返回 {名称: 数组} 的字典动手示例:跑仓库自带的训练脚本
仓库里有一个自包含的线性回归训练脚本:examples/python/linear_regression.py,直接用python examples/python/linear_regression.py运行即可。它的流程值得逐行读一遍:生成随机设计矩阵X和带噪声的标签y→ 定义损失0.5 * mx.mean(mx.square(X @ w - y))→ 用mx.grad(loss_fn)拿到梯度函数 → 循环 10000 次做w = w - lr * grad并mx.eval(w)固化结果 → 最后打印损失、与真实参数的距离和吞吐(it/s)。你可以把它当模板,替换成自己的数据就得到一个最小训练闭环。
排坑与性能:eval、内存、GPU 分析
- 忘记 eval 会导致计时失真:训练循环里如果不 eval,计算图会一直累积,
time.perf_counter()测到的只是建图时间。每步(或每几步)eval 一次参数,既是正确性也是性能问题。 - 峰值内存可以省一半:得益于延迟计算,先以 float32 实例化大模型、再换成 float16 权重,中间不会真的算出 float32 那份数据,峰值内存接近减半。
- 用 Metal 调试器分析 GPU:以
-DMLX_METAL_DEBUG=ON构建后,调用mx.metal.start_capture()/mx.metal.stop_capture()(需配合MTL_CAPTURE_ENABLED=1环境变量)就能捕获 GPU 追踪文件,在 Xcode 里回放。指南在 docs/src/dev/metal_debugger.rst。
- 多设备张量并行:要把大模型分片到多个设备时,
mlx.nn提供了AllToShardedLinear和ShardedToAllLinear等现成分层,两者前后衔接可以省掉中间通信。完整示例见 examples/python/distributed_tensor_parallel.py。
去哪继续学
- 快速上手:docs/src/usage/quick_start.rst
- 更多示例:
examples/python/(含逻辑回归、分布式数据/张量并行、量化推理)
建议你先pip install mlx,然后原样跑一遍examples/python/linear_regression.py,把延迟计算和mx.eval的节奏跑熟,再动手替换成自己的数据。等你熟悉了这条主线,函数变换和张量并行这两块会顺理成章地接上。
【免费下载链接】mlxMLX: An array framework for Apple silicon项目地址: https://gitcode.com/GitHub_Trending/ml/mlx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考