李沐-动手学深度学习d2l包安装及m1 gpu加速踩坑记录
- 前段时间一直在看沐神的 动手学深度学习 , 个人是已经看完了,也顺带抛砖引玉放一下自己的 学习笔记 , 之前一直是用服务器跑的代码,最近发现pytorch已经支持了m1mac的加速,据说能有1080的速度,作为一个调参侠那是万万不能忍,刚好公司也发了一台最新的mac,打算安装试一试,下面是安装中碰到的坑。
环境安装
- miniconda已经原生支持了m1,pytorch要安装支持m1加速版本,本文全程使用iterm2安装的,需要一点点命令行的知识。
- 安装与激活
# 下载
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh
# 给权限
chmod +x Miniconda3-latest-MacOSX-arm64.sh
sh Miniconda3-latest-MacOSX-arm64.sh
# 安装完后刷新
source ~/.zshrc
# 首先必须确保自己的mac系统版本在12.3以上
import platform
platform.platform()
- 创建指定环境的conda环境
# 创建指定环境
CONDA_SUBDIR=osx-arm64 conda create -n ml python=3.9 -c conda-forge
# 修改 CONDA_SUBDIR 为 osx-arm64
conda env config vars set CONDA_SUBDIR=osx-arm64
# 重新对conda环境进行激活
conda activate
conda activate ml
- 安装支持m1加速版本的pytorch,mac系统不低于12.3
# MPS acceleration is available on MacOS 12.3+
pip3 install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cpu
- 2022年10月24日更新---------------------------
- transformers的安装也需要先安装环境
- 如果是NLP方向的小伙伴,还可以顺带安装上transformers,学完沐神的视频后,真正工程应用还是得从这开始,所以早晚都得装。
# 直接在 ARM64 环境中安装可能会导致错误, 这里最好先构建rust环境
curl — proto ‘=https’ — tlsv1.2 -sSf https://sh.rustup.rs | sh
# 安装transformers
pip install transformers datasets
- 测试是否已经支持mps
- 到目前为止,第一步算是解决了
d2l安装
- m1的兼容性真的是一言难尽,简单来说,直接在m1上pip install d2l是无法安装的,主要原因就是d2l==0.17.3 这个包需要 numpy==1.18.5, 但是m1 mac不支持直接pip或者 conda 安装这个版本的numpy。
- 尝试了网上各种办法,什么离线下载安装,什么docker安装,效果都一言难尽,不过在看d2l源码的时候,发现沐神其实简单粗暴的把所有代码都集成到了d2l文件夹下面,我们可以 下载源码 后解压查看。
- 那么既然沐神所有代码都引用的这个文件,那么我们直接下载这个源码不就好了嘛,这个源码同样可以在我笔记中找到,沐神一般调用d2l的方式是from d2l import torch as d2l,那么我们只要在自己项目下新建个d2l文件夹,把torch.py放进去,就直接解决问题了,另外d2l导入了numpy,pandas,matplotlib这些常用包,自己手动安装就好了。
m1加速
- 最新版本pytorch是支持m1GPU加速的,有免费性能为啥不白嫖呢(bushi),首先我们要测试一下自己的设备是否已经支持了gpu加速,输入torch.device('mps')后如果没有报错,那么就表示没有问题。
- 沐神写d2l的时候,还没有考虑到m1mac加速的情况,所以这里我们只能对源码进行修改,以增加对m1的支持,在源码里面,搜gpu,将 try_gpu和try_all_gpus函数进行修改
# 修改try gpu函数
def try_gpu(i=0):
"""Return gpu(i) if exists, otherwise return cpu().
Defined in :numref:`sec_use_gpu`"""
if torch.cuda.device_count() >= i + 1:
return torch.device(f'cuda:{i}')
try:
return torch.device('mps')
except:
return torch.device('cpu')
# 修改try gpu函数
def try_all_gpus():
"""Return all available GPUs, or [cpu(),] if no GPU exists.
Defined in :numref:`sec_use_gpu`"""
devices = [torch.device(f'cuda:{i}')