在 M1 Mac 上构建高效的 Python 深度学习环境

当手头的 MacBook 从 Intel 切换到 Apple Silicon,许多开发者第一次运行 pip install 时都会心头一紧:为什么这么慢?明明是更强大的芯片,却感觉像是在用 Rosetta 翻译一层又一层的代码。这背后其实是一个关键问题——你是否真正跑在了原生 ARM64 架构上?

M1 芯片的强大不仅在于性能提升,更在于其能效比和统一内存架构(UMA),但这些优势只有在软件栈完全适配的前提下才能释放。而深度学习这类高负载任务,尤其依赖底层计算框架与硬件的紧密协同。因此,搭建一个原生支持 ARM64、可隔离管理、且能调用 Metal GPU 加速的开发环境,成了每个 M1 用户的必修课。

Miniconda 正是解决这一挑战的理想工具。它不像 Anaconda 那样臃肿,而是只保留核心组件,让你从零开始精确控制每一个依赖项。更重要的是,Conda 的虚拟环境机制完美支持多项目并行开发,避免了“这个项目用 PyTorch 2.0,那个项目只能用 1.12”的版本地狱。


安装前准备:先打好地基

任何稳健的开发环境都离不开基础编译工具链。尽管 M1 Mac 出厂即强,但仍需手动安装 Xcode 命令行工具:

xcode-select --install

这条命令会为你带来 clang 编译器、make 构建系统以及 git 版本控制工具。它们看似不起眼,却是后续通过 pip 或 conda 编译 C/C++ 扩展模块的关键支撑。比如某些 Python 包需要本地编译 native extension 时,如果没有这些工具,就会直接报错退出。

如果你看到提示 “command line tools are already installed”,那说明系统已经就绪,可以跳过这一步。


获取正确的 Miniconda 安装包

Miniconda 是 Anaconda 的精简版,仅包含 Python 解释器和 Conda 包管理器,非常适合追求轻量与灵活性的研究人员或工程师。

重点来了:必须下载适用于 Apple Silicon(ARM64)的版本。官网提供了两个 macOS 版本,很容易混淆:

  • Miniconda3-latest-MacOSX-x86_64.sh —— Intel 架构
  • Miniconda3-latest-MacOSX-ARM64.sh —— M1/M2 等 Apple Silicon 芯片专用

选错就意味着你的 Python 运行在 Rosetta 2 模拟层下,白白浪费 M1 的性能潜力。

推荐使用终端下载,确保准确无误:

curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-ARM64.sh

这样不仅能避免浏览器自动重定向到错误版本,还能方便地写入自动化脚本中重复使用。


执行安装并初始化环境

进入下载目录后执行安装脚本:

bash Miniconda3-latest-MacOSX-ARM64.sh

安装过程中有几个关键点需要注意:

  1. 阅读许可协议后输入 yes
  2. 建议使用默认路径 ~/miniconda3 —— 方便后续查找和维护
  3. 最后询问是否初始化 Conda 时,选择 yes

初始化的作用是让 Conda 自动注入 shell 启动脚本,在每次打开终端时激活 base 环境。如果当时没选也没关系,后面还可以手动补救。

安装完成后关闭当前终端窗口,重新打开一个新的终端,你会看到提示符前出现了 (base),说明 Conda 已成功加载。


配置 Zsh Shell(macOS 默认 Shell)

现代 macOS 使用 Zsh 作为默认登录 Shell。如果你从未修改过 shell 类型(可通过 echo $SHELL 确认),那么需要将 Conda 初始化代码写入 ~/.zshrc 文件中。

如果安装未自动配置?

运行以下命令生成初始化脚本:

~/miniconda3/bin/conda init zsh

该命令会自动检测 .zshrc 是否存在 Conda 配置段,若没有则追加一段类似如下的代码块:

# >>> conda initialize >>>
__conda_setup="$('/Users/yourname/miniconda3/bin/conda' 'shell.zsh' 'hook' 2>/dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/Users/yourname/miniconda3/etc/profile.d/conda.sh" ]; then
        . "/Users/yourname/miniconda3/etc/profile.d/conda.sh"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

这段脚本的核心作用是在每次启动 shell 时动态加载 Conda 命令,使其可在任意位置调用 conda activate

⚠️ 注意事项:不要手动复制粘贴这段代码而不理解其来源。最好始终优先使用 conda init 命令,因为它会根据实际路径自动生成正确内容。

完成编辑后,立即应用更改:

source ~/.zshrc

此时你应该能看到终端提示符前出现 (base),表示 Conda 环境已激活。


验证 Conda 是否正常工作

最简单的验证方式是查看版本信息:

conda --version
# 输出示例:conda 24.1.2

再检查当前存在的环境列表:

conda info --envs

输出中应至少包含 base 环境,并且当前激活环境前有星号标记。

如果不小心把环境搞乱了,或者想彻底重装,也可以完全卸载 Miniconda:

# 删除主安装目录
rm -rf ~/miniconda3

# 清理配置与缓存
rm -rf ~/.conda
rm -rf ~/.condarc

# 移除 shell 配置文件中的初始化代码
vim ~/.zshrc  # 找到并删除 # >>> conda initialize >>> 至 <<< 的整段内容

清理完毕后即可重新运行安装脚本,实现干净重启。


提速利器:配置国内镜像源

由于官方 Conda 仓库位于境外,直接使用常会出现超时或下载缓慢的问题。为此,推荐切换为国内高校提供的镜像源,例如中科大 USTC 或清华大学 TUNA。

添加中科大镜像通道:

conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/main/
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/cloud/msys2/

同时开启通道 URL 显示以便调试:

conda config --set show_channel_urls yes

如果你更习惯清华源,也可以替换为:

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/

这些镜像通常每日同步一次,稳定性良好,能显著提升包安装效率。


创建独立的开发环境

为了防止不同项目的依赖冲突(比如一个项目需要 TensorFlow 2.12,另一个只能兼容 2.10),强烈建议为每个项目创建独立的 Conda 环境。

以创建名为 ml-dev 的通用机器学习环境为例:

conda create -n ml-dev python=3.9
conda activate ml-dev

激活后,所有 pip installconda install 操作都将局限于该环境中,不会影响全局或其他项目。

关于 Python 版本的选择,目前最稳妥的是 3.8 ~ 3.10。虽然 Python 3.11+ 已发布,但由于部分科学计算库尚未完全适配 ARM64 架构下的新特性,可能会遇到编译失败或运行异常的情况。保持适度保守,往往能让开发过程更顺畅。


安装 TensorFlow:发挥 Apple Silicon 的 GPU 实力

Apple 为 M1 及后续芯片专门优化了 TensorFlow 的 macOS 发行版,通过 Metal 图形 API 实现 GPU 加速。这套组合被称为 tensorflow-macos + tensorflow-metal,是由 Apple 官方团队维护的高性能方案。

首先创建专用环境:

conda create -n tf-metal python=3.9
conda activate tf-metal

接着安装由 Apple 提供的核心依赖包:

conda install -c apple tensorflow-deps==2.13.0

这个包非常关键,它会自动安装一系列经过验证的底层组件,包括 NumPy、SciPy、Clang 编译器等,确保整个技术栈兼容性最佳。你可以根据需求调整版本号(如 2.12.0),但务必保证与后续安装的 tensorflow-macos 版本一致。

然后使用 pip 安装主程序和 Metal 插件:

pip install tensorflow-macos==2.13.0
pip install tensorflow-metal

其中:
- tensorflow-macos 是 Apple 维护的原生 macOS 版本
- tensorflow-metal 是启用 GPU 加速的插件,利用 Metal Performance Shaders 实现矩阵运算加速

安装完成后,测试是否成功启用 Metal:

import tensorflow as tf

print("TensorFlow Version:", tf.__version__)
print("Built with CUDA:", tf.test.is_built_with_cuda())  # 应为 False
print("GPU Available:", tf.config.list_physical_devices('GPU'))

预期输出中应包含:

GPU Available: [PhysicalDevice(name='/physical_device:METAL:0', device_type='METAL')]

这表明 Metal 设备已被识别并可用于计算。你可以进一步运行简单的矩阵乘法来验证加速效果:

tf.random.set_seed(42)
a = tf.random.normal([1000, 1000])
b = tf.random.normal([1000, 1000])
c = tf.matmul(a, b)
print("Matrix multiplication completed.")

一旦看到顺利输出,恭喜你,已经跑通了完整的 CPU+GPU 协同流水线。


安装 PyTorch:无缝接入 MPS 后端

PyTorch 对 Apple Silicon 的支持也非常成熟。自 1.12 版本起,官方就开始提供原生 ARM64 构建包,并通过 MPS(Metal Performance Shaders)后端实现 GPU 加速。

进入你的目标环境(如 ml-dev 或新建 pt-metal):

conda activate ml-dev
pip install torch torchvision torchaudio

注意:这里不要使用 conda install pytorch,因为传统 conda 渠道可能仍指向 x86_64 构建版本,导致无法启用 MPS。

安装完成后,验证是否可用 Metal 加速:

import torch

print("PyTorch Version:", torch.__version__)
print("MPS Available:", torch.backends.mps.is_available())
print("MPS Built:", torch.backends.mps.is_built())

if torch.backends.mps.is_available():
    device = torch.device("mps")
    print("Using device:", device)

    x = torch.rand(1000, 1000).to(device)
    y = torch.rand(1000, 1000).to(device)
    z = torch.mm(x, y)
    print("Metal-accelerated matrix multiply succeeded.")

只要输出中 is_available() 返回 True,就说明 Metal 加速已就绪。

💡 小贴士:MPS 并非对所有操作都支持加速。对于不支持的操作,PyTorch 会自动回退到 CPU 执行,因此整体性能提升取决于具体模型结构。一般而言,卷积、线性层、激活函数等常见操作均有良好支持。


最终确认:我们真的跑在 ARM64 上吗?

一切看似顺利,但还有一个终极问题:我们是不是还在 Rosetta 2 的模拟层里兜圈子?

最简单的方法是运行:

arch

如果输出是 arm64,说明当前 shell 运行在原生模式下。

再深入一步,检查 Python 自身的架构:

import platform
print(platform.machine())      # 应输出 'arm64'
print(platform.processor())    # 应输出 'arm'

此外,打开「活动监视器」→「CPU」标签页,运行一段 Python 脚本,查看“种类”列:

  • 若显示 Apple,表示运行在 ARM64 原生模式
  • 若显示 Intel,说明正被 Rosetta 2 模拟运行

只有原生 ARM64 才能充分发挥 M1 芯片的算力与能效优势。尤其是深度学习训练这类长时间高负载任务,原生运行带来的不仅是速度提升,更是续航时间的显著延长。


让环境可复现:导出为 YAML 配置文件

一个好的工程实践是将环境配置固化下来,便于团队协作或未来重建。

你可以将常用依赖导出为 environment.yml

# environment.yml
name: ml-dev
channels:
  - defaults
  - conda-forge
dependencies:
  - python=3.9
  - pip
  - numpy
  - scipy
  - jupyter
  - pip:
    - torch
    - torchvision
    - torchaudio
    - tensorflow-macos==2.13.0
    - tensorflow-metal

以后只需一条命令即可重建相同环境:

conda env create -f environment.yml

这种方式特别适合课程教学、实验室部署或多设备同步场景,真正做到“一次定义,处处运行”。


这套基于 Miniconda 的 M1 开发环境,既轻量又强大。它避开了 Anaconda 的臃肿,充分利用了 Conda 的环境隔离能力,结合 Apple 官方优化的深度学习后端,实现了真正的原生 ARM64 + Metal GPU 加速。无论是做算法研究、模型复现,还是日常工程开发,都能提供稳定高效的体验。

更重要的是,这种构建思路本身具有延展性——当你未来接触新的框架或工具时,也能沿用同样的方法论:选对架构 → 隔离环境 → 配置镜像 → 验证运行。这才是技术掌控感的真正来源。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐