本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 [署名 4.0 国际 (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/deed.zh) 本文作者: 苏洋 创建时间: 2022年12月10日 统计字数: 22672字 阅读时间: 46分钟阅读 本文链接: https://soulteary.com/2022/12/10/play-the-stable-diffusion-model-on-macbook-devices-with-m1-and-m2-chips.html ----- # 在搭载 M1 及 M2 芯片 MacBook设备上玩 Stable Diffusion 模型 本篇文章,我们聊了如何使用搭载了 Apple Silicon 芯片(M1 和 M2 CPU)的 MacBook 设备上运行 Stable Diffusion 模型。 ## 写在前面 在上一篇文章[《使用 Docker 来快速上手中文 Stable Diffusion 模型:太乙》](https://soulteary.com/2022/12/09/use-docker-to-quickly-get-started-with-the-chinese-stable-diffusion-model-taiyi.html)中,我们聊过了如何使用配备了“传统的 Nvidia 显卡”的设备(云服务器)来运行 Stable Dif fusion 模型。在之前的文章中我提到过,接下来将聊聊如何使用 CPU 来运行 “SD 模型应用”。 本篇文章,我们就先从 Apple Silicon 这类 ARM 芯片开始(M1 / M1 Pro / M1 Max / M1 Ultra / M2),用 CPU 来运行 Stable Diffusion 。十一月末,为 [Apple Core ML Tools 开源项目](https://github.com/apple/coremltools)贡献代码的主要工程师之一,正式发布了一个新的开源项目:[apple/ml-stable-diffusion](https://github.com/apple/ml-stable-diffusion)。 下面我们就来聊聊这个项目该如何简单、快速的上手。 ### 支持运行的设备 本文中,我的实验环境是 Apple M2 CPU 的 MacBook Pro,机器内存容量为 16GB。同样还能够运行本文的设备包含: - 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 ## 基础环境准备 想要在 ARM 芯片的 Mac 设备上运行这个模型应用,我们需要做几件事: - 准备 Python 基础运行环境 - 准备软件运行所需要的软件包 ### 为 MacOS 设备安装 Python 环境管理工具 在[《用让新海诚本人惊讶的 AI 模型制作属于你的动漫视频》](https://soulteary.com/2022/06/04/create-your-own-anime-video-with-an-ai-model-that-surprised-makoto-shinkai.html)这篇文章中,我分享过关于“使用 Conda 简化 Python 程序环境准备工作”,正巧年底 Conda 版本更新,这里就顺带也更新一个版本的安装和使用方式。 ![CONDA 开源项目](https://attachment.soulteary.com/2022/12/10/conda.jpg) 虽然我们可以从 Conda 官方网站的下载页面得到合适的安装程序。不过,我一般从 [Conda 官方的 “Archive” 页面](https://repo.anaconda.com/archive/)进行下载,因为能够更加直观的看到,我们想要下载的目标文件的各种信息,比如:名称、版本、尺寸、更新时间、文件指纹。 ```bash Filename Size Last Modified SHA256 Anaconda3-2022.10-MacOSX-arm64.sh 472.5M 2022-10-17 16:15:38 200700077db8eed762fbc996b830c3f8cc5a2bb7d6b20bb367147eb35f2dcc72 ``` 这里为了更快的得到下载文件,可以通过“清华源”中的 [Conda 镜像](https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/)来加速下载过程。比如,官方的原始下载地址 `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` 来验证下载文件的完整性: ```bash shasum -a 256 ~/Downloads/Anaconda3-2022.10-MacOSX-arm64.sh 200700077db8eed762fbc996b830c3f8cc5a2bb7d6b20bb367147eb35f2dcc72 /Users/soulteary/Downloads/Anaconda3-2022.10-MacOSX-arm64.sh ``` 接着,执行 `bash Anaconda3-2022.10-MacOSX-arm64.sh` 进行安装,“一路 Next”,完成程序的安装即可。 和之前的文章里的观点相同,国内用户推荐在使用 Conda 时,先进行软件源配置操作。这样可以减少在下载软件包过程中造成的不必要时间浪费。使用 `vi ~/.condarc` 编辑 Conda 配置文件,在其中加入下面的内容(以“清华源”为例): ```bash channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/ - defaults show_channel_urls: true ``` 在完成了 `~/.condarc` 的内容修改后,重启 Shell。然后,使用 `conda info` 查看配置是否生效: ```bash conda info active environment : base active env location : /Users/soulteary/anaconda3 shell level : 1 user config file : /Users/soulteary/.condarc populated config files : /Users/soulteary/.condarc conda version : 22.9.0 conda-build version : 3.22.0 python version : 3.9.13.final.0 virtual packages : __osx=13.0.1=0 __unix=0=0 __archspec=1=arm64 base environment : /Users/soulteary/anaconda3 (writable) conda av data dir : /Users/soulteary/anaconda3/etc/conda conda av metadata url : None channel URLs : https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/osx-arm64 https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/noarch https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/osx-arm64 https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/noarch https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/osx-arm64 https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/noarch https://repo.anaconda.com/pkgs/main/osx-arm64 https://repo.anaconda.com/pkgs/main/noarch https://repo.anaconda.com/pkgs/r/osx-arm64 https://repo.anaconda.com/pkgs/r/noarch package cache : /Users/soulteary/anaconda3/pkgs /Users/soulteary/.conda/pkgs envs directories : /Users/soulteary/anaconda3/envs /Users/soulteary/.conda/envs platform : osx-arm64 user-agent : conda/22.9.0 requests/2.28.1 CPython/3.9.13 Darwin/22.1.0 OSX/13.0.1 UID:GID : 502:20 netrc file : None offline mode : False ``` 如果输出的内容中包含我们刚刚设置的“清华源”,就说明我们的配置生效了。 ### 快速准备 MacOS 上的 Python 运行环境 在完成 Conda 的安装之后,我们就可以用它来快速的创建不影响本地机器环境(MacOS),只和项目关联的干净的 Python 运行环境了。 检查 [apple/ml-stable-diffusion/setup.py](https://github.com/apple/ml-stable-diffusion/blob/main/setup.py) 文件,我们可以看到,项目支持运行的环境有 Python 3.7 ~ Python 3.9,那我们随便取个中间数 3.8 吧: ```bash conda create -n coreml_stable_diffusion python=3.8 -y ``` 等待上面的命令执行完毕,我们指定的名为 `coreml_stable_diffusion` 的环境就初始化好啦,环境使用的具体 Python 版本为 3.8 (虚拟环境的版本可以和系统不一样)。 当然,默认创建好之后,并不会直接切换到创建好的新环境,我们还需要使用命令,来完成环境的切换。 ```bash conda activate coreml_stable_diffusion ``` 当命令执行完毕之后,我们会看到终端前的展示字符串会出现变化,展示我们当前正所处于的虚拟环境: ```bash (base) # conda activate coreml_stable_diffusion (coreml_stable_diffusion) # ``` 因为,我们后续需要使用 `pip` 命令来安装程序依赖的软件包,为了减少时间的浪费,这里我们同样可以使用命令,来调整软件下载源为“清华源”: ```bash pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple ``` 如果我们关闭了终端,你会发现环境“失效了”,这时还是可以用和上文中提到的相同的命令 `conda activate`,来激活(切换)回我们之前配置好的环境。 ```bash conda activate coreml_stable_diffusion ``` ### 避免 MacOS 上 Tokenizers 软件包安装出错 如果你经常在 MacOS 上折腾 “Huggingface” 等项目,尤其是运行相对新一些的模型项目,大概率会遇到 [“Failed building wheel for tokenizers”](https://github.com/huggingface/transformers/issues/2831)这个问题。 解决问题的方法很简单,只需要在 MacOS 上完成 Rust 的安装即可: ```bash curl https://sh.rustup.rs -sSf | sh ``` 完成安装之后,可以使用 `rustc --version` 来做一个简单的命令“可执行”的验证: ```bash # rustc --version rustc 1.65.0 (897e37553 2022-11-02) ``` 当然,为了加速 rust 软件包的下载,同样建议在 Rust 的配置文件(`~/.cargo/config`)中,完成“清华源”的配置: ```bash # vi ~/.cargo/config [source.crates-io] registry = "https://github.com/rust-lang/crates.io-index" replace-with = 'tuna' [source.tuna] registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git" ``` 完成配置文件的保存,接下来在遇到需要 Rust 编译,或下载依赖包的时候,速度也会变的飞快。 如果你没有补全 `rustc` 的依赖,那么大概率会遇到类似下面的报错: ```bash Building wheels for collected packages: pyyaml, tokenizers Building wheel for pyyaml (pyproject.toml) ... done Created wheel for pyyaml: filename=PyYAML-6.0-cp38-cp38-macosx_11_0_arm64.whl size=45335 sha256=e27236fa2771f8d6ffbba947c48931a8fcf95ad33d77b91d4c693d04d5344710 Stored in directory: /Users/soulteary/Library/Caches/pip/wheels/fe/be/21/a238a4532fd03d32998d6a07c6b4f572ea8cb4eaa89ddc2a41 Building wheel for tokenizers (pyproject.toml) ... error error: subprocess-exited-with-error × Building wheel for tokenizers (pyproject.toml) did not run successfully. │ exit code: 1 ╰─> [51 lines of output] running bdist_wheel running build running build_py creating build creating build/lib.macosx-11.1-arm64-cpython-38 creating build/lib.macosx-11.1-arm64-cpython-38/tokenizers copying py_src/tokenizers/__init__.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers creating build/lib.macosx-11.1-arm64-cpython-38/tokenizers/models copying py_src/tokenizers/models/__init__.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/models creating build/lib.macosx-11.1-arm64-cpython-38/tokenizers/decoders copying py_src/tokenizers/decoders/__init__.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/decoders creating build/lib.macosx-11.1-arm64-cpython-38/tokenizers/normalizers copying py_src/tokenizers/normalizers/__init__.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/normalizers creating build/lib.macosx-11.1-arm64-cpython-38/tokenizers/pre_tokenizers copying py_src/tokenizers/pre_tokenizers/__init__.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/pre_tokenizers creating build/lib.macosx-11.1-arm64-cpython-38/tokenizers/processors copying py_src/tokenizers/processors/__init__.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/processors creating build/lib.macosx-11.1-arm64-cpython-38/tokenizers/trainers copying py_src/tokenizers/trainers/__init__.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/trainers creating build/lib.macosx-11.1-arm64-cpython-38/tokenizers/implementations copying py_src/tokenizers/implementations/byte_level_bpe.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/implementations copying py_src/tokenizers/implementations/sentencepiece_unigram.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/implementations copying py_src/tokenizers/implementations/sentencepiece_bpe.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/implementations copying py_src/tokenizers/implementations/base_tokenizer.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/implementations copying py_src/tokenizers/implementations/__init__.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/implementations copying py_src/tokenizers/implementations/char_level_bpe.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/implementations copying py_src/tokenizers/implementations/bert_wordpiece.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/implementations creating build/lib.macosx-11.1-arm64-cpython-38/tokenizers/tools copying py_src/tokenizers/tools/__init__.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/tools copying py_src/tokenizers/tools/visualizer.py -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/tools copying py_src/tokenizers/__init__.pyi -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers copying py_src/tokenizers/models/__init__.pyi -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/models copying py_src/tokenizers/decoders/__init__.pyi -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/decoders copying py_src/tokenizers/normalizers/__init__.pyi -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/normalizers copying py_src/tokenizers/pre_tokenizers/__init__.pyi -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/pre_tokenizers copying py_src/tokenizers/processors/__init__.pyi -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/processors copying py_src/tokenizers/trainers/__init__.pyi -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/trainers copying py_src/tokenizers/tools/visualizer-styles.css -> build/lib.macosx-11.1-arm64-cpython-38/tokenizers/tools running build_ext running build_rust error: can't find Rust compiler If you are using an outdated pip version, it is possible a prebuilt wheel is available for this package but pip is not able to install from it. Installing from the wheel would avoid the need for a Rust compiler. To update pip, run: pip install --upgrade pip and then retry package installation. If you did intend to build this package from source, try installing a Rust compiler from your system package manager and ensure it is on the PATH during installation. Alternatively, rustup (available at https://rustup.rs) is the recommended way to download and update the Rust compiler toolchain. [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for tokenizers Successfully built pyyaml Failed to build tokenizers ERROR: Could not build wheels for tokenizers, which is required to install pyproject.toml-based projects ``` ### 完成 Stable Diffusion 项目的初始化 我们可以通过 `git clone` 命令,或者直接下载[包含代码的压缩包](https://github.com/apple/ml-stable-diffusion/archive/refs/heads/main.zip),来获得项目的代码: ```bash git clone https://github.com/apple/ml-stable-diffusion.git ``` 项目比较小,所以下载速度还是蛮快的: ```bash # git clone https://github.com/apple/ml-stable-diffusion.git Cloning into 'ml-stable-diffusion'... remote: Enumerating objects: 65, done. remote: Counting objects: 100% (14/14), done. remote: Compressing objects: 100% (13/13), done. remote: Total 65 (delta 0), reused 14 (delta 0), pack-reused 51 Receiving objects: 100% (65/65), 9.05 MiB | 406.00 KiB/s, done. Resolving deltas: 100% (1/1), done. ``` 将工作目录切换到项目目录中,然后使用 `pip install` 完成项目依赖的安装: ```bash cd ml-stable-diffusion pip install -r requirements.txt ``` 至此,基础环境准备工作就都就绪了。 ## 转换和运行模型应用 基础环境就绪之后,我们需要转换 Huggingface 上的 PyTorch / TF 开放模型到 Apple Core ML 模型格式。 ### 转换 PyTorch 模型为 Apple Core ML 模型 项目仓库中 `python_coreml_stable_diffusion/torch2coreml.py` 文件中,封装了调用 `coremltools.models.MLModel` 工具方法来转换其他格式模型到 Core ML 模型的逻辑: ```bash coreml_model = coremltools.models.MLModel(...) coreml_model.convert(...) coreml_model.save(...) ``` 所以,作为用户我们的使用就比较简单了,只需要执行下面的命令: ```bash python -m python_coreml_stable_diffusion.torch2coreml --convert-unet --convert-text-encoder --convert-vae-decoder --convert-safety-checker -o ./models ``` 命令执行会比较久,十来分钟左右,包含从 Huggingface 下载模型,加载并转换模型格式。默认情况下,模型使用的是 `CompVis/stable-diffusion-v1-4`,如果你希望使用其他的模型,可以通过添加 `--model-version` 参数,支持的模型版本除了默认的 “v1.4” 之外,还有: `runwayml/stable-diffusion-v1-5` 和 `stabilityai/stable-diffusion-2-base`。 如果你使用的 Mac 设备是 8GB 版本,在执行过程中,会得到内存不足之类的提示,可以用下面的命令进行替换: ```bash python -m python_coreml_stable_diffusion.torch2coreml --convert-vae-decoder -o ./models && \ python -m python_coreml_stable_diffusion.torch2coreml --convert-unet -o ./models && \ python -m python_coreml_stable_diffusion.torch2coreml --convert-text-encoder -o ./models && \ python -m python_coreml_stable_diffusion.torch2coreml --convert-safety-checker -o ./models && ``` 命令执行完毕,我们将在 `./models` 目录,得到必须的四个模型,尺寸都不算小: ```bash # du -hs ./models/* 580M ./models/Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_safety_checker.mlpackage 235M ./models/Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_text_encoder.mlpackage 1.6G ./models/Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_unet.mlpackage 95M ./models/Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_vae_decoder.mlpackage ``` 当然,相比 HuggingFace 的原始模型来说,还是小了一些的: ```bash du -hs ~/.cache/huggingface/diffusers/models--CompVis--stable-diffusion-v1-4/ 5.1G /Users/soulteary/.cache/huggingface/diffusers/models--CompVis--stable-diffusion-v1-4/ ``` ### 运行转换后的模型进行验证 完成模型构建之后,我们可以运行模型,来验证模型转换是否成功: ```bash python -m python_coreml_stable_diffusion.pipeline --prompt "magic book on the table" -i ./models -o ./output --compute-unit ALL --seed 93 ``` 在上面的命令中,我们做了几件事,告诉程序使用 `./models` 目录中的模型进行计算,将生成的图谱保存在 `./output` 目录中,允许使用所有类型的运算单元(`CPU/GPU`),使用一个固定的随机数种子,确保每次生成的结果都是一样的,方便我们进行测试复现。当然,最重要的是,我们将要生成图片的文本描述写在 `--prompt` 参数中,告诉模型应用要生成“一本放在桌子上的魔法书”。如果你的设备只有 8GB 的内存,这里需要调整下 `--compute-unit` 参数,指定参数值为 `CPU_AND_NE`。 程序运行之后,需要等几分钟: ```bash WARNING:coremltools:Torch version 1.13.0 has not been tested with coremltools. You may run into unexpected errors. Torch 1.12.1 is the most recent version that has been tested. INFO:__main__:Setting random seed to 93 INFO:__main__:Initializing PyTorch pipe for reference configuration Fetching 16 files: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 16/16 [00:00<00:00, 9876.21it/s] INFO:__main__:Removed PyTorch pipe to reduce peak memory consumption INFO:__main__:Loading Core ML models in memory from ./models INFO:python_coreml_stable_diffusion.coreml_model:Loading text_encoder mlpackage INFO:python_coreml_stable_diffusion.coreml_model:Loading ./models/Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_text_encoder.mlpackage INFO:python_coreml_stable_diffusion.coreml_model:Done. Took 4.4 seconds. INFO:python_coreml_stable_diffusion.coreml_model:Loading unet mlpackage INFO:python_coreml_stable_diffusion.coreml_model:Loading ./models/Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_unet.mlpackage INFO:python_coreml_stable_diffusion.coreml_model:Done. Took 73.1 seconds. INFO:python_coreml_stable_diffusion.coreml_model:Loading a CoreML model through coremltools triggers compilation every time. The Swift package we provide uses precompiled Core ML models (.mlmodelc) to avoid compile-on-load. INFO:python_coreml_stable_diffusion.coreml_model:Loading vae_decoder mlpackage INFO:python_coreml_stable_diffusion.coreml_model:Loading ./models/Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_vae_decoder.mlpackage INFO:python_coreml_stable_diffusion.coreml_model:Done. Took 5.5 seconds. INFO:python_coreml_stable_diffusion.coreml_model:Loading safety_checker mlpackage INFO:python_coreml_stable_diffusion.coreml_model:Loading ./models/Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_safety_checker.mlpackage INFO:python_coreml_stable_diffusion.coreml_model:Done. Took 2.2 seconds. INFO:__main__:Done. INFO:__main__:Initializing Core ML pipe for image generation INFO:__main__:Stable Diffusion configured to generate 512x512 images INFO:__main__:Done. INFO:__main__:Beginning image generation. 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 51/51 [01:50<00:00, 2.17s/it] INFO:__main__:Generated image has nsfw concept=False ``` 当程序运行完毕之后,我们将能够在 `./output` 目录中,找到生成的图片。 ![“magic book on the table”](https://attachment.soulteary.com/2022/12/10/magic-book.jpg) 但是,每次使用都要等三四分钟才能得到图片,未免太慢了。而且想生成不同的图,不论是需要调整“随机数种子”,还是要改变“描述文本”,都得在命令行中完成,遇到文本特别长的时候,非常不方便。 有没有什么方法,可以让 ML Stable Diffusion 的生成图片,使用起来方便些呢? ## 为 ML Stable Diffusion 编写一个 Web UI 在以往和 [Python 相关](https://soulteary.com/tags/python.html)的内容里,我提到过 `gradio` 这个有趣的工具,能够为 Python 应用,快速创建简洁美观的 Web 界面。Huggingface 中非常多的应用界面都是用它完成的。 ![Python 应用 WebUI 搭建神器:Gradio](https://attachment.soulteary.com/2022/12/10/gradio.jpg) 为了解决上面的问题,我们可以用它来创建一个 Web 界面,把 ML Stable Diffusion 的图片生成和 Web 界面“绑定”到一起。实现代码很简单,不到 100 行: ```python import python_coreml_stable_diffusion.pipeline as pipeline import gradio as gr from 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( "