ComfyUI
ComfyUI 通用文档由上游官方维护。本页收录 Ascend NPU 适配的快速上手。
快速开始 (Ascend NPU)
在单卡昇腾 NPU 上部署 ComfyUI,并用上游自带的 API 例程 script_examples/basic_api_example.py 通过 /prompt 接口提交默认文生图工作流,端到端产出一张 PNG。
ComfyUI 原生支持昇腾 NPU:检测到 torch_npu 且 torch.npu.is_available() 为真时,设备管理自动选用 npu 设备,无需额外启动参数。本文以无头服务(默认端口 8188)+ API 例程的方式运行,全程无需人工交互;交互式 Web UI 用户浏览器访问 http://<机器IP>:8188 即可。
前置条件
硬件
Atlas 900 A2 单卡(Ascend NPU),并按需完成物理机或容器内的设备挂载。
基础软件
在跑本文档之前,你的机器上需要已经装好并可用:
可用的 Python 环境
可用的 CANN(参考快速安装昇腾环境)
与 CANN 匹配的
torch+torch_npu,且torch能正常import、torch.npu.is_available() == True(参考 Ascend PyTorch 安装文档,按 torch ↔ torch_npu ↔ CANN 三方兼容矩阵选择版本)
按上游 README 的方式设置 CANN 环境变量:
source /usr/local/Ascend/ascend-toolkit/set_env.sh
本文档示例使用的版本
配套机器:
机器类型:Atlas 900 A2 单卡
操作系统:Ubuntu 22.04
软件版本:
组件 |
版本 |
|---|---|
Python |
3.12 |
CANN |
9.1.0 |
torch |
2.9.0+cpu |
torch_npu |
2.9.0.post2 |
ComfyUI |
master(原生 NPU 支持) |
huggingface_hub |
最新稳定版 |
模型 |
stable-diffusion-v1-5/stable-diffusion-v1-5 的 |
环境检查
检查 Python 版本:
python --version
输出结果如下:
Python 3.12.xxx
检查 torch / torch_npu 是否装好且 NPU 设备可用:
python -c "import torch, torch_npu; print('torch=', torch.__version__); print('torch_npu=', torch_npu.__version__); print('is_available:', torch.npu.is_available()); print('count:', torch.npu.device_count())"
输出结果如下:
torch= 2.9.0+cpu
torch_npu= 2.9.0.post2
is_available: True
count: 1
Note
如果 import torch_npu 失败,回到 Ascend PyTorch 安装文档 检查 torch / torch_npu / CANN 三方兼容矩阵。
获取代码
克隆上游仓库并 checkout 到流水线注入的最新 release tag:
git clone https://github.com/comfyanonymous/ComfyUI.git
cd ComfyUI
git checkout <ref>
echo "HEAD $(git log -1 --format=%h)"
输出结果如下:
HEAD xxx
Note
上文 <ref> 为流水线注入的上游最新 release tag;xxx 为最新 commit 的短哈希。
安装依赖
ComfyUI 的 requirements.txt 里 torchvision / torchaudio 未 pin 版本。为避免 pip 解析器为满足「最新 torchvision/torchaudio」而把已装好的 torch 2.9.0 升级、破坏 torch ↔ torch_npu ↔ CANN 配套,先显式安装与 torch 2.9.0 配套的 pair(torchvision 0.24.x ↔ torchaudio 2.9.x),已装则跳过;再装 requirements.txt(已满足的 torch 不会被改动)与 huggingface_hub:
cd ComfyUI
python -m pip install "torchvision==0.24.0" "torchaudio==2.9.0"
python -m pip install -r requirements.txt
python -m pip install huggingface_hub
Note
requirements.txt按上游原样安装;huggingface_hub为 Hugging Face 下载模型所需,需显式安装。torch / torch_npu 栈沿用机器上已装好的版本(前置条件),本文档不重装。
验证依赖可用:
python -c "import torchsde, einops, transformers, tokenizers, safetensors, aiohttp, PIL, av, huggingface_hub; print('deps ok')"
输出结果如下:
deps ok
下载模型
默认使用 Hugging Face Hub 进行模型下载,可执行下面 Python 代码下载:
import time, sys
from pathlib import Path
from huggingface_hub import snapshot_download
d = None
for i in range(3):
try:
d = snapshot_download('stable-diffusion-v1-5/stable-diffusion-v1-5', allow_patterns=['v1-5-pruned-emaonly.safetensors'])
if (Path(d) / 'v1-5-pruned-emaonly.safetensors').is_file():
break
print('attempt %d/3: file not complete, retrying' % (i+1), file=sys.stderr)
d = None
except Exception as e:
print('attempt %d/3 failed: %s' % (i+1, e), file=sys.stderr)
time.sleep(15)
assert d, 'snapshot_download failed after 3 attempts'
print(d)
下载完成后检查模型文件是否就位:
ls -lhL <model>/v1-5-pruned-emaonly.safetensors
输出结果如下:
...v1-5-pruned-emaonly.safetensors
Note
allow_patterns只下载v1-5-pruned-emaonly.safetensors(约 4.3 GB,SD 1.5 单文件 checkpoint,即basic_api_example.py默认工作流引用的ckpt_name),跳过仓库里的 diffusers 分片格式。
启动服务(单卡 NPU)
把 checkpoint 链接进 models/checkpoints/(CheckpointLoaderSimple 的 ckpt_name 按文件名索引),后台启动 ComfyUI 服务:
cd ComfyUI
mkdir -p models/checkpoints
ln -sf <model>/v1-5-pruned-emaonly.safetensors models/checkpoints/
nohup python main.py --disable-auto-launch --listen 127.0.0.1 --port 8188 > /tmp/comfyui.log 2>&1 &
echo $!
--disable-auto-launch:无头容器内不要尝试拉起浏览器。设备选择由
comfy/model_management.py自动完成(检测到torch_npu即用npu设备),无需额外参数。
等待服务就绪:
for i in $(seq 1 120); do
curl -sf http://127.0.0.1:8188/system_stats > /dev/null && break
sleep 5
done
curl -sf http://127.0.0.1:8188/system_stats > /dev/null || { echo "server not ready"; tail -n 100 /tmp/comfyui.log; exit 1; }
echo "server ready"
输出结果如下:
server ready
确认 ComfyUI 的设备管理选中的是 NPU:
cd ComfyUI
python -c "import comfy.model_management as mm; print('comfy device:', mm.get_torch_device())"
输出结果如下:
comfy device: npu...
Note
get_torch_device() 与服务进程走同一套检测逻辑,单卡上返回 npu:0。
运行 API 例程(文生图)
提交上游例程 script_examples/basic_api_example.py(默认文生图工作流:SD 1.5,512x512,20 步 euler),轮询 /queue 等待出图完成:
cd ComfyUI
python script_examples/basic_api_example.py && echo "prompt queued"
python - <<'EOF'
import json, time, sys
from urllib import request
deadline = time.time() + 900
while time.time() < deadline:
try:
with request.urlopen('http://127.0.0.1:8188/queue') as r:
d = json.load(r)
except Exception as e:
print('queue poll error:', e)
sys.exit(1)
run = len(d.get('queue_running') or [])
pend = len(d.get('queue_pending') or [])
if (run, pend) == (0, 0):
print('queue drained')
sys.exit(0)
time.sleep(5)
print('queue not drained before deadline')
sys.exit(1)
EOF
ls output/ComfyUI_*.png > /dev/null 2>&1 || { echo "no output image"; tail -n 100 /tmp/comfyui.log; exit 1; }
ls output/ComfyUI_*.png | tail -n 1
输出结果如下:
...prompt queued
...queue drained
...ComfyUI_000xxx
Note
basic_api_example.py只负责把工作流 POST 到/prompt(不等待执行完成),完成后轮询/queue直到 running / pending 均清空。SaveImage节点把结果写到output/ComfyUI_00001_.png(全新 checkout 首跑序号为 00001)。
检查生成结果
cd ComfyUI
python -c "
import glob
paths = glob.glob('output/ComfyUI_*.png')
assert paths, 'no output png'
data = open(paths[0], 'rb').read()
assert data[:8] == b'\x89PNG\r\n\x1a\n', 'not a png'
assert len(data) > 10000, 'png too small: %d' % len(data)
print('png ok:', paths[0], len(data), 'bytes')
"
输出结果如下:
png ok: ...ComfyUI_000xxx bytes
Note
校验 PNG 魔数与体积下限,确保 NPU 上产出的不是空图或损坏文件。
外部链接
GitHub:comfyanonymous/ComfyUI
文档中心:ComfyUI Docs