微信扫码
与创始人交个朋友
我要投稿
今天,小纸条来和大家继续聊聊关于本机CPU来运行大模型应用的实战——如何使用搭载Apple Silicon这类ARM芯片(M1 / M1 Pro / M1 Max / M1 Ultra / M2)的 MacBook设备上,使用CPU来运行Stable Diffusion 模型!
为什么选择Stable Diffusion模型而不是最新的开源文生图最强框架Flux呢?虽然Stable Diffusion已经由于Stability团队自立门户,更新改名为了更强的Flux,但是Stable Diffusion存量的生态还是需要Flux慢慢追赶的,另外模型的部署万变不离其宗,而且我们如果想要在MAC上玩转SD,有Apple官方团队的大神直接开源了现成的项目给我们快速实践拿反馈,性价比多高!
这是一个开源项目:apple/ml-stable-diffusion,项目在apple的github上托管,作者是Apple Core ML Tools开源项目
(https://github.com/apple/coremltools)的主要工程师之一。
看到update时间,4h前还有更新,放心不少...
下面我们就来聊聊这个项目该如何简单、快速的上手。
本文中,我的实验环境是 Apple M2 CPU 的 MacBook Pro,机器内存容量为 32GB。同样还能够运行本文的设备包含:
2022 年生产的MacBook Air (M2)、13寸的 MacBook Pro (M2)、Mac Studio (2022)
2021 年生产的 14寸和16寸的 MacBook Pro、24寸的 iMac (M1)
2020 年生产的 Mac mini (M1)、MacBook Air (M1)、13寸的 MacBook Pro (M1)
搭载了 M1 芯片的第五代 iPad Pro
关于环境遇到过的坑都在文章最后的部分,希望大家不要遇到,但是遇到希望帮到大家(里里外外写了5天哦...留个赞赞吧)
1. 基础环境准备
1.1. 为MacOS设备安装 conda
先说下为什么要安装Conda。Conda是一个强大的开源包管理系统和环境管理器,是很多开源的模型和框架初始化环境的首选工具。这主要功于Conda跨系统支持、环境隔离、依赖性解析、版本管理和易于使用的特性。Conda允许用户在不同操作系统上创建隔离的环境,每个环境都可以拥有独立的软件包版本,从而有效避免项目间的依赖冲突。它还能够自动处理软件包之间的复杂依赖关系,简化了安装过程。此外,Conda支持版本控制,使得用户能够为每个项目安装和管理不同版本的软件包,这对于需要特定版本依赖的项目至关重要。
Conda的环境隔离功能似的环境配置可以被保存和共享,让其他开发者能够轻松复现相同的开发环境。此外,Conda还拥有一个庞大的软件包生态系统,尤其是在机器学习领域,许多常用的软件包可以通过Conda轻松安装,简化了环境的设置和管理,还提高了项目的可维护性和可扩展性,这些都是其在开源框架中被广泛采用的必要性和合理性所在。
了解了conda的必要性后,我们来开始环境的安装!我们可以从https://repo.anaconda.com/archive/进行下载,因为这里能够更加直观的看到,我们想要下载的目标文件的各种信息,比如:名称、版本、试用的系统、尺寸、更新时间、文件指纹。
为了更快的得到下载文件,可以通过“清华源”中的 Conda 镜像来加速下载过程。比如,官方的原始下载地址 https://repo.anaconda.com/archive/Anaconda3-2022.10-MacOSX-arm64.sh ,那么加速下载的地址就是:
https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2022.10-MacOSX-arm64.sh,完成 Conda 安装文件下载之后,我们可以执行 shasum -a 256 来验证下载文件的完整性:
shasum -a 256 ~/Downloads/Anaconda3-2022.10-MacOSX-arm64.sh
然后我们执行 bash Anaconda3-2022.10-MacOSX-arm64.sh进行安装,一路默认配置即可,完成程序的安装。
我们也可以将清华的镜像默认添加在我们的.condarc配置文件中,MAC系统的用户跟着我如下操作:
touch ~/.condarcnano ~/.condarc
将下面的清华源的内容复制进去,ctrl+X保存
完成后,使用 conda info 查看配置是否生效
1.2. 准备MacOS上安装Python运行环境
Conda安完成后,我们就可以用它来创建一个项目专用的干净的Python运行环境了。
通过检查 apple/ml-stable-diffusion/setup.py 文件,可以知道项目支持运行的环境有 Python 3.7 ~ Python 3.9,这里大家之后如果想本地跑别的模型,也最好先检查一下setup.py,避免装错了环境还要重装的时间成本。至于本次的python版本,大家选择3.7~3.9之间合适的就好
我们执行下面的命令来,来激活一个名为coreml_stable_diffusion的python的环境给项目使用
conda create -n coreml_stable_diffusion python=3.9 -y
执行完成后,我们指定的名为 coreml_stable_diffusion 的环境就初始化好了,接着执行下面的命令来切换到我们创建好的新环境
如下图,证明我们已经进入了初始化好的新的环境
conda activate coreml_stable_diffusion
接下来我们需要使用 pip 命令来安装程序依赖的软件包,这里我们同样可以将软件下载源更改为“清华源”,来加快下载的速度。
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
如图执行,就证明配置成功了。
2. 项目初始化
执行下面的命令,将项目clone到本地
git clone https://github.com/apple/ml-stable-diffusion.gitcd ml-stable-diffusionpip install -r requirements.txt
最后,我们看到顺利安装完成的控制台输出
至此,基础环境准备工作就都就绪了。
3. 转换PyTorch模型为Apple Core ML模型
基础环境就绪之后,我们需要转换 Huggingface 上的 PyTorch / TF 开放模型到 Apple Core ML 模型格式。项目仓库中 python_coreml_stable_diffusion/torch2coreml.py 文件中,封装了调用 coremltools.models.MLModel 工具方法来转换其他格式模型到 Core ML 模型的逻辑:
首先,我们需要获取一个huggingface上的token,我们在下面的网址中创建一个即可
https://huggingface.co/settings/profile
然后我们按照如下命令进行设置
# 设置 Hugging Face API Token 环境变量,记得图换掉export HUGGING_FACE_HUB_TOKEN=hf_XXXXX # 设置 Hugging Face 镜像站点export HF_ENDPOINT=https://hf-mirror.com # 运行脚本python -m python_coreml_stable_diffusion.torch2coreml \ --convert-unet \ --convert-text-encoder \ --convert-vae-decoder \ --convert-safety-checker \ --model-version runwayml/stable-diffusion-v1-5 \ -o ./models
命令行中的runwayml/stable-diffusion-v1-5还可以替换为CompVis/stable-diffusion-v1-4、stabilityai/stable-diffusion-2-base,选择方式如下:
1. 如果你需要一个稳定的、经过验证的模型,并且对生成图像的质量要求不是特别高,可以选择 CompVis/stable-diffusion-v1-4,是早期版本,生成的图像质量较好,但在某些方面可能不如后续版本
2. 如果你希望获得更好的图像质量和细节,并且需要一些额外的功能,可以选择 runwayml/stable-diffusion-v1-5,是对 v1.4 的改进版本,提供了更好的图像质量和细节
3. 如果你需要最新的技术和最好的图像质量,并且希望有更多的配置选项和灵活性,可以选择 stabilityai/stable-diffusion-2-base,是最新版本,引入了新的架构改进和更多的训练数据,生成的图像质量更高,支持更多的功能和配置选项
然后我们就进入了漫长的模型转化
看到图上的内容,证明转化完成啦(太不容易了),完成后我们可以在 ./models 目录,得到必须的四个模型
# du -hs ./models/*580M ./models/Stable_Diffusion_version_runwayml_stable-diffusion-v1-5_safety_checker.mlpackage235M ./models/Stable_Diffusion_version_runwayml_stable-diffusion-v1-5_text_encoder.mlpackage1.6G ./models/Stable_Diffusion_version_runwayml_stable-diffusion-v1-5_unet.mlpackage 95M ./models/Stable_Diffusion_version_runwayml_stable-diffusion-v1-5_vae_decoder.mlpackage
相比原来的模型,小点是点!
4. 运行转换后的模型
python -m python_coreml_stable_diffusion.pipeline \ --prompt "a photo of an astronaut riding a horse on mars" \ -i ./models \ -o ./output \ --compute-unit ALL \ --seed 93 \ --model-version runwayml/stable-diffusion-v1-5
命令含义如下:
1. python -m
python_coreml_stable_diffusion.pipeline
表示使用 Python 模块
python_coreml_stable_diffusion.pipeline 来运行脚本
2. --prompt "a photo of an astronaut riding a horse on mars"指定了生成图像的提示词,一个在火星上骑马的宇航员
3. -o ./output表示生成的图像将被保存在当前目录下的 ./output 文件夹中
4. --compute-unit ALL指定了 Core ML 模型在设备上的计算单元。ALL 表示使用所有可用的计算单元,包括 CPU 和 GPU(如果可用),如果你的设备只有 8GB 的内存,这里需要调整下 --compute-unit 跟着的参值为 ,ALL改为CPU_AND_NE,表示使用 CPU 和神经引擎(适用于 Apple 设备)
5. --seed 93参数指定了随机种子,使用相同的随机种子可以确保生成的图像具有可重复性
6. --model-version 表示我们当前使用了哪个模型,要和上一步转化的版本一致哦,默认会用CompVis_stable-diffusion-v1-4这个版本
程序运行之后,稍微等一下,看到图中的结果,就证明运行成功了
5. 通过页面的方式生成图片
代码贴在下面
import python_coreml_stable_diffusion.pipeline as pipeline import gradio as grfrom diffusers import StableDiffusionPipeline def init(args): pipeline.logger.info("Initializing PyTorch pipe for reference configuration") pytorch_pipe = StableDiffusionPipeline.from_pretrained(args.model_version, use_auth_token=True) user_specified_scheduler = None if args.scheduler is not None: user_specified_scheduler = pipeline.SCHEDULER_MAP[ args.scheduler].from_config(pytorch_pipe.scheduler.config) coreml_pipe = pipeline.get_coreml_pipe(pytorch_pipe=pytorch_pipe, mlpackages_dir=args.i, model_version=args.model_version, compute_unit=args.compute_unit, scheduler_override=user_specified_scheduler) def infer(prompt, steps): pipeline.logger.info("Beginning image generation.") image = coreml_pipe( prompt=prompt, height=coreml_pipe.height, width=coreml_pipe.width, num_inference_steps=steps, ) images = [] images.append(image["images"][0]) return images demo = gr.Blocks() with demo: gr.Markdown( "<center><h1>Core ML Stable Diffusion</h1>Run Stable Diffusion on Apple Silicon with Core ML</center>") with gr.Group(): with gr.Row(): # 替换 Box 为 Row with gr.Column(): with gr.Row(): text = gr.Textbox( label="Prompt", lines=11, placeholder="Enter your prompt", ) with gr.Row(): btn = gr.Button("Generate image") with gr.Row(): steps = gr.Slider(label="Steps", minimum=1, maximum=50, value=10, step=1) with gr.Column(): gallery = gr.Gallery( label="Generated image", elem_id="gallery" ) text.submit(infer, inputs=[text, steps], outputs=gallery) btn.click(infer, inputs=[text, steps], outputs=gallery) demo.launch(debug=True, server_name="0.0.0.0") if __name__ == "__main__": parser = pipeline.argparse.ArgumentParser() parser.add_argument( "-i", required=True, help=("Path to input directory with the .mlpackage files generated by " "python_coreml_stable_diffusion.torch2coreml")) parser.add_argument( "--model-version", default="CompVis/stable-diffusion-v1-4", help= ("The pre-trained model checkpoint and configuration to restore. " "For available versions: https://huggingface.co/models?search=stable-diffusion" )) parser.add_argument( "--compute-unit", choices=pipeline.get_available_compute_units(), default="ALL", help=("The compute units to be used when executing Core ML models. " f"Options: {pipeline.get_available_compute_units()}")) parser.add_argument( "--scheduler", choices=tuple(pipeline.SCHEDULER_MAP.keys()), default=None, help=("The scheduler to use for running the reverse diffusion process. " "If not specified, the default scheduler from the diffusers pipeline is utilized")) args = parser.parse_args() init(args)
执行启动命令如下
python -m python_coreml_stable_diffusion.web -i ./models --compute-unit ALL --model-version runwayml/stable-diffusion-v1-5
看到上面这样图,就意味着启动成功啦,我们打开浏览器:http://localhost:7860/
随便测试一个,yeah成功
6. 踩过的坑们
6.1. Conda系统版本错误导致pip install -r requirements.txt一直不成功
本人就在操作的过程中经历了pip install -r requirements.txt怎么尝试都不成功,结果定位到是conda下载的版本问题...
这里要特别注意一下,Conda 为 macOS 提供了 x86(Intel)和 ARM(Apple Silicon,如 M1、M2 芯片)两个版本,x86 (Intel) 版本:适用于基于 Intel 处理器的 Mac 电脑,而ARM (Apple Silicon) 版本:适用于基于 Apple Silicon 处理器(如 M1, M2 等)的 Mac 电脑,python也一样有对应两种架构的版本。如果我们没有安装与系统对应的版本,macOS Big Sur及更高版本支持通过 Rosetta 2帮我们让错误的版本运行,但是性能会下降。(就是因为即使下错了还能正常运行,所以找问题找了好久T- T)
如果我们使用 Homebrew 来安装 Miniconda,Homebrew 会自动为我们选择适合当前系统架构的版本,所以问题就来了!Homebrew如果指定的版本不对,那conda下的就不对,比如如果和我一样在x86的版本下的conda激活了python环境,那么本教程里的依赖是怎么样装都会报错的(比如mlx找不到)
我们可以用1.2那一步的conda info来查看自己安装的包对应的系统版本,如下图,virtual packages中显示的是x86_64,这就证明你下载的是一个x86的版本
而正确的应该是这样的
为了确保安装的是 ARM 版本的 Python,我们需要进一步验证和检查一些配置。详细的步骤如下:
1. 清理现有的 x86 版本,卸载现有的 Python:
arch -arm64 brew uninstall python@3.13
2. 清理 Homebrew 缓存,删除 Homebrew 的缓存目录以确保不会重新使用之前的下载。
rm -rf $(brew --cache)
3. 确保 Homebrew 使用 ARM 架构,设置环境变量
export HOMEBREW_ARCH=arm64
4. 确保 Homebrew 的路径和配置是正确的,检查 Homebrew 前缀,应该输出 /opt/homebrew 而不是 /usr/local。
arch -arm64 brew --prefix
5. 如果上一步输出 /opt/homebrew,则检查 PATH 环境变量:
## 确保你的 PATH 环境变量中包含了 /opt/homebrew/binecho $PATH ## 如果 /opt/homebrew/bin 不在 PATH 中,你可以通过以下方式添加它:export PATH="/opt/homebrew/bin:$PATH" ## 上述命令添加到你的 shell 配置文件(如 .zshrc 或 .bashrc)中,以便每次打开终端时都能生效## 如果输出是 /bin/zsh,则你需要编辑 .zshrc 文件;如果输出是 /bin/bash,则你需要编辑 .bashrc 文件。echo $SHELL ## 将下面的内容添加至你系统生效的.zshrc 或 .bashrc中 # Set Homebrew to use ARM architectureexport HOMEBREW_ARCH=arm64 # Add Homebrew's ARM path to PATHexport PATH="/opt/homebrew/bin:$PATH" ## 检查 HOMEBREW_ARCH 环境变量,应该输出 arm64echo $HOMEBREW_ARCH ## 检查 PATH 环境变量,应该看到 /opt/homebrew/bin 在 PATH 中echo $PATH
6. 如果上一步输出 /usr/local,则重新安装homebrew
## 验证 Homebrew 前缀,应该输出 /opt/homebrew,如果是/usr/local,则重新安装homebrewarch -arm64 brew --prefix ## 卸载现有的 Homebrew/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)" ## 重新安装 Homebrew,或者通过github(https://github.com/Homebrew/brew.git /opt/homebrew)下载zip解压/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
7. 更新 Homebrew,以确保所有配置都是最新的。
arch -arm64 brew update
8. 重新安装 ARM 版本的 conda,homebrew 会自动检测我们的 Mac 架构(x86 或 ARM)并下载相应的 Miniconda 版本
brew install --cask miniconda
9. 验证安装,检查coda,结果应该和我们1.2步骤中正确的结果一样
conda info
10. (按需)如果你想知道你的python下载的是哪个架构,可以这样来看,看结果是arm还是x86关键字
python3 -c 'import platform; print(platform.machine())'
11. 如果也需要更换的话,可以用同样的思路重新安装 ARM 版本的 Python,我们用arm举例。使用 arch -arm64 命令来确保在 ARM 架构下安装。
arch -arm64 brew install python
12. 验证安装,检查 Python 路径:
which python3
13. 验证 Python 版本和架构:
arch -arm64 /opt/homebrew/bin/python3 -c 'import platform; print(platform.platform())'
应该可以看到类似于 macOS-
6.2. pip install -r requirements.txt 特定包找不到
这里特别说明一下,如果大家(也会)遇到了某个包在清华源因为没有定时同步导致版本找不到,可以尝试下面的方式。
比如遇到像下面mlx的包找不到的情况
然后尝试不走代理直接下载也还是不行,绕过二进制包强行使用源码还都是不行!
then,打开下面的网站
https://pypi.org/project/mlx/#files
搜索到自己丢失的那个包的包名
下载完成后,如果是像这样的.whl文件,可以使用以下命令来安装,注意路径要正确:
pip install /path/to/mlx-0.18.1-py3-none-any.whl
6.3. 模型转化失败
在执行模型转化的时候,出现以下问题:
coremltools 模块导入失败:libmilstoragepython 和 libcoremlpython 模块没有被正确导入。
torchvision 循环导入问题:torchvision 模块在初始化过程中出现了循环导入的问题,导致 AttributeError: partially initialized module 'torchvision' has no attribute 'extension'。
表明 coremltools 的某些子模块没有被正确安装,我们尝试重新安装 coremltools
6.4. 为什么本机安装的python是3.10,却可以用conda激活的其他版本的python?
在我们的系统中,可以安装多个版本的 Python,并且可以使用 Conda 来创建和管理不同版本的 Python 环境。即使在系统中安装了 Python 3.10,我们仍然可以创建并激活使用 Python 3.9 或 3.8 的 Conda 环境。这是因为 Conda 管理的是虚拟环境,每个环境可以有自己的 Python 版本和其他依赖项。
当我们使用 Conda 创建一个环境并安装特定版本的 Python 时,这个 Python 版本是与该环境绑定的。Conda 环境中的所有包(包括 Python 解释器)都存储在该环境的目录中。因此,当我们删除或释放一个 Conda 环境时,该环境中安装的所有包(包括 Python 解释器)也会被删除。
我们可以通过 Conda 来创建和管理不同的 Python 环境,甚至即使我们的系统上没有全局安装 Python也可以。Conda 是一个包管理和环境管理系统,它能够独立地安装和管理 Python 及其依赖库。
当我们使用 Conda 创建一个新的环境时,可以指定所需的 Python 版本,Conda 会下载并安装该版本的 Python 到新环境中。所以其实我们也不需要在系统级别单独安装 Python,因为每个 Conda 环境都会包含自己的 Python 解释器副本。
6.5. 模型转化失败
执行模型转化时因为网络连接失败
python -m python_coreml_stable_diffusion.torch2coreml \ --convert-unet \ --convert-text-encoder \ --convert-vae-decoder \ --convert-safety-checker \ --model-version runwayml/stable-diffusion-v1-5 \ -o ./models
我们可以直接去官网把模型下下来!
https://huggingface.co/models?sort=trending&search=stable-diffusion-2-base
https://huggingface.co/stabilityai/stable-diffusion-2-1-base
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2024-03-30
2024-05-09
2024-07-07
2024-07-01
2024-06-24
2024-07-23
2024-06-08
2024-06-05
2024-06-21
2024-07-11
2024-11-12
2024-11-11
2024-10-29
2024-10-22
2024-10-18
2024-10-16
2024-10-15
2024-10-10