发布于 ,更新于 

解决 Stable Diffusion WebUI 安装 xformers 出现 Torch 无法使用 GPU 的问题

2023 年 5 月 25 日,星期四

我不知道为啥这个月写了五篇技术博客,但是因为放假赋闲在家,每天都在捣鼓新玩意,能碰到这么多破事也不奇怪。好在,最后都是有惊无险地解决了。

但是这次是比较重量级的依赖地狱

问题描述

在 Stable Diffusion WebUI 中,欲安装 xformers,使用如下命令:

1
python launch.py --medvram --opt-split-attention --xformers

(或用 pip install -U xformers 单独安装)

出现如下信息和错误:

1
2
3
4
5
6
7
8
9
10
11
12
Installing collected packages: mypy-extensions, typing-inspect, torch, pyre-extensions, xformers
Attempting uninstall: torch
Found existing installation: torch 1.12.1+cu113
Uninstalling torch-1.12.1+cu113:
Successfully uninstalled torch-1.12.1+cu113
Attempting uninstall: xformers
Found existing installation: xformers 0.0.17
Uninstalling xformers-0.0.17:
Successfully uninstalled xformers-0.0.17
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
torchvision 0.13.1+cu113 requires torch==1.12.1, but you have torch 2.0.1 which is incompatible.
Successfully installed mypy-extensions-1.0.0 pyre-extensions-0.0.29 torch-2.0.1 typing-inspect-0.9.0 xformers-0.0.20

意为:torchvision 0.13.1+cu113 需要 torch==1.12.1,但是你安装的是 torch 2.0.1,这是不兼容的。

再次尝试启动 WebUI,出现如下错误:

1
2
3
4
5
Error code: 1
stdout: <empty>
stderr: Traceback (most recent call last):
File "<string>", line 1, in <module>
Torch is not able to use GPU; add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check

意为:Torch 无法使用 GPU;命令行使用 --skip-torch-cuda-test 可以跳过这个检查。

无法使用 GPU,这可麻烦大了!

但是在急着往 QQ 群里发截图求助之前,动动脑子,上网查查,还是能找到解决方案的。

初步探索

此时,torchvisiontorch 的版本不兼容,当然是跑不起来的。这和新来的 xformers 无关,也就是说,命令行去掉 --xformers 也无法启动。

由于 torchvision 依赖 torch,先考虑重装 torch

1
pip install torch==1.12.1

出现如下信息和错误:

1
2
3
4
5
6
7
8
Installing collected packages: torch
Attempting uninstall: torch
Found existing installation: torch 2.0.1
Uninstalling torch-2.0.1:
Successfully uninstalled torch-2.0.1
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
xformers 0.0.20 requires torch==2.0.1, but you have torch 1.12.1 which is incompatible.
Successfully installed torch-1.12.1

又遇到了版本不兼容问题,但这次是 xformerstorch。先考虑把 xformers 卸载:

1
pip uninstall xformers

很不幸地,并没有解决问题,WebUI 依然无法启动。(注:此时如果不用命令行参数 --medvram--opt-split-attention,WebUI 可以启动,但是仍然无法工作。)

解决方案

第一步,检查 CUDA 版本

1
nvidia-smi

部分输出如下:

1
NVIDIA-SMI 526.98       Driver Version: 526.98       CUDA Version: 12.0

此时可以把问题锁定到 Pytorch 和 CUDA 版本不兼容上。

第二步,用 torch 库检查 CUDA 版本

1
2
3
4
import torch
print(torch.version.cuda) # CUDA 版本
print(torch.__version__) # Pytorch 版本
print(torch.cuda.is_available()) # GPU 是否可用

第一个输出为 None,表示 pytorch 对应版本的 CUDA 未安装

第二个输出,很有意思,因为我确实没想到之前 pip install torch==1.12.1 的时候给我自己挖坑了:

输出是 1.12.1+cpu,是 1.12.1 没错,但是是 CPU 版本!

那就好办了———安装正确的 Pytorch 版本:

Pytorch 官网,找到需要的版本。


重新安装 1.12.1(不建议)

找到对应 1.12.1 的命令行:

1
2
3
4
5
6
7
8
# CUDA 11.6
pip install torch==1.12.1+cu116 torchvision==0.13.1+cu116 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu116
# CUDA 11.3
pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113
# CUDA 10.2
pip install torch==1.12.1+cu102 torchvision==0.13.1+cu102 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu102
# CPU only
pip install torch==1.12.1+cpu torchvision==0.13.1+cpu torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cpu

由于我的 CUDA 版本是 12.0,而且高版本 CUDA 也是兼容低版本的,此处选择 11.6 或者 11.3 应该都可以。(之前装的是 1.12.1+cu113,现在重装了 11.6,总之是可以用了。)

重装完毕,再次运行 WebUI,成功启动!

版本不是越新越好,要看清楚自己的环境,选择合适的版本。

建议直接升级到 2.0.1 并安装 xformers。(这可能导致一些其他不支持 pytorch 2 的项目无法运行)

1
2
3
webui-user.bat --reinstall-torch
pip3 install torch==2.0.1+cu117 torchvision==0.15.2+cu117 torchaudio==2.0.2+cu117 --index-url https://download.pytorch.org/whl/cu117
python launch.py --xformers # 这一步不能使用 webui-user.bat --xformers

第二步安装完成后,应该使用上面的 Python 代码检查 Pytorch 配置是否正确。以笔者的环境为例,输出如下:

1
2
3
11.7
2.0.1+cu117
True

应该注意:如果此处用 pip install -U xformers==0.0.20 手动安装 xformers会自动安装 cpu 版本的 torch,这样就重蹈覆辙了。

这以后就可以使用以下参数启动 WebUI 了:

1
python launch.py --medvram --opt-split-attention --xformers

笔者使用 RTX 2050(显存只有 4GB)测试时,速度从 2s/it 提升到 2it/s,效果显著。

2023 年 5 月 30 日,星期二

归新乡记

前情提要:归异乡记

上次归异乡三天之后我便回了新乡,自此便是忙碌又清闲的日子。

这次是从故乡新乡

「故乡」指「老家」,因此可以将「家」诗意化为「新乡」。这两个「乡」恐怕并不是对等的——一个是地理概念,一个是心理概念。不过,家总归只有一个,回家总归是一件确定的事情。

顺便一提,我真当不是铁道迷巴士迷啥的。一般意义上的游记指的是游玩的经历,而我的游记真的只是一路上的经历,不去观察记录交通工具那就什么内容都没有了。

14:24,「故乡」长途汽车站

此处略去了地名。

坐上 8 元的长途汽车——实际上是市内——至少从行政区划上来说没有出市,只不过和市区十万八千里远。

尽管根据搜索引擎,这班车有个三位数的编号,但是无论公交站台、公交车还是高德地图都似乎对此毫不知情。

看着右上悬挂的经典红色 LED 显示屏,在隧道里观察着它在时间、车内温度与车外温度之间的切换,感觉坐上国内的公交车真是怀念啊。

自打我高中以来,由于无论是学校还是培训机构都离家不远,一般都是步行或者汽车接送——这里的「家」其实不是今天的「新乡」,而是在学校附近租的房子——而原来离家很近的牙医却变成了坐地铁一小时的距离。不管怎么说,也轮不到公交车。

回头看,我在初中也不怎么需要坐公交车,当时靠自行车与地铁就能解决一切问题。所以我对公交车的记忆其实停留在了初中的春游和秋游——我不记得到活动地点逛了点啥买了点啥,也已经忘记车上谁唱的歌数量最多,但是可以确定的是,当时的公交车右上角也有同样的红色视线在闪烁。

往前看,我在香港也不怎么坐巴士,主要靠步行和地铁——地铁太过便利,让人忘了香港其实还有别的公共交通工具。香港的双层巴士虽然看上去很酷,但是只仅如此远远不及我从机场坐 E22 路不小心坐成了 E22A,一路上在极为狭窄的面对面座位上让自己蜷缩到窗边举起手机遮住脸然后看本子、过早地准备下车导致行李摔了然后又没有及时按下车铃最后狼狈地滚下车这种种奇闻在一个半小时之内展开的经历来得酷。——顺便一提,我不是へんたい,我对公交车及其作为文化符号的各种想象一点兴趣都没有。

在经历了半小时的昏睡——就像是我小学时某次春游不小心把头靠到别人肩上一样——之后,乘客们非常整齐地准备在下一站下车,不太整齐地解开安全带,警报也杂乱无章地响了起来。

临安公交西站,到了——脑海中回荡着虚构的声音。

15:14,九州街站

杭州地铁 16 号线,或称杭临城际铁路。

一进站我就看到了非常新鲜的景象——16 号线是四车厢,站台短到从一端可以轻松看清另一端。

望向墙上的线路图,我要从起点站九州街站坐到终点站绿汀路站,绿汀路是唯一的换乘站,可换乘 3、5 号线。

比起深圳的双拥街站还是荒凉太多了。双拥街虽然也称得上是市郊,但 10 号线至少中间段就有换乘站了,而且客流量总归有接近满座的时候。

这儿呢——那就只能用农村概括了。

发车间隔 9 分钟,其中停车等候 5 分钟,这个频次倒是算不上很低。

15:26,在青山湖到八百里站路段进入地上段。

15:40,在南湖到中泰站路段进入地下段。

16 号线唯一一个右侧开门的站是绿汀路站,而我一直坐在噪音更高的左侧,好处是能更好地观察到站台上的人流。

而到绿汀路站,我总算是看到了报站屏幕上的车厢、扶梯和出入口信息。这时我才意识到,这和深圳地铁的报站何其相似(尽管 16 号线对侧开门的时候不显示),恐怕和港铁(杭港地铁)脱不开关系。——顺便,在绿汀路站,右侧车门姑且算是有存在的意义了。

15:54,绿汀路站

上文提到,绿汀路站是三线换乘站,B3 层是 3 号线(往吴山前村)- 16 号线(往九州街)与 16 号线(下客站台)- 3 号线(往星桥)两队岛式站台同台换乘,B2 层是 5 号线(往金星)- 5 号线(往姑娘桥)的岛式站台。由于 B3 层的站台从左往右分别是 3-16-16-3,B2 层 5 号线的两个站台分别在 3 号站台的上方,因此来到 B2 层会感觉特别空旷——中间还多了一对站台的空间。虽说如此,不太有扩展的可能性了。

由于 3 号线是常规的八车厢,站台长度也比起 16 号线的列车长了一倍。16 号线列车停在正中间(3-6 车厢),左右闲置的空间,咋看又是什么战未来的设计,实际上 16 号线其他车站都是四车厢,想延长也难。另外,看这个客流量,应该不太有必要。再仔细看 1、2、7、8 车厢的门,发现根本没有屏蔽门,仅只是用玻璃隔开了。

杭州地铁 5 号线,姑娘桥方向。虽说不是始发站,停车等候的时间却相当长。发车间隔约 4 至 5 分钟。

5 号线是相当朴实无华且枯燥的,最大的特色是长,很长,非常长,从城市西北角蜿蜒到东南角。

仔细品鉴车上的线路图,未曾料想杭州地铁的密度也如此高了,市中心是五颜六色——恐怕有七八种颜色——织成的蜘蛛网。既然都成网了,自然没必要再去研究环线的必要了。青蓝色的 5 号线和海浪青的 19 号线交织在一起,虽然符合杭州地铁早期设计的配色方案,但是难免让人傻傻分不清楚。

报站屏以硕大无朋的黑体陈列 39 个站名,外加同样硕大的「X号线」换乘标志,这狭小的一方空间实在是让人眼花缭乱。我觉得可以充分利用色彩,让换乘站的站名染上对应的颜色,然后下放悬挂一个数字表示换乘线号,多线换乘也可以用渐变色来表示。

当然只是我觉得而已。

16:17,「新乡」站

回到家等于回到电脑等于在互联网上复活。——对我来说手机并不算互联网,我虽然安装了 QQ,却只用来电脑登录验证;安装了微信,却没什么理由称为通讯工具;安装了微博,却只在需要绕过网页版限制的时候播放摇一摇开屏广告。

项目、笔记、写作,全都要倚仗电脑。手机,没有社交用途,没有生产力,只是消费工具

河北南京

汉化嵌字看了都得沉默
汉化嵌字看了都得沉默

实际上并不是 Stellar 的 bug,是我自己傻了。

时间线中的结点标题格式为 <!-- node xxx -->,而我不小心漏了 node,导致结点标题被解释成 HTML 注释,而正文被解释成标题,由于标题挤不下,又必须显示在同一行内,因此就会出现段落与段落看似竖向排列(把它们都假设成单个字那就是正常的标题排版),而段落内文字横向排列的奇异现象。

QQ 群各路专家立即开展了教育意义丰厚的学术讨论,最终达成以下共识:

河 北
南 京

顺便一提,今天给每篇日志的开头加上了「当月精选集」,这样方便跳转到其他日志,也可以让读者少看点废话和低质量内容——如果有人真的会看的话。