欢迎光临
我们一直在努力

深入浅出完整解析ComfyUI、Diffusers、Stable Diffusion WebUI等主流AIGC创作框架核心基础知识

写在前面

图片

欢迎大家关注Rocky的知乎:Rocky Ding 《三年面试五年模拟》AIGC/LLM/AI Agent算法工程师/开发工程师求职面试秘籍独家资源:【三年面试五年模拟】WeThinkIn/AIGC-Interview-Book,欢迎大家Star~

Rocky最新撰写的10万字AI Agent(AI智能体)深入浅出全维度解析文章: 深入浅出完整解析AI Agent(AI智能体)的核心基础知识


大家好,我是Rocky。

图01 文章引言配图

码字不易,希望大家能多多点赞,给Rocky更多坚持写下去的动力,谢谢大家!


大家好,我是Rocky。

2022年是AIGC时代的元年,AIGC图像创作领域全面爆发。Stable Diffusion系列模型、FLUX系列模型、LoRA系列模型、ControlNet系列模型、GAN系列模型以及各种AIGC技术组成的变化万千的AIGC图像创作“工作流”伴随着持续繁荣的开源生态,让AIGC图像创作领域在ToB和ToC方向都具备了不可限量的势能!

那么这些变化万千的AIGC图像创作“工作流”在哪些载体上运行呢?或者说海量的AIGC图像创作内容是从哪里源源不断地生产出来呢?这里就要提到我们本文的核心内容——AIGC图像创作框架了。

AIGC图像创作框架正是AIGC图像创作“工作流”的运行载体,目前主流的AIGC图像创作框架有ComfyUI、Diffusers以及Stable Diffusion WebUI。在传统深度学习时代,PyTorch、TensorFlow以及Caffe是传统深度学习模型的运行基础框架,到了AIGC时代,Rocky相信ComfyUI就是AI绘画领域的“PyTorch”、Stable Diffusion WebUI就是AI绘画领域的“TensorFlow”、Diffusers就是AI绘画领域的“Caffe”。

图02 文章引言配图

因此在本文中,Rocky主要对上述三个AIGC图像创作框架的全维度各个方面都做一个深入浅出的分析总结(从0到1对ComfyUI/Diffusers/Stable Diffusion WebUI进行安装搭建,从0到1使用ComfyUI/Diffusers/Stable Diffusion WebUI进行AI绘画的保姆级教程,深入浅出介绍ComfyUI/Diffusers/Stable Diffusion WebUI的各模块功能介绍,深入浅出介绍ComfyUI/Diffusers/Stable Diffusion WebUI的主流插件用法,ComfyUI/Diffusers/Stable Diffusion WebUI的最新资源汇总,相关配套工具使用等),和大家一些探讨学习,让我们在AIGC时代更好地融入和从容。

相信很多刚入门AIGC图像创作/AI绘画的小伙伴都对如何配置AIGC图像创作/AI绘画框架一头雾水,一时半会儿也找不到快速入门的AI绘画应用平台,同时苦于没有算力支持AI绘画模型的使用,这些因素让很多热爱AIGC图像创作/AI绘画的小伙伴们望而止步。

接下来,就跟着Rocky的脚步,我们一起来从0到1全方位使用主流AIGC图像创作框架进行AI绘画的创作吧!

1. AIGC创作框架干货资源汇总

AIGC图像创作框架主流资源分享:

  • ComfyUI项目地址:ComfyUI
  • Diffusers项目地址:diffusers
  • Stable Diffusion WebUI(AUTOMATIC1111)项目地址:AUTOMATIC1111/stable-diffusion-webui
  • Stable Diffusion WebUI Forge项目地址:stable-diffusion-webui-forge
  • SD.Next项目地址:sdnext
  • Fooocus项目地址:Fooocus
  • Rocky会持续把更多AIGC图像创作框架的干货资源发布到本节中,让大家更加方便的查找AIGC图像创作框架的最新资讯。

    2. 深入浅出完整讲解ComfyUI核心基础知识

    ComfyUI作为目前AIGC图像创作/AI绘画领域的最主流节点式框架,是基于gradio架构研发的。ComfyUI的核心本质是一个以创作画布为中心的节点图工作流引擎。它把图像创作过程拆成一系列可连接、可复用、可保存的节点,例如加载模型、编码prompt、采样、解码、加载LoRA、应用ControlNet、超分、图像后处理编辑、保存图像等。可以构建丰富多样的AIGC图像创作工作流,实现更加精准的AIGC图像功能定制,同时让AIGC图像创作的流程更加解耦和可复现。

    这里的“创作画布”不是一个简单的UI概念,而是ComfyUI在主流框架中激烈竞争并脱颖而出的底层设计思想。Stable Diffusion WebUI更像一个参数面板:用户在固定表单里填写prompt、seed、steps、CFG、采样器和插件参数,然后等待生成结果。

    ComfyUI则更像一张可以无限展开的视觉工程画布:Base模型、文本条件、图像条件、局部mask、ControlNet、IP-Adapter、LoRA、采样器、VAE、超分、局部修复等模块,都可以被放在同一张画布上,并通过连线显式表达它们之间的因果关系。

    Rocky认为,创作画布的跨周期价值,是把AIGC图像创作从“调参数”升级为“搭系统”。在早期AIGC图像创作阶段,用户关心的是如何用一个prompt生成一张优质的图像;但到了多模型、多参考图、多ControlNet、多LoRA、多区域编辑的AIGC图像创作生态繁荣阶段,真正重要的已经不是某个单独参数,而是整条创作链路如何被组织、复现、调试和复用,ComfyUI的画布思想正好完美承载了这种复杂性。

    图03 ComfyUI框架经典工作流界面

    ComfyUI框架经典工作流界面

    AIGC图像创作工作流中的每一个模块都有特定的的功能,我们可以通过调整模块的排列组合达到不同的AIGC图像创作功能,但节点式的工作流也提高了一部分使用门槛。

    与此同时,ComfyUI对内部的AI绘画流程进行了优化,生成图片的耗时比Stable Diffusion WebUI减少了10%-25%左右(不同GPU的提升效果不同)。在生成超大图片(分辨率1024×1024以上)时也不会导致显存溢出,但可能会因为图像切块运算导致生成的图像出现割裂和不自然的现象。

    2.1 从0到1在端脑云平台快速上手使用ComfyUI

    我们只需要按照下面详细的创建新应用的流程,创建一个ComfyUI的应用即可使用ComfyUI框架!

    图04 2.1 从0到1在端脑云平台快速上手使用ComfyUI

    如上图所示,我们打开端脑云平台界面,点击左侧的“我的应用”,就可以看到正在运行中的ComfyUI应用,我们点击右侧的“进入应用”,即可使用ComfyUI框架进行AI绘画了!

    同时,我们点击“文件管理”按钮,就能进入后台管理ComfyUI框架的SD系列模型,LoRA模型,ControlNet模型等核心组件,方便的搭建自己的AI绘画模型武器库。大家可以点击如下链接进行注册使用,挖掘脑云平台上ComfyUI框架的更多玩法:Cephalon Cloud

    图05 2.1 从0到1在端脑云平台快速上手使用ComfyUI

    从上图可以看到,ComfyUI框架中每个模块都是解耦的,Load Checkpoint模块用于加载SD系列模型;CLIP Text Encode模块用于输入正向提示词和负向提示词;Empty Latent Image用于生成初始的Latent特征;Ksampler模块用于控制扩散过程;VAE Decode模块用于将Latent Feature重建成像素级的图像。

    我们接着输入以下提示词:Landscape painting, a thatched wooden house with bamboo fences in front of it covered in blooming roses (close-up), flowers and plants on the ground, stone path, sunset glow, red clouds all over the sky, dreamy, fantastical, cinematic lighting, beautiful, aesthetic, wlop, digital painting, trending on ArtStation, highly detailed, epic composition, official media, 8k uhd, distant

    并且点击“Queue Prompt”,开始生成图片:

    图06 2.1 从0到1在端脑云平台快速上手使用ComfyUI

    上面的工作流是经典的文生图工作流,那么图生图工作流、ControlNet工作流、Inpainting工作流、图像超分工作流等更多玩法,还需要大家自己亲自使用构建。

    2.2 ComfyUI框架核心基础原理讲解(全网最详细代码解析)

    从之前的章节我们已经知道ComfyUI 是AIGC时代的“基于有向无环图(DAG)的可视化推理管线”AIGC图像创作框架。ComfyUI把“模型加载、算子节点、图调度执行、API/服务层、扩展节点生态”等模块清晰分层,核心在于把Stable Diffusion、FLUX、Z-Image、Qwen-Image、Seedream等AIGC大模型推理流程拆成节点,每个节点都有自己独立的功能,每个模块通过输入和输出的线连在一起变成一个完整的工作流,最后组合成图后由执行引擎调度运行。

    正是因为ComfyUI简单易懂和极具扩展性的设计思想,目前在AI绘画/AIGC图像创作领域中得到了广泛的应用,延展出繁荣的生态。

    接下来Rocky通过对ComfyUI中代表性的处理流程进行深入浅出的分析,希望能够帮助读者理解ComfyUI中的各种核心实现,以及与外部节点算法库集成的各种细节,从而可以解决应用ComfyUI过程中出现的各种问题,或者基于ComfyUI进行二次开发工作。

    【一】ComfyUI运行入口与核心服务进程代码解析

    核心文件名称作用讲解
    main.py 常用启动入口(解析 CLI 配置、初始化模型路径、前端资源、启动服务器)
    server.py WebSocket/HTTP 服务层与会话管理,处理前端通信、任务提交/进度回传、图的执行触发
    protocol.py 与前端/客户端通信协议的小型约束
    app/ app_settings.py、frontend_management.py:前端静态资源、设置管理。model_manager.py、user_manager.py:运行期模型/用户管理。custom_node_manager.py:自定义节点扫描/装载。logger.py:日志集成。
    api_server/ 若开启独立 API 模式,这里提供 REST 路由与服务工具(routes/、services/、utils/file_operations.py)
    execution.py 计算图与调度执行:把前端/协议层提交的“图”编译为可执行计划,协调调度、错误恢复、资源管理,与 comfy/ 模型层打通。
    comfy_execution/ 图执行引擎: graph.py、graph_utils.py:图结构、拓扑排序、依赖与节点 IO 管理。caching.py:节点级缓存/中间结果复用策略(哈希输入/参数以避免重复计算)。progress.py:进度、步骤回调、可中断机制。validation.py:图与节点输入校验。utils.py:执行期工具。
    node.py DAG内置节点的实现。内置标准节点的集中定义(图像加载/保存、提示词、采样、ControlNet、LoRA、VAE、调度器等)。节点声明输入/输出类型、执行逻辑,供图引擎装配。
    comfy_extras/ 扩展节点与功能(更广的 IO、图像处理、后处理、实验性算子等)
    custom_nodes/ 用户侧自定义节点存放目录(样例 example_node.py.example)。启动时由 app/custom_node_manager.py 自动发现并注册。
    comfy_api_nodes/ 基于 Comfy API 的“节点化封装”,把三方/外部推理服务(如 OpenAI、Stability、Runway、Luma、Pika 等)包装为可组合节点: nodes_*.py:各厂商/平台的节点集合。apis/、util/、mapper_utils.py:统一鉴权、参数映射、错误处理与工具。允许在同一图中混合本地推理与云端推理。
    comfy/ (推理与模型底层)文生图/图生图核心:sd.py(除SD采样算法外其他模块包含VAE、CLIP等算法模块的前后处理逻辑)、model_base.py(在开源SD代码的基础上进一步封装了diffusion的一些关键模型对象)、model_management.py(实现模型在不同设备上的加载、卸载与显存管理等功能)、model_patcher.py(对模型进行权重修改,支持LORA动态加载等功能)、model_sampling.py、sample.py、samplers.py(核心采样算法前后处理相关逻辑)、extra_samplers/。文本/图像编码器:text_encoders/、image_encoders/、audio_encoders/、clip_*.py、sd1_clip.py、sdxl_clip.py。控制/适配:controlnet.py(controlnet等相关控制型算法模型的处理逻辑)、t2i_adapter/、lora.py(lora模型加载的相关逻辑)、lora_convert.py、weight_adapter/。Diffusers 适配:diffusers_load.py、diffusers_convert.py。其它底层:ops.py(算子)、utils.py(通用工具)、options.py(可选项)、latent_formats.py、rmsnorm.py 等。大量具体模型实现在 ldm/ 子目录(Stable Diffusion/UNet/VAE 等结构与组件)。
    models/ 模型权重的默认目录结构(如 checkpoints/、vae/、loras/ 等)。
    folder_paths.py 统一管理与发现模型/资源的查找路径、覆盖机制(结合 extra_model_paths.yaml.example)。
    middleware/ cache_middleware.py:请求/响应或任务级缓存挂钩,可与执行缓存协作,提高多用户/多请求复用率。
    工程与配置 pyproject.toml、requirements.txt:依赖与打包配置。comfy_config/:配置解析(config_parser.py)与类型(types.py)。middleware/、utils/、node_helpers.py、latent_preview.py、cuda_malloc.py:辅助模块与性能工具。script_examples/:Python 客户端示例(HTTP/WebSocket 调用、提交图、接收图像)。output/:默认输出目录。

    接下来Rocky再将上面表格中的核心文件代码已流程图的形式展现,让大家能够更加直观的学习感受ComfyUI的魅力:

    图07 2.2 ComfyUI框架核心基础原理讲解(全网最详细代码解析)

    我们再来学习一下ComfyUI的模型管理机制:

    • ComfyUI自带的model loader大部分会先把模型加载到内存中,然后在运行时按需加载到GPU(KSampler节点运行前);
    • Controlnet模型在ControlNetLoader节点会加载到内存中,然后在ControlnetApply节点基于strength生成一个新的模型副本,最终在KSampler节点统一加载到GPU中;
    • CheckpointLoaderSimple节点在一些条件下底模会直接加载到显存中,后续若底模引用发生变化(比如加了LoRA相关Patch),则会在KSampler节点卸载原底模,加载新底模;
    • 核心模型加载到GPU上都是通过comfy/model_management.py::load_models_gpu()API来实现,最终加载到GPU上的模型都通过comfy/model_management.py::current_loaded_models 数组来缓存。
    • 核心模型从GPU卸载到Memory,会调用comfy/model_management.py::cleanup_models()API来实现;卸载时机是每次进行workflow的调度前,会检查comfy/model_management.py::current_loaded_models 数组中每个模型的引用计数,如果无其他对象引用该模型,则会进行模型卸载。
    • ComfyUI每次调度workflow过程中每个节点的执行结果会被缓存,下次请求执行时会通过节点参数以及前置依赖节点的参数是否变化或者节点的ISCHANGED()方法来判断是否清理缓存和重新执行当前节点。节点的缓存清理和模型的引用计数相关联 。

    到这里,我们已经知道ComfyUI是基于节点式的AIGC图像创作框架了,那么我们该如何本质的理解其工作原理与框架思想呢?

    我们以Stable Diffusion模型为例,先拆解一下ComfyUI完整工作流程,具体如下所示:

    图08 Stable Diffusion模型的完整工作流程

    Stable Diffusion模型的完整工作流程

    可以看到,Stable Diffusion模型的完整推理流程可以解耦成Condition注入、扩散模型去噪、VAE编码与解码等几个模块,ComfyUI正是基于这些工作模块,对每个模块单独进行封装,制作出了一个个AIGC图像节点(node),我们可以方便的对这些节点进行连接与搭建,从而形成各式各样的AIGC图像创作工作流。

    接下来,我们再对每个节点进行详细的讲解。

    首先是获取输入Prompts的Tokens。由于计算机不理解原始的输入文字,因此首要任务是使用分词器将每个单词转换为token符号。

    图09 使用分词器将输入Prompts转换成Token符号

    使用分词器将输入Prompts转换成Token符号

    print(tokenizer('dog in batman costume'))
    {'input_ids': [49406, 1929, 530, 7223, 7235, 49407], 'attention_mask': [1, 1, 1, 1, 1, 1]}

    如果我们打开在Stable Diffusion官方提供的tokenizer文件夹,就可以找到的文件vocab.json,里面包含了几乎所有输入文字的对应Token符号字典。

    "<|startoftext|>": 49406,

    "dog</w>": 1929,

    "in</w>": 530,

    "batman</w>": 7223,

    "costume</w>": 7235,

    "<|endoftext|>": 49407,

    我们完成输入文本到Tokens的转化后,接下来需要进行Token到Text Embeddings特征的编码。

    图10 Token到Text Embeddings特征的编码

    Token到Text Embeddings特征的编码

    在我们获得Text Embeddings特征后,还需要通过Attention机制将其转换成Transformer特征,注入到Stable Diffusion的扩散模型中。

    图11 Text Embeddings特征通过Attention机制转换成Transformer特征

    Text Embeddings特征通过Attention机制转换成Transformer特征

    有了上面的这些文本特征信息,再加上图像的Latent特征,我们就可以使用Stable Diffusion的扩散模型部分进行去噪生成过程了。

    图12 Stable Diffusion的扩散模型部分的去噪生成过程

    Stable Diffusion的扩散模型部分的去噪生成过程

    注意,Stable Diffusion 1.x、2.x以及XL版本的扩散模型部分是基于U-Net架构的;如果是Stable Diffusion 3或者FLUX.1版本,其扩散模型部分是基于Transformer架构的。

    同时我们需要配置调度器的TimeSteps数值:

    scheduler.set_timesteps(inference_steps)
    print(scheduler.timesteps)

    tensor([999.0000, 964.5517, 930.1035, 895.6552, 861.2069, 826.7586, 792.3104,
    757.8621, 723.4138, 688.9655, 654.5172, 620.0690, 585.6207, 551.1724,
    516.7241, 482.2758, 447.8276, 413.3793, 378.9310, 344.4828, 310.0345,
    275.5862, 241.1379, 206.6897, 172.2414, 137.7931, 103.3448, 68.8966,
    34.4483, 0.0000])

    上述的TimeSteps有30个步骤,同时间隔相同的距离(34.4483个单位)。

    最后,我们需要VAE的编码器将输入图像转换为潜在空间中的张量,并且使用VAE的解码器将潜在空间中的张量转换为图像。

    图13 VAE的编码器和解码器的编码与解码过程

    VAE的编码器和解码器的编码与解码过程

    上述的整个扩散模型推导过程,就在ComfyUI以节点图的形式生动呈现,方便用户的高效AIGC图像工作流搭建与优化。

    2.3 ComfyUI特性介绍

    • 简洁的节点/图形/流程图界面,用于快速实验和创建复杂的AI绘画工作流,无需编写任何代码。
    • 完全支持 SD系列和FLUX.1系列等主流AI绘画大模型。
    • 异步队列系统。
    • 只重新执行同一工作流中在两次执行之间发生变化的部分。
    • 如果没有GPU也能使用,自动切换至CPU。
    • 支持加载ckpt、safetensors、pt和diffusers等不同格式的AI绘画模型。
    • 支持LoRA系列模型、ControlNet系列模型、GAN系列模型、Embeddings系列模型、传统深度学习模型等AI行业的所有主流模型。
    • 生成的PNG文件中包含了完整的工作流信息,能够方便在ComfyUI上再次加载。
    • 可以使用Json形式保存/加载工作流。
    • 支持AI绘画模型的融合实验和模型保存(Model Merging)。
    • 与Stable Diffusion WebUI相比,启动速度极快。

    除此之外,ComfyUI的节点图还有四个设计关键点:

  • 节点是功能单元。 每个节点只做一件相对清晰的事,例如加载模型、编码文本、采样、解码、保存。它让复杂生成流程从“黑盒按钮”变成“可拆解流程”。
  • 连线是数据依赖。 节点之间传递的不是抽象概念,而是具体数据类型,例如 MODEL、CLIP、VAE、CONDITIONING、LATENT、IMAGE、MASK。这使得用户可以明确知道信息如何流动。
  • 画布是创作过程的空间化表达。 在ComfyUI里,用户可以在画布上组织一个视觉生产系统。哪一个模块是正向prompt,哪一个模块是负向prompt,哪一个模块是参考图条件,哪一个模块是局部mask,哪一步做Latent upscale,哪一步做VAE decode等,都会被空间化地呈现出来。这让复杂图像创作更加直观与形象。
  • 工作流是可复现资产。 ComfyUI可以保存/加载JSON工作流,也可以从生成图片中恢复工作流元数据。这个设计很适合工程场景和团队协作。
  • 图14 2.3 ComfyUI特性介绍

    如上图所示,Rocky认为,ComfyUI值得掌握的设计思想,是把模型能力组织成有明确接口、可组合、可检查的流程。 也顺应了AIGC图像创作逐渐向复杂组合工作流发展的趋势。Stable Diffusion WebUI把常见操作集中在任务面板,Diffusers通过Pipeline与代码组件组织调用,Fooocus通过预设减少配置负担,ComfyUI则把节点之间的数据依赖与信息传递过程直接呈现给用户。

    这也是ComfyUI能够在众多AIGC图像创作框架中形成差异化的原因:把AIGC图像创作抽象成一张可编排、可扩展、可复现的视觉工作流画布。当AIGC图像创作进入复杂工作流时代,创作画布就不再是交互形式,而是生产力基础设施。

    2.4 ComfyUI文生图全解析

    第一次打开 ComfyUI,很多人会卡在同一个地方:提示词认识,模型也下载好了,画布上的线却不知道该怎么接。照着别人的工作流能出图,删掉一个节点就报错;换个模型,又不知道哪些参数应该跟着改。

    解决这个问题,可以从一张最简单的文生图工作流开始。我们先做出一张“林间木屋”的图片,再围绕它学习图生图、LoRA、ControlNet 和超分辨率。场景固定下来,每增加一个模块,它改变了什么,就容易看清楚了。

    学 ComfyUI,先把数据从哪里来、经过什么处理、最后交给谁弄明白。节点名字会变,数据之间的关系更值得记住。

    本节默认大家已经按前面的章节启动了 ComfyUI,能够打开画布。本教程使用 SD 1.5 模型,先以 512×512、单张图片完成练习。选择这套配置,是因为它的基础工作流比较短,LoRA、ControlNet 配套资料也容易找到。

    准备一个适用于 SD 1.5、包含完整推理组件的 checkpoint,例如 v1-5-pruned-emaonly.safetensors。优先选择 .safetensors 文件。不同权重的画风和提示词习惯有差别,练习中途先不要换模型。

    通常把 checkpoint 放进下面的目录:

    ComfyUI/
    ├── models/
    │ ├── checkpoints/ # SD 主模型
    │ ├── loras/ # 后面使用的 LoRA
    │ ├── controlnet/ # 后面使用的 ControlNet
    │ └── upscale_models/ # 后面使用的超分辨率模型
    ├── input/ # 输入图片
    └── output/ # 保存的生成结果

    如果使用桌面版、整合包或者云平台,模型目录可能已被平台映射到其他位置。以实际配置的模型目录为准;文件放好后刷新模型列表,仍然找不到再重启后端。模型出现在下拉列表里,才说明当前实例扫描到了这个文件。

    这里还有一个容易踩的坑:模型文件扩展名相同,不代表加载方式相同。 某些模型只提供扩散网络权重,需要单独加载文本编码器和 VAE,不能直接套用下面这张完整 checkpoint 工作流。SDXL、FLUX 等模型也有各自的推荐模板。初学时先保证模型体系统一,再迁移到其他架构。

    在空白画布双击,搜索节点的英文名并添加。不同版本的中文翻译、分类位置可能不同,下面同时列出显示名称和内部类型,方便大家核对:

    节点内部类型数量负责什么
    Load Checkpoint CheckpointLoaderSimple 1 加载主模型、文本编码器和 VAE
    CLIP Text Encode (Prompt) CLIPTextEncode 2 分别编码正向、负向提示词
    Empty Latent Image EmptyLatentImage 1 设置潜空间画布尺寸与批次数量
    KSampler KSampler 1 根据模型、条件和噪声执行采样
    VAE Decode VAEDecode 1 将采样结果解码成可见图片
    Save Image SaveImage 1 保存图片,通常写入工作流元数据

    图15 2.4 ComfyUI文生图全解析

    第一步,接好模型。 Load Checkpoint 有三个输出:MODEL、CLIP、VAE。把 MODEL 接到 KSampler.model;把 CLIP 分别接到两个文本编码节点的 clip 输入;把 VAE 接到 VAE Decode.vae。

    第二步,接好提示词。 两个 CLIP Text Encode 的结构相同,分别改名为“正向提示词”和“负向提示词”。正向节点的输出接 KSampler.positive,负向节点的输出接 KSampler.negative。名字只是方便阅读,真正决定用途的是它接到了哪个输入口。

    第三步,接好画布。 将 Empty Latent Image 的 LATENT 输出接到 KSampler.latent_image。宽高设为 512,batch_size 设为 1。

    第四步,接好图片出口。 将 KSampler 的 LATENT 输出接到 VAE Decode.samples,再把解码后的 IMAGE 接到 Save Image.images。

    完整连线可以对照这张表检查:

    从哪里出来接到哪里数据类型
    Load Checkpoint.MODEL KSampler.model MODEL
    Load Checkpoint.CLIP 两个 CLIP Text Encode.clip CLIP
    正向文本编码.CONDITIONING KSampler.positive CONDITIONING
    负向文本编码.CONDITIONING KSampler.negative CONDITIONING
    Empty Latent Image.LATENT KSampler.latent_image LATENT
    KSampler.LATENT VAE Decode.samples LATENT
    Load Checkpoint.VAE VAE Decode.vae VAE
    VAE Decode.IMAGE Save Image.images IMAGE

    为什么中间还要经过 VAE?因为这套 Stable Diffusion 工作流主要在压缩后的潜空间中采样。对于这里使用的 SD 1.5 VAE,512×512 的图片对应空间尺寸为 64×64 的潜变量。LATENT 不是一张可以直接保存成照片的 RGB 图片,必须先解码。

    还要纠正一个常见误解:Empty Latent Image 创建的是空潜变量,SD 1.5 的这个节点内部用零张量初始化;随机噪声由采样流程根据 seed 准备。 所以这个节点负责尺寸和批量设置,种子则在 KSampler 里控制。

    基于此,我们可以推理生成第一张图。

    在正向提示词中输入:

    a small wooden cabin in a pine forest, a stone path leading to the door,
    warm light from the windows, early morning mist, natural colors,
    wide shot, architectural photography

    负向提示词先保持简洁:

    text, watermark, blurry, distorted architecture, oversaturated

    这组提示词把主体、环境、构图、光线和表现形式交代清楚了。先观察模型能否画对“木屋、松林、通向门口的小路”,再增加细节。把一长串画质词塞进去,往往会让初学者更难判断哪个词起作用。

    KSampler可以使用下面这组参数:

    参数本次练习设置怎么理解
    seed 123456789 固定本次噪声随机性,方便做对照
    control_after_generate fixed 生成后保留种子;属于前端控件
    steps 24 采样步数,先让画面稳定成形
    cfg 7 无分类器引导强度,影响文本条件引导
    sampler_name dpmpp_2m 本次使用的采样算法
    scheduler karras 本次使用的噪声调度方式
    denoise 1.0 文生图采用完整去噪范围

    这些参数适用于本节的常规 SD 1.5 练习。LCM、Turbo、Lightning 等加速模型或加速 LoRA,通常有专门的步数、CFG 和采样要求,不能直接套用。

    点击界面的运行按钮。不同版本可能显示为 Run、Queue Prompt 或“运行”。第一次运行需要加载模型,通常会比后续运行慢。成功后,Save Image 会显示预览,文件写入当前实例的输出目录。云平台还可能提供独立的下载入口。

    不要要求自己的画面与某张教程配图逐像素一致。即使提示词和 seed 相同,只要模型文件、VAE、软件版本、计算精度或硬件环境不同,结果就可能变化。seed 是复现记录中的一项,完整工作流和具体模型才是复现的基础。

    有了第一张图,先保存工作流,再做三个小实验。每次只改一个变量,并把对照图片留下。

  • 只改 seed。 固定提示词和其他参数,试三个种子。观察木屋位置、树木分布和路径走向。它适合寻找构图,不适合承担“修复某扇窗户”的精确任务。
  • 固定 seed,只改 CFG。 分别试 5、7、9。看提示词响应有没有增强,同时检查颜色是否过饱和、边缘是否发硬。CFG 并非画质分数,过高可能损害画面。
  • 固定其他参数,只改 steps。 比较 16、24、32。观察屋檐、树枝和雾气的变化。超过一定步数以后,收益可能很小,也可能出现不同的细节走向,不能把耗时直接等同于画质。
  • sampler_name 和 scheduler 分别涉及“用什么数值方法走完采样”和“沿着怎样的噪声序列走”。初学阶段先固定这两个选项。构图还没弄明白,就同时切十几个采样器,得到的是一堆难以解释的结果。

    宽高也要单独考虑。SD 1.5 先从 512×512 起步,熟悉之后再试 512×768 等尺寸;宽高取 8 的倍数,能与这里的 VAE 下采样关系对齐。直接把初始画布拉到 2048×2048,会大幅增加计算量,还可能出现重复主体或不稳定构图。下面是一些常见的工程问题及其解决方案,给大家参考:

    现象优先检查处理顺序
    checkpoint 下拉框里没有模型 文件位置、文件是否下载完整、后端实际使用的目录 确认目录 → 刷新列表 → 必要时重启
    提示缺少必填输入 KSampler 的 model、positive、negative、latent_image 是否齐全 顺着上面的连线表逐项检查
    CLIP 输入无效 checkpoint 是否带有可用的文本编码器 换完整 checkpoint,或使用该架构的官方分离加载模板
    显存不足 分辨率、batch_size、其他占用显存的任务 先回到 512×512、batch_size=1;解码阶段溢出再考虑分块 VAE
    输出黑图、异常色块 模型/VAE 是否匹配,后台是否出现 NaN、精度相关报错 先用已知正常的基础模型和默认配置定位,不要只改提示词
    点了运行却没保存图片 是否有 Save Image,是否接到了最终 IMAGE 补上保存节点,检查输出目录与文件名前缀

    最后,把工作流另存为 JSON。ComfyUI 默认保存的 PNG 通常也带有工作流元数据,可以拖回画布恢复节点。但经过社交平台压缩、截图或关闭元数据保存后,这些信息可能丢失。保留原始 PNG 和 JSON 两份,会省下很多返工时间。

    2.5 ComfyUI图生图全解析

    文生图跑通以后,图生图只需要改变一个关键入口:给采样器的初始潜变量,来自一张已有图片。

    可以拿一张照片做风格转换,也可以把简单草图交给模型补充材质和光影。我们继续使用林间木屋这个场景,先让草图保留大致布局,再观察重绘强度如何影响结果。

    复制上一节的工作流,保留主模型、两个文本编码节点、KSampler、VAE Decode 和 Save Image。删除 Empty Latent Image,添加三个节点:

    • Load Image:上传输入图片,内部类型为 LoadImage。
    • Upscale Image:统一输入尺寸,内部类型为 ImageScale;它也能缩小图片。
    • VAE Encode:将图片编码成潜变量,内部类型为 VAEEncode。

    把它们按下面的顺序连接:

    Load Image.IMAGE → Upscale Image.image
    Upscale Image.IMAGE → VAE Encode.pixels
    Load Checkpoint.VAE → VAE Encode.vae
    VAE Encode.LATENT → KSampler.latent_image

    原有的 Load Checkpoint.VAE → VAE Decode.vae 连线继续保留。同一个 VAE 分别承担编码与解码;不要因为新建了编码节点,就把解码器的 VAE 连接移走。

    Load Image 还有一个 MASK 输出,这次不用连接。普通图生图会重绘整个画面;只有需要“只改窗户、其他区域尽量不动”时,才继续学习遮罩与局部重绘工作流。单纯上传图片,不会自动启用局部重绘。`Load Image` 还有一个 `MASK` 输出,这次不用连接。普通图生图会重绘整个画面;只有需要“只改窗户、其他区域尽量不动”时,才继续学习遮罩与局部重绘工作流。单纯上传图片,不会自动启用局部重绘。

    图16 2.5 ComfyUI图生图全解析

    这里准备了一张 512×512 木屋草图,可以保存后上传到 Load Image。它是为练习绘制的几何草图,用于提供屋顶、房屋、树木和小路的位置,不是模型生成效果图。

    图17 2.5 ComfyUI图生图全解析

    第一步,整理尺寸。 在 Upscale Image 中将 upscale_method 设为 lanczos,宽高设为 512,crop 设为 center。草图本身是方图,不会产生额外裁切。

    换成自己的照片时,要先决定保留什么。把横图强行变成方图,如果选择不裁切并同时指定宽高,可能发生拉伸;中心裁切则可能切掉边缘主体。希望保留整张图,可以先让宽高比保持一致,再在外部补边或选用合适的画布尺寸。尺寸处理会直接影响后面的构图。

    第二步,写清楚希望得到的画面。 正向提示词沿用木屋描述,或者把最后的 architectural photography 改为 watercolor illustration, soft brush strokes。建议先沿用摄影版本,熟悉 denoise 之后再试水彩。

    第三步,设置重绘强度。 其他参数沿用上一节,将 denoise 改为 0.55,固定 seed,再运行。

    观察结果时,先检查三件事:木屋有没有留在主要位置,小路是否还能通向房门,平涂色块是否被转化成材质和光影。草图越简单,需要补出的信息越多;如果画面仍然像色块,可以逐步提高 denoise。如果房屋明显换了位置,则先降低 denoise。

    图18 2.5 ComfyUI图生图全解析

    denoise 决定图生图从怎样的噪声水平开始重绘,会影响原图约束与新内容生成之间的关系。 它不是“原图保留百分比”:0.3 不意味着精确保留 70% 的像素。

    在当前 KSampler 实现中,较低 denoise 会改变使用的噪声调度区间。因此,将 steps=24、denoise=0.5 理解成“只执行 12 步”也不准确。把它当作重绘强度来调,实际效果用对照图判断即可。

    图19 2.5 ComfyUI图生图全解析

    实验denoise重点观察
    A 0.25 原布局通常约束较强;草图色块是否仍然很明显
    B 0.55 材质和风格是否发生足够变化;屋顶与小路是否还稳
    C 0.80 新细节是否更多;主体位置和形状是否开始明显偏离

    三次运行使用同一个模型、同一张输入图、同一组提示词和 seed,只改 denoise。这样得到的图片才有比较价值。保存时可以使用 cabin_d025、cabin_d055、cabin_d080 作为文件名前缀。

    denoise=1.0 通常会大幅削弱输入图约束,但不能据此保证它与纯文生图完全等价;denoise=0 也不是保证原图逐像素不变,VAE 编码和解码本身就可能带来损失。

    实际使用时,照片轻度调整可以从较低数值试起,草图转成完整画面通常需要更强重绘。这里没有跨模型通用的分界线。尤其是“保持人物身份”这类要求,仅靠调低 denoise 很难保证,还需要专门的身份控制与结果核验。

    “调低了没变化,调高了又不像原图”,这是图生图最常见的问题。原因在于:我们既希望保留原来的结构,又希望模型重建大量新细节,两个目标有时会相互牵制。可以按下面的顺序处理:

  • 先查提示词是否与原图冲突。 输入明明是正面木屋,却要求俯视城市街区,模型很难同时满足。先让主体、视角、数量一致。
  • 再查输入尺寸和裁切。 门被裁掉、人物被拉长,后面的采样很难自动恢复原本构图。
  • 只需要小范围修改时,改用局部重绘。 全图 img2img 会让每个区域都参与变化,难以保证背景和文字完全不动。
  • 需要保留边缘、深度或姿态时,加入 ControlNet。 让结构条件承担布局约束,denoise 就有更大的调整空间。
  • 图生图把已有画面带入生成过程;ControlNet 会从明确的结构条件中施加约束。理解了这个区别,下一节的节点就很容易接上了。

    2.6 ComfyUI中LoRA、ControlNet、GAN等使用全解析

    接着上一章节做到这里,我们已经可以生成木屋,也可以让草图变成更完整的画面。接下来会遇到三个更具体的需求:想让它长期保持某种插画风格;想让门窗、屋顶和小路的位置更稳定;想把满意的结果放大到可以交付的尺寸。

    这三件事,分别对应本节要接入的 LoRA、ControlNet 和超分辨率模型。先把作用位置分清,工作流就不会越搭越乱。

    模块作用能力接入位置不能直接保证什么
    LoRA 引入特定风格、角色或其他学到的能力 主模型/文本编码器路径 精确锁定构图或每个局部细节
    ControlNet 用边缘、姿态、深度等条件引导结构 条件分支,供采样阶段使用 自动复制参考图颜色、身份和所有细节
    Real-ESRGAN 等超分模型 放大已经生成的图片,改善可感知细节 解码后的 IMAGE 路径 恢复低清图中已经不存在的真实信息

    LoRA 可以理解为附加在基础模型上的轻量参数补丁。常见的风格 LoRA 会让模型更容易生成某类视觉语言,角色 LoRA 则可能强化某个人物或物体的特征。它需要依托相容的基础模型使用,SD 1.5 的 LoRA 不能因为文件后缀相同,就拿去直接给 SDXL 或 FLUX 使用。

    本次先挑选一个明确标注适用于 SD 1.5 的普通风格 LoRA,放进 models/loras/。下载前看清楚基底、触发词、建议权重和样例参数。这里不使用 LCM 等加速 LoRA,以免把风格控制和采样方案变化混在一起。

    打开文生图工作流,添加 Load LoRA 节点,内部类型为 LoraLoader。按下面五步修改:

  • 断开 Load Checkpoint.MODEL → KSampler.model,改为 Load Checkpoint.MODEL → Load LoRA.model。
  • 将 Load Checkpoint.CLIP 接到 Load LoRA.clip。
  • 将 Load LoRA.MODEL 接到 KSampler.model。
  • 将 Load LoRA.CLIP 分别接到正向、负向两个文本编码节点的 clip,替换之前来自 checkpoint 的直连。
  • VAE 仍由 checkpoint 直接提供给解码节点。
  • 图20 2.6 ComfyUI中LoRA、ControlNet、GAN等使用全解析

    两个强度参数分别是:

    • strength_model:控制 LoRA 对扩散模型补丁的强度。
    • strength_clip:控制 LoRA 对文本编码器补丁的强度。如果文件没有相应的文本编码器权重,这个参数就没有可作用的对应部分。

    优先使用作者推荐值。没有明确说明时,可以先用 0.6 / 0.6 试跑,再把它当作实验起点,而不是标准答案。

    触发词与加载节点承担不同职责。 触发词帮助模型调用训练时关联的概念,模型权重则必须由 LoRA 加载节点实际加载。不要把其他界面的 <lora:文件名:权重> 写法当作 ComfyUI 原生文本节点会自动执行的加载命令。

    图21 2.6 ComfyUI中LoRA、ControlNet、GAN等使用全解析

    LoRA模型的效果,怎样做有效对照呢?

    先固定 seed、提示词、checkpoint 和所有采样参数,把 LoRA 两个强度都设为 0,保存一张基线图。然后试 0.4 / 0.4、0.6 / 0.6、0.8 / 0.8,看屋顶材质、树木笔触和整体色调是否逐步接近目标风格。

    风格太淡,先确认模型兼容性、触发词和连线;画面过度锐化、细节粘连或人物变形,再降低强度。部分 LoRA 会建议模型强度和 CLIP 强度分开设置,应遵循它自己的使用说明。

    需要叠加多个 LoRA 时,可以串联多个 Load LoRA,把前一个的 MODEL、CLIP 输出分别接给后一个,最后再进入采样和文本编码。但每多加一个,冲突来源就多一个。先单独验证每个 LoRA,再组合;出现问题时,逐个归零检查,比同时修改三个权重快得多。

    假设我们希望木屋材质发生变化,但屋顶轮廓和门窗位置尽量沿着草图走。这个时候,可以使用 Canny ControlNet:先提取边缘,再把边缘图作为结构条件交给模型。

    这里有三个需要配套的东西:基础模型、ControlNet 权重、控制图类型。 本文使用 SD 1.5 checkpoint,就要搭配 SD 1.5 的 ControlNet;选择 Canny 权重,就要提供符合其预期的边缘图。深度模型、姿态模型、线稿模型对输入的要求各不相同,不能随便互换。

    官方 ControlNet v1.1 权重仓库提供 control_v11p_sd15_canny.pth 等模型。将对应的完整权重文件放进 models/controlnet/,然后在 Load ControlNet 中选择它。不要把配置文件或下载错误页面当成模型权重。

    这一节使用 ComfyUI 自带的 Canny 节点,当前显示名称为 Detect Edges (Canny)。它只做边缘检测,不需要再下载一个预处理模型。OpenPose、深度等任务通常需要对应的预处理器及其依赖,安装方式和输入规范应跟着具体节点与模型走。

    换任务时,可以先按想保留的信息选择控制类型:Canny 适合约束建筑、物体的明显轮廓;Depth 侧重空间远近和体积关系;OpenPose 侧重人物关节与姿态;Lineart、Scribble 分别面向线稿、涂鸦等输入。它们不会从同一张照片中提取完全相同的信息。比如树叶纹理干扰了建筑轮廓,换用深度控制可能比一味加大边缘强度更合适。

    接着我们开始搭建 Canny ControlNet 工作流。

    先从文生图工作流复制一份,暂时不加 LoRA。保留 Empty Latent Image,也就是说,这次先做“结构条件控制的文生图”。另外添加:

    节点内部类型作用
    Load Image LoadImage 上传木屋草图
    Upscale Image ImageScale 将参考图整理为 512×512
    Detect Edges (Canny) Canny 提取边缘
    Preview Image PreviewImage 先检查边缘图
    Load ControlNet ControlNetLoader 加载 SD 1.5 Canny 权重
    Apply ControlNet (Advanced) ControlNetApplyAdvanced 将控制信息附加到正、负条件

    先把图片支路接好:

    Load Image.IMAGE → Upscale Image.image
    Upscale Image.IMAGE → Canny.image
    Canny.IMAGE → Preview Image.images
    Canny.IMAGE → Apply ControlNet (Advanced).image
    Load ControlNet.CONTROL_NET → Apply ControlNet (Advanced).control_net

    然后修改提示词支路:把正、负两个文本编码输出,分别接到 Apply ControlNet (Advanced).positive / negative,再将该节点新的 positive / negative 输出分别接到 KSampler。原先绕过 ControlNet、直接进入 KSampler 的两条文本条件线应被替换。

    图22 2.6 ComfyUI中LoRA、ControlNet、GAN等使用全解析

    Apply ControlNet (Advanced) 在当前版本还有可选的 vae 输入。本文使用的经典 SD 1.5 Canny 模型不要求接入它;其他架构的控制模型是否需要 VAE,应以对应模板为准,不要把这条经验扩展到所有模型。

    本次先使用以下配置:

    参数起始值调整时观察什么
    Canny.low_threshold 0.4 较弱的边缘能否进入候选范围
    Canny.high_threshold 0.8 强边缘是否足够清晰;两个阈值共同影响结果
    ControlNet.strength 0.8 结构跟随程度与画面自然程度
    start_percent 0.0 从采样过程起始范围介入
    end_percent 0.8 在后段停止施加该控制,给细节留出一定空间
    KSampler.denoise 1.0 此处仍然从空潜变量做文生图

    这里的 Canny 阈值是当前内置节点使用的 0~1 范围,不要直接抄入其他工具常见的 100 / 200。start_percent / end_percent 则表示控制在采样噪声过程中的作用区间,不能把 0.8 理解成“精确保留 80% 结构”。

    运行前先看边缘预览:屋顶、门窗和小路能辨认,说明关键结构进入了控制信号;如果整幅图都是草木碎线,可以适当提高阈值或简化输入;如果关键轮廓消失,就降低阈值后重新观察。不要急着调 ControlNet 强度来弥补一张错误的控制图。

    在使用ControlNet时,可能会出现如下常见的工程问题,我们可以根据情况进行解决:

    轮廓太硬、材质不自然时,先降低 strength。 也可以让 end_percent 提前结束,再固定其他参数对照。把强度拉满并让它全程作用,不一定能得到最好的结果。

    人物姿态对了,脸却不像参考人物,并不奇怪。 姿态骨架描述关节布局,Canny 图描述边缘,这些信号本身不等于身份信息。需要保留人物身份时,应另行选择相应技术,并检查结果,而不是无限提高 ControlNet 权重。

    图生图与 ControlNet 可以一起用。 把同一张尺寸整理后的图片分成两路:一路经 VAE Encode 进入 KSampler.latent_image,一路经 Canny 进入控制条件。这样既保留图像初始化,又额外约束轮廓。先用中等 denoise 和单个 ControlNet 跑通,再逐步增加约束,避免两套控制相互拉扯。

    在 ComfyUI 创作流程里,大家经常接触到的 GAN 应用是 ESRGAN、Real-ESRGAN 这一类超分辨率模型。它们可以放在扩散生成之后,处理已经解码的图片。

    GAN 训练涉及生成器与判别器之间的对抗学习。使用预训练的 Real-ESRGAN 做放大时,我们加载的是用于恢复图像的生成网络,不需要在 ComfyUI 里再连接一个判别器,更不需要现场训练 GAN。

    同时,超分辨率是任务名称,GAN 是训练方法的一类。 Upscale Image (using Model) 支持的模型不全是 GAN,不能看到一个超分节点,就把它统称为 GAN 节点。

    本节使用 Real-ESRGAN 官方项目提供的 RealESRGAN_x4plus.pth 作为四倍放大示例。把 PyTorch 权重放到 models/upscale_models/。不要把另一个运行程序使用的 NCNN .bin/.param 文件放进这里当作同一种格式加载。

    打开已经能出图的工作流,添加:

    • Load Upscale Model,内部类型 UpscaleModelLoader。
    • Upscale Image (using Model),内部类型 ImageUpscaleWithModel。
    • 一个新的 Save Image,用来保存放大结果。

    接线如下:

    Load Upscale Model.UPSCALE_MODEL → Upscale Image (using Model).upscale_model
    VAE Decode.IMAGE → Upscale Image (using Model).image
    Upscale Image (using Model).IMAGE → 新的 Save Image.images

    保留原来的保存节点,文件名前缀设为 cabin_base;新的保存节点设为 cabin_upscale。这样一轮运行可以同时留下基础图和放大图,便于检查超分究竟改善了什么。

    图23 2.6 ComfyUI中LoRA、ControlNet、GAN等使用全解析

    这里的四倍倍率来自选中的模型。这个超分节点本身没有通用的“任意倍率”控件。想得到指定交付尺寸,可以在它后面加普通 Upscale Image 做尺寸整理。

    也可以导入图片超分工作流:它从 Load Image 开始,不要求加载 Stable Diffusion。上传已经生成的木屋图片,选择超分权重,就可以单独完成放大。

    图24 2.6 ComfyUI中LoRA、ControlNet、GAN等使用全解析

    放大后,把屋檐、窗框、树枝等区域按相同显示倍率检查一遍。纹理更锐利,不代表原本看不见的真实细节被准确找回;文字、人脸和重复纹理尤其需要留意。超分模型可能生成看起来合理的新纹理,也可能把噪声锐化成假细节。

    还要区分“超分放大”和“二次扩散重绘”。如果想在更大尺寸上重新生成细节,可以在放大之后增加 VAE Encode → KSampler → VAE Decode,第二个采样器从较低 denoise 试起。这会增加计算开销,并引入内容变化。人物五官、门窗数量和商品标识都可能被重新画过,应先确认任务能否接受。

    四倍模型输出的 2048×2048 也不等于 3840×2160 的 UHD 4K。如果要做 16:9 画面,应提前安排画布比例,再通过放大和尺寸整理交付。把方图硬拉成横图,主体比例会一起失真。

    现在可以把前面的节点串起来。目标仍然是林间木屋:用风格 LoRA 统一视觉表现,用 Canny ControlNet 约束草图轮廓,最后做超分放大。

    LoRA+ControlNet+超分工作流采用以下结构:

    checkpoint 的 MODEL、CLIP → Load LoRA → 模型与文本编码路径
    草图 → 尺寸整理 → Canny → Apply ControlNet (Advanced)
    正向、负向文本条件 → Apply ControlNet (Advanced) → KSampler
    Empty Latent Image → KSampler → VAE Decode → 保存基础图
    VAE Decode → 模型超分 → 保存放大图

    导入后先选择四类文件:checkpoint、LoRA、ControlNet、超分模型,再上传木屋草图。JSON 中的 SELECT_… 文件名是清楚标注的占位名,需要替换为自己环境里实际存在的文件。LoRA 触发词也要根据所选模型补充。

    建议按三个阶段启用,避免一开始就同时排查所有模块:

  • 先确认构图。 LoRA 两个强度设为 0,运行 Canny 控制分支,检查屋顶和小路的位置。
  • 再确认风格。 保持 seed 和 ControlNet 参数不动,逐步增加 LoRA 强度。风格与结构冲突时,分别降低 LoRA 或 ControlNet 强度做对照。
  • 最后检查放大。 同时保留基础图和超分图,查看新增纹理是否合理。尺寸达标后,再决定是否需要二次重绘。
  • 这条综合工作流沿用空潜变量入口,属于带结构控制的文生图。若要改成图生图,只需按 2.5 的方法把整理后的原图送入 VAE Encode,再用其输出替换空潜变量,并重新设置 denoise。

    到这一步,工作流里每一组节点都有明确责任:文本描述画面,LoRA 调整学到的表现能力,ControlNet 提供结构约束,采样器生成潜变量,VAE 还原图片,超分模型处理最终尺寸。以后拿到一张复杂工作流,可以先按这些职责拆开,再逐段检查输入和输出。

    真正值得留下来的,是一条能解释、能修改、能复现的工作流。 把模型名称和版本、提示词、seed、关键参数、输入图、JSON 与最终图片一起保存。下一次需要改画风、换场景或批量交付时,就能从已有结果继续推进。

    2.7 ComfyUI的动态显存(Dynamic VRAM)机制讲解

    一个真实AIGC图像创作工作流可能先运行文本编码器,再执行多轮去噪,最后进行VAE解码和局部修复等。这些模型参与计算的时间不同,扩散模型内部的权重也会按执行顺序被访问。如果让所有权重一直占据显存,会挤压不同阶段的有效计算资源;如果每次都重新在GPU和CPU之间搬运权重,又会增加工作流的低效等待时间。

    ComfyUI的Dynamic VRAM围绕权重工作流进行调度:让当前需要的权重进入物理显存,在空间允许时保留可复用结果,在压力升高时回收可释放的驻留权重。 它调整的是权重的存储位置与生命周期。实际收益取决于工作流大小、访问顺序、缓存命中以及数据搬运成本。

    Dynamic VRAM的核心思想是:把显存管理从“静态预估占用”改造成“按需物理化、按压力淘汰、按计算路径调度”的动态权重工作流管理。

    可以把它理解成ComfyUI为PyTorch模型权重引入了一层更细粒度的内存调度系统:

    模型文件/权重切片
    → mmap或文件切片引用
    → VBAR虚拟显存地址空间
    → 计算真正访问某层权重时触发fault
    → 有显存则物理加载并复用
    → 显存紧张则释放低优先级权重
    → 极端情况下只为当前算子创建临时GPU张量

    这里最关键的是VBAR。VBAR可以理解为一块为模型权重准备的GPU虚拟地址空间。创建VBAR时,并不等于把全部模型权重都真实塞进物理VRAM;它更像先把“这些权重未来可能住在哪里”安排好。只有当某一层真正参与计算,系统才通过类似 fault 的机制把对应权重物理化到GPU显存里。

    从执行机制看,Dynamic VRAM大致可以分成六步:

  • 模型加载阶段不急于深拷贝全部权重。 ComfyUI对safetensors加载路径做了更贴近动态显存的处理。权重可以先以mmap或文件切片引用的方式存在,框架记录每个tensor对应的文件偏移、大小和几何信息,而不是一上来就把所有权重完整复制成常驻PyTorch张量。
  • 模型准备阶段建立VBAR和动态pin状态。 在本地ComfyUI代码里,ModelPatcherDynamic会为非CPU加载设备维护 dynamic_vbars 和 dynamic_pins。模型被准备为Dynamic VRAM加载时,权重不再全部强制加载到GPU,而是优先进入“可按需加载”的状态。
  • 算子执行前触发权重物理化。 进入具体Linear、Conv或Attention相关模块时,ComfyUI会检查模块是否有 _v 这类VBAR分配信息。执行前通过 vbar_fault 判断这段权重是否已经驻留。如果已经驻留,就直接使用;如果没有驻留,就从文件切片、pinned host buffer或缓存路径把当前算子需要的权重加载到合适的位置。
  • 显存够用时缓存权重,显存紧张时动态释放。 如果GPU显存足够,当前层权重会被保留在VRAM里,后续重复访问可以更快。如果显存压力上升,ComfyUI可以从VBAR里释放一部分低优先级权重,而不是让整条工作流直接OOM。当前活跃模型、最近访问的VBAR和即将参与计算的权重会拥有更高优先级。
  • 加载失败时走临时张量兜底。 如果某段权重无法长期驻留在VBAR里,Dynamic VRAM并不必然崩溃。它可以只为当前层创建临时GPU张量,把本次计算需要的权重拷进去,用完后释放或复用。这意味着显存压力从“全模型必须同时住进VRAM”变成“当前计算窗口需要什么就加载什么”。
  • 预取与异步offload降低等待时间。 ComfyUI还引入了动态VBAR预取和异步offload能力。比如 model_prefetch.py 会根据 prefetch_dynamic_vbars 准备后续模块的权重;启动参数里也提供了 –async-offload、–disable-async-offload、–fast-disk 等选项,让快NVMe、pinned memory和GPU stream之间的配合更灵活。
  • 图25 2.7 ComfyUI的动态显存(Dynamic VRAM)机制讲解

    所以,Dynamic VRAM真正改变的不是某个单点参数,而是模型权重的生命周期,与传统显存管理策略相比的优势如下表所示:

    对比维度传统显存管理Dynamic VRAM
    权重加载方式 尽量提前加载或按估算搬运 按计算访问路径动态物理化
    显存判断方式 依赖模型大小和经验预估 运行时根据真实压力调度
    OOM处理 预估失败时容易直接崩溃 优先释放、降级到临时张量或按需重载
    系统内存占用 容易堆积CPU副本或触发分页 更强调文件切片、缓存和可释放内存
    复杂工作流适配 模型越多越难预估 更适合多模型、多LoRA、多阶段工作流
    开发者心智负担 需要手动猜低显存策略 更接近自动化资源调度

    这套机制带来的直接收益,可以概括为四点:

    第一,降低复杂工作流的系统内存压力。 Dynamic VRAM减少了“GPU一份、CPU再常驻一份、页面文件再兜底一份”的低效内存形态。模型权重可以更多依赖文件映射、切片读取和按需加载,系统内存不再需要长期承载那么多完整副本。

    第二,显著降低因权重卸载不足导致的OOM风险。 传统低显存方案经常遇到“前面能跑,后面突然爆”的问题。Dynamic VRAM把释放、重载和临时张量兜底放到运行时路径里,目标是让工作流在显存紧张时降速,而不是直接崩溃。

    第三,在部分场景下提升模型加载和LoRA应用速度。 因为模型加载节点不一定要立刻把所有权重深拷贝到PyTorch常驻张量里,所以首次加载、切换prompt、加载LoRA等动作在一些大模型场景中会更快。公开测试中,类似FLUX 2 Dev bf16这类任务的首次启动、改prompt和加载LoRA耗时都有明显下降;WAN 2.2 14B双模型视频任务在32GB内存机器上也能看到端到端耗时的大幅改善。

    第四,让“高VRAM占用”不再等同于内存泄漏。 Dynamic VRAM倾向于把最快的VRAM用作真实工作集缓存。如果监控面板里看到GPU显存占用较高,不一定是坏事;关键要看工作流是否稳定、是否触发OOM、端到端耗时是否下降。现代推理系统的目标不是让显存看起来很空,而是让显存被有效利用,并且在压力到来时能及时释放。

    3. 深入浅出完整讲解Diffusers核心基础知识

    大家很多人第一次接触 Diffusers,大概率是从这样几行代码开始的:

    from diffusers import DiffusionPipeline
    import torch

    pipe = DiffusionPipeline.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5",
    torch_dtype=torch.float16,
    ).to("cuda")

    image = pipe("An image of a squirrel in Picasso style").images[0]

    只用三行代码加载模型,一行代码生成图片,架构十分轻量。但如果我们只把 Diffusers 理解成“几行代码出图”的工具,就会低估它的价值。

    Rocky认为,Diffusers 真正值得学习研究的地方,不是它让我们更快调用Stable Diffusion或者FLUX这些AIGC大模型,而是它把扩散模型从论文代码、开源 checkpoint、AIGC配套插件和训练脚本里拆出来,变成了一套可复用、可替换、可部署的生成式AICG工作流。

    今天的AIGC领域,AIGC大模型迭代的非常快:Stable Diffusion、SDXL、SD3、FLUX、Qwen-Image、Wan、Hunyuan Video、CogVideoX、Seedream等,一代接一代奋勇争先。

    但在持续的技术更新迭代过程中,有很多本质的思想依旧是跨越周期充满价值的:

    • 文本、图像、视频等条件要先被编码;
    • 模型通常不是一步生成,而是多步把噪声“还原”成内容;
    • 采样器决定每一步怎么走;
    • VAE 或 decoder 负责把 latent 变成最终图像、视频或音频;
    • LoRA、ControlNet、IP-Adapter 负责把生成从“随机惊艳”拉向“可控交付”;
    • 量化、offload、compile、cache 决定大模型能不能在真实机器上跑得动。

    而Diffusers的核心价值就在其中。它不是某个大模型的外壳,而是一套把这些大模型落地应用各个环节组织起来的AIGC基础设施。

    图26 3. 深入浅出完整讲解Diffusers核心基础知识

    3.1 Diffusers是扩散模型的“组件化工作台”

    Rocky认为,如果用一句话概括 Diffusers,那么它是一套面向扩散模型和新一代生成模型的组件化运行框架。

    更通俗一点说,它像一个 AIGC 工程工作台。这个工作台上放着:

    • Pipeline:把一次生成任务串起来;
    • Model:真正做神经网络计算;
    • Scheduler:控制去噪路径和采样节奏;
    • VAE / Decoder:把 latent 还原成最终内容;
    • Loader / Adapter:接 LoRA、ControlNet、IP-Adapter、single-file checkpoint;
    • Quantizer / Hook:处理量化、offload、cache、compile 这些生产化问题。

    所以学习 Diffusers,我们不能只问“怎么生成一张图”。更重要的问题是:

  • 一个 AIGC 生成任务到底由哪些组件组成?
  • 每个组件在工作流里负责什么?
  • 为什么换 scheduler 会影响速度和质量?
  • 为什么 LoRA、ControlNet、IP-Adapter 能插进去?
  • 为什么同一个模型在不同显卡上速度和显存差异很大?
  • 为什么现在的生成模型越来越需要量化、缓存和编译?
  • 这几个问题理解了,Diffusers 就不再只是一个库,而是一张理解 AIGC 工程化的基座。

    Rocky 在产业一线的体感是:AIGC 上半场很多人比的是谁会调工具,下半场比的是谁能把生成能力拆成稳定、可控、可复用、低成本的AIGC生产系统。Diffusers 恰好是这个转变里非常重要的一块拼图。

    一个最简化的 Diffusers 工作流如下所示:

    # 这是机制示意,不是完整生产代码
    prompt_embeds = text_encoder(tokenizer(prompt))
    latents = torch.randn([batch, channels, height // 8, width // 8], device=device)

    scheduler.set_timesteps(num_inference_steps)

    for t in scheduler.timesteps:
    model_input = scheduler.scale_model_input(latents, t)
    noise_pred = denoiser(
    model_input,
    t,
    encoder_hidden_states=prompt_embeds,
    )
    latents = scheduler.step(noise_pred, t, latents).prev_sample

    image = vae.decode(latents / vae.config.scaling_factor)

    这段代码背后有三个最核心的角色:

    角色通俗理解工程职责
    denoiser 修图师 根据当前噪声和条件,预测下一步往哪里修
    scheduler 导航系统 决定每一步从哪个噪声强度走到哪个噪声强度
    VAE 翻译器 把 latent 空间里的结果翻译回人能看的图片

    Diffusers 的工程思想,就是把这些角色拆清楚。拆清楚以后,事情就变得可控了:

    • 我们可以换模型;
    • 我们可以换 scheduler;
    • 我们可以换 VAE;
    • 我们可以加 LoRA;
    • 我们可以插 ControlNet;
    • 我们可以量化 transformer;
    • 我们可以对视频模型做 cache;
    • 我们可以把某些组件 offload 到 CPU。

    这就是“组件化”的意义。

    3.2 Diffusers的设计思想:能够快速接入兼容AIGC新技术的跨周期基座

    Diffusers 的设计有一个很有意思的地方:它并不迷恋过度抽象。大家第一次看Diffusers,可能会觉得它的 pipeline 文件很多,相似代码也不少,似乎不够“优雅”。

    但如果我们真的在AIGC一线持续深耕,就会理解为什么它要这样设计。

    因为AIGC生成大模型的迭代更新是在太快了。

    今天一个大模型用U-Net,明天一个大模型换DiT,后天又是MMDiT、rectified flow、video transformer、3D transformer、统一多模态架构等等。

    如果一开始就做一个非常漂亮、非常抽象、非常统一的框架,很可能没过几个月就被新模型撕开口子。

    所以 Diffusers 选择了一条更现实的路:

    • Pipeline 尽量单文件、自包含;
    • Scheduler 一个算法一个文件;
    • 模型架构尽量放在自己独立的文件里;
    • 相似逻辑可以复制,但用 # Copied from 机制保持同步;
    • 不把关键推理流程藏得太深;
    • 优先让贡献者能读懂、能调试、能接入。

    这不是偷懒,而是一种适合AIGC开源生态的工程判断。

    Rocky 认为,AIGC创作框架的长期生命力,很多时候不是来自抽象有多完美,而是来自它能不能让新模型、新论文、新社区资产快速进入生态中持续繁荣。

    Diffusers的三个设计取向非常鲜明:

    【1. 可用性优先,而不是默认追求极限性能】

    Diffusers 默认不会替我们打开所有激进优化。

    它通常先保证模型能在更多平台、更少依赖、更高精度下稳定运行。我们要追求速度和显存,需要自己选择 torch_dtype、scheduler、attention backend、offload、compile、quantization。

    这对新手来说多了一点学习成本,但对工程系统是好事。

    因为生产环境最怕“框架默默替我们做了很多事”,最后出问题不知道从哪里查。

    【2. 显式优先,而不是把复杂性藏起来】

    Diffusers 不是把扩散采样封进一个不可见黑箱,而是把很多关键过程留在 pipeline 里。

    例如 Stable Diffusion pipeline 的核心去噪循环,我们可以很清楚地看到:

    for i, t in enumerate(timesteps):
    latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents
    latent_model_input = scheduler.scale_model_input(latent_model_input, t)

    noise_pred = unet(
    latent_model_input,
    t,
    encoder_hidden_states=prompt_embeds,
    return_dict=False,
    )[0]

    if do_classifier_free_guidance:
    noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
    noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text – noise_pred_uncond)

    latents = scheduler.step(noise_pred, t, latents, return_dict=False)[0]

    这段代码不复杂,但非常关键。

    它把“扩散模型怎么生成图”这件事讲得很直接:

    • 当前 latent 进模型;
    • 模型预测噪声或更新方向;
    • CFG 把文本条件拉进来;
    • scheduler 更新 latent;
    • 重复很多步。

    这比一句“调用 pipeline 生成图片”更有学习价值。

    【3. 可修改优先,不牺牲新模型接入速度】

    在传统工程里,重复代码常常被认为不好。

    但在生成模型领域,过早抽象有时候更危险。因为新模型的特殊结构太多,强行抽象会让贡献者不敢改、不会改、改了影响一大片。

    Diffusers 保留较低抽象层级,本质上是在给社区留空间。

    这也是它能不断接入 Stable Diffusion、SDXL、SD3、FLUX、Wan、CogVideoX、Hunyuan Video、Qwen-Image、Seedream等大模型的重要原因。

    3.3 Diffusers的核心模块深入浅出讲解

    【1. Pipeline:一次生成任务的总导演】

    DiffusionPipeline 是经典pipeline的基类。它不一定亲自做神经网络计算,而是负责把一堆组件组织起来:

    • text encoder;
    • tokenizer;
    • denoiser,比如 UNet 或 Transformer;
    • VAE;
    • scheduler;
    • image processor;
    • safety checker;
    • adapter;
    • 量化配置;
    • offload hook。

    在 Diffusers 里,一个 pipeline 不只是一个 Python 类,它还是一个可以保存、加载、复用的组件清单。其中的关键机制是 register_modules():

    class DiffusionPipeline(ConfigMixin, PushToHubMixin):
    config_name = "model_index.json"

    def register_modules(self, **kwargs):
    for name, module in kwargs.items():
    if module is None:
    register_dict = {name: (None, None)}
    else:
    library, class_name = _fetch_class_library_tuple(module)
    register_dict = {name: (library, class_name)}

    self.register_to_config(**register_dict)
    setattr(self, name, module)

    通俗理解:Pipeline 会记住自己由哪些零件组成,这些零件分别是什么类、来自哪个库。

    以后 from_pretrained() 才能把整个生成系统重新装起来。这就是 model_index.json 的意义。它让一个复杂AIGC创作系统可以被序列化、分享、加载和迁移。

    【2. Model:真正干活的神经网络】

    Diffusers 的模型在 src/diffusers/models 下。主要包括:

    模型类别做什么常见例子
    UNet 经典扩散去噪器 UNet2DModel、UNet2DConditionModel
    Transformer / DiT 新一代图像和视频生成骨干 Flux、SD3、Wan、CogVideoX、Qwen-Image
    Autoencoder 像素和 latent 互转 AutoencoderKL、视频 VAE、tiny VAE
    ControlNet / Adapter 额外条件控制 ControlNet、T2I-Adapter、IP-Adapter
    Attention / Embedding 基础层 attention processor、timestep embedding

    这些模型通常继承 ModelMixin 和 ConfigMixin。这意味着它们不只是 PyTorch nn.Module,还天然具备:

    • from_pretrained();
    • save_pretrained();
    • 配置保存;
    • 权重分片加载;
    • safetensors 支持;
    • 低内存加载;
    • device map;
    • 量化协作;
    • 部分编译能力。

    在小模型时代,一个模型类只要能forward就够了。但在AIGC大模型时代,模型类还要回答很多工程问题:

    • 权重太大,怎么加载?
    • 显存不够,怎么分布?
    • 要部署,怎么保存?
    • 要量化,怎么替换 Linear?
    • 要加速,哪些 block 可以 compile?

    这就是 ModelMixin 的价值。

    【3. Scheduler:很多人低估了它,但它决定“怎么走”】

    如果把 denoiser 理解成“修图师”,scheduler 就是“导航系统”。模型负责预测方向,scheduler 负责决定怎么走过去。同样一个模型,换不同 scheduler,速度、质量、风格稳定性都可能变化。Scheduler 通常负责:

    • 创建 timesteps 或 sigmas;
    • 定义噪声强度变化;
    • 缩放模型输入;
    • 把模型输出解释成噪声、样本、速度或 flow;
    • 计算上一个时间步的 sample。

    以 DDPM scheduler 为例,初始化时会构造 beta、alpha 和累计 alpha:

    self.betas = torch.linspace(beta_start, beta_end, num_train_timesteps)
    self.alphas = 1.0 – self.betas
    self.alphas_cumprod = torch.cumprod(self.alphas, dim=0)

    推理前设置采样步:

    scheduler.set_timesteps(num_inference_steps)

    每一步更新:

    latents = scheduler.step(model_output, timestep, latents).prev_sample

    Diffusers 的好处,是把 scheduler 从模型里拆了出来。这让开发者可以在同一个模型上尝试 DDIM、Euler、DPM-Solver、FlowMatch Euler 等不同采样方式。

    Rocky 认为,理解 scheduler,是从“会用生成工具”走向“理解生成系统”的关键一步。

    【4. Loader 和 Adapter:连接社区资产的接口】

    真实 AIGC 工作流里,很少只跑一个 base model。

    我们可能会:

    • 加 LoRA 控风格;
    • 加 IP-Adapter 保主体一致;
    • 加 ControlNet 控姿态、线稿、深度;
    • 换 VAE 改颜色和细节;
    • 加 textual inversion;
    • 加载 single-file checkpoint;
    • 加载各种Adapter控制技术;
    • 从社区格式迁移到 Diffusers 格式。

    这些能力主要由 loaders 和各种 mixin 支撑。它们看起来像周边功能,但实际非常核心。

    因为 AIGC 的生态不是单个模型生态,而是“base model + adapter + checkpoint + workflow + 参数经验”的混合生态。

    Diffusers 能成为基础设施,一个重要原因就是它能吸收这些资产,而不是只支持官方标准模型。

    【5. Modular Diffusers:从单任务 pipeline 走向组合式工作流】

    经典 DiffusionPipeline 的特点是:一个任务,一个 pipeline。文生图一个 pipeline,图生图一个 pipeline,inpainting 一个 pipeline,ControlNet 又一个 pipeline。这种方式对学习很友好,因为我们打开文件就能看到完整流程。

    但当产品变复杂时,就会遇到问题:任务越来越多,条件越来越多,组合越来越多,pipeline 文件会越来越膨胀。

    所以 Diffusers 开始引入 Modular Diffusers,它把工作流拆成几个阶段:

    • encoders.py
    • before_denoise.py
    • denoise.py
    • decoders.py
    • modular_blocks_<model>.py
    • modular_pipeline.py

    这个方向很重要。因为未来的 AIGC 产品不会只是“输入一句话,生成一张图”。它会越来越像:

    多模态输入 + 多条件控制 + 多模型协作 + 多阶段生成 + 中间态编辑 + 质量评估 + 资源调度。

    经典 pipeline 像一条写好的生产线。而Modular Diffusers 更像可以重新拼装的生产系统。

    【6. Quantizer 和 Hook:大模型落地的部署现实层】

    当模型越来越大,问题就从“能不能生成”变成了“能不能在有限算力上跑得起、跑得稳、跑得便宜”。

    Diffusers 的量化和 hook 体系,就是为这个现实问题服务的。

    量化模块支持多种后端:

    后端主要作用Rocky 的理解
    bitsandbytes 4bit/8bit 权重量化 最常见的低显存路线
    torchao PyTorch 原生量化生态 更贴近未来 PyTorch 标准化
    GGUF 预量化单文件格式 社区分发和低显存推理常用
    Quanto Optimum 体系量化 有历史价值,但当前已出现 deprecation 信号
    NVIDIA ModelOpt FP8 等硬件优化 更适合 NVIDIA 高端部署场景
    AutoRound 预量化模型加载 偏离线校准后的模型分发

    Pipeline 级量化示例:

    import torch
    from diffusers import DiffusionPipeline
    from diffusers.quantizers import PipelineQuantizationConfig

    pipeline_quant_config = PipelineQuantizationConfig(
    quant_backend="bitsandbytes_4bit",
    quant_kwargs={
    "load_in_4bit": True,
    "bnb_4bit_quant_type": "nf4",
    "bnb_4bit_compute_dtype": torch.bfloat16,
    },
    components_to_quantize=["transformer", "text_encoder_2"],
    )

    pipe = DiffusionPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    quantization_config=pipeline_quant_config,
    torch_dtype=torch.bfloat16,
    ).to("cuda")

    这段代码背后的思想很朴素:

    一个 pipeline 里不同组件的体积、来源、数值敏感性都不一样,不能粗暴地“一刀切”。

    比如 Flux 里 transformer 很重,T5 text encoder 也很重;有些组件来自 Diffusers,有些来自 Transformers。PipelineQuantizationConfig 允许你按组件指定量化策略。

    这就是生产化能力。

    3.4 Diffusers的应用领域介绍

    Diffusers早期最强的标签是Stable Diffusion推理库,但现在它已经不只是AIGC图像创作研发库。

    【1. 图像生成】

    这是最成熟的方向。

    包括:

    • 文生图;
    • 图生图;
    • 局部重绘;
    • 超分辨率;
    • 图像变化;
    • 商品图生成;
    • 海报和视觉素材;
    • 游戏概念图;
    • 角色设定;
    • 电商图和营销图。

    Stable Diffusion、SDXL、SD3、Flux、Qwen-Image、Hunyuan Image、Kolors、PixArt、Sana 等模型,都可以放在这条线里理解。

    【2. 可控生成和图像编辑】

    真正进入生产以后,用户要的往往不是“随机出一张好看的图”,而是“按我的要求稳定出图”。

    这就需要:

    • ControlNet 控姿态、线稿、深度、边缘;
    • T2I-Adapter 做轻量控制;
    • IP-Adapter 保持主体或参考图风格;
    • LoRA 注入角色、画风、产品特征;
    • Inpainting 做局部替换;
    • InstructPix2Pix 做指令式编辑。

    这类能力的本质,是把生成从“惊艳的魔术”变成“可重复的工作流”。

    魔术的价值在第一次不敢相信。

    产品的价值在第十次仍然稳定可用。

    【3. 视频生成】

    视频生成是 Diffusers 越来越重要的方向。

    CogVideoX、Wan、LTX、Mochi、Hunyuan Video、SkyReels 等 pipeline,已经把 Diffusers 推向更重的生成任务。

    视频比图像难很多,因为它多了时间维度:

    • 显存更大;
    • attention 更重;
    • 序列更长;
    • 帧间一致性更难;
    • 推理时间更长;
    • cache 和 offload 更关键。

    Rocky 判断,视频生成会倒逼 Diffusers 从“模型调用库”继续升级为“重型生成工作流优化库”。

    【4. 音频和音乐生成】

    Diffusers 也支持 AudioLDM、Stable Audio、ACE Step、LongCat Audio DiT 等方向。

    虽然音频和图像表现形式不同,但底层仍然可以抽象为:

    条件输入 -> latent 表示 -> 迭代生成 -> decoder 输出。

    这说明 Diffusers 的抽象不是只为图片服务,而是围绕“从噪声到数据”的生成范式服务。

    【5. 训练和微调】

    Diffusers 也提供大量训练脚本:

    • DreamBooth;
    • LoRA;
    • textual inversion;
    • ControlNet;
    • text-to-image training;
    • consistency distillation。

    训练脚本的价值,不只是让我们照着跑。更重要的是,它让我们看到每个组件在训练和推理中的位置。

    3.5 Diffusers的加速和量化技术讲解

    Diffusers专门对AIGC大模型构建了加速与量化工具,Diffusers 的加速大致有六层。

    【1. dtype:先把精度选对】

    最基础的是把大模型从 float32 换成 bf16 或 fp16:

    pipe = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    torch_dtype=torch.bfloat16,
    ).to("cuda")

    bf16 通常比 fp16 更稳,现代 GPU 支持也越来越好。fp16 更常见,但某些模型更容易数值不稳定。这一步很简单,但不能解决所有问题。它主要降低存储和计算开销,不会改变“多步迭代”这个根因。

    【2. Attention backend:让最重的注意力计算更省】

    图像和视频模型里,attention 往往是大头。PyTorch 2.x 的 SDPA 会根据硬件自动选择更合适的后端,Diffusers 也支持 xFormers 等 memory-efficient attention。

    示意代码:

    from torch.nn.attention import SDPBackend, sdpa_kernel

    with sdpa_kernel(SDPBackend.EFFICIENT_ATTENTION):
    image = pipe(prompt, num_inference_steps=30).images[0]

    高分辨率图像和视频生成里,这类优化会更明显。

    【3. Scheduler和少步采样】

    很多时候,最直接的加速不是换硬件,而是减少采样步数。但减少步数不是简单地把 50 改成 10。我们需要看模型是否适合少步采样,scheduler 是否匹配,质量是否能接受。

    Turbo、LCM、Schnell 这类模型或蒸馏路线,就是为了让少步生成更可用。

    Rocky 的建议是:生产环境不要迷信最高步数,要按任务倒推采样策略。

    灵感草图、批量预览、短平快素材,可以少步。

    商品图、广告主视觉、视频关键镜头,就要更谨慎。

    【4. torch.compile:让重复计算变得更快】

    torch.compile 可以把 PyTorch 计算图编译成更优化的内核。

    在 Diffusers 里,通常编译最重的组件:

    pipe.unet.to(memory_format=torch.channels_last)
    pipe.vae.to(memory_format=torch.channels_last)

    pipe.unet = torch.compile(pipe.unet, mode="max-autotune", fullgraph=True)
    pipe.vae.decode = torch.compile(pipe.vae.decode, mode="max-autotune", fullgraph=True)

    但 compile 有现实成本:

    • 第一次编译慢;
    • 输入 shape 变化可能重新编译;
    • 动态尺寸场景收益不稳定;
    • 某些模型或算子可能有 graph break。

    所以 Diffusers 还支持 regional compilation,也就是只编译反复出现的 block:

    pipe.unet.compile_repeated_blocks(fullgraph=True)

    这很适合 transformer 类模型,因为 transformer layer 重复很多次。

    只编译重复块,可以降低冷启动成本,同时保留较多运行时收益。

    【5. Offload:显存不够时,先让模型跑起来】

    Offload 的核心不是加速,而是降低显存压力。

    常见方式包括:

    • model CPU offload;
    • sequential CPU offload;
    • group offload;
    • Modular Diffusers 的自动 CPU offload。

    通俗理解:

    GPU 显存放不下所有组件,就让暂时不用的组件先回 CPU,需要时再搬上 GPU。

    这会带来数据搬运成本,所以不一定更快。

    但它能让很多原本跑不起来的模型跑起来。

    对个人开发者和消费级显卡来说,这是非常现实的能力。

    对生产系统来说,要认真评估吞吐、延迟和稳定性。

    【6. Cache:利用相邻 step 的相似性】

    扩散生成有一个特点:相邻 timestep 的中间特征通常不会完全不同,这就给 cache 留下空间。

    Diffusers 支持多种缓存机制:

    • Pyramid Attention Broadcast;
    • FasterCache;
    • FirstBlock Cache;
    • TaylorSeer Cache;
    • MagCache。

    例如 TaylorSeer Cache:

    from diffusers import FluxPipeline, TaylorSeerCacheConfig

    pipe = FluxPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    torch_dtype=torch.bfloat16,
    ).to("cuda")

    config = TaylorSeerCacheConfig(
    cache_interval=5,
    max_order=1,
    disable_cache_before_step=10,
    taylor_factors_dtype=torch.bfloat16,
    )
    pipe.transformer.enable_cache(config)

    Cache 的本质,是少算一些“变化不大”的中间结果。

    它不是免费午餐。

    速度提升通常会换来一定质量风险,所以必须结合任务验收。

    视频生成、长序列生成、多帧一致性场景,会越来越依赖这类技术。

    【7. 量化能力:让大模型进入可承受的成本区间】

    量化解决的核心问题是显存和成本。

    如果一个模型原本需要 40GB 显存,量化后能在 16GB 或 24GB 显卡上跑起来,它的可用范围就完全不同。

    但这里要说清楚:

    量化不等于一定更快。

    有时候量化会更省显存,但因为反量化和特殊 kernel,速度未必提升。

    所以评估量化,不要只看 bit 数,要看完整结果:

    维度关键问题
    显存 是否从跑不起来变成跑得起来?
    速度 是否真的降低端到端延迟?
    质量 人脸、文字、纹理、视频一致性是否下降?
    稳定性 目标硬件、PyTorch、CUDA、驱动是否匹配?
    维护性 是否能保存、复用、部署、和 offload/compile 共存?

    bitsandbytes是最常见的 4bit/8bit 路线,bitsandbytes 是很多开发者最熟悉的低显存方案。

    from diffusers import BitsAndBytesConfig, SD3Transformer2DModel

    quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    )

    transformer = SD3Transformer2DModel.from_pretrained(
    "stabilityai/stable-diffusion-3-medium-diffusers",
    subfolder="transformer",
    quantization_config=quantization_config,
    )

    它的意义很直接:降低门槛。

    但不要把 4bit 当信仰。

    某些场景下,4bit 的质量损失、反量化开销、算子支持问题,都需要实测。

    3.6 Diffusers的推理过程讲解

    我们以最经典的文生图为例,把一次 Diffusers 推理拆开。

    【第一步:检查输入和默认参数】

    Pipeline 会先检查 prompt、negative prompt、embedding、图片尺寸、callback 参数等。

    这一步看起来不性感,但工程里非常重要。

    因为很多生成问题不是模型问题,而是输入尺寸不对、embedding batch 不对、prompt 和 negative prompt 数量不匹配、callback 张量不合法。

    Diffusers 倾向于直接报错,而不是默默帮你修。

    这对开发者是好事。

    默默修正会让 demo 看起来丝滑,但会让生产排错变得非常痛苦。

    【第二步:把 prompt 变成 embedding】

    模型不直接理解字符串。

    Prompt 会先经过 tokenizer,再进入 text encoder,变成一组向量。

    如果启用 classifier-free guidance,pipeline 还会同时准备 negative prompt embedding。

    示意代码:

    prompt_embeds, negative_prompt_embeds = pipe.encode_prompt(
    prompt=prompt,
    device=device,
    num_images_per_prompt=num_images_per_prompt,
    do_classifier_free_guidance=True,
    negative_prompt=negative_prompt,
    )

    prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds])

    这就是为什么 negative prompt 不是“玄学咒语”。

    它本质上是在 CFG 里提供一个反方向的条件。

    【第三步:scheduler 准备时间表】

    num_inference_steps=30 不只是一个速度参数。

    它决定 scheduler 要走多少步。每一步的 timestep 或 sigma 决定当前噪声强度,以及下一步怎么更新。

    这就是为什么同样一个 prompt,换 scheduler 或步数,结果会变。

    采样不是一个按钮,而是一条路径。

    【第四步:初始化 latent】

    如果用户没有传入 latents,pipeline 会从高斯噪声采样。

    固定 seed 的本质,就是固定这团初始噪声。

    只要模型、prompt、scheduler、参数和硬件数值路径基本一致,输出就能高度复现。

    【第五步:循环去噪】

    这是整个生成过程的核心。每一步都做三件事:

  • denoiser 根据当前 latent、时间步和 prompt embedding 预测更新方向;
  • CFG 把文本条件和无条件结果拉开;
  • scheduler 根据预测结果更新 latent。
  • CFG 的直觉公式是:

    guided_pred = uncond_pred + guidance_scale * (text_pred – uncond_pred)

    guidance_scale 越高,模型越“听话”。

    但太高也会带来副作用:过曝、僵硬、细节崩、构图不自然。

    这也是为什么很多新模型和新 pipeline 不再迷信很高的 CFG。真正好的生成,不是越听 prompt 越好,而是在语义控制、视觉自然性和细节稳定性之间找到平衡。

    【第六步:callback 允许你在中途介入】

    Diffusers 支持在每个 step 结束时用 callback 读取或修改中间张量。

    这对高级产品很有价值:

    • 中途预览;
    • 交互式打断;
    • 动态 prompt;
    • latent 调试;
    • 多阶段编辑;
    • 自定义采样控制。

    这也是 Diffusers 和纯黑箱推理服务的区别。

    它不是只给你结果,而是允许你进入过程。

    【第七步:VAE 解码】

    去噪结束后,latent 还不是图片。

    Pipeline 会调用 VAE:

    image = vae.decode(latents / vae.config.scaling_factor)

    VAE 负责把 latent 翻译成人眼能看的像素图。

    所以换 VAE 会影响颜色、纹理、细节和某些风格倾向。

    这不是“换个后处理滤镜”,而是在改变 latent 到像素空间的解码方式。

    【第八步:后处理输出】

    最后 image processor 会把 tensor 转成 PIL、NumPy 或 latent。

    部分 pipeline 还会做 safety checker 或其他后处理。

    到这里,一次生成才真正结束。

    Rocky 建议大家记住这条主线:条件编码 -> 初始化 latent -> scheduler 设置路径 -> 多步去噪 -> VAE 解码 -> 后处理输出。

    不同模型会有差异,但大多数生成工作流都绕不开这条主线。

    4. 深入浅出完整讲解Stable Diffusion WbUI核心基础知识(全网最详细)

    Stable Diffusion WebUI是一个基于gradio架构的AIGC图像创作框架,不仅支持Stable Diffusion的最基础的文生图、图生图以及图像inpainting功能,还支持Stable Diffusion的很多拓展功能,很多与Stable Diffusion相关的拓展应用都可以用插件的方式安装在Stable Diffusion WebUI上,非常方便实用。

    图27 Stable Diffusion WebUI界面

    Stable Diffusion WebUI界面

    得益于新手友好的操作流程与丰富的插件生态,Stable Diffusion WebUI曾经成为AIGC图像创作领域最火爆的框架。

    它曾经是很多人应用学习Stable Diffusion的第一入口,但今天再看WebUI,它已经不是“领先的主流工具”,而是一个已经完成历史使命、被新范式取代、但仍然有跨周期价值的AIGC创作框架样本。

    我们需要知道,WebUI不是因为功能太少而衰落,而是因为它的“参数面板范式”跟不上复杂AIGC工作流的结构化需求。 它在SDXL阶段之后仍有过维护和新模型适配,例如后续版本继续补充SD 3支持、采样器和性能优化;但从生态势能看,WebUI的主战场已经被ComfyUI系统性取代。原因不只是ComfyUI“更新更快”,而是ComfyUI把创作过程从表单调参升级成了节点化、画布化、可复现的工作流系统。

    目前端脑云平台已经集成了Stable Diffusion WebUI,我们能够方便的在端脑云平台上使用Stable Diffusion Web UI进行AIGC图像创作。

    接下来,就让我们跟随着Rocky的脚步,一起使用端脑云平台中的Stable Diffusion WebUI进行AIGC图像创作!

    4.1 从0到1在端脑云平台快速上手使用Stable Diffusion WebUI

    我们首先打开端脑云网站:

    图28 4.1 从0到1在端脑云平台快速上手使用Stable Diffusion WebUI

    可以看到端脑云平台中有一个官方应用栏目,我们可以在里面找到Stable Diffusion WbUI框架、Stable Diffusion WbUI高级版框架、ComfyUI框架、Fooocus框架等热门AI绘画应用框架。

    我们点击Stable Diffusion WbUI框架,先选择应用类型,我们选择“Stable Diffusion WbUI”。然后我们选择使用方式,我们选择“应用模式”。接着我们再选择GPU性能,我们根据自己的需求,选择适合的GPU即可。最后我们点击“立即使用”,就能开启一个新的应用了!

    图29 4.1 从0到1在端脑云平台快速上手使用Stable Diffusion WebUI

    如下图所示,我们进入端脑云界面后,我们点击左侧的“我的应用”,可以看到正在运行的Stable Diffusion WbUI框架,我们点击右侧的“进入应用”,即可开始Stable Diffusion WbUI框架的使用:

    图30 4.1 从0到1在端脑云平台快速上手使用Stable Diffusion WebUI

    第一次打开Stable Diffusion WbUI框架时,会弹出一个登陆页面,我们只需要将端脑云界面上的登录账号和登录密码输入即可登录:

    图31 4.1 从0到1在端脑云平台快速上手使用Stable Diffusion WebUI

    登陆后,我们就能在端脑云上看到Stable Diffusion WbUI框架的可视化界面:

    图32 4.1 从0到1在端脑云平台快速上手使用Stable Diffusion WebUI

    图33 4.1 从0到1在端脑云平台快速上手使用Stable Diffusion WebUI

    我们可以看到,端脑云上已经集成了大量的Stable Diffusion WbUI的插件与依赖。主要的热门插件包括SadTalker、Temporal-Kit、Deforum、OpenPose编辑器、Inpatinting Anything、超级模型融合、WD1.4标签器、ADetailer、AnimateDiff等,可谓是非常丰富与齐全,基本上能满足我们的所有AIGC图像&视频创作的使用需求。

    大家可以通过Cephalon Cloud注册来方便地使用Stable Diffusion WbUI框架。

    接下来Rocky输入如下的Prompt:

    1girl,bangs,black_hair,blunt_bangs,bracelet,branch,building,city,city_lights,cityscape,couch,fishnets,indoors,ivy,jewelry,leaf,looking_at_viewer,night,night_sky,on_couch,palm_tree,plant,potted_plant,short_hair,sitting,skyline,skyscraper,solo,star_(sky),starry_sky,tanabata,tanzaku,tree,(Snakeskin mesh tights),(Fishnet shirt),single_thighhigh。

    可以看到,下图中生成了一张我们想要的图片:

    图34 4.1 从0到1在端脑云平台快速上手使用Stable Diffusion WebUI

    更多AI绘画玩法,大家可以在端脑云上逐步尝试学习!

    4.2 从0到1在本地安装部署Stable Diffusion WebUI进行AI绘画(全网最详细讲解)

    【1】本地安装Stable Diffusion WebUI

    首先,我们需要下载安装Stable Diffusion WebUI框架,我们只需要在命令行输入如下代码即可:

    git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git

    安装好后,我们可以看到本地的stable-diffusion-webui文件夹。

    下面我们需要安装其依赖库,我们进入Stable Diffusion WebUI文件夹,并进行以下操作:

    cd stable-diffusion-webui #进入下载好的automatic文件夹中
    pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

    和SD.Next的配置流程类似,我们还需要配置Stable Diffusion WebUI的repositories插件,我们需要运行下面的代码:

    sh webui.sh

    #主要依赖包括:BLIP CodeFormer generative-models k-diffusion stable-diffusion-stability-ai taming-transformers

    如果发现repositories插件下载速度较慢,出现很多报错,don’t worry,大家可以直接使用Rocky已经配置好的资源包,可以快速启动与Stable Diffusion XL兼容的Stable Diffusion WebUI框架。Stable Diffusion WebUI资源包可以关注公众号WeThinkIn,后台回复“WebUI资源”获取。

    【2】Stable Diffusion WebUI操作页面显示更多参数设置

    当我们刚安装好Stable Diffusion WebUI,并打开操作界面时,我们会发现有一些重要的参数配置是没有显示的,比如说:VAE设置、Clip skip设置、Eta noise seed delta设置等。

    我们可以通过点击Stable Diffusion WebUI操作界面的Settings按钮,进入Settings界面。然后再点击User interface按钮,可以看到Quicksettings list栏目,我们在栏目中分别搜索点击sd_vae、CLIP_stop_at_last_layers、eta_noise_seed_delta,选中这三个参数后,我们点击界面上方的Apply settings按钮,再点击Reload UI按钮,即可重启保存修改配置。完整流程如下图所示:

    图35 Stable Diffusion WebUI操作界面增加参数设置栏的流程

    Stable Diffusion WebUI操作界面增加参数设置栏的流程

    等重启完成后,我们可以看到Stable Diffusion WebUI操作界面上方多出了SD VAE栏目、Clip skip栏目以及Eta noise seed delta栏目,我们可以方便地调节这些关键参数。

    4.3 Stable Diffusion WebUI文生图全解析

    Stable Diffusion WebUI文生图的操作界面主要分为:模型区域、功能区域、参数区域、出图区域四个部分。

    图36 Stable Diffusion WebUI文生图的操作界面

    Stable Diffusion WebUI文生图的操作界面

  • **Prompt(正向提示词):**希望SD模型生成的内容。
  • **Negative Prompt(反向提示词):**不希望SD模型生成的内容。
  • **Sampling method(采样方法):**推荐选择 Euler a 或 DPM++ 系列,采样速度较快。
  • **Sampling steps(迭代步数):**设置的数值越大,生成的图像质量越好,同时生成时间也越长,一般设置为20-50区间就能生成质量较高的图片。
  • **Hires. fix(超分辨率精绘):**当我们开启Hires. fix后,在图像生成过程中会將SD系列模型原始生成的图当作“草图”,先用超分算法(Upscale)把原始生成图放大到我們指定的倍数(Upscale by),再将超分后的“草图”用图生图(img2img)的方式重新生成一次,最后获得优化生成后的图片。我们可以调整的参数还有Hires steps(精绘步数)和Denoising strength(噪声强度),Hires steps设置为20-30即可,Denoising strength设置为0.4-0.7即可。使用Hires. fix可以大幅提高生成图片中人物的脸部、眼睛、头发细节质量,同时图片整体的精细度也有肉眼可见的提升。
  • **Refiner:**SDXL的Refiner,在使用SDXL模型时可以启动用于提升生成图片的质量。
  • **Width/Height(生成图片的宽高):**设置的越大越消耗显存,生成时间也越长。使用SD模型时可以设置512×512、512×768等尺寸;使用SDXL模型时可以设置768×1024、1024×1024以及更大的尺寸。
  • **CFG Scale(classifier-free guidance scale):**CFG Scale设置的越大越与提示词相关,设置的越小则越不相关,一般建议4-12区间即可。过低的CFG会让出图饱和度偏低,过高的CFG则会出现粗矿的线条或过度锐化的图像,甚至于画面出现严重的崩坏。
  • **Batch count:**表示一共生成图片的批次数,是串行处理的,如果Batch count设置为2,Batch size设置为4,那么我们分两次并行生成4张图片,一共生成8张图片(2×4)。
  • **Batch size:**表示一个Batch中生成图片的数量,是并行处理的,Batch size设置的越大,占用的显存越大。
  • **Seed(种子数):**设置为-1 表示每次生成图片时使用随机种子,相同的种子数可以保持生成图像的一致性,如果觉得生成图片的构图不错,但对风格不满意,可以将种子数固定,再调整参数进行优化生成。
  • **Script:**包含了一些组合操作,比如Prompt matrix、Prompts from file or textbox、X/Y/Z plot等。
  • 在这里Rocky也向大家详细讲解一下Stable Diffusion WebUI文生图功能的底层Pipeline代码:

    import torch
    from diffusers import AutoencoderKL, UNet2DConditionModel, DDIMScheduler
    from transformers import CLIPTextModel, CLIPTokenizer
    from tqdm.auto import tqdm

    model_id = "runwayml/stable-diffusion-v1-5"
    # 1. 加载autoencoder
    vae = AutoencoderKL.from_pretrained(model_id, subfolder="vae")
    # 2. 加载tokenizer和text encoder
    tokenizer = CLIPTokenizer.from_pretrained(model_id, subfolder="tokenizer")
    text_encoder = CLIPTextModel.from_pretrained(model_id, subfolder="text_encoder")
    # 3. 加载扩散模型UNet
    unet = UNet2DConditionModel.from_pretrained(model_id, subfolder="unet")
    # 4. 定义noise scheduler
    noise_scheduler = DDIMScheduler(
    num_train_timesteps=1000,
    beta_start=0.00085,
    beta_end=0.012,
    beta_schedule="scaled_linear",
    clip_sample=False, # don't clip sample, the x0 in stable diffusion not in range [-1, 1]
    set_alpha_to_one=False,
    )

    # 将模型复制到GPU上
    device = "cuda"
    vae.to(device, dtype=torch.float16)
    text_encoder.to(device, dtype=torch.float16)
    unet = unet.to(device, dtype=torch.float16)

    # 定义参数
    prompt = [
    "A dragon fruit wearing karate belt in the snow",
    "A small cactus wearing a straw hat and neon sunglasses in the Sahara desert",
    "A photo of a raccoon wearing an astronaut helmet, looking out of the window at night",
    "A cute otter in a rainbow whirlpool holding shells, watercolor"
    ]
    height = 512
    width = 512
    num_inference_steps = 50
    guidance_scale = 7.5
    negative_prompt = ""
    batch_size = len(prompt)
    # 随机种子
    generator = torch.Generator(device).manual_seed(2023)

    with torch.no_grad():
    # 获取text_embeddings
    text_input = tokenizer(prompt, padding="max_length", max_length=tokenizer.model_max_length, truncation=True, return_tensors="pt")
    text_embeddings = text_encoder(text_input.input_ids.to(device))[0]
    # 获取unconditional text embeddings
    max_length = text_input.input_ids.shape[–1]
    uncond_input = tokenizer(
    [negative_prompt] * batch_size, padding="max_length", max_length=max_length, return_tensors="pt"
    )
    uncond_embeddings = text_encoder(uncond_input.input_ids.to(device))[0]
    # 拼接为batch,方便并行计算
    text_embeddings = torch.cat([uncond_embeddings, text_embeddings])

    # 生成latents的初始噪音
    latents = torch.randn(
    (batch_size, unet.in_channels, height // 8, width // 8),
    generator=generator, device=device
    )
    latents = latents.to(device, dtype=torch.float16)

    # 设置采样步数
    noise_scheduler.set_timesteps(num_inference_steps, device=device)

    # scale the initial noise by the standard deviation required by the scheduler
    latents = latents * noise_scheduler.init_noise_sigma # for DDIM, init_noise_sigma = 1.0

    timesteps_tensor = noise_scheduler.timesteps

    # Do denoise steps
    for t in tqdm(timesteps_tensor):
    # 这里latens扩展2份,是为了同时计算unconditional prediction
    latent_model_input = torch.cat([latents] * 2)
    latent_model_input = noise_scheduler.scale_model_input(latent_model_input, t) # for DDIM, do nothing

    # 使用UNet预测噪音
    noise_pred = unet(latent_model_input, t, encoder_hidden_states=text_embeddings).sample

    # 执行CFG
    noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
    noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text – noise_pred_uncond)

    # 计算上一步的noisy latents:x_t -> x_t-1
    latents = noise_scheduler.step(noise_pred, t, latents).prev_sample

    # 注意要对latents进行scale
    latents = 1 / 0.18215 * latents
    # 使用vae解码得到图像
    image = vae.decode(latents).sample

    【1】Prompt语法深入浅出讲解

    在Stable Diffusion WebUI中,正向提示词(Prompt)是引导SD系列模型生成图像内容的关键信息。我们可以在提示词中使用“()”可以增加SD模型对括号内提示词的注意力,即增加提示词权重;而使用“[]”则会减少提示词的权重。

    下面是一些具体的使用例子:

    a (word) – 提示词的权重增加1.1倍
    a ((word)) – 提示词的权重增加1.21倍(= 1.1 * 1.1)
    a [word] – 提示词的权重减少1.1倍
    a (word:1.5) – 提示词的权重增加1.5倍
    a (word:0.25) – 提示词的权重减少4倍(= 1 / 0.25)
    a \\(word\\) – 使用转义字符取消()的改变提示词权重效果,让()成为普通字符

    图37 不同提示词权重下的SD模型图片生成效果

    不同提示词权重下的SD模型图片生成效果

    那么Stable Diffusion WebUI是如何让这些权重注意力起作用呢?

    简单来说,在输入提示词到Stable Diffusion Text Encoder之前,WebUI通过上面讲到的权重规则将提示词分离成Text(文本)和Weight(权重)两个独立的部分。接着将Text部分输入Tokenizer模块转换成tokens,然后再输入Text Encoder模型编码成Text Embeddings。完成了上面的操作,我们再将权重和对应的Text Embeddings相乘,再乘上一个正则化系数,将对应的Embeddings向量进行缩放(scale),代表着这个提示词的增强和减弱。完整的提示词权重规则代码在stable-diffusion-webui/modules/prompt_parser.py脚本中,完整的提示词权重生效代码在stable-diffusion-webui/modules/sd_hijack_clip.py脚本中,大家可以按需查阅。

    下面有详细的流程注解,方便大家直观的理解WebUI的提示词权重生效逻辑:

    # 输入提示词
    Prompt = (woman)

    # 通过prompt_parser.py脚本解析成Text(文本)和Weight(权重)两个独立的部分
    parsed: [['woman', 1.1]]

    # 将Text(文本)输入Tokenizer模块转换成tokens
    tokenized: [[2308]]

    # 将tokens输入Text Encoder模型编码成Text Embeddings
    z_original = tensor([[ 0.5410, 1.2411, –0.4761, ..., –0.3535, –1.1046, –1.7921]])
    original_mean = z_original.mean()

    # 将Text Embeddings与对应的Weight(权重)相乘
    z_new = tensor([[ 0.5951, 1.3652, –0.5237, ..., –0.3888, –1.2150, –1.9714]])
    new_mean = z_new.mean()

    # 计算正则化系数
    r = (original_mean / new_mean)

    # 最终的Text Embeddings
    z = z_new * r
    z = tensor([[ 0.5943, 1.3634, –0.5230, ..., –0.3883, –1.2134, –1.9688]])

    除了正向提示词,负向提示词(Negative Prompt)同样重要,负向提示词的主要作用是指导SD系列模型避免生成包含某些特定元素或特征的图像。这是通过在图像生成过程中显式地告诉模型哪些内容是不希望出现的来实现的。通过这种方式,Negative Prompts增加了对生成结果的控制,帮助我们更精确地定制想要的输出图像。

    下面Rocky就带着大家详细了解一下负向提示词(Negative Prompt)是如何在SD系列模型中起作用的:

    【2】Negative Prompt深入浅出讲解

    我们知道SD系列模型采用了CFG技术来提升生成图像的质量。当我们使用CFG技术后,SD系列模型的去噪过程不仅仅依赖条件扩散模型,也依赖无条件扩散模型。具体的计算公式如下所示:

    pred_noise

    =

    w

    ⋅

    cond_pred_noise

    +

    (

    1

    −

    w

    )

    ⋅

    uncond_pred_noise

    =

    w

    ϵ

    θ

    (

    x

    t

    ,

    t

    ,

    c

    )

    +

    (

    1

    −

    w

    )

    ϵ

    θ

    (

    x

    t

    ,

    t

    )

    =

    ϵ

    θ

    (

    x

    t

    ,

    t

    )

    +

    w

    (

    ϵ

    θ

    (

    x

    t

    ,

    t

    ,

    c

    )

    −

    ϵ

    θ

    (

    x

    t

    ,

    t

    )

    )

    \\begin{aligned}\\text{pred\\_noise} &= w \\cdot \\text{cond\\_pred\\_noise} + (1-w) \\cdot \\text{uncond\\_pred\\_noise} \\\\ &= w\\mathbf{\\epsilon}_\\theta\\big(\\mathbf{x}_t, t, \\mathbf{c}\\big)+(1-w)\\mathbf{\\epsilon}_\\theta\\big(\\mathbf{x}_t, t\\big) \\\\ &=\\mathbf{\\epsilon}_\\theta\\big(\\mathbf{x}_t, t\\big)+w(\\mathbf{\\epsilon}_\\theta\\big(\\mathbf{x}_t, t, \\mathbf{c}\\big)-\\mathbf{\\epsilon}_\\theta\\big(\\mathbf{x}_t, t\\big)) \\end{aligned}

    pred_noise​=w⋅cond_pred_noise+(1−w)⋅uncond_pred_noise=wϵθ​(xt​,t,c)+(1−w)ϵθ​(xt​,t)=ϵθ​(xt​,t)+w(ϵθ​(xt​,t,c)−ϵθ​(xt​,t))​

    这里的

    w

    w

    w为guidance scale,当

    w

    w

    w越大时,condition起的作用越大,即生成的图像和输入文本更加一致。我们说的Negative Prompt就是无条件扩散模型的Text输入,当我们不输入Negative Prompt时会将Text置为空字符串来实现无条件扩散模型。

    在模型推理过程中,我们可以使用不为空的Negative Prompt来避免模型生成的图像包含我们不想要的内容,因为从上述公式可以看到这里的无条件扩散模型就是我们想远离的特征分布。

    当我们使用Negative Prompt时,会将无条件扩散模型中原本是空字符的unconditional_conditioning用Negative Prompt替代。

    下面的代码展示了我们只使用Prompt和同时使用Prompt与Negative Promtpt的区别:

    # 只使用Prompt
    prompts = ["a castle in a forest"]
    batch_size = 1

    c = model.get_learned_conditioning(prompts)
    uc = model.get_learned_conditioning(batch_size * [""])

    samples_ddim, _ = sampler.sample(conditioning=c, unconditional_conditioning=uc, [...])

    # 同时使用Prompt和Negative Prompt
    prompts = ["a castle in a forest"]
    negative_prompts = ["grainy, fog"]

    c = model.get_learned_conditioning(prompts)
    uc = model.get_learned_conditioning(negative_prompts)

    samples_ddim, _ = sampler.sample(conditioning=c, unconditional_conditioning=uc, [...])

    # SD系列模型在不使用Negative Prompt和使用Negative Prompt时,生成过程的区别
    if unconditional_conditioning is None or unconditional_guidance_scale == 1.:
    e_t = self.model.apply_model(x, t, c)
    else:
    x_in = torch.cat([x] * 2)
    t_in = torch.cat([t] * 2)
    c_in = torch.cat([unconditional_conditioning, c])
    e_t_uncond, e_t = self.model.apply_model(x_in, t_in, c_in).chunk(2)
    e_t = e_t_uncond + unconditional_guidance_scale * (e_t – e_t_uncond)

    当我们同时使用Prompt和Negative Prompt时,SD系列模型在生成图像的过程中会靠近Prompt中描述的概念与内容,而远离Negative Prompt中描述的概念与内容。

    基本的Negative Prompt主要有:worst quality, normal quality, low quality, low res, blurry, text, watermark, logo, banner, extra digits, cropped, jpeg artifacts, signature, username, error, sketch ,duplicate, ugly, monochrome, horror, geometry, mutation, disgusting

    生成二次元图片常用的Negative Prompt主要有:bad anatomy, bad hands, missing fingers, extra fingers, three hands, three legs, bad arms, missing legs, missing arms, poorly drawn face, bad face, fused face, cloned face, three crus, fused feet, fused thigh, extra crus, ugly fingers, horn, realistic photo, huge eyes, worst face, 2girl, long fingers, disconnected limbs

    生成真实场景图片常用的Negative Prompt主要有:bad anatomy, bad hands, missing fingers, extra fingers, three hands, three legs, bad arms, missing legs, missing arms, poorly drawn face, bad face, fused face, cloned face, three crus, fused feet, fused thigh, extra crus, ugly fingers, horn, cartoon, cg, 3d, unreal, animate, amputation, disconnected limbs

    下面的代码形象展示了不使用Negative Prompt和使用Negative Prompt之间的逻辑区别:

    # 不使用Negative Prompt
    prompts = ["a castle in a forest"]
    batch_size = 1

    c = model.get_learned_conditioning(prompts)
    uc = model.get_learned_conditioning(batch_size * [""])

    samples_ddim, _ = sampler.sample(conditioning=c, unconditional_conditioning=uc, [...])

    # 使用Negative Prompt

    prompts = ["a castle in a forest"]
    negative_prompts = ["grainy, fog"]

    c = model.get_learned_conditioning(prompts)
    uc = model.get_learned_conditioning(negative_prompts)

    samples_ddim, _ = sampler.sample(conditioning=c, unconditional_conditioning=uc, [...])

    【3】Hires. fix功能深入浅出解析

    Hires. fix(超分辨率精绘)功能是Stable Diffusion WebUI中img2img部分的一个非常重要的功能,其能够大幅度改善生成图片质量、增加细节并提升图片的分辨率。

    下图是使用Hires. fix功能前后的效果对比:

    图38 使用Hires. fix功能前后的生成图像效果对比

    使用Hires. fix功能前后的生成图像效果对比

    可以看到,图片生成质量有了明显的提升,那么Hires. fix功能的核心流程是什么样的呢?

    Rocky帮大家总结归纳了一下,主要可以分成下面几个步骤:

  • 使用SD模型进行文生图(txt2img)过程,生成初始图片。
  • 使用超分模型(GAN系列超分模型和生成式超分模型)对初始图片进行超分。
  • 使用SD模型进行图生图(img2img)过程,生成精绘的图片。
  • 输出最终的生成图片。
  • 下面是Hires. fix功能的完整图解,大家能够直观的了解Hires. fix功能的全流程:

    图39 Stable Diffusion WebUI Hires. fix功能的全流程

    Stable Diffusion WebUI Hires. fix功能的全流程

    接下来我们讲解一下Hires.fix功能包含的参数,由于WebUI中默认有一些参数没有展示,所以我们通过下面的步骤,就能展示Hires.fix功能的全部参数,有助于我们更加灵活地调节配置:

    图40 4.3 Stable Diffusion WebUI文生图全解析

    完成上述的四个步骤后,我们就能在WebUI界面看到完整的Hires. fix功能参数了:

    图41 WebUI Hires. fix功能完整参数

    WebUI Hires. fix功能完整参数

    从上图可以看到,Hires. fix功能的完整参数包括:

  • Upscaler:超分模型选择,推荐选择R-ESRGAN 4x+、R-ESRGAN 4x+ Anime6B、4x-UltraSharp等。
  • Hires steps:图生图过程采样步数,如果设置Hires steps = 0,则执行与第一阶段文生图相同的采样步数(Hires steps = Sampling steps),推荐设置10-15效果最佳。
  • Denoising strength:图生图过程加入的噪声强度,推荐设置0.4-0.5之间。
  • Upscale by:使用超分模型对图像超分的倍数,最大可以设置为4倍。
  • Resize width to和Resize height to:除了设置Upscale by,我们还可以设置明确的图像超分超分尺寸,Resize width to和Resize height to分别表示图像超分后的宽和高。
  • Hires checkpoint:表示在图生图阶段使用哪个SD系列模型作为底模型,如果设置Use same checkpoint,则选择与第一阶段相同的SD系列模型作为底模型。
  • Hires sampling method:表示在图生图阶段使用哪个采样算法,如果设置Use same sampler,则选择与第一阶段相同的采样算法。
  • Prompt for hires fix pass:表示在图生图阶段使用的提示词,如果设置为空,则执行与第一阶段文生图相同的提示词。
  • Negative for hires fix pass:表示在图生图阶段使用的负向提示词,如果设置为空,则执行与第一阶段文生图相同的负向提示词。
  • 图42 Sampling steps设置为20时,Hires. fix功能不同Hires steps的效果对比

    Sampling steps设置为20时,Hires. fix功能不同Hires steps的效果对比

    图43 Hires. fix功能不同Denoising strength的效果对比

    Hires. fix功能不同Denoising strength的效果对比

    有了Hires. fix功能,我们就可以用一个小分辨率(512×512)为基准,生成1024×1024乃至2048×2048分辨率的高质量图像,同时不会出现生成图像内容结构混乱的情况。

    【四】采样方法介绍

    SD系列模型的文生图和图生图功能都需要用到采样方法,下面Rocky就带着大家一起了解一下目前的主流采样方法:

    1. Euler:使用欧拉方法进行采样,它是一种简单的数值积分方法,适用于简单的扩散模型,但可能不够准确。

    2. LMS:代表最小均方(Least Mean Square)方法,它是一种迭代算法,通过根据观测误差来调整模型参数,以逐步提高采样准确性。

    3. Heun:使用Heun方法进行采样,也称为改进的欧拉方法,它在欧拉方法的基础上进行了改进,提供了更准确的数值积分结果。

    4. DPM2:代表动态粒子扩散模型(Dynamic Particle Model 2),是一种基于粒子的采样方法,通过在扩散模型中移动粒子来进行采样。

    5. DPM++2S a:DPM++2S a是DPM++2S方法的改进版本,它可能在采样效果上有所改善。

    6. DPM++2M:DPM++2M是DPM++2S方法的另一个改进版本,它可能在采样效果上有所改善。

    7. DPM++SDE:DPM++SDE代表DPM++稳定扩散估计器,采用稳定性差分方程(Stabilized Differential Equation)方法进行采样。

    8. DPM++2M SDE:DPM++2M SDE是DPM++2M方法与稳定性差分方程(Stabilized Differential Equation)方法的结合,可能提供更准确的采样结果。

    9. DPM fast:DPM fast是DPM方法的一种快速版本,它在时间效率上进行了优化,可能会比其他方法更快,但可能损失一些采样准确性。

    10. DPM adaptive:DPM adaptive是DPM方法的一种自适应版本,它根据模型的情况自动调整采样策略,以提供更准确的采样结果。

    11. LMS Karras:LMS Karras是LMS方法的Karras改进版本,可能在采样效果上有所改善。

    12. DPM2 Karras:DPM2 Karras是DPM2方法的Karras改进版本,可能在采样效果上有所改善。

    13. DPM2 a Karras:DPM2 a Karras是DPM2 a方法的Karras改进版本,可能在采样效果上有所改善。

    14. DPM++2S a Karras:DPM++2S a Karras是DPM++2S a方法的Karras改进版本,可能在采样效果上有所改善。

    15. DPM++2M Karras:DPM++2M Karras是DPM++2M方法的Karras改进版本,可能在采样效果上有所改善。

    16. DPM++SDE Karras:DPM++SDE Karras是DPM++SDE方法的Karras改进版本,可能在采样效果上有所改善。

    17. DPM++2M SDE Karras:DPM++2M SDE Karras是DPM++2M SDE方法的Karras改进版本,可能在采样效果上有所改善。

    18. DDIM:代表可微分扩散不变量采样方法(Differentiable Diffusion Invariant Moment),是一种基于扩散不变量的采样方法,可以提供更精确的采样结果。

    19. PLMS:代表部分最小均方(Partial Least Mean Square)方法,它是一种迭代算法,类似于LMS方法,但在计算上更高效。

    20. UniPC:代表统一粒子扩散模型(Unified Particle Model),是一种基于粒子的采样方法,适用于多种扩散模型。一种可以在5~10步实现高质量图像的方法。

    **祖先采样器:**名称中带有a标识的采样器都是祖先采样器。这一类采样器在每个采样步中都会向图像添加噪声,导致结果具有随机性。部分没有带a的采样器也属于祖先采样器,如Eular a,DPM2 a,DPM++2S a,DPM++2S a KARRAS,DPM++ SDE,DPM++SDE KARRAS。

    **Karras Noise Schedule:**带有Karras字样的采样器,最大的特色是使用了Karras论文中的噪声计划表,主要表现是去噪的程度在开头会比较高,在接近尾声时会变小,有助于提升图像质量。

    4.4 Stable Diffusion WebUI图生图全解析

    在Stable Diffusion WebUI中,图生图(img2img)功能可以生成与原图一样构图的图像,或者指定一部分内容进行重绘编辑(inpainting)。

    Stable Diffusion WebUI图生图的操作界面同样也分为:模型区域、功能区域、参数区域、出图区域四个部分。

    图44 4.4 Stable Diffusion WebUI图生图全解析

    上述界面中Prompt、Negative Prompt、Sampling method、Sampling steps、Batch count、Batch size、Width、Height、CFG Scale、Seed等参数的含义是与文生图一致的。下面Rocky向大家详细讲解WebUI图生图功能中一些特殊的参数,希望能给大家带来帮助:

  • Resize mode:一共有四种图像的缩放模式。Just resize表示只调整图片大小,如果输入与输出长宽比例不同,图片会被拉伸。Crop and resize表示裁剪与调整大小,如果输入与输出长宽比例不同,会以图片中心向四周,将比例外的部分进行裁剪。Resize and fill表示调整大小与填充,如果输入与输出分辨率不同,会以图片中心向四周,将比例内多余的部分进行填充。
  • Denoising strength:进行图生图功能的重绘幅度,设置的值越大越自由发挥,越小则越和原图接近。
  • Resize to:表示在进行图生图时,将输出图像尺寸固定到特定的宽高上。
  • Resize by:表示在进行图生图时,将输出图像尺寸固定为输入图像的特定倍数上。
  • Mask blur:表示在进行Inpainting操作时,对Mask掩膜边缘应用的模糊程度。它通过在掩膜的边缘区域添加一定程度的模糊,使得掩膜的过渡区域更加平滑,从而使修补区域与原始图像之间的衔接更加自然。
  • Mask mode:表示设置的Mask蒙版模式,Inpaint masked表示只重绘涂色部分,Inpaint not masked表示重绘涂色之外的部分。
  • Masked Content:表示在进行Inpainting操作时,对Mask掩膜区域在修补之前填充的初始内容进行设定。这个初始内容不会直接出现在最终的输出结果中,但会影响修补过程中的计算,从而影响最终生成的图像。简而言之,**Masked Content决定了在开始修补掩膜区域之前,该区域内部被视为是什么内容。其中四个选项分别为:**Fill用于删除对象,生成与背景一致的内容;Original用于细微修改,保留原始特征;Latent Noise用于生成全新内容,增加创造性;Latent Nothing用于在潜在空间中提供空白输入,依赖模型推断。
  • Inpaint area:表示进行Inpainting的重绘区域。**Whole Picture(整张图片)**表示对整个图像的尺寸进行处理,即使只修改了部分区域。**Only Masked(仅掩膜区域)**表示仅对掩膜区域进行处理,其余部分尺寸保持不变。
  • Only masked padding,pixels:可以指定的一个整数值(以像素为单位)。它用于在Mask掩膜区域的周围添加一定数量的像素,从而扩大SD模型在处理掩膜区域时所考虑的上下文范围。
  • Stable Diffusion WebUI的图生图的底层Pipeline代码如下所示:

    import PIL
    import numpy as np
    import torch
    from diffusers import AutoencoderKL, UNet2DConditionModel, DDIMScheduler
    from transformers import CLIPTextModel, CLIPTokenizer
    from tqdm.auto import tqdm

    model_id = "/本地路径/stable-diffusion-v1-5"
    # 1. 加载autoencoder
    vae = AutoencoderKL.from_pretrained(model_id, subfolder="vae")
    # 2. 加载tokenizer和text encoder
    tokenizer = CLIPTokenizer.from_pretrained(model_id, subfolder="tokenizer")
    text_encoder = CLIPTextModel.from_pretrained(model_id, subfolder="text_encoder")
    # 3. 加载扩散模型UNet
    unet = UNet2DConditionModel.from_pretrained(model_id, subfolder="unet")
    # 4. 定义noise scheduler
    noise_scheduler = DDIMScheduler(
    num_train_timesteps=1000,
    beta_start=0.00085,
    beta_end=0.012,
    beta_schedule="scaled_linear",
    clip_sample=False, # don't clip sample, the x0 in stable diffusion not in range [-1, 1]
    set_alpha_to_one=False,
    )

    # 将模型复制到GPU上
    device = "cuda"
    vae.to(device, dtype=torch.float16)
    text_encoder.to(device, dtype=torch.float16)
    unet = unet.to(device, dtype=torch.float16)

    # 预处理init_image
    def preprocess(image):
    w, h = image.size
    w, h = map(lambda x: x – x % 32, (w, h)) # resize to integer multiple of 32
    image = image.resize((w, h), resample=PIL.Image.LANCZOS)
    image = np.array(image).astype(np.float32) / 255.0
    image = image[None].transpose(0, 3, 1, 2)
    image = torch.from_numpy(image)
    return 2.0 * image – 1.0

    # 参数设置
    prompt = ["A fantasy landscape, trending on artstation"]
    num_inference_steps = 50
    guidance_scale = 7.5
    strength = 0.8
    batch_size = 1
    negative_prompt = ""
    generator = torch.Generator(device).manual_seed(2023)

    init_image = PIL.Image.open("init_image.png").convert("RGB")

    with torch.no_grad():
    # 获取prompt的text_embeddings
    text_input = tokenizer(prompt, padding="max_length", max_length=tokenizer.model_max_length, truncation=True, return_tensors="pt")
    text_embeddings = text_encoder(text_input.input_ids.to(device))[0]
    # 获取unconditional text embeddings
    max_length = text_input.input_ids.shape[–1]
    uncond_input = tokenizer(
    [negative_prompt] * batch_size, padding="max_length", max_length=max_length, return_tensors="pt"
    )
    uncond_embeddings = text_encoder(uncond_input.input_ids.to(device))[0]
    # 拼接batch
    text_embeddings = torch.cat([uncond_embeddings, text_embeddings])

    # 设置采样步数
    noise_scheduler.set_timesteps(num_inference_steps, device=device)
    # 根据strength计算timesteps
    init_timestep = min(int(num_inference_steps * strength), num_inference_steps)
    t_start = max(num_inference_steps – init_timestep, 0)
    timesteps = noise_scheduler.timesteps[t_start:]

    # 预处理init_image
    init_input = preprocess(init_image)
    init_latents = vae.encode(init_input.to(device, dtype=torch.float16)).latent_dist.sample(generator)
    init_latents = 0.18215 * init_latents

    # 给init_latents加噪音
    noise = torch.randn(init_latents.shape, generator=generator, device=device, dtype=init_latents.dtype)
    init_latents = noise_scheduler.add_noise(init_latents, noise, timesteps[:1])
    latents = init_latents # 作为初始latents

    # Do denoise steps
    for t in tqdm(timesteps):
    # 这里latens扩展2份,是为了同时计算unconditional prediction
    latent_model_input = torch.cat([latents] * 2)
    latent_model_input = noise_scheduler.scale_model_input(latent_model_input, t) # for DDIM, do nothing

    # 预测噪音
    noise_pred = unet(latent_model_input, t, encoder_hidden_states=text_embeddings).sample

    # CFG
    noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
    noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text – noise_pred_uncond)

    # 计算上一步的noisy latents:x_t -> x_t-1
    latents = noise_scheduler.step(noise_pred, t, latents).prev_sample

    # 注意要对latents进行scale
    latents = 1 / 0.18215 * latents
    # 解码
    image = vae.decode(latents).sample

    我们接下来再对图生图的一些关键参数进行详细的讲解。

    【Masked content参数详解】

    下面是Masked content参数设置不同的效果区别:

    图45 4.4 Stable Diffusion WebUI图生图全解析

    【Resize mode参数详解】

    下面是Resize mode参数设置不同的效果区别:

    图46 4.4 Stable Diffusion WebUI图生图全解析

    【Soft inpainting参数详解】

    Soft Inpainting(软重绘)是一种在 Inpainting 过程中,采用软过渡技术的重绘方法。与传统的硬边界修补不同,Soft Inpainting 在处理掩膜区域时,使用了软化的边界和权重,使得修补区域与周围环境更好地融合,避免了突兀的边缘或明显的拼接痕迹。

    在WebUI界面中,Soft Inpainting 作为 Inpainting 设置中的一个选项,我们可以根据需要启用或禁用该功能。

    Soft Inpainting的核心作用:

    1. 改善边缘过渡:在进行Inpainting时,如果掩膜区域的边缘过于锐利,模型可能会在修补区域与原始图像之间产生明显的分界线。这会导致生成的图像看起来不自然,修补痕迹明显。Soft Inpainting通过软化掩膜边缘,使模型在处理修补区域时,能够逐渐过渡到原始图像,从而减少边缘伪影,提升视觉效果。

    2. 提升修补质量:软化的边缘使得模型在生成内容时,可以更好地考虑周围像素的信息,生成的内容与原始图像更加一致,细节更加丰富。

    Soft Inpainting核心原理:

    1. 掩膜权重的软化:传统 Inpainting使用二值化的掩膜,掩膜区域的像素值为 1,非掩膜区域为 0。这种硬边界可能导致过渡不自然。与此同时,Soft Inpainting对掩膜进行软化处理,使得掩膜的边缘区域具有介于 0 和 1 之间的权重值。掩膜值越接近 1,表示该区域越需要被修补;越接近 0,表示需要保留原始内容。

    2. 模型的处理方式:在修补过程中,模型根据软化后的掩膜权重,对生成内容和原始图像进行加权融合。由于掩膜边缘的权重是连续变化的,生成的内容在边缘区域会与原始图像平滑过渡,避免了硬边界导致的突兀效果。

    输出像素

    =

    (

    掩膜权重

    )

    ×

    生成内容

    +

    (

    1

    −

    掩膜权重

    )

    ×

    原始像素

    \\text{输出像素} = (\\text{掩膜权重}) \\times \\text{生成内容} + (1 – \\text{掩膜权重}) \\times \\text{原始像素}

    输出像素=(掩膜权重)×生成内容+(1−掩膜权重)×原始像素

    3. 掩膜模糊与 Soft Inpainting 的关系:掩膜模糊(Mask Blur)通过对掩膜进行模糊处理,使边缘过渡更加平滑。Soft Inpainting在掩膜模糊的基础上,进一步利用软化的掩膜权重,在生成过程中进行权重融合。二者配合使用,可以显著提升修补效果。

    【图生图界面中img2img、Sketch、inpaint、inpaint Sketch这四者的功能区别】

    一、img2img(图像到图像):img2img(图像到图像)功能允许用户输入一张初始图像,模型根据该图像和提示词(Prompt),生成一张新的图像。生成的图像在内容、风格或细节上可能与原图像有所不同,具体取决于提示词和设置的参数。

    二、Sketch(草图):Sketch功能允许用户在空白画布上绘制草图,模型根据用户绘制的轮廓和提示词,生成完整的图像。草图作为图像的基本结构,引导模型生成符合预期的内容。

    三、Inpaint(图像修补):Inpaint功能允许用户在已有的图像上指定需要修改的区域(通过掩膜),模型在该区域内根据提示词生成新的内容,而不影响图像的其他部分。

    四、Inpaint Sketch(修补草图):Inpaint Sketch功能结合了Inpaint和Sketch的特点。用户在指定的掩膜区域内绘制草图,模型根据草图和提示词,在该区域生成新的内容。这样,用户可以更精确地控制修补区域的结构和细节。

    四者的功能区别总结如下所示:

    功能输入内容处理范围主要作用
    img2img 原始图像 + 提示词 整张图像 基于原始图像生成新的图像,改变风格、内容等
    Sketch 用户绘制的草图 + 提示词 根据草图确定的范围 根据草图生成完整的图像,从零开始创作
    Inpaint 原始图像 + 掩膜 + 提示词 掩膜区域 修改或替换图像的特定区域
    Inpaint Sketch 原始图像 + 掩膜 + 掩膜内的草图 + 提示词 掩膜区域 在掩膜区域内根据草图精确生成新的内容

    Stable Diffusion WebUI的图生图页面中还有Inpaint选项,我们可以使用Inpaint功能对输入的图像进行重绘。

    下面是Inpaint这个工作流的主要流程代码:

    import PIL
    import numpy as np
    import torch
    from diffusers import AutoencoderKL, UNet2DConditionModel, DDIMScheduler
    from transformers import CLIPTextModel, CLIPTokenizer
    from tqdm.auto import tqdm

    def preprocess_mask(mask):
    mask = mask.convert("L")
    w, h = mask.size
    w, h = map(lambda x: x – x % 32, (w, h)) # resize to integer multiple of 32
    mask = mask.resize((w // 8, h // 8), resample=PIL.Image.NEAREST)
    mask = np.array(mask).astype(np.float32) / 255.0
    mask = np.tile(mask, (4, 1, 1))
    mask = mask[None].transpose(0, 1, 2, 3) # what does this step do?
    mask = 1 – mask # repaint white, keep black
    mask = torch.from_numpy(mask)
    return mask

    def preprocess(image):
    w, h = image.size
    w, h = map(lambda x: x – x % 32, (w, h)) # resize to integer multiple of 32
    image = image.resize((w, h), resample=PIL.Image.LANCZOS)
    image = np.array(image).astype(np.float32) / 255.0
    image = image[None].transpose(0, 3, 1, 2)
    image = torch.from_numpy(image)
    return 2.0 * image – 1.0

    model_id = "/本地路径/stable-diffusion-v1-5"
    # 1. 加载autoencoder
    vae = AutoencoderKL.from_pretrained(model_id, subfolder="vae")
    # 2. 加载tokenizer和text encoder
    tokenizer = CLIPTokenizer.from_pretrained(model_id, subfolder="tokenizer")
    text_encoder = CLIPTextModel.from_pretrained(model_id, subfolder="text_encoder")
    # 3. 加载扩散模型UNet
    unet = UNet2DConditionModel.from_pretrained(model_id, subfolder="unet")
    # 4. 定义noise scheduler
    noise_scheduler = DDIMScheduler(
    num_train_timesteps=1000,
    beta_start=0.00085,
    beta_end=0.012,
    beta_schedule="scaled_linear",
    clip_sample=False, # don't clip sample, the x0 in stable diffusion not in range [-1, 1]
    set_alpha_to_one=False,
    )

    # 将模型复制到GPU上
    device = "cuda"
    vae.to(device, dtype=torch.float16)
    text_encoder.to(device, dtype=torch.float16)
    unet = unet.to(device, dtype=torch.float16)

    prompt = "a mecha robot sitting on a bench"
    strength = 0.75
    guidance_scale = 7.5
    batch_size = 1
    num_inference_steps = 50
    negative_prompt = ""
    generator = torch.Generator(device).manual_seed(0)

    with torch.no_grad():
    # 获取prompt的text_embeddings
    text_input = tokenizer(prompt, padding="max_length", max_length=tokenizer.model_max_length, truncation=True, return_tensors="pt")
    text_embeddings = text_encoder(text_input.input_ids.to(device))[0]
    # 获取unconditional text embeddings
    max_length = text_input.input_ids.shape[-1]
    uncond_input = tokenizer(
    [negative_prompt] * batch_size, padding="max_length", max_length=max_length, return_tensors="pt"
    )
    uncond_embeddings = text_encoder(uncond_input.input_ids.to(device))[0]
    # 拼接batch
    text_embeddings = torch.cat([uncond_embeddings, text_embeddings])

    # 设置采样步数
    noise_scheduler.set_timesteps(num_inference_steps, device=device)
    # 根据strength计算timesteps
    init_timestep = min(int(num_inference_steps * strength), num_inference_steps)
    t_start = max(num_inference_steps – init_timestep, 0)
    timesteps = noise_scheduler.timesteps[t_start:]

    # 预处理init_image
    init_input = preprocess(input_image)
    init_latents = vae.encode(init_input.to(device, dtype=torch.float16)).latent_dist.sample(generator)
    init_latents = 0.18215 * init_latents
    init_latents = torch.cat([init_latents] * batch_size, dim=0)
    init_latents_orig = init_latents
    # 处理mask
    mask_image = preprocess_mask(input_mask)
    mask_image = mask_image.to(device=device, dtype=init_latents.dtype)
    mask = torch.cat([mask_image] * batch_size)

    # 给init_latents加噪音
    noise = torch.randn(init_latents.shape, generator=generator, device=device, dtype=init_latents.dtype)
    init_latents = noise_scheduler.add_noise(init_latents, noise, timesteps[:1])
    latents = init_latents # 作为初始latents

    # Do denoise steps
    for t in tqdm(timesteps):
    # 这里latens扩展2份,是为了同时计算unconditional prediction
    latent_model_input = torch.cat([latents] * 2)
    latent_model_input = noise_scheduler.scale_model_input(latent_model_input, t) # for DDIM, do nothing

    # 预测噪音
    noise_pred = unet(latent_model_input, t, encoder_hidden_states=text_embeddings).sample

    # CFG
    noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
    noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text – noise_pred_uncond)

    # 计算上一步的noisy latents:x_t -> x_t-1
    latents = noise_scheduler.step(noise_pred, t, latents).prev_sample

    # 将unmask区域替换原始图像的nosiy latents
    init_latents_proper = noise_scheduler.add_noise(init_latents_orig, noise, torch.tensor([t]))
    latents = (init_latents_proper * mask) + (latents * (1 – mask))

    # 注意要对latents进行scale
    latents = 1 / 0.18215 * latents
    image = vae.decode(latents).sample

    在Stable DIffusion WebUI的图生图页面中,还包含了两个标签反推功能,分别是Interrogate CLIP和InterrogateDeepBooru。其中CLIP模型根据图像内容,生成自然语言标签;而DeepBooru则根据图像内容生成tag标签。两者的具体效果如下图所示:

    图47 CLIP反推生成效果与DeepBooru反推生成效果对比

    CLIP反推生成效果与DeepBooru反推生成效果对比

    想要使用CLIP模型进行标签反推,我们需要进行如下配置:

    • 将model_base_caption_capfilt_large.pth模型放入“/本地路径/stable-diffusion-webui/models/BLIP/”路径下。
    • **使用CLIP反推时可能会出现报错:**报“downloading default CLIP interrogate categories: FileExistsError”。原因是我们还缺少interrogate相关配置文件,下载后解压并将interrogate文件夹放到“/本地路径/stable-diffusion-webui/“路径下,同时删除interrogate_tmp文件夹。
    • 将bert-base-uncased模型放入“/本地路径/stable-diffusion-webui/”路径下。

    完成上面的三个模型与依赖文件的配置,即可运行CLIP模型!

    想要使用DeepBooru模型进行标签反推,我们需要进行如下配置:

    • 将model-resnet_custom_v3.pt模型放入“/本地流经/stable-diffusion-webui/models/torch_deepdanbooru/”路径下。

    完成上面的配置,即可运行DeepBooru模型!

    当我们看到一些AI绘画生成的具备艺术价值的图片,可以方便地使用Interrogate CLIP和InterrogateDeepBooru快速反推获得提示词。

    4.5 Stable Diffusion WebUI Extras页面使用解析

    Stable Diffusion WebUI Extras页面如下所示:

    图48 Stable Diffusion WebUI Extras页面

    Stable Diffusion WebUI Extras页面

    Stable Diffusion WebUI Extras页面中的功能主要包括:图像超分、人脸修复、图像裁剪、图像变换等AIGC时代的AI绘画前处理与后处理,其中的核心功能是图像超分。

    **为什么WebUI中要将图像超分和人脸修复等功能单独在一个页面进行配置呢?**本质上是因为AI绘画领域通过以AI绘画大模型为核心构建的完整工作流,让AI绘画在各个细分领域生根发芽,而图像超分和人脸修复等功能正是AI绘画工作流中不可或缺的部分。

    在Stable Diffusion WebUI框架中,一种集成了13种图像超分算法,包括:Lanczos、Nearest、ESRGAN_4x、LDSR、R-ESRGAN 2x+、R-ESRGAN 4x+、R-ESRGAN 4x+ Anime6B、R-ESRGAN AnimeVideo、R-ESRGAN General 4xV3、R-ESRGAN General WDN 4xV3、ScuNET、ScuNET PSNR以及SwinIR_4x。

    Lanczos和Nearest属于传统超分算法,核心是Nearest插值和Lanczos插值。这两种超分算法仅使用图像的像素值执行数学运算来放大图像尺寸并填充新像素。当图像本身被损坏或扭曲,这些算法就无法准确地填充缺失的有效信息。

    与此同时,ESRGAN_4x、LDSRR-ESRGAN 2x+、R-ESRGAN 4x+、R-ESRGAN 4x+ Anime6B、R-ESRGAN AnimeVideo、R-ESRGAN General 4xV3、R-ESRGAN General WDN 4xV3等超分算法都是基于GAN模型架构的,在对图像进行超分的同时能够较好的填充细节,下图是传统超分算法与R-ESRGAN超分模型的效果对比:

    图49 R-EsRGAN模型与Lanczos算法的超分效果比对

    R-EsRGAN模型与Lanczos算法的超分效果比对

    除了基于GAN模型架构的超分算法,也有基于扩散模型架构的超分算法,比如LDSR(Latent Diffusion Super Resolution),虽然它的效果很好,但是超分耗时较久,所以在实时场景中一般不建议使用。

    SRGAN模型倾向于保留精细的细节,并产生清晰锐利的图像。

    Real-ESRGAN模型与ESRGAN模型相比,倾向于产生更平滑的图像,同时在真实图像上的效果有比较多的提升。

    那么哪种图像超分算法效果最好呢?

    • 当我们使用真实图像进行超分处理时,推荐使用R-ESRGAN 4x+超分算法。
    • 当我们使用二次元图像进行超分处理时,推荐使用R-ESRGAN 4x+ Anime6B超分算法。

    在Stable Diffusion WebUI Extras页面中,我们除了能够进行图像超分处理,我们还能够对图像进行人脸修复操作。

    我们可以选择**GFPGAN和CodeFormer两个算法进行人脸修复(Face restoration)**操作,我们可以使用一个或者两个组合的方式,具体效果如下:

    图50 GFPGAN和CodeFormer算法人脸修复效果对比

    GFPGAN和CodeFormer算法人脸修复效果对比

    想要使用GFPGAN算法进行人脸修复,我们需要进行如下配置:

    • 将GFPGANv1.4.pth、detection_Resnet50_Final.pth和parsing_parsenet.pth模型放入“/本地路径/stable-diffusion-webui/models/GFPGAN/”路径下。

    想要使用CodeFormer算法进行人脸修复,我们需要进行如下配置:

    • 将codeformer-v0.1.0.pth模型放入“/本地路径/stable-diffusion-webui/models/Codeformer/”路径下。
    • 将detection_Resnet50_Final.pth和parsing_parsenet.pth模型放入“/本地路径/stable-diffusion-webui/repositories/CodeFormer/weights/facelib/”路径下。

    5. AIGC图像创作框架的主流热门插件深入浅出讲解

    在本章节中,Rocky将带着大家详细了解AIGC图像创作框架生态中的主流热门插件,这些插件都给我们带来了巨大的使用价值,提高了AIGC图像创作工作流的效率,为AIGC图像创作生态的繁荣作出了很大的贡献。

    由于各类插件种类繁多,Rocky在本章节中着重挑选一些高价值的插件功能进行讲解,大家可以通过这些案例举一反三进行学习,并尝试使用、构建、整合各类插件资源与工具!

    5.1 ADetailer插件功能

    ADetailer插件能够自动修复Stable Diffusion生成图像的脸部和手部的崩坏。

    ADetailer能够自动识别生成图像中的人脸,并对脸部进行mask覆盖,从而能够施展Inpainting功能对图像中的人脸部分进行重绘,从而优化脸部的质量与细节。

    ADetailer插件本质上是一个节省时间、简化图像修复增强过程的算法解决方案,将原来的人工手动mask填充+手动Inpainting过程完全自动化了。

    在整个过程中,就涉及到传统深度学习时代的YOLO系列检测模型用于检测图像中的人脸、人体、手部等特征。目前涉及到的模型以及功能如下所示:

    • **Face_xxxx:**检测并重新绘制人脸
    • **Hand_xxxx:**检测并重新绘制手部
    • **Person_xxxx:**检测并重新绘制整个人
    • **Mediapipe_face_xxxxx:**检测和重绘人脸

    图51 使用ADetailer对脸部进行修复

    使用ADetailer对脸部进行修复

    图52 使用ADetailer对手部进行修复

    使用ADetailer对手部进行修复

    图53 使用ADetailer对全身进行修复

    使用ADetailer对全身进行修复

    与此同时,在ADetailer进行自动化重绘时,我们可以输入特定的提示词和负向提示词,更加精准的控制Inpainting过程。

    值得一提的是,ADetailer还可以与ControlNet组合使用,让整个生成过程更加可控。

    5.2 深入浅出完整解析EasyPhoto的AI写真功能

    AI写真是AIGC时代中AIGC图像创作领域的一个非常重要的商业变现与可持续发展方向。妙鸭相机作为AIGC时代的一款收费产品,成功向大家展示了如何凭借少量的人脸图片进行AI写真生成,能够迅速提供真、像、美的AI个人写真,在极短的时间内便拥有了众多的付费客户。

    目前,作为开源版的妙鸭相机——EasyPhoto插件已经能够很好的适配Stable Diffusion WebUI,EasyPhoto允许用户上传几张同一个人的照片,快速的训练Lora模型,再结合用户上传的模板图片,快速生成真、像、美的AI写真图片。

    Rocky认为,EasyPhoto 真正值得学习的地方,是它把人脸筛选、LoRA 训练、ControlNet 控制、Mask 重建和后处理串成了一个完整的产品级闭环工作流。

    这也是很多 AIGC 应用从 Demo 走向产品时必须补上的一课:单点大模型能力只负责“会不会”,工程闭环才决定“稳不稳”。

    图54 EasyPhoto效果展示

    EasyPhoto效果展示

    **AI 写真领域的一直有一个核心矛盾:既要像本人,又要像一张完整照片。**人像生成过程中这两个目标经常互相拉扯。

    第一个目标是身份一致性。生成结果要像用户本人,眼睛、脸型、五官比例、整体气质不能偏离太远。

    第二个目标是照片完整性。图片不能只有脸对了,身体、发丝、衣服、背景、光照、边缘、颜色也要协调。很多生成结果之所以看起来“AI 味”很重,并不是因为脸完全不像,而是局部对了、整体散了。

    所以 EasyPhoto 不是简单地把用户照片丢给 Stable Diffusion,也不是只训练一个人像 LoRA 就结束。它更像一个人像生产流水线:

  • 先从用户输入里挑出最适合学习身份的照片。
  • 再把背景、噪声、低清晰度这些不该学习的东西尽量剔除。
  • 用 LoRA 把用户身份压缩进一个轻量可调用的个性化权重。
  • 推理时用人脸融合、姿态对齐、ControlNet、多次重建和后处理共同约束结果。
  • 这里的关键判断是:LoRA 负责“这个人是谁”,ControlNet 负责“这个人怎么站、轮廓怎么稳、颜色怎么贴合模板”,后处理负责“这张图能不能像一张可交付的照片”。

    下面Rocky将带着大家一起学习EasyPhoto的AI写真工作流,下面是EasyPhoto相应的资源,我们能够方便地使用:

    EasyPhoto项目ComfyUI版本地址:https://github.com/THtianhao/ComfyUI-Portrait-Maker

    EasyPhoto项目Stable Diffusion WebUI地址:📷 EasyPhoto:Your Smart AI Photo Generator

    EasyPhoto工作流主要分训练和推理两个阶段。

    【EasyPhoto训练阶段】

    我们可以将EasyPhoto的训练阶段整体上分成数据预处理和LoRA模型训练两个部分,完整流程图如下所示:

    图55 EasyPhoto训练过程完整流程图

    EasyPhoto训练过程完整流程图

    EasyPhoto 的思路更接近真实AIGC产品:训练之前,先把数据整理干净。

    用户上传的照片天然不稳定。有的清晰,有的模糊;有的是正脸,有的是侧脸;有的背景复杂,有的美颜严重;还有些照片虽然是同一个人,但年龄、发型、光照、镜头畸变差异很大。

    如果把这些数据原样喂给 LoRA,模型不仅会学习用户的身份,也会学习噪声、背景、低清晰度、错误姿态和照片缺陷。人像 LoRA 的风险在于它太会学习了:你给它什么,它就尽量记住什么。

    EasyPhoto 的预处理可以拆成两个层次:

  • 人像排序与 Top-k 选择:找出更像本人、更适合训练的照片。
  • 人像显著性分割、修复与增强:尽量去掉不该被 LoRA 吸收的干扰信息。
  • **我们首先用人脸特征向量找到“更像本人”的照片。**EasyPhoto 会通过人脸检测、人脸对齐和人脸识别模型,把每张照片中的人脸转换成一个定长特征向量。

    直观理解,这个向量就是人脸身份的一种数字表达。不同照片之间可以计算相似度,同一个人比较接近,不同人差异更大。系统可以先求出一组用户照片的平均特征,再判断每张照片离这个平均身份有多近。

    我们可以通过人脸特征向量选出最像自己的图片,因为每个人在不同时期的样貌是有些许差异的,所以我们需要选出输入图片中最像自己的图片用于后续的LoRA模型训练。

    人脸特征向量计算需要先进行人脸检测;然后进行人脸对齐,使其成为一张标准的人脸(人脸“正则化”);最后通过人脸识别提取出这个人脸的特征向量。 经过人脸特征向量的提取后,我们可以得到一个特征向量来表示人脸,如下所示:

    # 这是一个的128维的人脸特征向量
    feature_vector = [
    0.12, –0.23, 0.33, 0.45, –0.56, 0.67, –0.78, 0.89, 0.91, –1.02,
    1.13, –1.24, 1.35, –1.46, 0.57, –0.68, 0.79, –0.80, 0.81, –0.92,
    0.93, –1.04, 1.15, –1.26, 1.37, –1.48, 1.59, –1.60, 0.61, –0.72,
    0.73, –1.84, 1.95, –1.06, 0.17, –0.28, 0.39, –0.40, 0.41, –0.52,
    0.53, –1.64, 1.75, –1.86, 0.97, –0.08, 0.19, –0.30, 0.31, –0.42,
    0.43, –1.54, 1.65, –1.76, 0.87, –0.98, 0.09, –0.10, 0.11, –0.22,
    0.23, –1.34, 1.45, –1.56, 0.67, –0.78, 0.89, –0.90, 0.91, –0.02,
    0.13, –1.24, 1.35, –1.46, 0.57, –0.68, 0.79, –0.80, 0.81, –0.92,
    0.93, –1.04, 1.15, –1.26, 1.37, –1.48, 1.59, –1.60, 0.61, –0.72,
    0.73, –1.84, 1.95, –1.06, 0.17, –0.28, 0.39, –0.40, 0.41, –0.52,
    0.53, –1.64, 1.75, –1.86, 0.97, –0.08, 0.19, –0.30, 0.31, –0.42,
    0.43, –1.54, 1.65, –1.76, 0.87, –0.98, 0.09, –0.10, 0.11, –0.22
    ]

    整个人脸特征向量计算的过程可以用下图表示:

    图56 人脸特征向量计算过程示意图

    人脸特征向量计算过程示意图

    通过对人脸特征向量之间的比对,我们就可以判断人脸之间的相似程度了。

    在计算出人脸特征向量后,EasyPhoto 还会考虑人脸偏移角度,我们需要进行人脸偏移角度的计算。一个简单做法是用双眼连线相对于水平线的倾斜程度估算人脸姿态。

    人脸偏移角度的计算方法有很多,EasyPhoto中通过双眼的旋转角度计算人脸的偏移角度。我们以水平线为基准,双眼的旋转角度就是眼睛连线相对于水平线的倾斜角,如下图所示:

    图57 人脸偏移角度

    人脸偏移角度

    如果这个倾斜角为0,则代表双眼完全正视,一般情况下,如果人像存在侧拍、侧身、歪头等情况,倾斜角是不会为0的,因此我们可以通过计算倾斜角度来选出最正的人像,用于接下来的图像质量评分计算和在预测阶段中作为参考人像进行使用,进行人脸融合。

    这一步看似很小,但对人像写真很关键。因为后面的生成不是只靠 LoRA 记忆身份,还会用参考人像做人脸融合、Canny 控制、OpenPose/Face pose 控制。参考样本一旦选歪,后面的控制链路都会被带偏。

    完成人脸特征向量计算和人脸偏移角度计算后,我们就可以进行人像的排序。

    我们先对人脸偏移角度进行归一化:

    • 人脸偏移角度为0的时候,得分为1
    • 人脸偏移角度为90的时候,得分为0

    我们再根据人脸特征向量,计算用户上传图像自身与自身的相似程度,首先计算人像数据的平均特征,然后计算每一张图片与平均特征的相似程度,相似程度也用一个0-1之间的得分来表示。

    我们接着将人脸特征相似度得分与人脸偏移得分进行相乘,选出得分最高的,作为参考人像。同时使用人脸特征相似度得分与图像质量评分进行相乘,选出得分最高的Top-K个人像进行训练。

    完成上面的工作后,我们还需要进行人像图片进行显著性分割,避免 LoRA 学到脏信息。我们在训练阶段想要LoRA模型学习到的是人像特征而不是其它的特征,背景和衣服不一定都是有价值信息,所以训练数据中人相特征越显著越好。

    EasyPhoto 的目标是保留用户身份特征,而不是把每张照片里的背景、发型噪声、衣服纹理都强行写进个性化模型。

    所以我们对Top-k个人像数据使用图像分割模型进行显著性分割,将背景进行了去除,再通过人脸检测框裁剪出人脸周围的区域。

    更重要的是低质量照片处理。用户上传的照片可能模糊、有噪点、压缩严重,甚至带有划痕和局部破损。LoRA 如果直接学习这些图,很可能把“低质量感”也学进去。

    所以接下来我们就进入图像预处理阶段的最后一个步骤——图像修复。

    由于用户的输入图片不一定是高质量图片,图片可能存在模糊、噪声、不清晰等问题,所以我们需要使用一些修复算法与超分算法将低质量图像进行修复后再用于LoRA模型的训练。不然LoRA模型会学到模糊、噪声、不清晰等不好的特征,从而影响图像生成效果。

    图58 5.2 深入浅出完整解析EasyPhoto的AI写真功能

    我们用之前的图像质量评分判断选出质量最低的一些图像,使用GPEN人像修复增强算法进行图像修复和超分,同时使用ABPN人像美肤算法提升人像的皮肤质感,从而提升了图片综合质量。

    Rocky认为,这个地方很能体现 AIGC 产品工程的基本功:数据不是原材料搬运,数据是生成质量的第一层约束。 模型训练只是把数据里的规律放大,如果数据里混着大量错误规律,训练越努力,偏差也可能越稳定。

    完成了上面的数据预处理流程,下面我们可以进行人脸LoRA模型的训练了。

    EasyPhoto分别在Stable Diffusion的Text Encoder和U-Net部分的自注意力机制中添加LoRA进行训练。

    下面是一些LoRA模型训练的关键参数,我们可以按需进行调整:

    参数名含义
    resolution 训练时输入图片的分辨率,默认值为512
    validation & save steps 验证图片与保存中间权重的steps数,默认值为100,代表每100步验证一次图片并保存LoRA权重
    max train steps 最大训练步数,默认值为800
    max steps per photo 每张图片的最大训练次数,默认为200
    train batch size 训练的批次大小,默认值为1
    gradient accumulation steps 是否进行梯度累计,默认值为4,若train batch size设置为4,每个Step相当于输入四张图片进行训练
    dataloader num workers 数据加载的works数量,windows下无法使用,Linux正常设置
    learning rate 训练LoRA模型的学习率,默认为1e-4
    rank LoRA 权重的特征长度,默认为128
    network alpha LoRA训练的正则化参数,一般为rank的二分之一,默认为64

    在EasyPhoto中,最终LoRA模型的训练步数等于:

    Final training step = Min(photo_num * max_steps_per_photos, max_train_steps)

    以上面的默认参数为例,如果图片数量小于4,则训练步数为200x图片数量;如果大于等于4,则训练步数为800。

    默认逻辑可以理解为:如果用户图片少,训练步数随图片数量增加;如果图片数量达到一定规模,则使用相对固定的训练步数。这样做的目的不是追求理论最优,而是在AIGC产品里给出一个能跑、相对稳定、可控的训练预算。

    同时,在LoRA模型的训练过程中,我们还需要通过LoRA模型融合来获取最佳的LoRA模型。

    直接取最后保存的LoRA模型并不能保证就是最符合人像特征的。因此,EasyPhoto在训练中加入了LoRA模型融合的机制。

    EasyPhoto会在每100个Step处添加一次模型验证并且保存LoRA权重,模型验证时使用一些模板图像进行图生图功能,生成人像正脸照。以默认参数为例,我们一共进行800步的训练,那么我们可以得到8个LoRA模型和8组验证结果,我们提取验证结果与训练图片的人脸特征向量,进行人脸相似度的计算。

    再将能够生成人脸相似度较高的几个LoRA模型进行融合。由于每组验证结果包含多张图片(默认为4张),我们会根据每组验证结果中图片被选中的比例作为这个LoRA模型在进行模型融合时的权重。

    也就是说,它不是训练完才看结果,而是在训练过程中持续观察“哪个阶段的 LoRA 更像用户”。

    可以把这个机制理解成一个小型评审系统:

  • 每隔固定步数保存一份 LoRA。
  • 每份 LoRA 都用模板图做一组正脸验证。
  • 对验证结果提取人脸特征向量。
  • 与原始训练图片的人脸特征做相似度比较。
  • 挑出表现更好的 LoRA,再按被选中比例做权重融合。
  • 这个设计的价值在于,它承认 LoRA 训练过程存在波动。某个中间权重可能比最后权重更保身份,也可能某些阶段更像本人但画面质量不稳定。通过验证图反推权重占比,EasyPhoto 试图把偶然性压低一点。

    这不是纯算法优雅,而是产品工程务实:当你无法保证单一 checkpoint 永远最好,就让验证集参与选择。

    到这里,EasyPhoto的训练阶段就完整的介绍好了,Rocky再给大家进行总结梳理一下,方便大家快速学习:

  • 上传5到20张人像数据作为训练集,包括不同的角度和光照,同时最好是半身照片且不要佩戴眼镜。
  • 采用人脸特征相似度和图像质量对所有图片进行评分,筛选最佳图像和Top-K图像。
  • 采用人脸检测和显著性分割,对Top-K图像进行人脸检测和抠图,并去除背景。
  • 采用图像修复模型和美肤模型优化部分低质量人脸数据,提升训练数据的整体质量。
  • 对处理后的训练图片进行标注,并设置超参数用于人脸LoRA模型的训练。
  • LoRA模型的训练过程中采用基于人脸特征相似度的验证步骤,间隔一定的step保存模型权重,并根据相似度来融合LoRA模型。
  • 【EasyPhoto推理阶段】

    训练阶段解决了“用户是谁”,推理阶段则要解决“如何把这个人放进模板场景里,而且画面不崩”。

    EasyPhoto 的推理流程主要采用StableDiffusion模型 + 人像LoRA模型 + ControlNet模型进行,可以概括为三段:

  • 初步重建:先得到一个像用户、姿态大体正确的基础结果。
  • 边缘完善:针对人脸周围、身体轮廓和画面接缝做第二次修正。
  • 后处理:通过超分、人脸增强等方式提升最终交付质量。
  • 图59 EasyPhoto推理过程完整流程图

    EasyPhoto推理过程完整流程图

    这套设计背后的逻辑是:扩散模型一次生成很难同时满足身份、姿态、颜色、边缘和清晰度。与其把所有压力压到一次采样,不如拆成多个阶段,每个阶段解决一类主要矛盾。

    首先我们进入初步重建阶段,先给扩散模型一个靠谱的起点。这个阶段又可以分为人脸融合、人脸裁剪与仿射变换、Stable Diffusion重建与颜色转移三个部分。

    图60 5.2 深入浅出完整解析EasyPhoto的AI写真功能

    **人脸融合:先把“像本人”的底图做出来。**EasyPhoto 会使用人脸融合算法,把用户参考图的人脸身份迁移到模板图上,得到一个较像用户、同时保留模板外观结构的基础图。

    我们先将在训练阶段筛选出的最佳人像图像作为目标脸型,通过人脸融合算法与模版图中的人脸进行融合,生成一张与目标脸型相似,且具有模版人脸外貌特征的新图像,为后续的AI写真提供了一个较好的基础图像。

    图61 5.2 深入浅出完整解析EasyPhoto的AI写真功能

    这个人脸融合不是简单贴脸。其机制大致是:用属性编码器提取模板图的外观属性,用人脸识别模型提取用户图的身份特征,再通过特征融合结构把身份信息嵌入到模板属性空间里。局部形变可以通过类似光流的方式适配用户脸型,让融合结果既保留模板姿态,又接近用户身份。

    图62 5.2 深入浅出完整解析EasyPhoto的AI写真功能

    人脸融合算法(cv_unet_face_fusion_torch)使用多尺度属性编码器提取模板图属性特征,使用预训练人脸识别模型提取用户图的ID特征,再通过引入可行变特征融合结构, 将ID特征嵌入属性特征空间的同时,以光流场的形式实现面部的自适应变化,最终融合结果真实、高保真和一定程度内对目标用户脸型的自适应感知。

    完成了人脸融合后,我们需要进行人脸裁剪与仿射变换,让姿态控制有可靠锚点。

    训练阶段已经选出了更像用户、更正的人像。推理阶段可以利用这个结果,对人脸区域进行裁剪,并通过五个人脸关键点做仿射变换,把用户脸部对齐到模板图中的位置。

    我们找出在训练阶段验证时生成的和用户相似度最高的正脸图片,在此基础上我们裁剪这个正脸照片并且进行仿射变换,利用五个人脸关键点,将其贴到模板图像上,得到一个Replaced Image,将在后续使用Stable Diffusion重建时提供openpose信息。

    图63 5.2 深入浅出完整解析EasyPhoto的AI写真功能

    这个被替换和对齐后的图像可以为后续 ControlNet 提供 OpenPose、Face pose 等控制信息。换句话说,人脸融合解决“像谁”,仿射对齐解决“放在哪里、怎么对齐”。

    很多人像生成翻车,本质不是脸部身份完全失败,而是脸部、头部轮廓、眼睛位置和身体姿态之间关系不稳定。仿射变换就是在生成前先把几何关系固定住。

    有了融合人脸图像和仿射变换的人脸图像后,我们就可以进行Stable Diffusion重建和颜色转移了。

    在这一步中我们主要使用训练阶段获得的LoRA模型进行人脸重建生成,但只使用LoRA模型是不够的,很容易生成不和谐的图像,我们需要施加一些ControlNet控制。

    图64 5.2 深入浅出完整解析EasyPhoto的AI写真功能

    在这里EasyPhoto使用了三个ControlNet控制和一个Mask:

  • 使用人脸融合图像的Canny控制(防止人像崩坏)
  • 使用人脸融合图像的颜色控制(使生成的颜色且符合模板)
  • 使用Replaced Image的openpose+Face pose控制(使得眼睛与轮廓更像本人)
  • 使用训练获得的LoRA模型
  • 使用Mask对人像区域进行重建生成
  • 控制信号主要作用
    LoRA 注入用户身份特征
    Canny 稳住轮廓边缘,降低结构崩坏
    颜色控制 让生成结果与模板色调更协调
    OpenPose / Face pose 稳定姿态、眼睛位置和脸部朝向
    Mask 限定重建区域,避免无关区域被大幅破坏

    这里有一个产品经验很重要:AI 写真不是让模型自由发挥,而是在尽可能多的关键维度上给模型“收窄搜索空间”。

    LoRA 给身份,Canny 给边缘,OpenPose 给姿态,颜色控制给观感,Mask 给编辑边界。多个条件叠起来,扩散模型才更容易生成既像本人又像模板照片的结果。

    重建后如果出现颜色偏移,还需要做颜色迁移,让结果和原图或模板图在整体色调上更自然。这类步骤很容易被初学者忽略,但它往往决定成片是否像“同一张照片里的内容”。

    重建生成完成后的图像可能存在一些颜色的偏移,EasyPhoto会使用一个color_transfer方法,保证重建后的图片与原图的颜色协调。

    完成上面的操作后,我们就可以进入边缘完善这个阶段了。初步重建后,结果通常已经能看出用户身份,但边缘区域可能仍然存在问题:脸和头发交界不自然,脖子、衣领、背景接缝有断裂感,局部纹理和光照不统一。所以 EasyPhoto 又做了一次边缘完善。

    图65 5.2 深入浅出完整解析EasyPhoto的AI写真功能

    边缘完善阶段又可以分为两步,分别是人脸融合和Stable Diffusion重建。与初步重建阶段类似,在边缘完善阶段我们再做一次人脸融合来提升人脸的相似度。

    在完成初步重建后,生成的人像图片整体效果已经不错了,但在边缘上可能依旧存在不和谐的问题。因此,EasyPhoto进行了第二次Stable Diffusion重建进行图像的边缘完善。同样需要在使用LoRA模型的基础上施加一些Controlnet控制,EasyPhoto主要使用了两个ControlNet控制和一个Mask:

  • 使用人脸融合图像的tile控制(防止颜色过于失真)
  • 使用人脸融合图像的canny的控制(防止人像崩坏)
  • 使用训练获得的LoRA模型
  • 通过Mask对人像周围区域进行重建(不是人像区域)
  • 最后,我们需要进行后处理阶段,一共包含了人像美肤和超分辨率重建两个步骤,能够让生成的AI写真更美更清晰。

    图66 5.2 深入浅出完整解析EasyPhoto的AI写真功能

    EasyPhoto 的后处理主要包括两类:

    1. 人脸增强:提升面部细节,让五官、皮肤、局部纹理更清楚。 2. 超分辨率:提升整体分辨率和清晰度,让成片更接近可分享、可保存的写真。

    这一步不要轻视。用户不会按模型模块打分,用户只看最终图像。脸是否清楚、皮肤是否自然、边缘是否干净、分辨率是否够用,都会影响产品满意度。

    从商业闭环看,后处理就是把“技术结果”变成“可交付结果”的最后一道工序。很多 AI Demo 看起来惊艳,但无法成为稳定产品,原因往往不是核心模型完全不行,而是缺少这些看似琐碎、实际决定体验的后处理链路。

    Rocky认为,这也是 AI 图像应用里非常典型的工程思维:不要期待一次生成解决所有问题。真正稳定的工作流往往是分层修正,每一层只解决它最擅长的问题。

    到这里,EasyPhoto的推理阶段就完整的介绍好了,Rocky再给大家进行总结梳理一下,方便大家快速学习:

  • 对输入的模板图进行人脸检测(crop & warp)并结合数字分身进行模板图的人脸替换。
  • 挑选用户输入的最佳ID Photo和模板照片进行人脸融合。
  • 使用融合后的图片作为基底图片,使用替换后的人脸作为ControlNet条件,加上数字分身对应的LoRA模型,进行img2img的局部重绘生成,同时进行图像颜色上的协调。
  • 再次进行人脸融合,同时使用Stable Diffusion + LoRA+ControlNet进行图像边缘完善。
  • 采用人脸美肤模型和超分辨率重建模型生成优美的高清AI写真图。
  • 把 EasyPhoto 重新看一遍,可以发现它的价值不只是“会训练人像 LoRA”。它更重要的贡献是把 AI 写真拆成几个可管理变量。

    变量EasyPhoto 的处理方式解决的问题
    身份 人脸特征筛选、LoRA 训练、LoRA 融合 更像用户本人
    数据质量 分割、修复、超分、美肤 避免低质量样本污染训练
    姿态 正脸参考、关键点仿射、OpenPose/Face pose 稳定眼睛、脸型和身体结构
    轮廓 Canny、Mask、分阶段重建 降低结构崩坏和边缘穿帮
    颜色 颜色控制、颜色迁移、Tile 降低色调割裂
    成片质感 人脸增强、超分辨率 提升最终可用性

    这张表背后的启发是:AIGC 产品不是把模型越堆越多,而是把用户真正感知到的问题拆成变量,再为每个变量设计约束和修正机制。

    在这个意义上,EasyPhoto 更像一个人像生成工程模板,而不仅是一个插件。

    5.3 深入浅出完整解析Facechain的AI写真功能

    除了EasyPhoto插件外,FaceChain项目也能完成AI写真功能,并且FaceChain具备多张图片精细化生成AI写真和一张图片快速生成AI写真(10秒左右)两种适应不同场景需求的功能。

    FaceChain是阿里达摩院发布的一个功能上对标“秒鸭相机”的开源项目,顾名思义,FaceChain就是对人脸(face)做一连串(chain)的操作处理。

    那么这些处理包括哪些呢,又是怎么串联起来的呢?接下来Rocky就分别从精细化生成AI写真和一张图片快速生成AI写真两个功能向大家详细介绍。

    我们首先来介绍FaceChain精细化生成AI写真的功能,其完整工作流程如下所示:

    图67 FaceChain精细化生成AI写真工作流

    FaceChain精细化生成AI写真工作流

    训练阶段

  • 输入:用户上传的清晰人脸图像。
  • 输出:人脸LoRA模型。
  • 首先,我们分别使用基于朝向判断的图像旋转模型、基于人脸检测和关键点模型的人脸精细化旋转方法处理用户上传图像,得到包含正向人脸的图像。

    接着,我们使用人体解析模型和人像美肤模型,以获得高质量的人脸训练图像。

    然后,我们使用人脸属性模型和文本标注模型,结合标签后处理方法,产生训练图像的精细化标签。

    最后,我们使用上述图像和标签数据基于Stable Diffusion模型训练人脸LoRA模型。

    推断阶段

  • 输入:训练阶段用户上传的图像和预设的Prompt提示词。
  • 输出:个人写真图像。
  • 首先,我们将人脸LoRA模型和风格LoRA模型的权重融合到Stable Diffusion模型中。

    接着,我们使用Stable Diffusion模型的文生图功能,基于预设的输入提示词初步生成个人写真图像。

    然后,我们使用人脸融合模型进一步改善写真图像的人脸细节,其中用于融合的模板人脸通过人脸质量评估模型在训练图像中择优挑选。

    最后,我们使用人脸识别模型计算写真图像与模板人脸的相似度,以此对写真图像进行排序,并输出排名靠前的n个人写真图像作为最终输出结果。

    讲完了FaceChain精细化生成AI写真的功能,接下来Rocky再和大家一起分析FaceChain一张图片快速生成AI写真的功能。

    最新的FaceChain FACT版本中,用户仅需要提供一张照片即可10秒钟获得独属于自己的个人写真(支持多种风格)。FaceChain可实现兼具可控性与ID保持能力的无限风格写真与固定模板写真功能,同时对ControlNet和LoRA具有优秀的兼容能力。

    下面是FaceChain FACT版本的完整工作流:

    图68 5.3 深入浅出完整解析Facechain的AI写真功能

    5.4 ControlNet插件

    ControLnet的相关核心知识与实战应用,大家可以直接阅读Rocky在持续更新的《深入浅出完整解析ControlNet核心基础知识》文章:

    深入浅出完整解析ControlNet核心基础知识

    码字确实不易,希望大家能多多点赞!!!

    5.5 Segment Anything插件

    在WebUI中,Segment-Anything插件将自然语言、目标检测与图像分割的能力结合,使得我们可以通过简单的文字描述完成复杂的目标检测和图像分割任务。它在提高图像处理的自动化和精度方面有显著优势,特别是在大规模数据标注、精细分割和复杂场景的多对象处理上,非常适合需要高效处理和标注大量图像数据的场景。

    图69 5.5 Segment Anything插件

    Segment Anything插件主要结合了两种强大的AI算法技术——Grounding DINO和Segment Anything Model (SAM),从而实现复杂图像中的对象检测和分割任务。我们通过自然语言或者标签提示,精准地识别和分割图像中的目标区域,广泛应用于图像理解、图像编辑、自动化标注等场景。

    Grounding DINO是一种强大的目标检测模型,它的独特之处在于能够根据自然语言提示进行目标检测。相比传统的目标检测模型(如 Faster R-CNN 或 YOLO),Grounding DINO 允许用户通过输入具体的描述,来定位目标对象。比如输入 “a cat on the sofa”,模型就能在图像中找到沙发上的猫。

    Segment Anything Model (SAM)是一种通用的分割模型,能够处理不同类型的图像分割任务,甚至在无监督情况下也能分割出非常复杂的物体。SAM 可以从像素级别精确分割出图像中的区域,因此非常适合用于精细化处理图像。

    Segment Anything插件的功能极大地增强了图像分割的灵活性和易用性:

    • 自动化标注:由于Grounding DINO和SAM的自动化能力,我们不再需要手动标记数据。只需提供简单的描述性标签,插件就能够自动生成高质量的分割结果并保存为标注数据。这对于减少标注时间和提高数据集的质量具有重要意义。
    • 图像理解与分析:在图像理解任务中,该插件可以用于自动提取图像中的目标对象,并且可以通过自然语言输入高效地完成复杂的目标检测和分割任务。
    • 高效图像编辑:特别适合图像编辑或标注任务,我们可以快速提取出图像中的特定对象进行后续处理,如替换背景、修改颜色等。
    • 支持细粒度分割:Segment Anything插件不仅可以处理较大区域的分割任务,也能够胜任更精细的对象分割任务。例如,在图像中要分割一只猫的具体部分如“猫的耳朵”,通过语言描述(如“the cat’s ear”),插件可以首先通过 Grounding DINO 定位猫,然后通过 SAM 模型对耳朵进行精细分割。这对于需要高精度的图像处理任务(如医疗影像分析、自动驾驶场景理解等)尤为重要。
    • 多对象分割:Segment Anything插件还支持多对象分割。如果图像中有多个目标对象,我们可以通过提供多个提示词来分别识别和分割不同的对象。比如在一张包含猫和狗的图片中,我们可以分别输入“cat”和“dog”,模型会依次分割出图像中的猫和狗,并对它们进行标注。这种多对象分割能力非常适合应用于复杂场景,如无人驾驶中对不同物体(如行人、车辆、障碍物)的分割识别。

    5.6 AnimateDiff插件

    AnimateDiff是一个文生视频的算法,我们可以输入一段文本提示词,从而生成大约几秒钟的短视频。同时,将AnimateDiff与ControlNet进行组合使用,可以进行视频生成视频和视频编辑功能。

    AnimateDiff最大的特点是其加入了运动模型模块(Motion Modeling Module)。该模块的作用是学习和捕捉运动的先验知识,使生成的动画在帧与帧之间具有连贯性和合理性。它可以理解为一种对运动模式和规律的学习器,通过对大量视频数据的学习,掌握不同物体的运动方式和变化趋势,从而在生成动画时能够根据文本提示和已有的图像信息,合理地预测和生成下一帧的图像内容,实现动画片段中的运动平滑度和内容一致性。

    图70 5.6 AnimateDiff插件

    上图中展示的是AnimateDiff模型在训练阶段和推理阶段的整体流程,旨在将静态图像生成模型(Text-to-Image,T2I)扩展为文本驱动的视频生成模型。下面我们一起详细了解训练和推理过程。

    【AnimateDiff训练阶段】

    1. 输入视频片段:在训练阶段,模型使用一系列视频片段作为输入。这些视频片段包含多个连续帧,为模型提供了学习运动模式的丰富数据。

    2. 编码过程:视频片段被输入到编码器(图中的ε)中,转换为潜在的运动特征表示

    z

    0

    :

    N

    z_{0:N}

    z0:N​ ,这一步提取了视频的运动信息和帧间的动态关系。

    3. 添加噪声:在训练中,会给这些潜在特征添加一定的随机噪声(符合正态分布

    N

    (

    0

    ,

    I

    )

    N(0, I)

    N(0,I)),这是扩散模型的一部分,用于训练模型在多样化的输入情况下保持一致。

    4. 基础 T2I 模型和运动建模模块:

    – 基础 T2I 模型:图中的灰色部分表示已经预训练好的 T2I 模型的权重,这部分在训练过程中被“冻结”,即不再更新参数。

    – 运动模块:图中的蓝色部分表示新加入的、专门用于运动建模的模块。在训练阶段,这个模块从头开始初始化,并通过与视频片段数据的训练来学习合理的运动先验。

    5. 损失计算:通过扩散过程,模型输出带有噪声的图像,与目标噪声图像进行比较,计算损失。这一损失用于优化运动建模模块,使其能够从视频数据中学习到运动信息。运动建模模块的最终训练目标是:

    L

    =

    E

    E

    (

    x

    0

    1

    :

    N

    )

    ,

    y

    ,

    ϵ

    ∼

    N

    (

    0

    ,

    I

    )

    ,

    t

    [

    ∥

    ϵ

    −

    ϵ

    θ

    (

    z

    t

    1

    :

    N

    ,

    t

    ,

    τ

    θ

    (

    y

    )

    )

    ∥

    2

    2

    ]

    \\mathcal{L}=\\mathbb{E}_{\\mathcal{E}(x_0^{1:N}),y,\\epsilon\\sim\\mathcal{N}(0,I),t}\\left[\\|\\epsilon-\\epsilon_\\theta(z_t^{1:N},t,\\tau_\\theta(y))\\|_2^2\\right]

    L=EE(x01:N​),y,ϵ∼N(0,I),t​[∥ϵ−ϵθ​(zt1:N​,t,τθ​(y))∥22​]

    【AnimateDiff推理阶段】

    1. 插入运动建模模块:在推理阶段,训练好的运动建模模块被插入到已经预训练好的 T2I 模型中。这样,T2I 模型就具备了生成连续帧的能力,而不仅仅是生成单张静态图像。

    2. 生成过程:

    – 初始噪声生成:从标准正态分布

    N

    (

    0

    ,

    I

    )

    N(0, I)

    N(0,I)中采样初始噪声,这与生成单张图像的过程类似。

    – 迭代去噪:通过插入了运动建模模块的模型,开始迭代去噪过程。这一步的目标是逐渐将噪声转换为具有连续运动特征的图像序列。

    – 解码生成:经过一系列去噪和生成步骤,最终得到一个符合输入文本描述的动画图像序列。

    3. 视频输出:最终生成的结果是一个动画序列,即一段短视频,展示了根据输入文本描述生成的动画内容。

    5.7 Tiled Diffusion/VAE插件

    Stable Diffusion WebUI的Tiled Diffusion/VAE插件项目地址:multidiffusion-upscaler-for-automatic1111

    ComfyUI的Tiled Diffusion/VAE插件项目地址:ComfyUI-TiledDiffusion

    Tiled Diffusion/VAE插件能够让我们在显存不足的情况下,进行图像的超分辨率重建、2k-8k的高分辨率图像生成以及图像子区域的编辑生成。

    接下来我们就逐一介绍这个插件各个功能的详细作用。

    首先我们讲解一下Tiled VAE的核心功能,Tiled VAE的核心目标是通过分块处理大图像,解决显存不足的问题,同时保持生成图像中的子分块图像的边缘无缝连接。使用到的核心技术是通过估计GroupNorm的参数来实现无缝生成。下面是Tiled VAE的具体流程:

    1. 将大图像分割成多个小块(tiles)。

    2. 在编码器(encoder)和解码器(decoder)中,每个小块会分别进行填充(padding),通常为11/32像素。

    3. 将原始的VAE前向传播过程被分解为一个任务队列和一个任务处理器。任务处理器开始处理每个小块。当需要GroupNorm时,任务处理器会暂停,存储当前的GroupNorm的均值和方差,并将数据发送到RAM(Random Access Memory,随机存取存储器),然后转向处理下一个小块。

    4. 在所有GroupNorm的均值和方差被汇总后,任务处理器会对每个小块应用GroupNorm并继续处理。同时使用Zigzag执行顺序(如从左到右,再从右到左)处理这些小块,可以减少数据在 RAM 和 VRAM 之间的传输次数。这种顺序避免了频繁切换数据块,从而提高了处理效率。

    在我们安装好Tiled Diffusion/VAE插件后,我们可以在WebUI界面看到如下的Tiled VAE参数配置框:

    图71 5.7 Tiled Diffusion/VAE插件

    我们点击启动Tiled VAE,其余参数可以保持不变。如果大家的显存实在太小,上述参数配置的情况下仍出现CUDA显存溢出的情况,可以再次调小“编码器分块大小”和“解码器分块大小”这两个参数。同时,如果我们设置的tile size尺寸太小,可能会导致生成图片的整体颜色变得灰暗且不清晰,这是可以开启“快速编码器颜色修复”功能进行修复。

    讲完了Tiled VAE的核心功能,接下来,我们再来解读Tiled Diffusion的核心功能。

    Tiled Diffusion能够在低显存(6GB及一下)情况下,对图像进行超分辨率重建、生成2k-8k分辨率的高质量高清大图以及图像子区域的编辑生成。

    我们要知道的是,Tiled Diffusion的底层思想来源于MultiDiffusion。一般来说,我们进行图像的Tiled处理时,会将输入的噪声图像划分成不同的区块,针对每一个区块分别进行特定的图像特征生成。但是这样处理会引入一个问题,那就是不同的区块之间会出现明显的边缘不连贯问题。针对这个问题,MultiDiffusion中提出将不同区块的不连续部分进行融合,然后再进行全局去噪过程,这样能保证最终生成图像的特征一致性与边缘平滑。

    图72 5.7 Tiled Diffusion/VAE插件

    下面是Tiled Diffusion的完整流程:

    1. 将Latent特征进行分块处理。

    2. Stable Diffusion预测每个分块图像的噪声,并进行去噪操作。

    3. 将去噪后的分块图像加在一起,同时每个像素的值会被除以它

    4. 将所有的分块图像拼接在一起,同时重叠的像素会取平均值或者使用融合后的噪声对整个图像进行一步去噪。

    5. 重复上述1-4步骤,直到所有采样时间步完成。

    接下来,我们详细讲解MultiDiffusion核心原理,作为进一步的深入浅出理解。

    MultiDiffusion是一个统一的生成框架,无需任何训练或微调。它通过一个最小二乘优化任务,将同一个Stable Diffusion模型在多个不同的图像空间和条件空间中生成的crop区域约束在一起,虽然最初各个crop区域生成的内容可能会不一致,不过不用担心,MultiDiffusion会通过全局去噪,不断融合各个crop区域,从而生成不同场景的高质量和连贯性的完整图像。同时MultiDiffusion方法在很大程度上依赖于Stable Diffusion的生成先验,最终生成结果的质量取决于Stable Diffusion提供的扩散路径。

    我们先来看一下Stable Diffusion模型的图像生成过程,它是MultiDiffusion方法的基础:

    Φ

    :

    I

    ×

    Y

    →

    I

    \\Phi: \\mathcal{I} \\times \\mathcal{Y} \\rightarrow \\mathcal{I}

    Φ:I×Y→I

    它的图像空间为

    I

    =

    R

    H

    ×

    W

    ×

    C

    \\mathcal{I} =\\mathbb{R}^{H \\times W \\times C}

    I=RH×W×C ,条件空间为

    Y

    \\mathcal{Y}

    Y ,其中去噪采样过程如下:

    I

    T

    ,

    I

    T

    −

    1

    ,

    …

    ,

    I

    0

     s.t. 

    I

    t

    −

    1

    =

    Φ

    (

    I

    t

    ∣

    y

    )

    I_{T}, I_{T-1}, \\ldots, I_{0} \\quad \\text { s.t. } \\quad I_{t-1}=\\Phi\\left(I_{t} \\mid y\\right)

    IT​,IT−1​,…,I0​ s.t. It−1​=Φ(It​∣y)

    这个过程展示了Stable Diffusion逐渐将高斯噪声

    I

    T

    I_T

    IT​ 去噪转化成干净图像

    I

    0

    I_0

    I0​ 。

    接下来我们再看一下MultiDiffusion通用生成框架的图像生成过程:

    Ψ

    :

    J

    ×

    Z

    →

    J

    \\Psi: \\mathcal{J} \\times \\mathcal{Z} \\rightarrow \\mathcal{J}

    Ψ:J×Z→J

    它的图像空间为

    J

    =

    R

    H

    ′

    ×

    W

    ′

    ×

    C

    \\mathcal{J}=\\mathbb{R}^{H^{\\prime} \\times W^{\\prime} \\times C}

    J=RH′×W′×C ,条件空间为

    Z

    \\mathcal{Z}

    Z 。从初始噪声开始,按图像切片序列生成一系列图像:

    J

    T

    ,

    J

    T

    −

    1

    ,

    …

    ,

    J

    0

     s.t. 

    J

    t

    −

    1

    =

    Ψ

    (

    J

    t

    ∣

    z

    )

    J_{T}, J_{T-1}, \\ldots, J_{0} \\quad \\text { s.t. } \\quad J_{t-1}=\\Psi\\left(J_{t} \\mid z\\right)

    JT​,JT−1​,…,J0​ s.t. Jt−1​=Ψ(Jt​∣z)

    下面我们开始建立MultiDiffusion和Stable Diffusion之间的关联。我们定义一组目标图像空间和参考图像空间之间的区域映射

    F

    i

    :

    J

    →

    I

    F_{i}: \\mathcal{J} \\rightarrow \\mathcal{I}

    Fi​:J→I ,以及一组相应的条件空间之间的映射

    λ

    i

    :

    Z

    →

    Y

    \\lambda_{i}: \\mathcal{Z} \\rightarrow \\mathcal{Y}

    λi​:Z→Y ,其中

    i

    ∈

    [

    n

    ]

    =

    {

    1

    ,

    …

    ,

    n

    }

    i \\in[n]=\\{1, \\ldots, n\\}

    i∈[n]={1,…,n} 。其中映射关系可表示为:

    I

    t

    i

    =

    F

    i

    (

    J

    t

    )

    ,

    y

    i

    =

    λ

    i

    (

    z

    )

    ,

    i

    ∈

    [

    n

    ]

    =

    {

    1

    ,

    …

    ,

    n

    }

    I_{t}^{i}=F_{i}\\left(J_{t}\\right),\\quad y_{i}=\\lambda_{i}(z), i \\in[n]=\\{1, \\ldots, n\\}

    Iti​=Fi​(Jt​),yi​=λi​(z),i∈[n]={1,…,n}

    我们的目标是使每个MultiDiffusion采样

    J

    t

    J_t

    Jt​ , 对于所有

    i

    ∈

    {

    1

    ,

    …

    ,

    n

    }

    i \\in\\{1, \\ldots, n\\}

    i∈{1,…,n} ,尽可能使得

    F

    i

    (

    J

    t

    )

    F_i(J_t)

    Fi​(Jt​) 接近常规Stable Diffusion的采样

    Φ

    (

    I

    t

    i

    ∣

    y

    i

    )

    \\Phi\\left(I_{t}^{i} \\mid y_{i}\\right)

    Φ(Iti​∣yi​),我们可以采用下面的优化过程达到目标:

    Ψ

    (

    J

    t

    ∣

    z

    )

    =

    arg

    ⁡

    min

    ⁡

    J

    ∈

    J

    L

    F

    T

    D

    (

    J

    ∣

    J

    t

    ,

    z

    )

    \\Psi\\left(J_{t} \\mid z\\right)=\\underset{J \\in \\mathcal{J}}{\\arg \\min } \\mathcal{L}_{\\mathrm{FTD}}\\left(J \\mid J_{t}, z\\right)

    Ψ(Jt​∣z)=J∈Jargmin​LFTD​(J∣Jt​,z)

    L

    F

    T

    D

    (

    J

    ∣

    J

    t

    ,

    z

    )

    =

    ∑

    i

    =

    1

    n

    ∥

    W

    i

    ⊗

    [

    F

    i

    (

    J

    )

    −

    Φ

    (

    I

    t

    i

    ∣

    y

    i

    )

    ]

    ∥

    2

    \\mathcal{L}_{\\mathrm{FTD}}\\left(J \\mid J_{t}, z\\right)=\\sum_{i=1}^{n}\\left\\|W_{i} \\otimes\\left[F_{i}(J)-\\Phi\\left(I_{t}^{i} \\mid y_{i}\\right)\\right]\\right\\|^{2}

    LFTD​(J∣Jt​,z)=i=1∑n​

    ​Wi​⊗[Fi​(J)−Φ(Iti​∣yi​)]

    ​2

    其中,

    W

    i

    ∈

    R

    +

    H

    ×

    W

    W_{i} \\in \\mathbb{R}_{+}^{H \\times W}

    Wi​∈R+H×W​ 是per-pixel权重,

    ⊗

    \\otimes

    ⊗ 是Hadamard乘积。

    如下图所示,MultiDiffusion生成过程是从噪声图像

    J

    T

    J_T

    JT​ 开始,在每个采样步骤中,通过一个优化任务,使得目标图像

    J

    t

    J_t

    Jt​ 的每个crop

    F

    i

    (

    J

    t

    )

    F_i(J_t)

    Fi​(Jt​) 将尽可能接近参考图像去噪采样

    Φ

    (

    F

    i

    (

    J

    t

    )

    )

    \\Phi\\left(F_{i}\\left(J_{t}\\right)\\right)

    Φ(Fi​(Jt​)) 。虽然各个采样

    Φ

    (

    F

    i

    (

    J

    t

    )

    )

    \\Phi\\left(F_{i}\\left(J_{t}\\right)\\right)

    Φ(Fi​(Jt​)) 可能会将图像拉向不同的方向,但MultiDiffusion会将这些不一致的方向融合到全局去噪

    Ψ

    (

    J

    t

    )

    \\Psi(J_t)

    Ψ(Jt​) 中,从而产生高质量的连贯图像。

    图73 5.7 Tiled Diffusion/VAE插件

    由于

    F

    i

    F_{i}

    Fi​是直接从目标图像

    J

    t

    J_{t}

    Jt​ 中进行crop的过程。在这种情况下

    L

    F

    T

    D

    (

    J

    ∣

    J

    t

    ,

    z

    )

    \\mathcal{L}_{\\mathrm{FTD}}\\left(J \\mid J_{t}, z\\right)

    LFTD​(J∣Jt​,z) 的优化问题可以通过二次最小二乘 (LS)分析法解决,

    J

    J

    J 的最优解的每个像素是Reference Model所有扩散采样的加权平均:

    Ψ

    (

    J

    t

    ∣

    z

    )

    =

    ∑

    i

    =

    1

    n

    F

    i

    −

    1

    (

    W

    i

    )

    ∑

    j

    =

    1

    n

    F

    j

    −

    1

    (

    W

    j

    )

    ⊗

    F

    i

    −

    1

    (

    Φ

    (

    I

    t

    i

    ∣

    y

    i

    )

    )

    \\Psi\\left(J_{t} \\mid z\\right)=\\sum_{i=1}^{n} \\frac{F_{i}^{-1}\\left(W_{i}\\right)}{\\sum_{j=1}^{n} F_{j}^{-1}\\left(W_{j}\\right)} \\otimes F_{i}^{-1}\\left(\\Phi\\left(I_{t}^{i} \\mid y_{i}\\right)\\right)

    Ψ(Jt​∣z)=i=1∑n​∑j=1n​Fj−1​(Wj​)Fi−1​(Wi​)​⊗Fi−1​(Φ(Iti​∣yi​))

    下面是MultiDiffusion的核心代码,其提取图像各区块,并进行去噪采样的过程就生动的展现出来了:

    with torch.autocast('cuda'):
    for i, t in enumerate(self.scheduler.timesteps):
    count.zero_()
    value.zero_()

    for h_start, h_end, w_start, w_end in views:
    # TODO we can support batches, and pass multiple views at once to the unet
    latent_view = latent[:, :, h_start:h_end, w_start:w_end]

    # expand the latents if we are doing classifier-free guidance to avoid doing two forward passes.
    latent_model_input = torch.cat([latent_view] * 2)

    # predict the noise residual
    noise_pred = self.unet(latent_model_input, t, encoder_hidden_states=text_embeds)['sample']

    # perform guidance
    noise_pred_uncond, noise_pred_cond = noise_pred.chunk(2)
    noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_cond – noise_pred_uncond)

    # compute the denoising step with the reference model
    latents_view_denoised = self.scheduler.step(noise_pred, t, latent_view)['prev_sample']
    value[:, :, h_start:h_end, w_start:w_end] += latents_view_denoised
    count[:, :, h_start:h_end, w_start:w_end] += 1

    # take the MultiDiffusion step
    latent = torch.where(count > 0, value / count, value)

    接下来,我们再看看如何以MultiDiffusion为核心,进行高分辨率图像的生成和图像子区域编辑(Region-based)生成。

    首先我们使用MultiDiffusion进行高分辨率图像的生成。对于高分辨率图像生成任务,此时MultiDiffusion对应的空间尺寸大于Stable Diffusion输出域的空间尺寸

    (

    H

    ′

    ≥

    H

    ,

    W

    ′

    ≥

    W

    )

    (H^{\\prime} \\geq H, W^{\\prime} \\geq W)

    (H′≥H,W′≥W)。

    F

    i

    (

    J

    )

    F_{i}(J)

    Fi​(J) 是高分辨率图像

    J

    J

    J 中一个尺寸为

    H

    ×

    W

    H \\times W

    H×W 的crop区域(属于Stable Diffusion空间域),通过预定义滑动窗口的方式获取覆盖高分辨率图像

    J

    J

    J 的 n 个这样的crop区域,设置权重

    W

    i

    =

    1

    W_i=1

    Wi​=1 ,文本提示

    y

    i

    =

    λ

    i

    (

    z

    )

    y_{i}=\\lambda_{i}(z)

    yi​=λi​(z),MultiDiffusion采样过程

    Ψ

    \\Psi

    Ψ 定义为:

    Ψ

    (

    J

    t

    ,

    z

    )

    =

    arg

    ⁡

    min

    ⁡

    J

    ∈

    J

    ∑

    i

    =

    1

    n

    ∥

    F

    i

    (

    J

    )

    −

    Φ

    (

    F

    i

    (

    J

    )

    ,

    y

    i

    )

    ∥

    2

    \\Psi\\left(J_{t}, z\\right)=\\underset{J \\in \\mathcal{J}}{\\arg \\min } \\sum_{i=1}^{n}\\left\\|F_{i}(J)-\\Phi\\left(F_{i}(J), y_{i}\\right)\\right\\|^{2}

    Ψ(Jt​,z)=J∈Jargmin​i=1∑n​∥Fi​(J)−Φ(Fi​(J),yi​)∥2

    上述公式同样是一个最小二乘问题,我们可以根据分析法计算它的最优解。

    总的来说,MultiDiffusion融合了Stable Diffusion提供的多条扩散采样路径。如下图所示,

    H

    ×

    4

    W

    H\\times4W

    H×4W的高分辨率图像是我们想要生成的,下图(a) 展示了在四种非重叠crop区域上独立使用Stable Diffusion时的生成结果。正如我们之前分析的那样,生成的crop区域之间没有一致性,相当Stable Diffusion生成四个随机样本进行拼凑。下图(b)展示了超参数相同的情况下,MultiDiffusion生成过程可以融合这些最初不相关的扩散采样路径,最终生成连贯的高分辨率图像。

    图74 MultiDiffusion生成高分辨率图像的效果

    MultiDiffusion生成高分辨率图像的效果

    最后我们再学习一下图像子区域编辑(Region-based)生成功能。

    在基于Region-based的图像子区域编辑生成任务中,我们给定一组区域掩码

    {

    M

    i

    }

    i

    =

    1

    n

    ⊂

    {

    0

    ,

    1

    }

    H

    ×

    W

    \\left\\{M_{i}\\right\\}_{i=1}^{n} \\subset\\{0,1\\}^{H \\times W}

    {Mi​}i=1n​⊂{0,1}H×W 和一组对应的文本提示词

    {

    y

    i

    }

    i

    =

    1

    n

    ⊂

    Y

    n

    \\left\\{y_{i}\\right\\}_{i=1}^{n} \\subset \\mathcal{Y}^{n}

    {yi​}i=1n​⊂Yn ,我们的目标是生成图像

    I

    ∈

    I

    I \\in \\mathcal{I}

    I∈I ,在每个区域中包含文本提示词所对应的内容,也就是说图像

    I

    ⊗

    M

    i

    I \\otimes M_{i}

    I⊗Mi​ 应该体现文本提示词

    y

    i

    y_i

    yi​ 。我们设置区域映射

    F

    i

    (

    I

    )

    =

    I

    F_{i}(I)=I

    Fi​(I)=I ,权重

    W

    i

    =

    M

    i

    W_{i}=M_{i}

    Wi​=Mi​ ,那么MultiDiffusion采样过程

    Ψ

    \\Psi

    Ψ 定义为:

    Ψ

    (

    J

    t

    ,

    z

    )

    =

    arg

    ⁡

    min

    ⁡

    J

    ∈

    I

    ∑

    i

    =

    1

    n

    ∥

    M

    i

    ⊗

    [

    J

    −

    Φ

    (

    J

    t

    ∣

    y

    i

    )

    ]

    ∥

    \\Psi\\left(J_{t}, z\\right)=\\underset{J \\in \\mathcal{I}}{\\arg \\min } \\sum_{i=1}^{n}\\left\\|M_{i} \\otimes\\left[J-\\Phi\\left(J_{t} \\mid y_{i}\\right)\\right]\\right\\|

    Ψ(Jt​,z)=J∈Iargmin​i=1∑n​∥Mi​⊗[J−Φ(Jt​∣yi​)]∥

    这也是一个最小二乘问题,我们可以根据分析法计算它的最优解。

    在MultiDiffusion的每一步中,

    J

    t

    J_t

    Jt​ 的每个像素都是由包含它的所有区域

    M

    i

    M_i

    Mi​ 的加权融合而来。这样我们仅需给出Bounding Box约束,MultiDiffusion就可以生成符合文本提示词描述的各种高质量图像。

    同时MultiDiffusion可以进一步支持从紧密的mask获得高保真图像。考虑到结构布局是在扩散过程的早期就确定的,因此我们应该尽量使得

    Φ

    (

    J

    t

    ∣

    y

    i

    )

    \\Phi\\left(J_{t} \\mid y_{i}\\right)

    Φ(Jt​∣yi​) 在生成过程的早期就关注区域

    M

    i

    M_i

    Mi​ 以匹配所需的布局,然后再考虑图像全局连贯性。基于此,区域映射

    F

    i

    F_i

    Fi​ 可以定义为:

    F

    i

    (

    J

    t

    ,

    t

    )

    =

    {

    J

    t

    ,

     if 

    t

    ≤

    T

    init 

    M

    i

    ⊗

    J

    t

    +

    (

    1

    −

    M

    i

    )

    ⊗

    S

    t

    ,

     if 

    T

    i

    n

    t

    <

    t

    ≤

    T

    F_{i}\\left(J_{t}, t\\right)=\\left\\{\\begin{array}{ll} J_{t}, & \\text { if } t \\leq T_{\\text {init }} \\\\ M_{i} \\otimes J_{t}+\\left(1-M_{i}\\right) \\otimes S_{t}, & \\text { if } T_{i n t}<t \\leq T \\end{array}\\right.

    Fi​(Jt​,t)={Jt​,Mi​⊗Jt​+(1−Mi​)⊗St​,​ if t≤Tinit ​ if Tint​<t≤T​

    其中

    S

    t

    S_t

    St​ 作为背景,是具有预设颜色的随机图像。

    T

    i

    n

    t

    T_{int}

    Tint​ 设置为生成过程的 20%(即

    T

    i

    n

    t

    =

    800

    T_{int} = 800

    Tint​=800 )。

    图75 5.7 Tiled Diffusion/VAE插件

    讲完详细的原理,我们在WebUI中对图像子区域进行编辑生成的实践。我们首先需要创建一个文生图画布,然后接着在这个画布中启动我们的编辑区域,我们可以选择多个编辑区域,每个编辑区域我们都可以拖动鼠标进行移动和调整区域大小。

    图76 5.7 Tiled Diffusion/VAE插件

    一般来说,我们先设定一个全局的编辑区域,用于生成我们想要的背景内容。然后接着我们再创建几个局部编辑区域,用于生成我们想要的前景内容(任务、建筑、产品等)。具体如下图所示:

    图77 5.7 Tiled Diffusion/VAE插件

    Tiled Diffusion还可以帮助Dtable Diffusion模型在有限的显存中生成超大分辨率(2k~8k)的图像,并且无需任何后处理即可生成无缝输出。但是与之相对应的,生成速度显著慢于常规的生成方法。

    图78 5.7 Tiled Diffusion/VAE插件

    在参数选择上,我们可以直接参考下图所示的参数配置:

    图79 5.7 Tiled Diffusion/VAE插件

    总的来说,Tiled Diffusion功能本质上是对图像的局部Tile区块和整体图像区块的重绘过程。

    Tiled Diffusion还可以对图像进行超分辨率重建和超分辨率重绘。这是我们需要选择一个超分模型,先将图像进行超分辨率重建,然后再按照上述讲到的Tiled Diffusion处理流程,对超分后的图像进行切片重绘和融合。

    图80 5.7 Tiled Diffusion/VAE插件

    Tiled VAE/Tiled Diffusion虽然能大幅节省超大图推理生成的资源,但也存在一些工程取舍:

  • 显存下降,但时间会上升。 大图被拆成多个tile后,每个tile显存更低,但需要多次前向推理,整体耗时通常更长。
  • 重叠越大,一致性越好,但计算越重。 overlap太小容易接缝明显;overlap太大又会增加重复计算。
  • 局部一致不等于全局语义一定正确。 Tiled Diffusion能缓解边界不连续,但如果全局构图本身没有被prompt、ControlNet或低分辨率初稿约束好,大图仍然可能出现主体重复、空间关系漂移或局部语义不一致。
  • 5.8 SuperMerge插件

    在WebUI中,SuperMerger插件是用于AI绘画模型合并和优化的一个功能强大且灵活的工具。它可以对多个不同的深度学习模型进行权重合并,并根据指定的参数生成一个新的合成模型。其核心作用是帮助我们优化AI绘画模型性能,或利用不同模型的优势生成更加多样化的模型。

    SuperMerger可以将两个或多个模型的权重按照指定的比例合并。例如,我们可以通过 50% 的权重来自模型 A,另外 50% 的权重来自模型 B,生成一个新的模型。这个过程允许用户结合多个模型的优势,生成一个在特定任务上表现更好的模型。

    SuperMerger可以通过模型合并生成一个新的模型,并将其保存为一个独立的模型文件。这意味着用户不需要从头开始训练新模型,而是可以通过现有模型的组合和调整生成新的变种模型。这个功能对AI绘画研究和应用开发非常重要,因为它大大降低了训练成本,尤其是当训练一个大规模模型需要大量资源时,SuperMerger 提供了一种快速优化的方案。

    SuperMerger 插件为 WebUI 提供了一个强大的模型合并和优化工具,允许我们结合不同AI绘画模型的优点,以低成本的方式生成高效、灵活的新AI绘画模型。它通过提供直观的操作界面,简化了复杂的模型合并任务,使研究者和开发者能够更快速地迭代和探索新模型,极大提高了工作效率。

    在具体功能上,我们可以使用SuperMerger融合出全新的SD系列模型和LoRA系列模型:

  • SD模型 + SD模型 -> 新SD模型
  • SD模型 + LoRA模型 -> 新SD模型
  • LoRA模型 + LoRA模型 -> 新LoRA模型
  • SD模型 – SD模型 -> 新SD模型
  • 那么在我们进行AI绘画大模型融合时,该如何设置模型权重配比呢?Don’t worry,Rocky也持续整理归纳了一些AI绘画大模型融合的权重配比参数,希望能给大家带来帮助:

    融合LoRA模型时,LoRA的权重设置经验:

    1. 影响除脸之外的部分(保持不变脸情况下改变其他部分)
    (强)1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1
    (弱)1,1,1,1,1,1,0.2,1,0.2,0,0,0.8,1,1,1,1,1

    2. 影响脸部(脸型、发型、眼型、瞳色等)
    (强)1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
    (弱)1,0,0,0,0,0,0,0,0.8,1,1,0.2,0,0,0,0,0
    (微弱)1,0,0,0,0,0,0,0,0.2,0.6,0.8,0.2,0,0,0,0,0

    3. 影响手部
    1,0,1,1,0.2,0,0,0,0,0,0,0,0,0,0,0,0

    4. 影响服装(搭配tag使用)
    1,1,1,1,1,0,0.2,0,0.8,1,1,0.2,0,0,0,0,0

    5. 影响动作(搭配tag使用)
    1,0,0,0,0,0,0.2,1,1,1,0,0,0,0,0,0,0

    6. 影响上色风格(搭配tag使用)
    1,0,0,0,0,0,0,0,0,0,0,0.8,1,1,1,1,1

    7. 角色(去风格化)
    1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0

    8. 背景(去风格化)
    1,1,1,1,1,1,0.2,1,0.2,0,0,0.8,1,1,1,0,0

    9. 减弱过拟合(等同于OUTALL)
    1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1

    Rocky也会持续更新补充,码字不易,希望大家能够多多点赞!!!

    6. 其他主流AIGC创作框架介绍

    前面我们已经把 ComfyUI、Diffusers 和 Stable Diffusion WebUI 的核心核心基础知识进行了深入浅出讲解。到这里,大家可能会有一个疑问:这些工具已经能完成文生图、图生图、局部重绘、条件控制,为什么还会出现 Fooocus、SD.Next、InvokeAI 等一批创作工具?

    我们把实际需求放进去,就容易理解了。有人想用十分钟给一篇文章找封面方向;有人要比较几个不同架构的模型;有人已经画好了人物,只想改一下衣服;也有人需要把复杂工作流交给运营同学每天使用。它们都叫“AI 绘画”,但需要操心的事情很不一样。

    创作框架的一项核心价值,是把模型能力组织成适合具体任务的操作过程。 模型负责提供生成能力,软件决定我们怎样表达意图、怎样约束生成、怎样修改结果,以及怎样把一次成功保留下来。接下来我们就看看其他主流AIGC创作框架的核心基础知识与特点。

    图81 6. 其他主流AIGC创作框架介绍

    6.1 Fooocus核心基础知识讲解

    端脑云平台也集成了AI 绘画工具 Fooocus,Fooocus 是对 stable diffusion 和Midjourney设计的重新思考:一方面保留了 SD 的开源属性,可以部署到本地免费使用;另一方面在操作界面上向 midjourney 学习,省去了 WebUI 中复杂的参数调节,让用户可以专注于提示和图像。可以和 Stable diffusion WebUI 一样部署到本地免费使用,同时具备 midjourney 一样便捷的操作界面。

    我们只需要按照上面的创建新应用的流程,创建一个Fooocus的应用即可使用Fooocus绘画框架!

    图82 6.1 Fooocus核心基础知识讲解

    如上图所示我们在端脑云平台左侧点击“我的应用”后,就能看到正在运行中的Fooocus应用,点击进入应用之后,可以看到Fooocus绘画框架的操作界面非常简洁。整个界面中只有生成图像展示窗口、正向提示词和生成按钮 3 项。同时勾选“Advanced”会弹出高级设置的窗口,可以调整画面宽高比、风格、图像数量、种子值、反向提示词、模型、lora 权重比值、图像锐利程度等。勾选“Input Image”可以上传图片进行超分,作为底图,进行重绘或者AI扩图。

    图83 6.1 Fooocus核心基础知识讲解

    我们在Prompt框中输入如下Prompt:1girl, solo, black_hair, hair_ornament, jewelry, closed_mouth, upper_body, flower, earrings, hair_flower, mole, lips, grey_eyes, eyelashes, makeup, facial_mark, lipstick, red_flower, mole_under_mouth, red_lips。

    然后点击Generate按钮,即可生成图片:

    图84 6.1 Fooocus核心基础知识讲解

    当我们点击“Input Image”后,就会出现如下的信息栏:

    图85 6.1 Fooocus核心基础知识讲解

    在Upscale or Variation栏中,我们可以上传图片,进行图像超分或者变换任务。在Image Prompt栏中,我们上传图片用作图像提示词,给我们的图像生成过程附加参考图。而Inpaint or Outpaint栏中,我们可以对上传的图片进行重绘和扩图。

    接下来我们再看看“Advanced”按钮的功能,我们点击“Advanced”按钮,可以看到右侧出现了高级设置的窗口:

    图86 6.1 Fooocus核心基础知识讲解

    在高级设置的窗口的Setting栏中,我们可以设置生成图片的Performance,图片尺寸,图片数量,负向提示词等配置。

    在Style栏中,端脑云平台中已经集成了100多个图像的生成风格,包括写实、胶片、电影质感、动漫、水彩、黏土、3D、等距、像素、霓虹、赛博朋克、波普、纸艺等各个方面,我们可以方便的选择我们想要的风格,生成相应的图像。

    在Model栏中,我们可以选择SD系列模型,端脑云平台中已经给出了非常多的高质量SD模型供我们选择,也有很多LoRA模型可以进行搭配。

    在最后一个Advanced栏中,我们可以调整图像生成过程中的Guidance Scale值和Image Sharpness值。

    6.2 SD.Next核心基础知识讲解

    可能会有读者疑惑,SD.Next 和 Stable Diffusion WebUI 是什么关系?

    SD.Next 的代码基础来自 AUTOMATIC1111 Stable Diffusion WebUI,随后发展出了自己的模型适配、资源管理、界面和工作流。熟悉 WebUI 的用户能够认出提示词、采样、LoRA、控制图等概念,但不要预设它和 A1111 的插件、内部接口完全一致。

    它适合这样一类需求:我们希望在一个可视化工作台里使用多个模型家族,配置自己的硬件,并完成生成、编辑、放大、图像处理等常用任务。它把不少需要分别安装、分别配置的能力放进统一入口,同时保留较多工程设置。

    图87 6.2 SD.Next核心基础知识讲解

    在同一个 SDXL 家族里切换两个微调模型,和从 SDXL 切换到 FLUX、SD3.5 或 Qwen-Image,工程复杂度不一样。后者可能涉及不同的文本编码器、去噪网络、潜空间约定、调度方式以及附加条件接口。要让它们正确运行,需要加载相应组件并构造匹配的推理管线。

    SD.Next 广泛使用 Diffusers 等底层组件来组织模型管线,同时在应用层处理模型加载、参数映射、任务入口和资源配置。大家可以把它和前面的 Diffusers 章节联系起来:Pipeline 负责将组件按具体模型的推理规则组织起来,创作应用再把这些规则转换成可以操作的界面。

    官方模型支持页列出了 SD 1.x/2.x、SDXL、SD3/3.5、FLUX.1/2、Qwen-Image、Z-Image 等多个家族。这里没必要背完整名单,但一定要理解“支持”的层次:

  • 能加载并完成基础生成。 权重、编码器、VAE 和运行环境要匹配。
  • 能完成我们需要的任务。 文生图可用,不自动意味着该模型的图生图、局部重绘和参考图引导都可用。
  • 能和附加组件一起工作。 LoRA、ControlNet、IP-Adapter、量化方式之间也有适配关系。
  • 例如,一套 SDXL ControlNet 不能直接当作 FLUX 的控制模型使用;一个基础生成模型能输出图片,也不意味着它具备专门编辑模型的指令编辑能力。多模型界面帮助我们管理这些差异,底层差异仍然存在。

    6.3 Stable Diffusion WebUI Forge核心基础知识讲解

    如果大家已经熟悉 A1111 WebUI,有稳定的提示词、模型和工作习惯,又希望改善资源管理,Forge 是值得了解的一条路线。

    Forge 以 Stable Diffusion WebUI 为基础,重点包括资源管理、推理执行和实验功能的集成。它保留了许多熟悉的操作概念,并在官方主线中提供 FLUX 等模型的使用说明。

    它的工程价值可以从显存理解。一次生成并不要求所有组件在全程都以相同方式驻留:文本编码、去噪、解码发生在不同阶段,某些权重和中间数据可以按需安排。Forge 围绕模型加载、显存使用与卸载等环节进行了优化,帮助部分原本资源紧张的任务运行起来。

    不过,改善显存管理不等于对所有设备、所有任务都获得同样加速。 显存够用时,减少传输可能更重要;显存紧张时,允许组件转移到内存可能更重要。换模型、换分辨率、叠加控制模块,都可能改变结果。评估时要固定同一任务,同时看速度、峰值显存和画质。

    原来使用 A1111 的同学,建议先在独立目录中安装 Forge,使用一套熟悉的模型与参数跑基础任务,再逐个验证扩展。兼容的模型权重可以复用,但扩展可能依赖特定版本的 Gradio、内部接口或推理实现,官方也提供了扩展与替代方案的讨论入口。[8]

    还需要注意仓库身份。围绕 Forge 有不同维护者的分支与衍生项目,网上某篇教程演示的新功能,可能属于其中一个分支。选型时把“仓库地址、分支、提交或发行版本”一起记下来,后面遇到问题才知道应该查哪份文档。

    对于“已经会 WebUI,想在熟悉的操作方式下继续工作”的需求,Forge 的学习成本相对容易控制;如果任务已经需要大量自定义分支与数据流,就应同时比较 ComfyUI 或直接编程实现的维护成本。

    6.4 SwarmUI核心基础知识讲解

    ComfyUI 很适合组织复杂流程,但一个节点图有几十个节点时,让每个使用者都理解整张图,并不总是合算。工程同学需要调试数据流,运营同学可能只需要上传商品图、选比例、输入场景描述。

    SwarmUI 原名 StableSwarmUI,采用模块化的 Web 界面设计。它提供面向日常使用的 Generate 页面,也提供进入 ComfyUI 工作流的入口,可以利用 ComfyUI 后端的能力。

    图88 SwarmUI 官方界面

    SwarmUI 官方界面

    可以用一个商品背景生成任务来理解这种分工。工程同学先验证参考图、遮罩、条件控制、采样与输出处理,确定哪些参数允许调整;使用者通过前端填写这些参数,发起任务,再查看输出。符合 SwarmUI 接入约定的自定义工作流,可以进一步把需要使用者提供的输入暴露出来。

    这样的设计让工作流的开发和日常执行能够分开。需要排查时,我们仍然可以回到节点图;流程稳定后,日常使用就不必重复寻找某个节点上的输入框。

    SwarmUI 还具有多后端和多 GPU 相关能力。理解这类功能时,要区分把多个任务分给多个后端执行,与把一个模型拆到多张 GPU 上运行。前者主要改善队列吞吐,后者涉及模型并行与通信,不能因为支持多个后端就推导出单张图一定更快。

    上手时可以先安装 SwarmUI,配置一个 ComfyUI 后端,在 Generate 页面完成基础生成,再进入 Comfy Workflow 理解工作流连接。已有 ComfyUI 环境可以按官方说明接入,但自定义节点、模型路径和节点版本仍需要对齐。

    对小团队而言,SwarmUI 值得借鉴的是这种分工:把反复使用的复杂流程整理成少量明确输入。后续需要补齐的内容,则包括任务记录、失败处理、版本固定和实际部署要求。一个方便的前端能够减少操作成本,团队交付仍需要完整的运行管理。

    6.5 InvokeAI核心基础知识讲解

    很多生成演示停在“出了一张好看的图”。设计工作通常还要继续:人物留下,背景换掉;衣服颜色调整一下;画面向右扩展,为文案留位置;前一版的光线更好,想找回来。

    InvokeAI 围绕这类连续创作提供了 Canvas、Workflows 和素材管理。它有本地应用形态,也存在商业产品与服务形态,实际采用时要区分使用的发行方式。

    图89 InvokeAI 官方功能图

    InvokeAI 官方功能图

    Canvas 把生成过程放回画布上下文。 用户可以选定区域、提供草图、使用画笔、做局部重绘和扩图。比如给人物更换外套,先圈定衣服区域,保留脸部和大部分背景,再生成新的服装方案。模型仍可能在边界处改变细节,但我们能够更明确地限定修改范围。

    Workflows 把重复步骤组织起来。 当一套处理反复出现,例如参考图输入、条件控制、生成、细化、输出,就可以用节点与工作流表达。InvokeAI 有自己的节点体系,不能默认 ComfyUI 的工作流文件拖进去就可以运行。即便两边都采用节点界面,节点定义、执行格式和依赖也可能不同。

    Board 与 Gallery 管理积累下来的素材。 保存图片、整理候选方案、读取生成元数据、把已有图片重新作为输入,这些看似普通的功能,在几十轮改稿中非常实用。它们让我们找得到前面的选择,也更容易沿着一个方向继续迭代。

    初次上手可以从官方 Launcher 安装,然后导入一个受支持模型,在 Canvas 中完成“生成底图—局部修改—扩展画面”的小任务。等这条链路跑顺,再学习工作流编辑,理解起来会具体得多。

    InvokeAI 适合插画、概念设计、产品视觉等反复修改的场景。需要留意的是,画布里的某种控制能力仍然取决于所选模型;应用支持多个模型,不代表每个模型都拥有完全相同的编辑功能。

    7. 推荐阅读

    Rocky会持续分享AIGC的干货文章、实用教程、商业应用/变现案例以及对AIGC行业的深度思考与分析,欢迎大家多多点赞、喜欢、收藏和转发,给Rocky的义务劳动多一些动力吧,谢谢各位!

    7.1 深入浅出完整解析AI Agent(AI智能体)的核心基础知识

    2025年可以说是AI Agent全面落地应用的元年,因此Rocky在持续撰写对AI Agent的全维度解析文章:

    深入浅出完整解析AI Agent(AI智能体)的核心基础知识

    7.2 深入浅出完整解析扩散模型DDPM、DDIM、Score-Based、SDE、LDM、Classifier/Classifier-Free Guidance、Rectified Flow核心基础知识

    Rocky对扩散模型的本质原理与和核心基础知识进行了全面系统的深入浅出分析讲解,同时不断跟进补充扩散模型的最新技术发展,希望能给大家带来帮助:

    深入浅出完整解析扩散模型DDPM、DDIM、Score-Based、SDE、LDM、Classifier/Classifier-Free Guidance、Rectified Flow核心基础知识

    7.3 深入浅出完整解析FLUX.2、Seedream(即梦)、Z-image、GLM-Image核心基础知识

    Rocky对AIGC时代“中场时刻”之后的主流AIGC创作大模型的核心基础知识进行了全面系统的深入浅出分析讲解,力求让大家通俗易懂理解AIGC时代的技术浪潮的本质价值:

    深入浅出完整解析FLUX.2、Seedream(即梦)、Z-image、Qwen-Image、GLM-Image核心基础知识

    7.4 深入浅出完整解析FLUX.1 Kontext和FLUX.1 Krea核心基础知识

    Rocky对FLUX.1 Kontext和FLUX.1 Krea的核心基础知识作了全面系统的梳理与解析:

    深入浅出完整解析FLUX.1 Kontext和FLUX.1 Krea核心基础知识

    7.5 深入浅出完整解析DeepSeek系列核心基础知识

    Rocky对DeepSeek系列模型的核心基础知识作了全面系统的梳理与解析:

    深入浅出完整解析DeepSeek系列核心基础知识

    7.6 深入浅出完整解析Stable Diffusion 3(SD 3)和FLUX.1系列核心基础知识

    Rocky也对Stable Diffusion 3和FLUX.1的核心基础知识作了全面系统的梳理与解析:

    深入浅出完整解析Stable Diffusion 3(SD 3)和FLUX.1系列核心基础知识

    7.7 深入浅出完整解析Stable Diffusion XL(SDXL)核心基础知识

    Rocky也对Stable Diffusion XL的核心基础知识作了全面系统的梳理与解析:

    深入浅出完整解析Stable Diffusion XL(SDXL)核心基础知识

    7.8 深入浅出完整解析Stable Diffusion(SD)核心基础知识

    Rocky也对Stable Diffusion 1.x-2.x系列模型的核心基础知识做了全面系统的梳理与解析:

    深入浅出完整解析Stable Diffusion(SD)核心基础知识

    7.9 深入浅出完整解析Stable Diffusion中U-Net的前世今生与核心知识

    Rocky对Stable Diffusion中最为关键的U-Net结构进行了深入浅出的全面解析,包括其在传统深度学习中的价值和在AIGC中的价值:

    深入浅出完整解析Stable Diffusion中U-Net的前世今生与核心知识

    7.10 深入浅出完整解析LoRA(Low-Rank Adaptation)模型核心基础知识

    对于AIGC时代中的**“ResNet”——LoRA模型**,Rocky也进行了深入浅出的全面讲解:

    深入浅出完整解析LoRA(Low-Rank Adaptation)模型核心基础知识

    7.11 深入浅出完整解析ControlNet核心基础知识

    AI绘画作为AIGC时代的一个核心方向,开源社区已经形成以Stable Difffusion为核心,ConrtolNet和LoRA作为首要AI绘画辅助工具的变化万千的AI绘画工作流。

    ControlNet正是让AI绘画社区无比繁荣的关键一环,它让AI绘画生成过程更加的可控,更有助于广泛地将AI绘画应用到各行各业中:

    深入浅出完整解析ControlNet核心基础知识

    7.12 深入浅出完整解析Sora等AI视频大模型核心基础知识

    AI绘画和AI视频是两个互相促进、相互交融的领域,2024年无疑是AI视频领域的爆发之年,Rocky也对AI视频领域核心的Sora等大模型进行了全面系统的梳理与解析:

    深入浅出完整解析Sora、Wan2.1、AnimateDiff、CogVideoX等AI视频大模型核心基础知识

    7.13 深入浅出完整解析AIGC时代Transformer核心基础知识

    在AIGC时代中,Transformer为AI行业带来了深刻的变革。Transformer架构正在一步一步重构所有的AI技术方向,成为AI技术架构大一统与多模态整合的关键核心基座,大有一统“AI江湖”之势。Rocky也对Transformer模型进行持续的深入浅出梳理与解析:

    深入浅出完整解析AIGC时代Transformer核心基础知识

    7.14 手把手教你成为AIGC算法工程师,斩获AIGC算法offer!

    在AIGC时代中,如何快速转身,入局AIGC产业?如何成为AIGC算法工程师?如何在学校中系统性学习AIGC知识,斩获心仪的AIGC算法offer?

    Don‘t worry,Rocky为大家总结整理了全面的AIGC算法工程师成长秘籍,为大家答疑解惑,希望能给大家带来帮助:

    手把手教你成为AIGC/LLM/AI Agent算法/开发工程师,斩获AIGC/LLM/AI Agent算法/开发offer!

    7.15 AIGC产业的深度思考与分析

    2023年3月21日,微软创始人比尔·盖茨在其博客文章《The Age of AI has begun》中表示,自从1980年首次看到图形用户界面(graphical user interface)以来,以OpenAI为代表的科技公司发布的AIGC模型是他所见过的最具革命性的技术进步。

    Rocky也认为,AIGC及其生态,会成为AI行业重大变革的主导力量。AIGC会带来一个全新的红利期,未来随着AIGC的全面落地和深度商用,会深刻改变我们的工作、生活、学习以及交流方式,各行各业都将被重新定义,过程会非常有趣。

    那么,在此基础上,我们该如何更好的审视AIGC的未来?我们该如何更好地拥抱AIGC引领的革新?Rocky准备从技术、产品、商业模式、长期主义等维度持续分享一些个人的核心思考与观点,希望能帮助各位读者对AIGC有一个全面的了解:

    深入浅出全面解析AIGC时代核心价值与发展趋势(2025年版)

    7.16 算法工程师的独孤九剑秘籍

    为了方便大家实习、校招以及社招的面试准备,同时帮助大家提升扩展技术基本面,Rocky将符合大厂和AI独角兽价值的算法高频面试知识点撰写总结成**《三年面试五年模拟之独孤九剑秘籍》,并制作成pdf版本**,大家可在公众号WeThinkIn后台**【精华干货】菜单或者回复关键词“三年面试五年模拟”**进行取用:

    【三年面试五年模拟】AIGC时代的算法工程师的求职面试秘籍(持续更新中)

    7.17 深入浅出完整解析AIGC时代中GAN系列模型的前世今生与核心知识

    GAN网络作为传统深度学习时代的最热门生成式Al模型,在AIGC时代继续繁荣,作为Stable Diffusion系列模型的“得力助手”,广泛活跃于Al绘画的产品与工作流中:

    深入浅出完整解析AIGC时代中GAN(Generative Adversarial Network)系列模型核心基础知识

    推荐阅读

    1. 深入浅出完整解析AI Agent(AI智能体)的核心基础知识

    2025年可以说是AI Agent全面落地应用的元年,因此Rocky在持续撰写对AI Agent的全维度解析文章:

    深入浅出完整解析AI Agent(AI智能体)的核心基础知识

    2. 深入浅出完整解析扩散模型DDPM、DDIM、Score-Based、SDE、LDM、Classifier/Classifier-Free Guidance、Rectified Flow核心基础知识

    Rocky对扩散模型的本质原理与和核心基础知识进行了全面系统的深入浅出分析讲解,同时不断跟进补充扩散模型的最新技术发展,希望能给大家带来帮助:

    深入浅出完整解析扩散模型DDPM、DDIM、Score-Based、SDE、LDM、Classifier/Classifier-Free Guidance、Rectified Flow核心基础知识

    3. 入浅出完整解析FLUX.2、Seedream(即梦)、Z-image、GLM-Image核心基础知识

    Rocky对AIGC时代“中场时刻”之后的主流AIGC创作大模型的核心基础知识进行了全面系统的深入浅出分析讲解,力求让大家通俗易懂理解AIGC时代的技术浪潮的本质价值:

    入浅出完整解析FLUX.2、Seedream(即梦)、Z-image、GLM-Image核心基础知识

    4. 深入浅出完整解析FLUX.1 Kontext和FLUX.1 Krea核心基础知识

    Rocky对FLUX.1 Kontext和FLUX.1 Krea的核心基础知识作了全面系统的梳理与解析:

    深入浅出完整解析FLUX.1 Kontext和FLUX.1 Krea核心基础知识

    5. 深入浅出完整解析DeepSeek系列核心基础知识

    Rocky对DeepSeek系列模型的核心基础知识作了全面系统的梳理与解析:

    深入浅出完整解析DeepSeek系列核心基础知识

    6. 深入浅出完整解析Stable Diffusion 3(SD 3)和FLUX.1系列核心基础知识

    Rocky对Stable Diffusion 3和FLUX.1的核心基础知识作了全面系统的梳理与解析:

    深入浅出完整解析Stable Diffusion 3(SD 3)和FLUX.1系列核心基础知识

    7. 深入浅出完整解析Stable Diffusion XL(SDXL)核心基础知识

    Rocky对Stable Diffusion XL的核心基础知识作了全面系统的梳理与解析:

    深入浅出完整解析Stable Diffusion XL(SDXL)核心基础知识

    8. 深入浅出完整解析Stable Diffusion(SD)核心基础知识

    Rocky对Stable Diffusion 1.x-2.x系列模型的核心基础知识做了全面系统的梳理与解析:

    深入浅出完整解析Stable Diffusion(SD)核心基础知识

    9. 深入浅出完整解析Stable Diffusion中U-Net的前世今生与核心知识

    Rocky对Stable Diffusion中最为关键的U-Net结构进行了深入浅出的全面解析,包括其在传统深度学习中的价值和在AIGC中的价值:

    深入浅出完整解析Stable Diffusion中U-Net的前世今生与核心知识

    10. 深入浅出完整解析LoRA(Low-Rank Adaptation)模型核心基础知识

    对于AIGC时代中的“ResNet”——LoRA模型,Rocky进行了深入浅出的全面讲解:

    深入浅出完整解析LoRA(Low-Rank Adaptation)模型核心基础知识

    11. 深入浅出完整解析ControlNet核心基础知识

    AIGC图像创作开源社区已经形成以Stable Difffusion/FLUX为核心,ConrtolNet和LoRA作为首要AI辅助工具的变化万千的AIGC图像创作工作流。

    ControlNet正是让AI图像创作社区无比繁荣的关键一环,它让AIGC图像创作过程更加的可控,更有助于广泛地将AIGC算法解决方案应用到各行各业中:

    深入浅出完整解析ControlNet核心基础知识

    12. 深入浅出完整解析Sora、Seedance、keling等AI视频大模型核心基础知识

    AI绘画和AI视频是两个互相促进、相互交融的领域,2024年无疑是AI视频领域的爆发之年,Rocky对AI视频领域核心的Sora、Seedance、Keling等大模型进行了全面系统的梳理与解析:

    深入浅出完整解析Sora、Seedance、keling等AI视频大模型核心基础知识

    13. 深入浅出完整解析AIGC时代Transformer核心基础知识

    在AIGC时代中,Transformer为AI行业带来了深刻的变革。Transformer架构正在一步一步重构所有的AI技术方向,成为AI技术架构大一统与多模态整合的关键核心基座,大有一统“AI江湖”之势。Rocky也对Transformer模型进行持续的深入浅出梳理与解析:

    深入浅出完整解析AIGC时代Transformer核心基础知识

    14. 深入浅出完整解析ComfyUI、Diffusers、Stable Diffusion WebUI等主流AIGC创作框架核心基础知识

    AIGC创作框架正是AIGC算法工作流的运行载体,目前主流的AIGC创作框架有ComfyUI、Diffusers、Stable Diffusion WebUI等。在传统深度学习时代,PyTorch、TensorFlow以及Caffe是传统深度学习模型的基础运行框架,到了AIGC时代,Rocky相信ComfyUI就是AIGC时代的“PyTorch”、Stable Diffusion WebUI就是AIGC时代的“TensorFlow”、Diffusers就是AIGC时代的“Caffe”:

    深入浅出完整解析ComfyUI、Diffusers、Stable Diffusion WebUI等主流AIGC创作框架核心基础知识

    15. 深入浅出完整解析ComfyUI、Diffusers、Stable Diffusion WebUI等主流AIGC创作框架核心基础知识

    在AIGC时代中,如何快速转身,入局AIGC产业?如何成为AIGC/LLM/AI Agent算法/开发工程师?如何在学校中系统性学习AIGC/LLM/AI Agent知识,斩获心仪的AIGC/LLM/AI Agent算法/开发offer?

    Don‘t worry,Rocky为大家总结整理了全面的AIGC/LLM/AI Agent算法/开发工程师成长秘籍,为大家答疑解惑,希望能给大家带来帮助:

    手把手教你成为AIGC/LLM/AI Agent算法/开发工程师,斩获AIGC/LLM/AI Agent算法/开发offer!

    16. AIGC产业的深度思考与分析

    2023年3月21日,微软创始人比尔·盖茨在其博客文章《The Age of AI has begun》中表示,自从1980年首次看到图形用户界面(graphical user interface)以来,以OpenAI为代表的科技公司发布的AIGC模型是他所见过的最具革命性的技术进步。

    Rocky也认为,AIGC及其生态,会成为AI行业重大变革的主导力量。AIGC会带来一个全新的红利期,未来随着AIGC的全面落地和深度商用,会深刻改变我们的工作、生活、学习以及交流方式,各行各业都将被重新定义,过程会非常有趣。

    那么,在此基础上,我们该如何更好的审视AIGC的未来?我们该如何更好地拥抱AIGC引领的革新?Rocky准备从技术、产品、商业模式、长期主义等维度持续分享一些个人的核心思考与观点,希望能帮助各位读者对AIGC有一个全面的了解:

    深入浅出全面解析AIGC时代核心价值与发展趋势(2025年版)

    17. AI算法工程师的独孤九剑秘籍

    为了方便大家实习、校招以及社招的面试准备,同时帮助大家提升扩展技术基本面,Rocky将符合大厂和AI独角兽价值的算法高频面试知识点撰写总结成《三年面试五年模拟》之独孤九剑秘籍:

    【三年面试五年模拟】AIGC时代的算法工程师的求职面试秘籍(持续更新中)

    18. 深入浅出完整解析AIGC时代中GAN(Generative Adversarial Network)系列模型核心基础知识

    GAN系列模型作为传统深度学习时代的最热门生成式Al模型,在AIGC时代继续繁荣,作为Stable Diffusion/FLUX系列大模型的“得力助手”,广泛活跃于AlGC图像创作的产品与工作流中:

    深入浅出完整解析AIGC时代中GAN(Generative Adversarial Network)系列模型核心基础知识

    赞(0)
    未经允许不得转载:171主机测评 » 深入浅出完整解析ComfyUI、Diffusers、Stable Diffusion WebUI等主流AIGC创作框架核心基础知识
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址