ComfyUI 工作流笔记:从计算机视觉基础到 AI 图像生成

前言

ComfyUI 用节点图组织 Stable Diffusion 工作流。它不像一键式 WebUI 那样隐藏大部分流程,而是把模型加载、文本编码、采样和解码拆成可连接的节点,便于观察每一步输入输出。下面按计算机视觉概念、常用节点和生成流程做一份整理。

ComfyUI 简介

ComfyUI 是一个基于**节点图(Graph/Nodes)**的 Stable Diffusion 用户界面,将复杂的图像生成流程分解为可视化的节点单元。每个节点代表一个特定功能(加载模型、编码文本、采样等),通过连线组合节点,即可构建从简单到复杂的工作流。

主要特点:

  • 模块化设计:每个步骤都是独立节点,易于理解和调试
  • 组合灵活:支持构建不同复杂度的自定义工作流
  • 内存优化:即使在低显存设备上也能运行,支持 CPU 模式
  • 版本兼容:支持 SD 1.x、SD 2.x、SDXL、SD3.5、FLUX 等多代模型
  • 可扩展性:可接入社区插件

传统 WebUI 采用线性交互界面,隐藏了大量技术细节。ComfyUI 则将整个流程可视化:

graph LR
    A["文本提示词"] --> B["CLIP编码"]
    B --> C["条件注入"]
    C --> D["噪声潜在空间"]
    D --> E["KSampler采样"]
    E --> F["VAE解码"]
    F --> G["最终图像"]

    style A fill:#38bdf8,stroke:#4ade80,stroke-width:2px,color:#000
    style E fill:#f59e0b,stroke:#4ade80,stroke-width:2px,color:#000
    style F fill:#8b5cf6,stroke:#4ade80,stroke-width:2px,color:#fff
    style G fill:#10b981,stroke:#4ade80,stroke-width:2px,color:#000

一个最简单的 Text-to-Image 工作流包含以下节点:

  1. Load Checkpoint:加载模型文件(.safetensors
  2. CLIP Text Encode (Prompt):将正向提示词编码为条件向量
  3. CLIP Text Encode (Negative Prompt):将负向提示词编码
  4. Empty Latent Image:创建初始随机噪声潜在空间
  5. KSampler:采样器,执行去噪过程
  6. VAE Decode:将潜在空间解码为像素图像
  7. Save Image:保存最终图像

计算机视觉基础

**计算机视觉(Computer Vision, CV)**是人工智能的一个分支,研究如何让计算机处理视觉信息。常见任务包括图像分类、目标检测、语义分割,以及图像生成(Stable Diffusion 属于此类)。

在计算机中,图像本质上是一个三维张量:

IRH×W×CI \in \mathbb{R}^{H \times W \times C}

其中 HH 是高度,WW 是宽度,CC 是通道数(RGB 彩色图像为 3)。一张 512×512 的 RGB 图像表示为形状 (512, 512, 3) 的张量,每个值范围通常是 [0,255][0, 255] 或归一化后的 [0,1][0, 1]

Stable Diffusion 属于深度学习范畴,主要用到扩散模型(Diffusion Model)。扩散模型的思想是逐步去噪:正向过程从真实图像 x0x_0 开始,逐步添加高斯噪声,经过 TT 步后变成完全的随机噪声 xTx_T;反向过程则训练一个神经网络 ϵθ\epsilon_\theta,学习如何从噪声 xtx_t 预测并去除噪声,逐步恢复为清晰图像。相比 GAN,扩散模型生成质量更高,训练也更稳定。

主要概念

Checkpoint 模型

Checkpoint 是包含完整 Stable Diffusion 模型权重的文件(通常为 .safetensors.ckpt 格式),内含三个主要组件:

  1. UNet:扩散模型的主体,负责预测噪声
  2. VAE:变分自编码器
  3. CLIP Text Encoder:文本编码器

SD 1.5 模型约 2-4 GB,SDXL 模型约 6-7 GB。不同 Checkpoint 可能专注于写实风格、动漫风格或艺术风格等,决定了生成图像的整体基调。

VAE(变分自编码器)

VAE 是一种压缩技术,将高维像素空间的图像压缩到低维潜在空间,大幅降低计算成本:

编码器(Encoder): 像素图像 (512×512×3) → 潜在空间 (64×64×4)
解码器(Decoder): 潜在空间 (64×64×4) → 像素图像 (512×512×3)

编码过程:z=Encoder(x), zN(μ,σ2)z = \text{Encoder}(x),\ z \sim \mathcal{N}(\mu, \sigma^2)

解码过程:x^=Decoder(z)\hat{x} = \text{Decoder}(z)

这样将 512×512×3=786,432512 \times 512 \times 3 = 786{,}432 维降至 64×64×4=16,38464 \times 64 \times 4 = 16{,}384 维(降低约 48 倍),扩散过程在潜在空间进行,速度提升数十倍,同时压缩后的 zz 仍保留了图像的语义信息。

在 ComfyUI 中,VAE Encode 将输入图像转为潜在空间(用于图生图),VAE Decode 将采样生成的潜在空间解码为最终图像。如果生成的图像颜色失真或模糊,通常需要更换 VAE 模型。

CLIP(文本编码器)

CLIP 是 OpenAI 开发的多模态模型,能将文本和图像映射到同一个向量空间,使语义相似的文本和图像在向量空间中距离接近。在 Stable Diffusion 中,CLIP 的 Text Encoder 部分将提示词转换为高维向量,作为扩散模型的条件信号:

Prompt: "a cat on the moon"CLIPcR77×768\text{Prompt: "a cat on the moon"} \xrightarrow{\text{CLIP}} \mathbf{c} \in \mathbb{R}^{77 \times 768}

其中 77 是最大 token 数量,768 是 CLIP ViT-L/14 的嵌入维度。

在去噪过程中,UNet 通过 Cross-Attention(交叉注意力)机制将文本向量 c\mathbf{c} 注入图像生成过程:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

其中 QQ 来自图像特征,K,VK, V 来自文本嵌入 c\mathbf{c}。ComfyUI 中分别用 CLIP Text Encode (Positive)CLIP Text Encode (Negative) 节点处理正负提示词。

LoRA(低秩适应)

完整微调一个 Stable Diffusion 模型需要数十 GB 显存和大量时间。LoRA 提供了轻量级的微调方案:冻结原始模型权重 W0W_0,仅训练两个低秩矩阵 AABB

W=W0+ΔW=W0+BAW = W_0 + \Delta W = W_0 + BA

其中 BRd×r, ARr×kB \in \mathbb{R}^{d \times r},\ A \in \mathbb{R}^{r \times k},秩 rd,kr \ll d, k

LoRA 文件通常仅 10-200 MB,可以同时加载多个并叠加不同风格,也不修改原始模型,方便实验。常见用途包括学习特定风格(水彩、油画)、特定人物角色或特定场景。ComfyUI 中用 Load LoRA 节点加载,强度在 0-1 之间调整。

Latent(潜在空间)

Latent 是图像经 VAE 编码后的压缩表示,是扩散过程实际操作的对象。对于 512×512 的图像,潜在空间形状为 (B,4,64,64)(B, 4, 64, 64),其中 BB 是批次大小,空间分辨率是原图的 1/8。

初始化方式有两种:Text-to-Image 从标准正态分布采样随机噪声 zTN(0,I)z_T \sim \mathcal{N}(0, I);Image-to-Image 则先用 VAE 编码输入图像,再添加部分噪声:

zt=αˉtz0+1αˉtϵz_t = \sqrt{\bar{\alpha}_t}\, z_0 + \sqrt{1 - \bar{\alpha}_t}\, \epsilon

ComfyUI 中对应 Empty Latent Image(纯噪声)、VAE Encode(图像编码)和 Latent Upscale(放大分辨率)等节点。

KSampler(采样器)

KSampler 是 ComfyUI 中执行扩散模型去噪过程的节点,基于 Katherine Crowson 的 k-diffusion 库。从随机噪声 zTz_T 开始,经过 TT 步迭代逐步去噪:

zt1=Sampler(zt,ϵθ,cpos,cneg,CFG)z_{t-1} = \text{Sampler}(z_t,\, \epsilon_\theta,\, \mathbf{c}_{\text{pos}},\, \mathbf{c}_{\text{neg}},\, \text{CFG})

常用参数:

  • Steps(采样步数):更多步数结果更精细但速度更慢,DPM++ 系列典型值 20-30 步,DDIM/Euler 需要 50-100 步
  • CFG Scale:控制提示词引导强度,典型值 7-12;过高会导致图像过饱和,过低则偏离提示词
  • Sampler(采样算法):Euler 简单快速适合测试,DPM++ 2M 高质量收敛快,DDIM 确定性采样适合复现结果
  • Scheduler(调度器):Karras 推荐用于 DPM++ 系列,收敛更稳定
  • Seed(随机种子):相同种子加相同参数得到相同结果,用于复现或微调特定图像
  • Denoise(去噪强度)1.0 为完全去噪(Text-to-Image),0.5-0.7 为部分去噪(Image-to-Image,保留原图结构)

CFG(分类器自由引导)

CFG 在推理时同时计算条件预测和无条件预测,然后线性外推以增强条件的影响:

ϵ~θ(xt,c)=ϵθ(xt,)+s(ϵθ(xt,c)ϵθ(xt,))\tilde{\epsilon}_\theta(x_t, \mathbf{c}) = \epsilon_\theta(x_t, \emptyset) + s \cdot \bigl(\epsilon_\theta(x_t, \mathbf{c}) - \epsilon_\theta(x_t, \emptyset)\bigr)

CFG Scale 为 1.0 时接近无条件生成,7.0 是推荐默认值,15.0 以上高度符合提示词但可能过饱和,30.0 以上通常导致失真。训练时以一定概率(约 10%)将条件替换为空,使模型同时学会无条件生成。

图像生成流程

以下是 Stable Diffusion 通过 ComfyUI 生成图像的一般流程:

graph TB
    subgraph Stage1["阶段 1:模型和条件准备"]
        A1[Load Checkpoint] -->|加载| A2["UNet + VAE + CLIP"]
        A3["正向提示词"] -->|CLIP Text Encoder| A4["正向条件向量 77×768维"]
        A5["负向提示词"] -->|CLIP Text Encoder| A6["负向条件向量 77×768维"]
    end

    subgraph Stage2["阶段 2:潜在空间初始化"]
        B1["Empty Latent Image"] -->|生成| B2["随机噪声 1×4×64×64"]
    end

    subgraph Stage3["阶段 3:迭代去噪"]
        C1["KSampler 执行 T 步迭代"]
        C2["UNet预测条件噪声"]
        C3["UNet预测无条件噪声"]
        C4["CFG引导合成最终噪声"]
        C5["采样器去噪一步"]
        C1 --> C2 --> C3 --> C4 --> C5
    end

    subgraph Stage4["阶段 4:解码为像素图像"]
        D1["VAE Decoder"] -->|解码| D2["最终图像 512×512×3"]
        D2 --> D3["Save Image"]
    end

    A2 --> B1
    B2 --> C1
    A4 --> C2
    A6 --> C3
    C5 --> D1

    style Stage1 fill:#1e293b,stroke:#4ade80,stroke-width:2px
    style Stage2 fill:#1e293b,stroke:#4ade80,stroke-width:2px
    style Stage3 fill:#1e293b,stroke:#4ade80,stroke-width:2px
    style Stage4 fill:#1e293b,stroke:#4ade80,stroke-width:2px

四个阶段简述:

  1. 文本处理:CLIP 将自然语言转换为数值向量,正负提示词分别编码,后续通过 CFG 结合
  2. 潜在空间初始化:从标准正态分布采样初始噪声;图生图模式下先用 VAE 编码输入图像
  3. 迭代去噪(最耗时):UNet 预测当前噪声,采样算法逐步去除,每步都受文本条件引导
  4. 图像解码:VAE Decoder 将压缩表示还原为高分辨率图像

标准 Text-to-Image 节点连接如下:

graph LR
    LoadCheckpoint["Load Checkpoint"]
    CLIPPos["CLIP Text Encode (Positive)"]
    CLIPNeg["CLIP Text Encode (Negative)"]
    EmptyLatent["Empty Latent Image"]
    KSampler["KSampler"]
    VAEDecode["VAE Decode"]
    SaveImage["Save Image"]

    LoadCheckpoint -->|MODEL| KSampler
    LoadCheckpoint -->|CLIP| CLIPPos
    LoadCheckpoint -->|CLIP| CLIPNeg
    LoadCheckpoint -->|VAE| VAEDecode

    CLIPPos -->|CONDITIONING| KSampler
    CLIPNeg -->|CONDITIONING| KSampler
    EmptyLatent -->|LATENT| KSampler
    KSampler -->|LATENT| VAEDecode
    VAEDecode -->|IMAGE| SaveImage

    style LoadCheckpoint fill:#38bdf8,stroke:#4ade80,stroke-width:2px,color:#000
    style KSampler fill:#f59e0b,stroke:#4ade80,stroke-width:2px,color:#000
    style VAEDecode fill:#8b5cf6,stroke:#4ade80,stroke-width:2px,color:#fff
    style SaveImage fill:#10b981,stroke:#4ade80,stroke-width:2px,color:#000

高级工作流

Image-to-Image(图生图):将输入图像经 VAE Encode 转为潜在空间,再送入 KSampler(设置 denoise=0.6 左右),保留原图结构的同时按提示词改变内容。

ControlNet(精确控制结构):从参考图像提取边缘(Canny)、深度图或姿态骨架,通过 ControlNet Apply 节点将这些结构信息注入条件,精确控制生成图像的构图和姿态。

LoRA 堆叠(组合多种风格):多个 Load LoRA 节点串联,每个节点设置独立的强度值,可以同时叠加风格 LoRA 和角色 LoRA,灵活组合不同效果。

常见问题排查

问题可能原因解决方案
图像模糊VAE 质量差更换为质量更好的 VAE 模型
颜色异常VAE 不匹配使用模型配套的 VAE
显存不足分辨率过高或批次过大降低分辨率或启用 --lowvram
不符合提示词CFG 过低提高 CFG Scale 到 7-12
图像过饱和CFG 过高降低 CFG Scale 或优化提示词

学习路径

入门:搭建基础 Text-to-Image 工作流,理解每个节点的作用,实验不同采样器和 CFG 值。

进阶:学习 LoRA 的使用,探索 ControlNet、IP-Adapter 等高级控制方式,优化工作流性能(批处理、并行节点)。

高级:编写自定义节点(Python),训练自定义模型和 Embedding,构建自动化生成流程(API 调用)。

参考资源

总结

ComfyUI 把 AI 图像生成流程拆成可视化节点,适合用来观察 Stable Diffusion 每个环节的输入和输出。VAE 负责像素与潜在空间的转换,CLIP 负责文本语义编码,KSampler 负责迭代去噪,LoRA 负责轻量级风格迁移。把这些节点的职责理清之后,就能读懂现有工作流,并按需求调整自己的生成方案。