租GPU服务器跑Stable Diffusion,听起来就是"下单、开机、装环境、启动WebUI"四步走,但真操作起来,不少人在第二步就开始怀疑人生:驱动装好了但是WebUI识别不到显卡,公网开了又被扫描器盯上,模型下载到一半磁盘满了,出图倒是能出,一放大分辨率就OOM。这篇文章我把完整链路重新走了一遍,从选服务器、基础环境、WebUI部署、公网访问到上线后的调优和故障排查,一次性说清楚。适合刚租了GPU服务器、想在Stable Diffusion WebUI上出图或者把这套服务分享给朋友使用的读者,顺便帮大家避开那些"看起来是小问题、实际上能卡你半天"的坑。
1. 选GPU服务器时最容易忽视的变量:显存之外还有计费和带宽
1.1 显存选多大才不白花钱:按模型档位和出图尺寸倒推
很多人一看"GPU服务器"就奔着显存去,非24GB不要。这个思路在训练大模型时没错,但Stable Diffusion的推理场景并不需要盲目堆显存,关键看你要跑什么模型、出多大图。
如果只跑SD 1.5出512×512的图,4GB显存也能勉强跑,但体验极差。我最早在一台4GB显存的机器上跑过,必须开--lowvram参数,出图过程中反复把权重从显存换到内存,一张图等上两三分钟是常事,中途切个模型还可能直接OOM。这个档位只适合"验证流程能不能走通"。
真正体验不错的入门底线是8GB显存。RTX 3060 8G、4060 Ti 8G这类卡跑SD 1.5很从容,512×512分辨率下开xformers,一张图几秒到十几秒;跑SDXL的话,8GB也能跑但需要--medvram,1024×1024大约十几秒一张。
如果预算允许,12GB到24GB是当前性价比最舒服的区间。RTX 3060 12GB是租用平台上最常见的卡型,跑SD 1.5各种模型加ControlNet基本无压力,SDXL也能流畅出图;RTX 3090或4090有24GB显存,不但能跑SDXL,还能同时挂多个ControlNet模块,甚至可以做LoRA训练。
我个人的选择逻辑很简单,按用途倒推,用下面这张表:
| 用途 | 最低显存 | 推荐显存 | 常见租用卡型 |
|---|---|---|---|
| SD 1.5 512×512尝鲜 | 4GB | 8GB | RTX 3050、RTX 3060 |
| SD 1.5 + ControlNet / LoRA | 8GB | 12GB | RTX 3060 12G |
| SDXL 1024×1024 | 8GB | 16GB+ | RTX 4070 Ti Super |
| SDXL + 多ControlNet + LoRA训练 | 16GB | 24GB | RTX 3090、RTX 4090 |
还有一个容易被忽略的点是显存带宽。3060 12GB和4060 Ti 16GB这类卡,显存容量够大,但带宽相对有限,在大分辨率出图时会成为瓶颈。同样是24GB显存,专业卡像A100、H100的带宽确实高得吓人,但用来跑SD纯属大材小用,而且价格可能是消费级卡的好几倍。Stable Diffusion推理不吃FP64、NVLink这些特性,消费级卡的Tensor性能已经完全够用,别为了"专业"两个字多花冤枉钱。
1.2 计费模式中的隐性扣费:关机费、流量费、存储费
我见过不少人在选服务器时只盯着"每小时多少钱",结果月账单出来吓一跳。算力租赁平台的计费远不只是单价乘以小时数这么简单,至少要问清楚三件事:
第一是关机是否收费。有些平台按量计费模式下,关机后GPU不再计费,但存储空间、IP地址可能仍然按小时或按天计费。第二是流量怎么算。GPU服务器通常有公网下行和上行流量,下载Stable Diffusion模型、安装依赖、以及远程访问WebUI时传输图片都会消耗流量,部分平台的流量费甚至比算力费还贵。第三是竞价实例的回收策略。有些平台提供竞价/抢占式实例,价格很低,但实例可能随时被回收。你跑个批量生图任务跑到一半,实例没了,图全白跑。
我的建议是:如果是长时间跑图或者跑后台服务,选包月、包周更省心;如果只是短期测试,按量计费配合自动关机策略即可。另一个省心的办法是看平台有没有已经预装WebUI的GPU镜像,有的平台甚至提供"SD一键部署"镜像,能省掉后面大半天的安装依赖时间,虽然版本可能不是最新的,但先跑通流程,后面再手动升级完全来得及。
1.3 机房网络和预装镜像:能省掉大半天的部署时间
GPU服务器选机房时,除了价格,还要考虑网络链路。国内云厂商的国内机房访问GitHub、HuggingFace这类站点经常不稳定,而Stable Diffusion的依赖包和模型偏偏都在这类站点上。虽然可以通过各种镜像源解决,但如果直接选择网络链路更友好的机房,或者选择某些已经配置好基础环境的镜像,能显著减少各种超时重试。
我自己的经验是,开局先看平台有没有"含Stable Diffusion WebUI"的镜像,哪怕需要付费也比手动折腾一天划算。如果没有预装镜像,就确认为你分配到的磁盘是不是高性能SSD、系统盘空间是多少、是否支持挂载数据盘。模型下载和解压对磁盘IO有一定要求,机械盘不是不能跑,但首次下载和加载模型时会明显慢。
2. 拿到服务器后的前30分钟:驱动核对、Python隔离与磁盘规划
2.1 第一件事是确认nvidia-smi输出,而不是急着装CUDA
登录GPU服务器后,很多新手做的第一件事是去装CUDA,结果越装越乱。正确做法是先运行nvidia-smi,看驱动是否已经装好、驱动版本对应的CUDA版本是多少。
这里有个常见的误区:nvidia-smi显示的CUDA版本并不是系统真的装了CUDA toolkit,它只是表示"当前驱动支持的最高CUDA版本"。Stable Diffusion WebUI运行时所依赖的PyTorch自带CUDA runtime,并不需要单独安装完整的CUDA toolkit。只要驱动版本号大于等于PyTorch官方要求的CUDA版本,就能正常运行。
如果nvidia-smi报错或者看不到显卡,说明驱动有问题。Ubuntu系统下最稳妥的方式是:
apt update apt install -y ubuntu-drivers-common ubuntu-drivers autoinstall reboot自动安装会选择合适的驱动版本。装完后重启,再跑nvidia-smi应该就能看到显卡信息了。这里还要提醒一句:很多云平台默认给的是root账号,操作是方便,但安全上我不建议长期用root跑WebUI,后面可以建一个普通用户来运行服务。
2.2 Python版本与虚拟环境:WebUI官方脚本对Python版本很挑剔
Stable Diffusion WebUI的启动脚本会自动创建虚拟环境并安装依赖,但它对Python版本有明确要求。目前官方支持较好的是Python 3.10和3.11,其中3.10最稳。如果你租的服务器自带系统是Ubuntu 20.04,默认Python通常是3.8,直接跑WebUI会遇到各种兼容性问题,最常见的是某些依赖库要求更高版本的Python。
这种情况下不要试图改系统的默认Python版本,容易把系统搞坏,而是额外安装Python 3.10:
apt install -y software-properties-common add-apt-repository ppa:deadsnakes/ppa apt update apt install -y python3.10 python3.10-venv python3.10-dev装完可以用update-alternatives切换默认版本,但更省事的方式是安装完直接记住Python 3.10的路径,启动WebUI时用./webui.sh --skip-torch-cuda-test等参数时它会自动找合适的Python。
还有个细节是pip源。国内服务器直接装依赖非常慢,尤其是torch这种几个GB的包,建议先把pip源换成国内镜像:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple或者用阿里云源、腾讯源都行,这步能省下大量等待时间。WebUI的venv虚拟环境也会读取这个pip配置,所以在系统级配置一次,后续WebUI创建venv时也能继承。
2.3 磁盘空间按"模型库"规划:200GB数据盘是舒适起点
"磁盘100GB肯定够了吧"是我见过最天真的假设。Stable Diffusion的胃口比你想象中大得多:WebUI本体和依赖大约占2到3GB;一个SD 1.5主模型4GB左右;SDXL主模型7GB左右;常见的二次元模型(Anything、Counterfeit等)也都在4GB到7GB之间;每个LoRA几十到几百MB;VAE文件300MB以上;ControlNet的每个模型从700MB到2.5GB不等。
把这些网络安全风险控制好,即使你只装两三个主模型,加几个LoRA和ControlNet,50GB很容易就出去了。如果再加上CAD、embeddings、一堆下载缓存文件,100GB真的不够看。我建议系统盘至少50GB,另外挂一块至少200GB的数据盘,用来放WebUI和模型目录。
如果用平台提供了数据盘,先把WebUI安装到数据盘上,比如:
mkdir -p /data mount /dev/vdb1 /data cd /data git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git这样就不用担心以后换镜像或者扩展装多了磁盘不够。查看目录占用可以用du -sh /data/stable-diffusion-webui,心里有数。
3. WebUI装机的三种路线:官方仓库、整合包与Docker怎么选
3.1 官方仓库部署的完整命令链和国内加速配置
市面上Stable Diffusion WebUI的整合包很多,但服务器环境我仍然推荐从官方仓库部署,原因很简单:整合包通常是针对Windows桌面环境做的,服务器上有一堆不必要的依赖,而且升级扩展时要自己处理各种路径问题;官方仓库则相对干净,遇到问题去GitHub Issues搜索时,大家的报错环境也和你更接近。
先安装基础系统包:
apt update apt install -y wget git python3.10-venv然后克隆官方仓库。考虑到国内网络访问GitHub的不稳定性,可以用镜像地址:
cd /data git clone https://gitclone.com/github.com/AUTOMATIC1111/stable-diffusion-webui.git如果gitclone不好用,也可以直接从原仓库克隆,只是可能要多试几次:
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git cd stable-diffusion-webui启动前先设置HuggingFace的镜像环境变量,否则首次启动会卡在下载模型和部分依赖上:
export HF_ENDPOINT=https://hf-mirror.com然后直接启动:
./webui.sh --listen --port 7860 --xformers首次启动会创建venv并下载torch等依赖,这个阶段会持续很久,如果SSH断连就前功尽弃。我习惯用tmux挂后台:
apt install -y tmux tmux new -s sd ./webui.sh --listen --port 7860 --xformers按Ctrl+B再按D退出tmux会话,WebUI继续在后台跑。再次进入用tmux attach -t sd。这个习惯能救很多次命。
3.2 启动参数组合:--listen、--xformers、--medvram的真实作用
WebUI的启动参数有很多,但不能无脑全开,得理解每个参数实际在干什么。
--listen是必备的,不加这个参数服务只监听127.0.0.1,外部无法访问。--port指定端口,默认7860,冲突时改7861之类的。
--xformers是我最常用的。它能降低显存占用并提升采样速度,尤其在N卡上效果明显。但注意,它依赖xformers库和当前环境的编译版本,部分显卡驱动组合下会有兼容性问题,启动直接报错。如果加了--xformers启动失败,先去掉再启动,等WebUI能正常运行时再尝试装xformers。
--medvram和--lowvram是显存不足时的兜底方案。--medvram把部分权重放在显存和内存之间做交换,6GB到8GB显存跑SDXL时会用到;--lowvram则是更激进的换入换出策略,适合4GB左右显存。8GB以上显存跑SD 1.5不需要开,开了反而因为反复交换权重而变慢。
还有两个参数我偶尔用:--precision full --no-half,当某些模型在fp16精度下出图出现黑图或异常色块时,加上这个参数可以解决;但它会显著增加显存占用和降低速度,非必要不开。--api则是开启REST API,后面接入自己的脚本时再详细说。
一个典型的组合是这样:
./webui.sh --listen --port 7860 --xformers --medvram --api先小成本验证启动是否正常,再逐个调整参数,别一上来把所有优化参数全加上,出了问题都不知道是哪个造成的。
3.3 模型放置目录与首次出图:先跑通512×512再谈扩展
WebUI启动后,浏览器访问http://服务器IP:7860,迎接你的应该是很简洁的生图界面。但这时候点击Generate大概率会报错,因为还没有模型。
主模型要放到models/Stable-diffusion/目录。用wget下载一个SD 1.5的官方权重文件:
cd /data/stable-diffusion-webui/models/Stable-diffusion wget https://hf-mirror.com/stable-diffusion-v1-5/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors这个文件大约4GB,同样建议在tmux里下载。下载完后回到WebUI界面,点右上角的刷新按钮,模型下拉框里就能看到它了。
除了主模型,常用的还有VAE(放在models/VAE/)、LoRA(放在models/Lora/)、ControlNet模型(放在models/ControlNet/)。扩展插件则装在extensions/目录下,可以通过界面的Extensions菜单在线搜索安装,也可以直接git clone到该目录然后重启WebUI。
首次出图时,建议先在512×512分辨率下测试,确认基本流程通了再去挑战1024或者SDXL。我见过太多人一上来就开1024×1024,结果OOM后误以为是机器不行。先小后大,先官方模型后自定义模型,排查会容易很多。
4. 公网访问的四条路线对比:直连端口、frp、Cloudflare Tunnel与安全底线
4.1 直接暴露7860端口的操作和为什么我不推荐
如果你租的GPU服务器有公网IP,最简单的方案就是WebUI加--listen,然后到云平台的安全组或防火墙放行7860端口,之后任何人访问http://IP:7860就能用。听起来很爽,但这是四套方案里风险最高的一种。
AI绘画服务对扫描器来说是个肥肉。IP一暴露,很快就会有大量扫描流量,试图访问WebUI的未授权接口,或者探测是否存在其他漏洞。Stable Diffusion WebUI默认不带登录认证,任何人都能消耗你的显存批量生图,轻则卡顿,重则显存被占满导致服务崩溃。我在一次测试中只把7860端口暴露了不到两小时,日志里就出现了几十条来自不同IP的访问记录。
所以如果一定要直连,至少要给WebUI加上登录认证。在启动参数里加:
--gradio-auth admin:你的密码但这只是基础防护。Gradio自带的认证机制比较简陋,无法防范CSRF和暴力破解。我的结论是:直连只适合临时测试,也最好配上防火墙限制来源IP,比如只允许你当前办公网络的IP段访问。
4.2 frp穿透:适合GPU服务器在内网环境的通用方案
很多算力租赁平台分配给用户的GPU服务器并没有独立的公网IP,而是在一个VPC内网里,需要自己配置公网访问。这种情况下,frp是我最常用的方案。它的原理很简单:GPU服务器通过内网连接一台有公网IP的中转服务器,把本地WebUI端口"转发"到中转服务器的某个公网端口上。
中转服务器不需要多高的配置,1核1G的轻量云就够用,但公网带宽要留意。下载和上传图片都会经过中转服务器,带宽太小体验会很难受。
先在中转服务器上下载frp并启动服务端。frp的安装包里包含frps(服务端)和frpc(客户端),下载对应架构的版本解压即可。
服务端配置frps.toml:
bindPort = 7000 auth.method = "token" auth.token = "你的强密码"启动服务端:
./frps -c frps.toml在GPU服务器上配置客户端frpc.toml:
serverAddr = "中转服务器公网IP" serverPort = 7000 auth.token = "你的强密码" [[proxies]] name = "sd-webui" type = "tcp" localIP = "127.0.0.1" localPort = 7860 remotePort = 7860启动客户端:
./frpc -c frpc.toml这样公网访问http://中转服务器IP:7860就能连到GPU服务器上的WebUI了。frp的auth.token一定要设置,否则任何能碰到7000端口的人都可以在中转服务器上开代理,等于给攻击者提供了跳板。
frp方案适合不需要固定域名的场景,但要注意中转服务器的流量费用。高频生图时,图片来回传输产生的流量可能比GPU服务器本身的费用还高。
4.3 Cloudflare Tunnel:有域名就能免公网IP暴露
如果GPU服务器没有公网IP,又不想额外买中转服务器,Cloudflare Tunnel是另一个很顺滑的选项。它通过Cloudflare的全球网络建立一条隧道,把本地服务暴露到一个自定义域名上,而且自带TLS加密,访问地址是HTTPS,比frp裸端口安全得多。
前提是你有一个域名,且DNS托管在Cloudflare。免费版就够用。
在GPU服务器上安装cloudflared:
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 chmod +x cloudflared mv cloudflared /usr/local/bin/登录和创建隧道:
cloudflared tunnel login cloudflared tunnel create sd-tunnel然后配置~/.cloudflared/config.yml:
tunnel: sd-tunnel credentials-file: /root/.cloudflared/<隧道ID>.json ingress: - hostname: sd.example.com service: http://localhost:7860 - service: http_status:404再配置DNS路由:
cloudflared tunnel route dns sd-tunnel sd.example.com启动隧道:
cloudflared tunnel run sd-tunnel之后访问https://sd.example.com就直达WebUI。国内访问Cloudflare网络的速度时好时坏,但对个人使用来说完全够用。这个方案的额外好处是可以在Cloudflare面板里配Access策略,对访问者做邮件验证码或Google登录验证,进一步保护WebUI。
4.4 公网访问前必须完成的安全加固清单
无论选哪条公网路线,我都建议在放行之前把下面这几件事做一遍,顺序也很重要:
- WebUI不要监听
0.0.0.0的场景,限制在127.0.0.1,公网访问交给frp或Cloudflare Tunnel处理。只有当你明确使用直连方案时才加--listen。 - 给WebUI加上登录认证。即使走frp或Tunnel,
--gradio-auth也能挡掉一批随便撞进来的人。 - 如果使用直连方案,在云平台安全组配置IP白名单,尽量只允许自己的办公网或家宽IP访问。
- 用nginx等反向代理加一层TLS和Basic Auth。把WebUI本身"藏"在内部,外部看到的是nginx的443端口,优雅很多。
- 注意日志。WebUI启动时如果刷出一堆异常访问,说明已经有人盯上端口了,及时关闭公网访问并检查有没有被上传异常文件。
安全这块没有"一次配置终身无忧"的说法,尤其是公网暴露的服务,定期看一眼日志和模型目录是值得养成的习惯。
5. 上线后的性能调优与故障处置:实测数据与排查顺序
5.1 出图速度到底由什么决定:显存带宽、半精度、采样器步数
服务跑通只是开始,出图速度才是大家真正关心的。实测下来,出图速度的核心影响因素依次是:显卡型号(显存带宽和算力)、是否开启半精度、是否使用xformers、采样器类型和步数。
我拿常见卡型做过几组量级参考,不同驱动和模型下会有些差异,但大致范围如下:
| 卡型 | 显存 | SD 1.5 512×512 20步 | SDXL 1024×1024 20步 |
|---|---|---|---|
| RTX 3060 12G | 12GB | 约1.5~2.5 it/s | 约0.5~1 it/s |
| RTX 3090 24G | 24GB | 约3~4 it/s | 约1.5~2.5 it/s |
| RTX 4090 24G | 24GB | 约5~8 it/s | 约3~5 it/s |
怎么让速度尽可能接近上限?有几个实操技巧:
- 保持开启
--xformers,多数情况下能提升20%到40%的速度并降低显存占用。 - 半精度(fp16)默认是开启的,别轻易关,
--no-half只用于解决黑图问题。 - 采样器步数不是越多越好,Euler a / DPM++ 2M这类采样器20步已经足够,堆到50步只会线性增加耗时,画质提升有限。
- 批量出图时
batch_size设1就好,在显存不足时强行加大batch只会OOM,速度并不会成倍提升。 - 一些扩展(比如部分放大算法、动画插件)后台会持续占用显存,不用时最好禁用。
5.2 几个高频故障的定位顺序:OOM、白图、端口冲突、启动卡住
我把自己在实际使用中遇到最多的四类问题按排查顺序列出来,遇到时照着这个顺序能省不少时间。
OOM(显存不足):界面直接报CUDA out of memory。先别急着怀疑机器配置,按这个顺序处理:关闭不需要的扩展(每个扩展都可能占用几百MB显存)→ 降低输出分辨率 → 打开--medvram→ 用nvidia-smi看是否有僵尸进程占着显存。特别是长期跑着WebUI不重启,某些扩展有显存泄漏,重启WebUI往往立刻解决。
输出全黑图或异常色块:通常是模型精度问题。可以加--precision full --no-half重启试一下。如果加了就好了,说明某个模型在fp16下确实有兼容问题。另一种情况是VAE缺失或匹配错误,去下载正确的VAE放在models/VAE/目录并手动指定。
端口冲突:启动日志会提示Address already in use。换端口就行,--port 7861。不推荐杀掉占用端口的进程,因为你可能正在跑另一个生图任务。
启动卡住:启动过程卡在某个下载步骤,大概率是网络问题。原因通常是下载模型或某依赖超时。把启动日志看完,确认是在下载什么东西,再设置对应镜像,然后重启。用tmux挂后台、反复重启时不设限,让它慢慢下载,这样最省心。
模型文件损坏:用wget下载大文件时中断,再续传后文件损坏,加载时报Error loading model。用wget -c断点续传,或者下载完成后检查文件大小是否和源文件一致。
5.3 API模式:把WebUI当作生图后端接入自己的脚本
WebUI不只是个网页,开--api之后它还提供了一组REST API,方便你把它当作一个生图服务接入自己的脚本。我倾向于先用网页调好参数,再通过API做批量生图,这样既保留了调试的直观性,又能自动化。
API的关键端点是/sdapi/v1/txt2img,用curl测试:
curl -X POST http://127.0.0.1:7860/sdapi/v1/txt2img \ -H "Content-Type: application/json" \ -d '{ "prompt": "a cute cat, masterpiece", "steps": 20, "width": 512, "height": 512, "batch_size": 1 }' -o result.json返回的JSON里images字段是base64编码的图片,用Python存成文件很方便:
import json import base64 with open("result.json", "r") as f: data = json.load(f) img_data = base64.b64decode(data["images"][0]) with open("output.png", "wb") as f: f.write(img_data)API模式下尤其要注意并发控制。WebUI本质上是单GPU资源,多个并发请求同时打到API上,显存会被瞬间打满。我的做法是在脚本里加一个简单的任务队列,或者用nginx限制/sdapi/路径的QPS,避免并发尖峰打崩服务。
这些经验是我实际部署过一轮之后沉淀下来的。最后再分享两个小习惯:一是关键路径的安装、启动命令都写成一个脚本放到/root/下,下次重置实例后照着跑一遍就行,不用再回忆;二是定期把模型目录和配置文件做一次快照,避免平台回收实例后好不容易下载的模型全部归零。GPU服务器这套东西,真正让人头疼的从来不是显卡本身,而是显卡之后每个环节的细节。把这几个环节理顺了,Stable Diffusion WebUI跑起来也就是一杯咖啡的功夫。