标签归档:AIGC

AI 编程真的会让程序员失业!

2025 年 1 月 20 日上午 10:24 ,这个包含了 1024 的时间点,字节发布了其 AI 编程 IDE: Trae www.trae.ai/

ai_1.png

对标 Cursor,Windsurf 的国内出海的一个 IDE,当前可使用 Claude-3.5-Sonnet 和 GPT-4o 大语言模型

深入使用,花了三个小时,不写一行代码,实现了一个前端后端分离架构,包含登录/退出,数据库查询,跨域,以及首页功能的小管理后台,包括前端和后端的代码。前端所使用技术栈为 Vue,后端使用了 golang + beego。

这 3 个小时有一个耗时点是想让 AI 来解决跨域的问题,我们知道跨域主要是 Access-Control-Allow-Origin 等头信息的处理,把前后端的代码上下文都给了,反复试 OPTIONS 请求跨域总是不成功,后来发现是后台接口实现所修改的跨域文件没有加载导致的。

除了通用功能,实际业务开发中,花了 30 分钟实现了 Java 的流式输出,其场景是要实现 DeepSeek 的模型调用,以实现打字机的输出效果。 ai_2.png

这里 AI 给的 golang 的实现,但是当前我需要的是 Java 的,这里的问题是没有把需求讲清楚。同时也表示在开始对话时,需要把一些背景信息讲清楚能提高整体的效率。

ai_3.png

ai_5.png

经过了大概 10 轮对话,他大概就了解我真正想要的是什么了,再经过 6 轮对话补全,把过程中有问题的地方和相关代码圈出来给到 AI,很快就有结果,并解决了问题。

ai_6.png

1. 使用过程中的感受

  1. 表述清楚需求很重要,在最开始的时候一些背景重要的背景信息可以提前给出,如技术栈,表结构、想做的事情等等;
  2. 给到更多的上下文,更容易得到正确的答案,在 Trea 中使用 # 号引入,当前支持代码、文件、目录及工作区间;
  3. 从 AI 中来,到 AI 中去,可以跳出 AI 来解决问题,当 AI 限入解决问题的死循环,可以找 google 要一些答案喂给 AI,后续应该会自动支持这个功能;
  4. 出错的地方,选中后,直接让 AI 解决,甚至不需要多说一句话,当然,你也可以多说几句,更清晰的表述你想要的东西;
  5. 多模态的能力,在界面有问题的地方,截图说明给到 AI 就能解决;
  6. 先做框架,再逐个功能实现,当前阶段,AI 解决小范围的问题会更合适一些。

到这里,对于这种通用类的功能,AI 已经能发挥出很大的能力了,再进化一段时间,程序员的大部分编码工作真的就会被 AI 取代了。那是不是我们就失业了呢?从纯粹写代码的角度来说,是的,但是从整个项目的角度不一定。

2. 程序员的当前职责

和康总有聊到这块,当前我们程序员基本在解决的问题包括决策、连接和编码三部分。

  • 决策:技术选型、架构设计等高层次决策,AI 尚无法完全替代。
  • 连接:跨部门需求分析、团队沟通与资源协调。
  • 编码:过去程序员的核心工作,但 AI 的介入正在加速其主要功能的边缘化。

2.1 决策

项目开发的过程实际上是一个个的决策过程组成的,决策是咱们的核心职责之一,是一个项目从业务需求到技术实现的过程中,如何选择解决方案的过程。

我们需要在不确定性和多种选择中,基于经验、知识和实际需求,做出技术上的关键决定。这些决策往往会对团队的效率、产品的质量和未来的技术发展方向产生深远影响。

决策指的它涉及从业务层面到技术层面的全局性规划,包括但不限于:

  • 需求分析
    • 理解并提炼业务需求,制定核心目标和功能优先级。
    • 与产品经理、业务方的沟通,明确业务目标和用户需求。
  • 技术选型
    • 决定使用何种技术栈(前端框架、后端框架、数据库、云服务等)。
    • 评估不同技术的可行性、扩展性和成本。
  • 架构设计
    • 系统架构的顶层设计,比如单体架构 vs 微服务架构。
    • 数据库选择(SQL vs NoSQL)、缓存策略、性能优化方案。
  • 风险评估与管理
    • 评估技术方案的风险(如性能瓶颈、技术债务、团队技术栈能力)。
    • 制定备选方案和应急措施。

AI 替代能力:

  • 当前能力
    • AI 已能提供强大的技术选型建议(如根据场景推荐框架、库、工具)。
    • 在简单的架构设计中,AI 已能生成初步方案(如微服务与单体架构优劣分析)。
  • 未来潜力
    • AI 可能在复杂的技术决策中辅助更精准的数据分析和方案评估。
    • 但最终决策依赖对业务需求的深刻理解,这仍需要人类的经验和判断。

程序员核心竞争力:

  • 理解业务需求和行业背景,能够将技术与业务深度结合。
  • 解决复杂的非结构化问题,比如协调跨团队需求冲突,平衡业务优先级。
  • 创新能力:AI 只能在已有知识中提供建议,真正的创新需要人类。

2.2 连接

连接是将技术方案具体化并协调各方资源,使其从理论走向实践的过程。重点包括:

  • 需求转化
    • 将业务需求拆解为可执行的技术任务。
    • 明确模块划分、接口定义以及交互方式。
  • 团队协作
    • 前后端、测试、运维、产品经理之间的沟通与协作。
    • 协调跨部门资源,解决技术与运营、市场等职能间的矛盾。
  • 接口与模块设计
    • 定义 API 接口规范(RESTful、GraphQL)。
    • 确保接口的安全性、性能和兼容性。
  • 测试与迭代
    • 制定测试方案,组织单元测试、集成测试。
    • 根据测试反馈快速调整,推动迭代优化。

AI 替代能力:

  • 当前能力
    • AI 已能快速生成接口文档、代码示例、测试用例。
    • 在协作方面,AI 可以辅助生成任务拆解、需求文档、项目计划等。
  • 未来潜力
    • AI 可以成为跨部门的沟通桥梁,如生成更加精确的技术-业务对接文档。
    • 但复杂、动态的沟通和协调仍是 AI 难以替代的领域。

程序员核心竞争力:

  • 优秀的沟通能力和团队协作能力,能在矛盾或模糊的需求中推动项目前进。
  • 对复杂系统的整体把控力,确保各模块之间的高效协作。
  • 快速适应变化的能力,能够在项目中临时调整资源和策略。

2.3 编码

编码是程序员的核心工作之一,涉及将设计方案转化为实际运行代码的过程。它包括:

  • 代码实现
    • 基于需求和设计文档,开发具体功能模块。
    • 包括前端开发(UI、交互逻辑)和后端开发(业务逻辑、数据库操作)。
  • 调试与优化
    • 修复 BUG,优化代码性能。
    • 解决复杂的技术难点(如跨域问题、性能瓶颈、并发冲突)。
  • 代码质量保障
    • 编写单元测试、集成测试,确保代码质量。
    • 遵循代码规范,进行代码审查。
  • 持续集成与发布
    • 使用 CI/CD 工具进行自动化构建和部署。
    • 实现代码版本管理和持续优化。

AI 替代能力:

  • 当前能力
    • AI 已能生成高质量的代码片段、调试建议,甚至完整的模块代码。
    • 对于常见的编码任务(如脚本处理类,CRUD 功能),AI 的效率和准确性已超过人类。
  • 未来潜力
    • AI 将进一步替代大部分重复性、模板化的编码工作。
    • 但对于复杂场景下的创新性编码,AI 的能力仍有限。

程序员核心竞争力:

  • 对技术深度的理解,能够在 AI 提供的代码基础上进行优化和扩展。
  • 解决复杂问题的能力,比如在非标准化场景下实现创新功能。
  • 对代码质量的把控能力,确保生成代码的安全性、性能和可维护性。

3. AI 替代的趋势与程序员未来的价值

3.1 当前 AI 会逐步替代哪些部分?

  1. 重复性、模板化的工作
    • 例如脚本类、通用类、CRUD 重复类的功能。
    • 常见的 BUG 修复、代码优化建议。
  2. 常规化的架构设计和技术选型
    • AI 将能处理大部分标准化场景下的技术决策。
    • 在数据驱动的决策场景中,AI 的效率更高。
  3. 文档、接口、测试的自动化
    • 自动生成 API 文档、测试用例,将成为默认功能。

3.2 程序员的核心竞争力是什么?

  1. 业务理解与技术结合能力
    • AI 不理解业务逻辑背后的真实需求,程序员能够通过与产品、业务沟通,设计出更贴合实际的解决方案。
  2. 复杂场景的解决能力
    • 比如跨团队协作、大规模分布式系统设计、非标准化需求的实现。
  3. 创新与创意能力
    • AI 是基于已有数据训练的,无法真正创新。程序员在新领域和新需求中的创意能力不可替代。
  4. 人际沟通与团队协作能力
    • 项目中的决策、问题协调、资源整合都需要人类来推动。

3.3 程序员未来应该做什么?

  1. 提升抽象能力和建模能力
    • 从写代码转向设计方案,专注于高层次的架构和技术规划。
  2. 拥抱 AI 工具
    • 熟练使用 AI 编程工具(如 Trea、Cursor)提升效率,将 AI 当作“助手”。
  3. 深耕行业知识
    • 了解特定行业的业务逻辑,成为领域专家。
  4. 培养软技能
    • 强化沟通能力、团队协作能力和项目管理能力。

画了一个思维导图,大概是这样:

ai_sj.png

 

深入源码解析 ComfyUI 的模块化节点设计架构

ComfyUI 是一个基于 Stable Diffusion 的开源 AI 绘图工具,采用了模块化的节点式工作流设计。它通过将 Stable Diffusion 的各个组件和处理步骤抽象为独立的节点,使得用户可以通过直观的拖拽、连接操作来构建复杂的图像生成流程。

ComfyUI 解决了传统 AI 绘图工具易用性差、扩展性低的问题。其模块化设计和直观的 Web 界面大大降低了用户的使用门槛,无需深入了解底层技术细节,即可快速构建和调整工作流。同时,ComfyUI 还提供了强大的自定义节点机制,允许开发者轻松扩展新的功能和模型,使其能够适应不断发展的AI绘图领域。

ComfyUI 最初由开发者 Comfyanonymous 在 2022 年末发起,旨在提供一个简单、直观的 Stable Diffusion Web UI。早期版本实现了基本的节点类型和 Web 界面,展示了其模块化设计的优势,吸引了一批 AI 绘图爱好者的关注。

在 2023 年春夏,ComfyUI 进入了快速发展阶段。项目不断增加新的节点类型,如 ControlNet、Inpaint、Upscale等,支持更多的图像控制和后处理功能。同时,ComfyUI 引入了自定义节点机制,大大扩展了其功能和适用范围。项目也集成了更多 Stable Diffusion 衍生模型,为用户提供了更多选择。

随着用户社区的不断壮大,ComfyUI 的生态也日益丰富。社区成员积极贡献工作流、节点脚本、训练模型等资源,推动项目的发展。ComfyUI 举办了一系列社区活动,促进了用户间的交流和创作。项目代码库也迎来了更多贡献者,社区力量成为 ComfyUI 发展的重要推动力。

2023 年冬开始,ComfyUI 开始着眼于生态融合和应用拓展。项目与其他 AI 绘图工具建立了联系,支持工作流的导入导出和 API 集成。ComfyUI 也开始探索更多应用场景,如虚拟主播、游戏 mod 等,拓宽了 AI绘图的应用范围。越来越多的开发者和公司开始关注和使用 ComfyUI,其发展前景备受看好。

前两周,Comfy 推出跨平台的 ComfyUI 安装包,现在我们可以一键安装 ComfyUI 了,这次更新不仅带来了全新的桌面版应用,还对用户界面进行了全面升级,并新增了自定义按键绑定、自动资源导入等一系列实用功能,让工作流程更加流畅。

今天我们深入到 ComyUI 的源码去看一下其实现原理和过程。

ComfyUI 执行的大概流程如下:

用户界面 -> 工作流定义 -> PromptQueue
   ↓
PromptExecutor 开始执行
   ↓
验证输入 (validate_prompt)
   ↓
构建执行图
   ↓
按顺序执行节点
   ↓
缓存结果
   ↓
返回结果到界面

1. ComfyUI 的初始化与执行流程详解

ComfyUI 的一个明显的优点是有着灵活的图形用户界面,可以用于处理复杂的图像生成和处理工作流。

它具有精良的架构设计,通过模块化设计、缓存优化、资源管理以及错误处理机制,确保了系统的高效性和可靠性。

1.1 系统初始化流程

ComfyUI 的启动过程分为几个主要阶段:预启动脚本的执行、节点系统的初始化、服务器的启动与 WebSocket 的连接。

1. 启动前准备

在系统启动前,ComfyUI 会首先执行预启动脚本,确保自定义节点的环境准备就绪。这一过程允许在加载节点之前执行一些必要的自定义操作。

def execute_prestartup_script():
    # 执行自定义节点的预启动脚本
    for custom_node_path in node_paths:
        if os.path.exists(script_path):
            execute_script(script_path)

2. 节点系统初始化

节点系统是 ComfyUI 的核心组件。此阶段会加载内置节点以及用户自定义的节点,并注册到系统中供后续使用。

def init_extra_nodes():
    # 加载内置节点
    import_failed = init_builtin_extra_nodes()
    # 加载自定义节点
    init_external_custom_nodes()
  • 内置节点: 位于 comfy_extras 目录下,定义了基本的图像处理功能。
  • 自定义节点: 用户可以通过 custom_nodes 目录添加自定义节点,扩展系统的功能。

3. 服务器初始化

服务器初始化是启动 ComfyUI 的 Web 服务器的过程。它包括 WebSocket 的初始化,允许前端和后端实时通信。此外,执行队列也会在此阶段创建,用于管理节点的执行顺序和任务调度。

class PromptServer:
    def __init__(self, loop):
        # 初始化 Web 服务器
        self.app = web.Application()
        # 初始化 WebSocket
        self.sockets = dict()
        # 初始化执行队列
        self.prompt_queue = None

1.2 工作流执行流程

工作流执行是 ComfyUI 的核心功能,它包括从提交工作流到执行节点的整个过程。以下是工作流执行的几个关键步骤。

1. 工作流验证

首先,系统会对提交的工作流进行验证,确保节点的类型存在、节点连接有效,并且每个节点的输入符合要求。

def validate_prompt(prompt):
    # 1. 验证节点类型是否存在
    # 2. 验证是否有输出节点
    # 3. 验证节点输入
    return (valid, error, good_outputs, node_errors)

2. 执行准备

在验证通过后,系统会初始化执行环境。这包括创建动态的提示(DynamicPrompt),以及初始化缓存系统,以避免重复计算并提高执行效率。

def execute(self, prompt, prompt_id, extra_data={}, execute_outputs=[]):
    # 1. 初始化执行环境
    with torch.inference_mode():
        # 2. 创建动态提示
        dynamic_prompt = DynamicPrompt(prompt)
        # 3. 初始化缓存
        is_changed_cache = IsChangedCache(dynamic_prompt, self.caches.outputs)

3. 节点执行

每个节点的执行流程包括获取节点的输入数据、检查是否有缓存的数据可以复用、执行节点逻辑、并缓存执行结果。节点执行是系统的核心环节,其过程如下:

def execute(server, dynprompt, caches, current_item, extra_data, executed, prompt_id, execution_list, pending_subgraph_results):
    # 1. 获取节点信息
    unique_id = current_item
    inputs = dynprompt.get_node(unique_id)['inputs']
    class_type = dynprompt.get_node(unique_id)['class_type']
    
    # 2. 检查缓存
    if caches.outputs.get(unique_id) is not None:
        return (ExecutionResult.SUCCESS, NoneNone)
    
    # 3. 获取输入数据
    input_data_all, missing_keys = get_input_data(inputs, class_def, unique_id, caches.outputs, dynprompt, extra_data)
    
    # 4. 执行节点
    output_data, output_ui, has_subgraph = get_output_data(obj, input_data_all)
    
    # 5. 缓存结果
    caches.ui.set(unique_id, {...})
  1. 获取节点信息: 获取当前节点的输入和类型信息。
  2. 检查缓存: 如果节点的输出已经缓存,则直接返回缓存结果,避免重复执行。
  3. 获取输入数据: 从上一个节点或缓存中获取需要的输入数据。
  4. 执行节点: 调用节点的执行函数,处理输入并生成输出数据。
  5. 缓存结果: 将执行结果缓存,以便后续节点使用。

1.3 执行队列管理

ComfyUI 通过执行队列管理工作流中的节点执行顺序。每个节点的执行任务会被放入队列中,系统按顺序处理这些任务。

def prompt_worker(q, server):
    e = execution.PromptExecutor(server, lru_size=args.cache_lru)
    
    while True:
        # 1. 获取队列任务
        queue_item = q.get(timeout=timeout)
        
        # 2. 执行提示
        e.execute(item[2], prompt_id, item[3], item[4])
        
        # 3. 资源管理
        if need_gc:
            comfy.model_management.cleanup_models()
            gc.collect()
  • 获取队列任务: 从队列中取出下一个需要执行的节点任务。
  • 执行节点: 调用执行器执行当前节点。
  • 资源管理: 在必要时触发模型清理和垃圾回收,确保系统资源不被过度占用。

1.4 缓存系统

ComfyUI 的缓存系统采用层次化设计,可以缓存节点的输出、对象和 UI 相关的数据,极大地提高了执行效率。

class HierarchicalCache:
    def __init__(self):
        self.outputs = {}  # 节点输出缓存
        self.ui = {}  # UI 相关缓存
        self.objects = {}  # 节点对象缓存
  • 输出缓存(outputs): 缓存节点的执行结果,避免重复计算。
  • 对象缓存(objects): 缓存大数据对象,如模型和图像,以减少加载时间。
  • UI 缓存(ui): 缓存与前端界面相关的信息,如预览图像和执行状态。

1.5 资源管理与错误处理

为了确保系统的稳定性,ComfyUI 提供了完善的资源管理和错误处理机制。在执行工作流的过程中,系统会自动清理未使用的模型和缓存,并在必要时触发内存回收。

资源管理

资源管理包括内存清理、模型卸载以及缓存清理。系统会根据内存使用情况自动卸载不必要的模型,并定期触发垃圾回收。

# 1. 内存清理
comfy.model_management.cleanup_models()
gc.collect()

# 2. 模型卸载
comfy.model_management.unload_all_models()

# 3. 缓存清理
cache.clean_unused()

错误处理

ComfyUI 实现了详细的错误处理机制,能够捕获并处理执行过程中发生的各种异常。对于节点执行中的错误,系统会记录错误信息并通知用户。

def handle_execution_error(self, prompt_id, prompt, current_outputs, executed, error, ex):
    # 1. 处理中断异常
    if isinstance(ex, comfy.model_management.InterruptProcessingException):
        self.add_message("execution_interrupted", mes)
    # 2. 处理其他错误
    else:
        self.add_message("execution_error", mes)
  • 处理中断异常: 当执行被中断时,系统会捕获异常并记录中断信息。
  • 处理其他错误: 处理其他执行错误,并通过 UI 向用户报告错误详情。

2. 节点系统架构

节点系统是 ComfyUI 的核心系统,其节点系统架构设计精巧,支持动态节点的加载、执行和扩展。今天我们详细介绍 ComfyUI 的节点系统架构,涵盖节点定义、执行流程、缓存机制、扩展性和系统特性等方面。

2.1 节点系统的基础架构

ComfyUI 的节点系统基于 Python 模块化设计,所有节点及其行为都通过类的形式进行定义。这些节点在启动时会进行注册,允许系统灵活地加载和使用内置节点与自定义节点。

核心节点定义与注册

ComfyUI 的节点系统在 nodes.py 中定义,并通过以下映射存储所有节点类及其显示名称:

NODE_CLASS_MAPPINGS = {}  # 存储所有节点类的映射
NODE_DISPLAY_NAME_MAPPINGS = {}  # 节点显示名称映射

节点通过类定义,并包含以下几个关键属性:

  • INPUT_TYPES: 输入参数的类型定义。
  • RETURN_TYPES: 返回数据的类型定义。
  • FUNCTION: 节点的具体执行函数。
  • CATEGORY: 节点的类别,用于在 UI 中分类显示。

节点类型

ComfyUI 支持两种类型的节点:

  • 内置节点: 在系统启动时加载,存储在 comfy_extras 目录下。内置节点提供了常见的图像操作、模型加载和处理功能。
  • 自定义节点: 用户可以在 custom_nodes 目录中添加自定义节点,系统在启动时自动加载这些节点。

节点加载机制

ComfyUI 提供了灵活的节点加载机制,允许动态加载内置节点和自定义节点:

def init_builtin_extra_nodes():
    extras_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "comfy_extras")
    extras_files = ["nodes_latent.py""nodes_hypernetwork.py"]

对于自定义节点,ComfyUI 使用动态模块导入的方式加载:

def load_custom_node(module_path: str, ignore=set(), module_parent="custom_nodes") -> bool:
    module_spec = importlib.util.spec_from_file_location(module_name, module_path)
    module = importlib.util.module_from_spec(module_spec)
    if hasattr(module, "NODE_CLASS_MAPPINGS"):
        for name, node_cls in module.NODE_CLASS_MAPPINGS.items():
            NODE_CLASS_MAPPINGS[name] = node_cls

这种设计使得 ComfyUI 可以方便地扩展和加载新节点,用户可以根据需求自定义节点功能并动态加载。

2.2 节点执行系统

节点的执行逻辑由 execution.py 中的 PromptExecutor 类负责。该类管理了节点的执行流程,包括输入验证、节点函数执行、结果缓存和输出返回等。

执行流程

节点的执行流程如下:

  1. 输入验证: 系统首先验证节点的输入是否符合预定义的输入类型。
  2. 获取输入数据: 从上一个节点或缓存中获取节点的输入数据。
  3. 执行节点函数: 根据定义的 FUNCTION 执行节点逻辑。
  4. 缓存结果: 执行结果会缓存,避免重复计算。
  5. 返回输出: 将执行结果返回给下游节点或 UI。

执行器的核心代码如下:

class PromptExecutor:
    def execute(self, prompt, prompt_id, extra_data=None, execute_outputs=[]):
        # 节点执行的主要逻辑

ComfyUI 通过此执行器确保节点按顺序执行,并管理节点间的数据流动。

2.3 缓存机制

为了提高性能,减少重复计算,ComfyUI 实现了多层缓存系统,缓存节点的输出、对象和 UI 相关数据。缓存的实现类为 HierarchicalCache,并且系统支持 LRU(最近最少使用) 缓存策略。后续章节会详细讲一下缓存,这里先略过。

2.4 数据流与依赖管理

ComfyUI 的节点系统依赖于图形化的数据流管理。节点之间通过输入和输出相互连接,系统会自动分析节点间的依赖关系,确保数据流在节点间正确传递。

节点图解析与执行顺序

  1. 节点图解析: ComfyUI 解析 JSON 格式的节点图,识别节点之间的连接关系。
  2. 依赖管理: 系统自动分析节点间的依赖,确保每个节点在其依赖的节点完成后执行。
  3. 执行顺序构建: 系统基于依赖关系构建节点的执行顺序,防止循环依赖和执行死锁的发生。

2.5 错误处理与资源管理

ComfyUI 实现了完善的错误处理机制,确保节点执行过程中出现错误时,系统能够及时捕获并反馈给用户,避免系统崩溃。同时,ComfyUI 通过自动垃圾回收和内存管理功能,定期清理未使用的模型和缓存,优化系统资源使用。

常见的错误处理机制包括:

  • 输入验证失败: 如果输入数据类型不匹配或数据缺失,系统会抛出异常。
  • 执行错误: 如果节点在执行过程中遇到错误,系统会捕获并将错误信息反馈到前端 UI。

垃圾回收机制由以下代码管理:

gc_collect_interval = 10.0  # 每10秒进行一次垃圾回收

2.6 前端接口与用户交互

ComfyUI 提供了 WebSocket 和 REST API 来管理前端与后端的通信。通过这些接口,前端 UI 可以实时监控节点的执行状态,并获取节点的执行结果。

WebSocket 通信

WebSocket 负责处理前端与后端的实时通信,包括节点执行状态的推送和执行命令的接收。

@routes.get('/ws')
async def websocket_handler(request):
    # 处理前端连接
    # 发送执行状态
    # 处理节点执行

REST API

REST API 用于获取节点信息和处理其他非实时请求。例如,可以通过以下 API 获取节点的详细信息:

@routes.get("/object_info/{node_class}")
async def get_object_info_node(request):
    # 获取节点信息

2.7 系统扩展与自定义

ComfyUI 的节点系统设计非常灵活,支持用户根据需求扩展新功能。用户可以通过编写自定义节点来扩展系统的功能,而无需修改核心代码。系统支持热插拔的节点加载机制,使得自定义节点的开发和调试更加便捷。

动态类型系统

ComfyUI 支持动态类型系统,可以根据运行时情况自动调整节点的输入输出类型,确保系统的灵活性和可扩展性。

插件与自定义节点

自定义节点通过 custom_nodes 目录加载,用户可以编写自己的节点并通过 NODE_CLASS_MAPPINGS 注册到系统中。

3. 缓存系统

在 ComfyUI 项目中,缓存系统的设计主要由以下几个部分组成:

3.1 缓存类型

ComfyUI 的缓存系统主要包括三种缓存类型:

  • outputs: 用于缓存节点的输出结果,减少不必要的重复计算。
  • ui: 缓存与用户界面相关的数据,比如预览图像、状态信息等。
  • objects: 专门用于存储大型对象,如模型等大体积数据。

这三种缓存通过 CacheSet 类进行初始化和管理,具体实现如下:

class CacheSet:
    def __init__(self, lru_size=None):
        if lru_size is None or lru_size == 0:
            self.init_classic_cache() 
        else:
            self.init_lru_cache(lru_size)
        self.all = [self.outputs, self.ui, self.objects]

3.2 缓存实现方式

缓存系统可以根据不同的需求选择不同的实现方式:

Classic Cache(传统缓存)

当没有设置 LRU 缓存大小时,缓存系统会初始化为经典的层级缓存。具体实现如下:

def init_classic_cache(self):
    self.outputs = HierarchicalCache(CacheKeySetInputSignature)
    self.ui = HierarchicalCache(CacheKeySetInputSignature)
    self.objects = HierarchicalCache(CacheKeySetID)
  • outputs 和 ui 都使用 CacheKeySetInputSignature 作为缓存键,用于基于输入签名进行缓存。
  • objects 使用的是 CacheKeySetID 作为缓存键,主要是为了存储大型对象,如模型数据。

LRU Cache(最近最少使用缓存)

如果设置了 LRU 缓存大小,系统会初始化为 LRU 缓存,适用于内存较充足的情况下,以优化性能。

def init_lru_cache(self, cache_size):
    self.outputs = LRUCache(CacheKeySetInputSignature, max_size=cache_size)
    self.ui = LRUCache(CacheKeySetInputSignature, max_size=cache_size)
    self.objects = HierarchicalCache(CacheKeySetID)
  • outputs 和 ui 使用 LRU 缓存,能够根据使用频率自动淘汰最少使用的缓存项,保证内存得到最优管理。
  • objects 仍然使用 HierarchicalCache,因为模型等大型对象的加载和卸载代价较高,不适合频繁淘汰。

3.3 缓存键策略

为了确保缓存的正确性,缓存系统使用两种不同的缓存键策略:

CacheKeySetInputSignature

  • 用于 outputs 和 ui 缓存。
  • 该缓存键基于节点的输入签名,包含节点类型、输入参数及祖先节点关系等,可以确保相同的输入得到相同的输出。

CacheKeySetID

  • 用于 objects 缓存。
  • 这是一种基于节点 ID 和类型的简单缓存键,用于存储与输入无关的大型对象,如模型等。

3.4 缓存清理机制

无论是传统缓存还是 LRU 缓存,ComfyUI 都提供了缓存清理机制,避免过多的缓存占用内存资源。

经典缓存清理

经典缓存会及时释放不再需要的数据,防止内存溢出。

LRU 缓存清理

LRU 缓存通过一个 generation 计数器和 used_generation 字典记录每个缓存项的使用时间。当缓存超出预设大小时,LRU 算法会移除最久未使用的项。

3.5 扩展性和调试

ComfyUI 的缓存系统支持扩展和调试:

  • 扩展性: 缓存系统支持自定义节点和模型的缓存策略,可以根据需要调整缓存大小和键生成逻辑。
  • 调试: 提供了 recursive_debug_dump 函数,能够以递归方式输出缓存的调试信息,方便开发者进行问题排查。
def recursive_debug_dump(self):
    result = {
        "outputs": self.outputs.recursive_debug_dump(),
        "ui": self.ui.recursive_debug_dump(),
    }
    return result

3.6 缓存小结

ComfyUI 的缓存系统设计非常灵活,它通过 CacheSet 类将不同类型的数据(节点输出、UI 数据、大型对象)分离管理,并支持经典缓存和 LRU 缓存两种策略。依靠层次化的缓存结构和精确的缓存键策略,ComfyUI 能够有效地减少重复计算,并优化内存使用。

4. 使用限制

在使用 ComfyUI 时,虽然系统本身没有硬性限制节点数量,但仍然存在一些与性能、资源管理和系统稳定性相关的限制。这些限制大多与历史记录、图像分辨率、缓存、内存管理等方面有关。

4.1 历史记录限制

ComfyUI 会保存工作流中的历史记录,用于回溯和调试。系统中对历史记录的最大保存数量有如下限制:

MAXIMUM_HISTORY_SIZE = 10000
  • 限制描述: 系统最多保存 10000 条历史记录。
  • 影响: 当历史记录达到上限时,旧的记录会被移除,无法继续回溯到更早的操作。
  • 建议: 如果不需要长时间保存历史记录,定期清理历史记录可以释放内存资源,提升系统的运行效率。

4.2 图像分辨率限制

ComfyUI 中对单个图像处理的最大分辨率有限制,防止超大图像导致系统崩溃或内存不足:

MAX_RESOLUTION = 16384
  • 限制描述: 系统允许的最大图像分辨率为 16384×16384 像素。
  • 影响: 超过此分辨率的图像无法处理,可能会导致内存溢出或显存不足的情况。
  • 建议: 尽量避免处理过于高分辨率的图像,尤其是在显存较小的 GPU 上运行时。对于需要处理大图像的工作流,可以考虑将图像分割成多个较小的瓦片。

4.3 VAE 解码瓦片大小限制

在图像生成过程中,VAE 解码器对瓦片大小进行了限制,以确保解码过程的效率与内存管理:

"tile_size": ("INT", {"default"512"min"128"max"4096"step"32})
  • 限制描述: VAE 解码时,允许的瓦片大小在 128 到 4096 像素之间。
  • 影响: 如果瓦片大小设置过大,系统可能会因为内存不足而运行缓慢或崩溃;瓦片大小过小则可能影响解码效率。
  • 建议: 根据 GPU 显存大小合理调整瓦片大小,找到性能和内存占用之间的平衡点。

4.4 文件上传大小限制

在使用 ComfyUI 时,文件上传的大小受限于系统的配置,特别是通过命令行参数 max_upload_size 来控制:

max_upload_size = round(args.max_upload_size * 1024 * 1024)
  • 限制描述: 上传文件的最大尺寸由命令行参数 max_upload_size 控制,单位为 MB。
  • 影响: 超过上传文件大小限制的文件将无法上传或处理。
  • 建议: 如果需要上传较大的文件,可以通过调整命令行参数来提高上传文件的大小限制。

4.5 缓存限制

ComfyUI 使用缓存系统来优化计算效率,减少重复计算。缓存的大小和管理方式可以通过 LRU(最近最少使用)策略进行控制:

def __init__(self, lru_size=None):
    if lru_size is None or lru_size == 0:
        self.init_classic_cache() 
    else:
        self.init_lru_cache(lru_size)
  • 限制描述: 缓存的大小受 LRU 策略控制,缓存过多时,系统会淘汰最少使用的缓存项。
  • 影响: 当缓存大小设置过小,可能会频繁清除缓存,导致重复计算;缓存过大则可能占用大量内存。
  • 建议: 根据内存资源合理设置缓存大小。对于内存充足的系统,可以增加缓存大小,以减少重复计算;对于内存紧张的系统,建议定期清理缓存。

4.6 执行队列限制

节点的执行通过队列进行管理,系统按顺序执行节点,避免同时执行过多节点造成性能瓶颈:

  • 限制描述: 系统使用队列调度节点执行,包括当前运行的队列和等待执行的队列。
  • 影响: 如果节点过多,执行速度会受到队列调度的影响,可能出现等待时间过长的情况。
  • 建议: 尽量简化工作流,避免过多的节点同时排队执行。如果遇到性能瓶颈,可以将大规模的工作流分解为多个子工作流逐步执行。

4.7 Tokenizer 限制

在文本处理方面,CLIP 模型的 Tokenizer 有一个最大长度限制:

"model_max_length"77
  • 限制描述: CLIP 模型的 Tokenizer 最多支持 77 个 token。可修改配置。
  • 影响: 超过 77 个 token 的输入文本将被截断,可能会影响文本生成的精度。
  • 建议: 尽量保持输入文本简洁,避免过长的描述。如果必须使用长文本,可以通过分段输入的方式进行处理。

4.8 限制小结

虽然 ComfyUI 对节点数量没有明确的硬性限制,但在使用过程中仍然受到一些系统资源和配置的限制。这些限制大多是为了确保系统的稳定性、优化性能以及合理使用内存资源。为了避免因这些限制导致的性能瓶颈或崩溃,建议在使用时遵循以下最佳实践:

  • 保持工作流简洁: 避免不必要的节点,定期清理历史记录和缓存。
  • 监控系统资源: 注意监控内存和显存的使用情况,避免资源耗尽。
  • 分解大型工作流: 对于复杂的工作流,可以分成多个子工作流来逐步执行,减少单次执行的节点数量。
  • 调整系统配置: 根据实际需求调整文件上传大小、缓存设置等参数。

通过合理地管理工作流和系统资源,ComfyUI 可以在大型工作流中保持高效运行,避免因资源限制导致的性能问题。

模块化设计带来的无限可能

ComfyUI 的模块化节点系统不仅提升了用户的易用性,还通过灵活的扩展机制和高效的缓存管理提供了强大的自定义能力。

它的图形化工作流设计大大降低了 AI 绘图的技术门槛,使得更多用户能够轻松上手,并根据自己的需求定制不同的图像生成方案。

随着社区的不断壮大和功能的持续扩展,ComfyUI 有望成为 AI 绘图领域的重要基础设施之一,为创作与开发者提供无限的可能性。

以上。

一文了解文生图中 ControlNet 的实现原理和生态发展

在聊 ControlNet 的之前,先了解一下 ControlNet 的基础模型 Stable Diffusion 的生成过程。

Stable Diffusion (SD) 是一种基于扩散模型的文本到图像生成技术,它可以根据输入的文字描述,生成与之语义相符的高质量图片。整个 SD 模型的架构包含了多个关键组件,它们分工协作、相互配合,共同完成了这一令人惊叹的创意生成任务。

Stable Diffusion 的实现原理

SD 的核心思路源自扩散模型。扩散模型是一类生成式模型,它的基本原理是:先将原始数据加入大量随机噪声,然后学习如何一步步去除噪声、恢复数据。 SD 正是利用了这一思路来生成图像。它先将原始图片加入高斯噪声,得到一张几乎全是噪点的图。然后,使用一个名为 UNet 的神经网络,通过多轮迭代去噪,最终生成干净、清晰的图像。

在训练阶段,SD 模型接受三个输入:原始图片、加噪后的图片、以及对原始图片的文本描述。其中,UNet 学习建立起加噪图片和原始图片之间的映射关系。通过最小化预测噪声与真实噪声的差异,UNet 掌握了去噪的能力。同时,由于训练数据中包含了图像-文本对,UNet 也学会了如何根据文本线索对图像去噪,这是后续根据文字生图的基础。

但是,直接对原始图片进行去噪训练会带来巨大的计算开销。为了提高效率,SD 先使用变分自编码器(VAE)将高维图像压缩到低维隐空间,然后在隐空间中进行去噪操作。VAE 不仅大幅降低了数据维度,它学习到的隐空间还具有良好的语义结构,使得相似图像在隐空间中更紧邻、更易融合。

为了让输入的文本 Prompt 有效地指引图像生成,SD 使用 CLIP 模型对文本进行编码。CLIP 模型擅长捕捉图像和文本的对齐关系,它生成的文本特征向量与图像视觉特征的分布更加一致。在生成阶段,文本编码和初始噪声图像一起输入 UNet,共同决定去噪的方向和结果,使得最终图像在语义上与文本描述相匹配。

但是,扩散模型通常需要上千步去噪迭代才能生成好的图像,这非常耗时。为了加速生成过程,SD 借鉴了 DDIM 等快速采样方法。它们通过跳过一些中间去噪步骤,在保证质量的同时大幅提升了生成速度。

SD 模型的生成流程可以概括为:输入的文本描述先被 CLIP 编码为语义向量,同时在隐空间中随机生成一张噪声图像。二者一同输入 UNet 进行多步去噪,并使用 DDIM 等采样加速。最终,去噪得到的隐空间图像通过 VAE 解码,还原为高清的 RGB 图片输出。

SD 的一大亮点是其开源、模块化的设计。得益于此,各个组件都可以灵活地替换升级,社区还发明了ControlNet、LoRA 等参数高效微调技术,使得 SD 模型可以快速适应各种新的应用场景。这极大地激发了开发者和艺术家们的创造力,SD 已成为当前 AIGC 领域的一大热点。

虽然 SD 已经很优秀了,超出了人们的想象,但是 SD 模型本身有一些问题需要解决,如无条件的生成,生成过程难以控制,无法根据用户的特定意图或要求来生成或编辑图像等。

这导致SD模型在实际应用中面临一些局限性,如缺乏可控性、灵活性不足、难以进行精细的图像编辑等。

2023 年年初 ControlNet 横空出世,通过引入额外的控制信号和可学习的控制器网络,解决了 SD 模型在可控图像生成方面的这些问题,使其能够根据用户提供的边缘、关键点、分割掩码等条件,生成满足特定约束的高质量图像,大大扩展了 SD 模型的应用场景和实用性。

ControlNet 的原理

ControlNet 是一种用于可控图像生成的扩散模型。它通过接受额外的控制信号(如边缘、关键点、分割掩码等)来指导图像生成过程,使生成的图像符合给定的控制约束。

ControlNet 解决的主要问题是如何在图像生成过程中引入更多的控制和约束,使生成的图像符合用户的特定要求。具体来说,ControlNet 解决了以下几个问题:

  1. 可控性问题:传统的扩散模型通常是无条件的,生成的图像无法根据用户的意图进行控制。ControlNet通过引入额外的控制信号,如边缘、关键点、分割掩码等,使得生成的图像能够满足特定的约束条件,提高了图像生成的可控性。
  2. 灵活性问题:以往的图像生成方法通常针对特定的任务或控制类型设计,泛化能力有限。ControlNet 提出了一种通用的控制器网络设计,可以适应不同类型的控制信号,无需为每种控制任务重新训练整个模型,大大提高了模型的灵活性和适用性。
  3. 图像编辑问题:传统的图像编辑方法通常需要复杂的人工操作或专门设计的算法。ControlNet 允许用户通过提供简单的控制信号(如涂鸦、关键点等)来指导图像的编辑过程,使得图像编辑更加直观和便捷。
  4. 多模态融合问题:在许多应用场景中,需要将不同模态的信息(如文本、语音、图像等)融合生成图像。ControlNet提 供了一种将不同模态信息编码为控制信号的方法,使得扩散模型能够根据多模态输入生成相应的图像。
  5. 数据效率问题:训练高质量的图像生成模型通常需要大量的数据和计算资源。ControlNet 通过固定预训练的扩散模型,只训练控制器网络,大大减少了训练所需的数据和计算量,提高了数据利用效率。

ControlNet 的核心思路是通过引入额外的控制信号,在扩散模型的生成过程中引导图像的合成使其符合预定的约束条件。其主要思路简单来说如下:

  1. 利用预训练的扩散模型作为图像生成的基础,保持其参数不变。
  2. 设计一个控制器网络,将其插入到扩散模型的每个去噪步骤中,使得扩散模型的每一步与对应的控制信号相结合,这个控制网络是 ControlNet 的核心。
  3. 控制器网络接受图像的潜在表示和对应步骤的控制信号表示,学习如何将它们融合以调制扩散过程。
  4. 通过控制器网络的调制,使扩散模型的去噪过程朝着满足控制约束的方向进行,最终生成符合要求的图像。ControlNet 支持多种类型的控制信号,如边缘、关键点、分割掩码、深度图等。针对不同类型的控制,控制器网络的结构可能有所不同,但基本原理类似。

ControlNet 通过引入可学习的控制器网络,有效解决了扩散模型在可控图像生成领域面临的局限性。

它支持多种类型的控制信号,如边缘、关键点、分割掩码等,使得用户能够根据特定意图对生成图像进行精细控制。ControlNet 生成的图像在满足控制约束的同时,保持了高质量和逼真性。

此外,ControlNet采用了固定预训练扩散模型、仅训练控制器网络的策略,大大提高了数据和计算效率。ControlNet 为图像生成和编辑任务带来了新的可能性,在创意设计、虚拟内容生成等领域展现出广泛的应用前景。

ControlNet 的性能在一定程度上依赖于控制信号的质量,噪声或不完整的控制信号可能导致生成图像的缺陷。

目前,ControlNet 主要针对低级视觉控制进行设计,对高层语义控制的支持有限。此外,ControlNet在生成高分辨率、细节丰富图像时,可能面临计算开销大、推理速度慢的挑战,在实时交互场景中的应用受到一定限制。

未来,提高 ControlNet 在语义理解、鲁棒性和计算效率方面的表现,将是其进一步发展的重点方向。同时,探索 ControlNet 与其他生成模型、编辑工具的结合,有望进一步拓展其应用范围和功能。

ControlNet 的生态

从 SD 模型版本支持来看,ControlNet 可以分为 SD1.5 和 SDXL 两个常用版本。其中 SD1.5 在生态方面更完善一些,SDXL 发展过程中,大家不约而同选择了闭源自己玩多一些。

从发行机构来看,分为官方模型和第三方模型。

官方模型多分支 SD1.5 和 SD2.0 模型,没有 SDXL 的模型,SDXL 的模型多来源于社区,大概的生态情况如下:

ControlNet 1.1 包括 14 个模型(10 个生产就绪模型、2 个实验模型、2 个融合版本):

10 个生产模型:

  • control_v11p_sd15_canny.pth Canny边缘检测模型:使用 Canny 算法提取图像主体轮廓的边缘线条,再进行填色。1.1 版本相对于之前的版本,消除训练数据缺陷,并通过大规模训练提升了模型性能和输出质量。
  • control_v11p_sd15_inpaint.pth Inpaint 修补模型:对图像局部重绘修饰,保留其他部分。用于小范围创意设计。
  • control_v11p_sd15_lineart.pth Lineart 线性检测模型:提取精细丰富的线稿,适用于产品设计等。
  • control_v11p_sd15_mlsd.pth MLSD 模型:善于提取直线线段,如建筑线条结构,适合建筑/室内设计风格。1.1 版本相对于之前的版本,扩充训练集并增加训练量,使直线检测能力得到进一步提高。
  • control_v11p_sd15_normalbae.pth Normal 法线贴图模型:检测像素的 RGB 值和表面法线方向,分离主体和背景,用于整体色彩调整。1.1 版本相对于之前的版本,采用更准确的法线贴图估计方法,增强了模型的鲁棒性和实用性。
  • control_v11p_sd15_openpose.pth Openpose 人体姿态检测模型:识别人体关键点和运动轨迹,用于调整人物姿态、表情等。1.1 版本相对于之前的版本,对 Openpose 实现细节进行改进,提高了人体姿态估计,尤其是手部的准确度。
  • control_v11p_sd15_scribble.pth Scribble 涂鸦模型:可以基于用户手绘的线条、涂鸦等输入生成相关图像。1.1 版本相对于之前的版本,适应更粗的涂鸦输入,同时通过修正数据和延长训练改善效果。
  • control_v11p_sd15_seg.pth Segmentation 语义分割网络:将图像分割为约 150 种颜色代表的物体,可单独处理天空、建筑、树木等要素。1.1 版本相对于之前的版本,扩展了对COCO数据集的支持,向下兼容旧版输入。
  • control_v11p_sd15_softedge.pth Softedge 软线性检测模型:一种边缘检测模型,生成更柔和自然的线条。1.1 版本相对于之前的版本,新的预处理方法和针对性数据筛选,使模型的边缘处理能力大幅提升,实用性与depth相当。
  • control_v11p_sd15s2_lineart_anime.pth Anime Lineart动漫线稿检测模型:Lineart的升级版,专门用于动漫线稿上色,效果更自然流畅。

2 个实验版本:

  • control_v11e_sd15_ip2p.pth IP2P 直接编辑模型:根据文本描述直接编辑图像,如”让房子着火”。需要用户有创意和想象力。
  • control_v11e_sd15_shuffle.pth Shuffle 随机处理模型:随机组合图像要素,生成风格化图像。可用于风格迁移。

2 个融合版本

  • control_v11f1e_sd15_tile.pth Tile 模型:将图像分割成小块处理,用于放大图像细节或图像修复。
  • control_v11f1p_sd15_depth.pth Depth 深度图模型:分析图像中物体的空间位置关系,常用于人物换背景,调整手臂位置等创意设计。1.1 版本相对于之前的版本,通过修复训练数据和采用无偏方法,使模型在更多场景下表现出色。

官方的文件名看起来是有规律的,其规则如下:

  1. 版本号(v11):表示 ControlNet 的版本号,如 v11 代表 1.1 版本,v10 代表 1.0 版本。版本号升级通常意味着模型性能和功能的优化和扩展。
  2. 模型状态(p):表示模型所处的状态,其中:

    • p表示正式版(production),该模型已经比较稳定,适合新手使用。
    • e表示实验版本(experimental),该模型仍在实验阶段,结果可能不太稳定,更适合研究者探索。
    • u表示未完成版本(unfinished),表示模型尚未完成。
  3. Stable Diffusion版本(sd15):表示该ControlNet模型所基于的Stable Diffusion版本,如sd15代表Stable Diffusion 1.5,sd21 代表Stable Diffusion 2.1。不同版本的Stable Diffusion在模型结构和训练数据上可能有所差异,因此 ControlNet 模型需要指定兼容的 SD 版本。
  4. 模型类型(canny):表示该 ControlNet 模型的主要功能和用途,如 canny 代表 Canny边缘检测,openpose 代表人体姿态估计,hed 代表 Holistically-Nested Edge Detection 用于提取软边缘,scribble 代表涂鸦等。不同类型的 ControlNet 模型在控制方式和生成效果上各有特点。

举个例子:control_v11p_sd15_canny 这个模型名称表示:这是一个 ControlNet 1.1 版本的模型,已经发布为正式版,基于 Stable Diffusion 1.5 训练,主要用于 Canny 边缘检测任务。

模型下载地址:https://huggingface.co/lllyasviel/ControlNet-v1-1/tree/main

第三方模型相对无序一些,并且以在 SDXL 表现较多,大概有如下的一些:

  • Lvmin 的模型集合:包括diffusers ControlNet、Controllllite、Stability AI Control LoRA、T2I Adapter等。
  • Qinglong的Controllllite SDXL模型:包括Normal Dsine、Tile realistic、Tile anime、MLSD、DW pose、Normal、Recolor Luminance、Softedge、Segment animeface等。
  • TTPLanet Tile Realistic:由社区为SDXL训练的逼真瓷砖模型。
  • 2vXpSwA7 cnllliteL:grey2color和anystyle模型。
  • MistoLine:SDXL softedge模型。
  • Kataragi的SDXL模型:包括 Inpaint、Recolor、Lineart、Line2Color 等,提供半精度模型和rank128 LoRA。
  • Xinsir的SDXL模型:包括Canny、Openpose、Scribble、Scribble-Anime等。

一些应用场景

ControlNet 目前在多个领域展现出了广阔的应用前景,主要有以下几个方面:

  1. 设计辅助:通过输入简单的线稿、轮廓或布局,ControlNet 可以帮助平面设计、工业设计、服装设计等领域快速生成多样的设计方案,提高设计效率和创意。
  2. 影视动漫创作:ControlNet 能够根据故事板或概念草图等粗略输入,生成细致的场景、人物、道具等素材,辅助影视、动画、游戏等视觉创意行业的前期创作。甚至是后期的合成及剪辑。
  3. 虚拟试衣/试妆:基于 ControlNet 的姿态估计和人像生成能力,可实现虚拟试衣、试妆等功能,应用于电商、社交、美妆等领域,提供沉浸式的交互体验。
  4. 建筑与室内设计:通过点线面等简单输入,ControlNet 可以辅助建筑外观、室内布局、家居陈设等设计任务,提供多种风格选择,用于方案展示和评估。
  5. 医疗影像分析:ControlNet 能够根据医学影像的轮廓或标注,生成更清晰、更符合诊断需求的医学图像,辅助医生进行疾病诊断和手术规划等。
  6. 教育与培训:基于ControlNet生成各种教学演示素材,如解剖图、示意图等,提高学习效率。在VR/AR场景中自动生成训练环境。
  7. 文旅与数字展览:通过简单的场景布局输入,ControlNet可快速生成丰富多样的游览场景、数字藏品,应用于文旅推广、虚拟展览等。
  8. 智能图像编辑:ControlNet可以实现图像修复、抠图、换背景、图像风格转换等常见图像编辑功能,提供更智能、更简便的图像处理工具。

小结

在 ControlNet 没有出来之前,很多时候能不能出来一个好看的画面,只能通过大量的 Prompt 测试实现,以数量去对冲概率。

在当下,如果能用好控制出图的三个最关键因素:提示词、Lora、ControlNet,能让「出图与我们想象的画面一致」概率更高。

通过前面的几个小节,我们可以看到:

  1. ControlNet 通过使用额外的条件控制输入,如语义分割图、边缘检测图等,让文本到图像生成更加可控。这大大提升了生成图像与用户期望相符的概率。
  2. ControlNet 的一大优势在于它的通用性和灵活性。通过使用不同类型的控制条件,可以引导模型生成各种不同风格和内容的图像。而且这些控制条件可以通过现有的 CV 模型自动获取,方便集成。
  3. 围绕 ControlNet 已经形成了活跃的生态。各种开源实现和 web 应用让普通用户也能轻松使用,专业的 GUI 让艺术创作者可以更高效地把控细节。社区也在不断贡献新的模型权重,扩展 ControlNet 的应用边界。
  4. 但 ControlNet 并非万能,提示词的设计、LoRA 模型的选择仍然是影响效果的关键因素。掌握并灵活组合这三者,才能最大限度提升「如我所愿」出图的成功率。
  5. 展望未来,ControlNet 为可控文生图开辟了新的方向,但仍有很多挑战亟待解决,如更精细的空间控制、更强的全局一致性等。相信随着研究的深入,ControlNet 会带来更多惊喜。

以上