标签归档:AIGC

深入源码解析 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 会带来更多惊喜。

以上

快速了解文生图 AIGC 的 15 个关键词

冯唐在《成事心法》中提到过这样一个观点:「只要你把这 100 个相关的关键词搞清楚,而且每个关键词,你都能给出合理的答案,那么你也可以成为这个领域的专家」。

想要快速了解 AIGC 文生图,从了解下面的 15 个关键词开始吧。

AI 概念名称

AI

AI,Artificial Intelligence,人工智能

人工智能这个词在大众想象中常常会勾起有关自主思考的机器人和智能机器的画面。但核心上,AI 是关于创建智能算法的学科,目的是执行通常需要人类智慧才能完成的任务。人工智能的概念自 20 世纪中叶以来就已存在,但它是在 1956 年的达特茅斯会议上,由约翰·麦卡锡正式提出的术语。

从那时起的几十年里,AI 已经从理论概念演变成一个涵盖机器学习、神经网络和深度学习等的强大领域。如今,AI 不仅仅是一个研究领域;它已成为我们日常生活中不可或缺的一部分,改变着行业并创造出曾经只存在于科幻小说中的新可能性。

AGI

AGI,Artificial General Intelligence,人工通用智能,也称为强人工智能或全能 AI

AGI 指一种具有普遍的认知能力的机器智能,它能在各种领域和任务中表现出与人类相当或更高的效能。与目前的人工智能系统(被称为弱 AI 或专用 AI )不同,这些系统通常设计用来解决特定问题或执行特定任务,AGI 将能够像人类一样学习、理解、推理和应用知识于新的和多样化的情境中。

AGI 的概念和 AI 一起发展,但成为独立研究的重点是在 21 世纪初

AIGC

AIGC,AI Generated Content,AI 生成内容

AIGC 指的是通过人工智能算法自动创建的内容,这些内容可以包括文字、图像、音频、视频和其它多媒体格式。

现在主要是利用了像生成对抗网络(GANs)和 Transformer 模型等技术,这些工具能够生成逼真和具有创造性的输出。

在文本领域,AIGC体现在自动撰写新闻、小说创作、营销文案编写等;在视觉艺术领域,AIGC 则能够创作出新的图像作品、动画和视频。

AIGC 技术的优势在于其高效性和能够处理大量内容的能力,从而在一定程度上减轻了人类内容创作者的负担,并为他们的工作提供辅助。例如,新闻机构可以利用 AIGC 生成初稿或基于数据的报告,艺术家可以使用 AI 来生成新颖的素材或灵感,而企业可以通过 AIGC 定制个性化的广告内容或提供客户支持。

然而,AIGC 也带来了一些挑战和风险。在版权和创意归属方面,AIGC 生成的内容可能引起版权所有者的争议。此外,AIGC 产生的内容可能被滥用,例如制作虚假新闻或所谓的深度伪造内容,这些都可能对公众信息的真实性和信任造成影响。

尽管存在挑战,AIGC 的未来发展前景依然被广泛看好。随着算法的不断进步和创作工具的日益智能化,AIGC 有望在提高内容创作效率、降低成本以及驱动创新方面发挥重要作用。同时,它也将促进新的艺术形式和娱乐方式的产生,为人类文化和创意表达开辟新的可能性。

GPU

图形处理单元 (GPU) 是一种专门设计来处理计算机图形和图像处理任务的芯片。

GPU 的历史可以追溯到 1990 年代初,但是它作为通用计算设备在 21 世纪初开始流行。NVIDIA 在 1999 年推出了市场上第一个真正的GPU,名为 GeForce 256。

GPU 最初是为了加速电脑游戏中的图形渲染而设计的,但它也已经成为现代人工智能和深度学习领域的核心硬件组件。

GPU 的设计理念是处理成千上万的并行任务,这使得它在执行大规模且复杂的计算时特别高效。与 CPU 的少量核心相比,GPU 拥有大量的小核心,它们可以在同一时间处理大量的数据。

GPU 内部的核心可以分为不同的类型,包括着色器核心、纹理单元和渲染输出单元等,共同执行复杂的图形处理操作。这些核心特别适合执行深度学习所需的高度并行的矩阵和向量运算。此外,GPU 的高内存带宽允许快速的数据读取和写入,这对于处理大型深度学习模型和数据集是必需的。

在 AI 应用中,GPU 显著加速了深度学习模型的训练和推理过程。训练过程涉及到数据的前向传播和反向传播算法,用以计算损失函数并且更新网络的权重。这些计算步骤需要重复进行,并且每一步都要处理大量的数据。GPU 可以同时执行这些步骤中的多个操作,从而大大减少了训练时间。

除了硬件上的优势,GPU 制造商还提供了专门优化的软件工具和库,如 NVIDIA 的 CUDA 和 cuDNN,这些工具为深度学习任务提供了额外的加速。这些软件库简化了在 GPU 上编程的过程,使研究人员和开发人员能够更容易地利用 GPU 进行大规模并行计算,而不需要深入了解其底层硬件架构。

无论是在科学研究、游戏渲染、多媒体内容创作还是 AI 和机器学习的推进中,GPU 都已经成为不可或缺的计算工具。它的并行处理能力、高速内存带宽和专用软件库共同推动了当今最前沿技术的发展,使得AI的训练和部署更加快速和高效。随着技术的进步,GPU 在现代计算生态系统中的作用将继续扩大。

AI 产品

DALL-E 系列

DALL-E 是一个由 OpenAI 研发的人工智能系统,能够根据文本描述生成相应的图像。这个名字是对艺术家萨尔瓦多·达利(Salvador Dalí)和动画片《WALL-E》的致敬。

DALL-E 于 2021 年 1 月 5 日由 OpenAI 首次发布;2022 年 4 月,OpenAI 宣布了新版本的DALL-E 2,声称它可以从文本描述中生成照片般逼真的图像,另外还有一个允许对输出进行简单修改的编辑器。2023 年 9 月份发布 DALL・E ‍3,与 2 相比,它可以利用 ChatGPT 生成提示,然后让模型根据该提示生成图像。

DALL-E 能够生成各种风格的图像,从照相写实主义图像到绘画和表情符号。它还可以「操纵和重新排列」图像中的对象。其创作者指出DALL-E 的一项能力是在没有明确指示的情况下将设计元素正确放置在新颖的作品中

DALL-E 使用了 Transformer 架构,这种架构最初是为了处理自然语言处理任务而设计的。OpenAI 通过将 Transformer 与生成对抗网络(GANs)等图像生成技术结合,使 DALL-E 能够理解文本提示并创造出新颖的、与文本内容相符的图像。

DALL-E 的技术架构基于 GPT-3 的多模态版本,它具备 120 亿个参数,并通过网络上收集的大量文本-图像对进行训练。这种训练使得 DALL-E 能够进行零样本学习,即在没有额外训练的情况下根据描述生成图像。生成的图像随后由 CLIP 模型进行评分和筛选,以提供最高质量的输出。CLIP 自身是一个强大的图像识别系统,它使用了超过 4 亿对图像和文本对进行训练,从而能够将图像与大量文本相关联,并识别出训练集之外的图像内容。

Midjourney

Midjourney 是由 Midjourney 公司开发的一种基于扩散模型的图像生成平台,于 2022 年 7 月进入公测阶段,面向大众开放。

Midjourney 的绘画能力很强,几乎无需 prompt 能力即可得到效果很不错的图,人像、细节方面尤为突出。

与大部分同类服务不同,Midjourney 选择在 Discord 平台上运行,用户无须学习各种烦琐的操作步骤,也无须自行部署,只要在Discord 中用聊天的方式与 Midjourney 的机器人交互就能生成图片。这一平台上手门槛极低,但其生成的图片效果却不输于 DALL·E 和 Stable Diffusion ,于是很快赢得了大量用户。据 Midjourney 的创始人大卫·霍尔兹(David Holz)介绍,仅在发布一个月之后,Midjourney 就已经盈利。

在 2022 年 9 月 5 日,在美国科罗拉多州博览会的年度美术比赛中,一张名为《太空歌剧院》的画作获得了第一名,然而这幅画并非出自人类画家之手,而是由游戏设计师杰森·艾伦(Jason Allen)使用 Midjourney 生成,再经 Photoshop 润色而来。它是首批获得此类奖项的人工智能生成图像之一。

Midjourney 创始人 David Holz 在说到关于 Midjourney 背后的理念时有说到:

MJ 的目标是成为新的人类基础设施,这样才能支撑更多人构建新事物。所以 MJ 的主题是反思、想象和协调。反思自己是谁,想要什么;想象会是什么;协调大家如何抵达。同时也会思考其人性的一面,例如人类通过计算机来想象就能像汽车旅行一样,这意味着什么;又或者人类在想象的过程中以什么方式互动等。

MJ 其实是水。人们误解了人工智能是什么,就像认为其是一只老虎,会吃掉我们。但其实水也很危险,能淹死我们,但流动的河水和老虎完全不同,水是危险的,但是你可以在其中游泳,造船,建造发电站等。水虽然是危险的,但却是文明的驱动力,作为知道如何与水共处的人类,我们能过的更好。水没有意志,也没有恶意,你可以淹死在其中,但并不能应该因此惧怕并禁止水。所以 MJ 试图弄清楚的是,我们如何将其用于人们?我们如何教人们游泳?我们如何造船?我们怎么把它堵起来?我们如何从害怕溺水的人变成未来冲浪的孩子?我们正在制造冲浪板而不是制造水。这才是一些深刻的意义。

困难和有趣是事情的两面,MJ 面临的许多问题无法量化。比如什么是一张「好的狗狗照片」,这很难回答,但也因此有趣。类似的问题还有「什么是好的图像」「人们想从图像中得到什么」「他们是如何沟通的」「他们如何通过文字描绘出他们想要的东西」 —— 这些问题几近哲学,但却很让人喜欢。

关于愿景,希望能以某种方式创造一个更有想象力的世界。因为今天世界最大的问题是信仰崩溃,包括对自己的,对未来的信念。而造成这种问题的主要愿意那就是缺乏想象力,缺乏自己可以成为什么人的想象力,缺乏对未来的想象力。所以想象力才是我们在世界上所需要的东西的重要支柱。所以我想通过 MJ 来将其变成一种可以「扩展人类想象力的力量」

当计算机比 99% 的人类更善于视觉想象时,这意味着什么?这并不意味着我们将停止想象。汽车比人类快,但这并不意味着我们停止步行。当我们远距离运输大量物品时,我们需要发动机,无论是飞机、轮船还是汽车。我们将这项技术视为想象力的引擎。所以这是一个非常积极和人性化的事情。

midjourney.com/showcase

Stable Diffusion

Stable Diffusion 是由 CompVis、Stability AI 和 LAION 的研究人员实现并开源的。从 Stable Diffusion 模型应用用户的角度来看,其核心是根据文本生成图像,可以通过一些技巧,或通过调整用户参数,来改变文本生成图像的过程,从而达到优化最终生成图像的目的。

得益于其卓越的图片生成效果、完全开源的特点以及相对较低的配置需求(可在消费级GPU上运行),在推出后不久它就流行开来,大量开发者以及公司加入它的社区参与共建,同时,还有很多公司基于 Stable Diffusion 推出了自己的 AI 绘画应用。

Stable Diffusion 是 AI 绘画最为重要的开源力量,创业生态的基石

Stable Diffusion 在多个方面表现出色,尤其是在图像质量和生成速度方面。它能够根据复杂的文本描述生成高分辨率和高质量的图像,这在以前的模型中往往难以实现。Stable Diffusion 还能够处理多样化的艺术风格和主题,从现实主义到超现实主义,从肖像画到风景画,甚至是科幻和奇幻的主题。用户可以通过详细的文本提示,引导模型创造出各种各样的视觉内容。

Stable Diffusion 的核心技术包括变分自编码器(VAE)和转换器网络。它通过大规模的图像和文本对数据集进行训练,学习了如何解释文本提示并将其转换为相应的图像。这种结合了自编码器和转换器的架构,不仅使得图像生成过程更为高效,而且还有助于保持生成图像的多样性和创造性。此外,Stable Diffusion 的模型训练采用了强调数据质量和多样性的方法,以确保生成的图像既准确又引人入胜。

AI 公司

OpenAI

OpenAI 成立于 2015 年 12 月,由埃隆·马斯克、萨姆·奥特曼、格雷格·布罗克曼、伊莱亚·萨斯克、约翰·舒尔茨菲尔德等科技行业领袖共同发起。OpenAI 的初衷是作为一个非营利组织,旨在推动和发展友好的人工智能,确保人工智能的发展能够惠及全人类。

在成立之初,OpenAI 提出了一系列雄心勃勃的目标,包括在人工智能领域进行开创性的研究,并且将研究成果公开分享,以促进整个领域的发展。OpenAI 迅速在人工智能研究领域崭露头角,特别是在强化学习和深度学习的应用上取得了显著的成就。

OpenAI 原本是以非营利组织的身份成立的,但在 2019 年初,OpenAI 宣布将采取一种新的「有限利润」公司结构,即 OpenAI LP,这是为了吸引更多的投资以支持其研究和开发。这个结构允许外部投资者投资,但限制了投资回报率。OpenAI LP 的创始投资者包括 Kholsa Ventures、Reid Hoffman 的基金、微软等。

所以,OpenAI 这个美国人工智能研究实验室由非营利组织OpenAI Inc,和其营利组织子公司 OpenAI LP 所组成。

OpenAI 已经推出了多个影响深远的产品和技术,其中包括 GPT 系列、DALL-E 系列、CLIP、Codex等。

除了这些产品,OpenAI 还在多个领域进行研究,包括机器人、强化学习、游戏(如Dota 2中的AI)、自然语言理解和生成等。

Stability AI

Stability AI 是由首席执行官 Emad Mostaque 创立的初创公司。Mostaque 毕业于牛津大学,拥有数学和计算机科学硕士学位(据福布斯的爆料说,其仅为学士学位)。他曾在多家对冲基金担任分析师,后来转向更加公众化的工作。Mostaque 在 2020 年创立了 Stability AI,旨在解决开源人工智能社区中的「组织」问题。

Stability AI 拥有超过 4,000 个 Nvidia A100 GPU 的集群,用于训练 AI 系统,包括 Stable Diffusion。然而,维护这个集群非常昂贵,据报道,Stability AI 的运营和云计算支出超过了 5000 万美元。但是,Mostaque 反复表示,公司的研发将使其能够更高效地训练模型。

除了 Stable Diffusion,Stability AI 还可能提供包括自然语言处理工具、数据分析服务以及 AI 模型定制和咨询服务在内的多种产品和解决方案。公司倡导开源精神,通过提供开源工具和资源,鼓励技术社区的参与与合作,以促进人工智能技术的创新和发展。

为了支持更大规模的用户定制版本的 Stable Diffusion,并投资更多的超级计算能力,Stability AI 在最近一轮融资中筹集了1.01 亿美元。这笔资金还将用于招聘更多员工,Mostaque 预计在未来一年内将员工规模从 100 人增加到 300 人。此外,Stability AI 还计划开发其他可商业化的项目,包括用于生成音频、语言、3D 和视频的 AI 模型。

模型相关

VAE

VAE,Variational Auto-Encoder,变分自编码器

VAE 是一种深度学习模型,用于学习输入数据的概率分布,并生成新的数据样本。它由两大部分组成:编码器将输入数据转换为潜在表示,解码器则将这些潜在表示转换回原始数据空间。VAE 的目标是通过最小化重构误差和正则化潜在空间来训练模型,从而能够生成与训练数据相似的新样本。

VAE 是在自编码器的基础上发展而来,它引入了概率图模型的概念,使得生成的数据能够具有多样性和连续性。自从 2013 年由 Kingma 和 Welling 提出以来,VAE 成为了无监督学习和生成模型领域的一个重要里程碑,催生了一系列相关研究和更复杂的模型变种。

VAE 模型是一个经典的生成式模型,在传统深度学习时代,GAN 的风头完全盖过了 VAE,但 VAE 简洁稳定的 Encoder-Decoder 架构,以及能够高效提取数据 Latent 特征和 Latent 特征像素级重建的关键能力,让其跨过了周期,在 AIGC 时代重新繁荣。

VAE 在 AIGC 领域中非常有用,尤其是在图像生成、文本生成、音乐创作等创造性任务中。它的特点是能够创建一个平滑且连续的潜在空间,使得我们可以通过遍历这个空间来生成具有细微变化的数据样本。此外,VAE 的正则化特性也使其在处理复杂数据分布时具有鲁棒性,并且能够有效防止过拟合。

技术上,VAE 的核心是基于神经网络的编解码器架构。编码器网络将数据映射到潜在空间的参数(均值和方差),而解码器网络则从潜在空间中采样点并重构数据。这个过程中,VAE 使用变分推断来逼近真实数据的概率分布,并通过一种特殊的损失函数(结合重构损失和KL散度)来训练网络。

CLIP

CLIP,Contrastive Language-Image Pre-training,对比图文预训练模型

CLIP 是 OpenAI 开发的一种多模态深度学习模型,设计用来理解图像内容及其对应的文本描述。通过将图像与文本匹配,CLIP 学会了识别图像中的物体、场景和动作,并理解相关的自然语言描述,如标签、说明和标题。

CLIP 包含两个主要部分:一个图像编码器和一个文本编码器。这两部分编码器在一个统一的向量空间内进行对比学习,以便最小化匹配文本和图像对之间的距离。这种方式允许 CLIP 在视觉和语言任务上表现出色。

CLIP 通过对比学习的方法进行预训练,学习了大量图像和文本对的共同表示。它超越了传统的图像分类模型,因为它不仅能够识别图像内容,还能理解与之相关的复杂文本信息。

CLIP 的主要特点是其对抗学习方式,类似于生成对抗网络(GAN)。在训练过程中,图像编码器致力于最小化匹配的文本和图像之间的距离,而文本编码器则尝试最大化它们之间的距离。这种方法有助于模型学习到更丰富、更准确的图像和文本表示。CLIP 在各种图像分类任务上都表现出色,并能够理解图像中的复杂概念,这使得它在多种视觉应用中非常有用。

CLIP 的应用非常广泛,包括但不限于图像检索、视觉问答、视觉导航以及图像生成。此外,基于 CLIP 的原理,OpenAI 还开发了 DALL-E 模型,该模型能够根据文本描述生成相应的图像。

Diffusion

Diffusion 模型是一种生成模型,用于在人工智能生成内容(AIGC)中创建高质量的图像、音频或其他数据形式。

Diffusion Model 的灵感来自 non-equilibrium thermodynamics (非平衡热力学), 理论首先定义扩散步骤的马尔可夫链,缓慢地将随机噪声添加到数据中,然后学习逆向扩散过程以从噪声中构造所需的数据样本。

与传统的生成模型如 GANs 不同, Diffusion 模型通过模拟数据的概率分布来生成新的实例。这些模型从一个随机噪声分布开始,逐渐引入结构,最终生成与训练数据类似的样本。扩散模型是通过固定过程学习,并且隐空间具有比较高的维度。

Diffusion模型建立在去噪自编码器等前期工作的基础上,并因其在生成高质量样本方面的卓越性能而受到关注。与容易出现训练困难和模式崩溃的生成对抗网络(GANs)相比,Diffusion模型的训练过程更加稳定,能够更可靠地生成多样化的高质量内容。

技术上,Diffusion模型包含正向扩散过程和逆向扩散过程。正向过程逐步加入噪声,直至数据完全随机化;而逆向过程则是学习如何从随机噪声中重建数据,这是通过训练一个神经网络来实现的,它能够在每一步预测并减少噪声,逐渐恢复出清晰的数据。

Diffusion 模型在过去几年中得到了快速发展,部分原因是它们在生成高质量样本方面的能力,尤其是在图像和音频生成上。它们在质量和多样性方面逐渐超过了 GANs,这是因为 Diffusion 模型在训练过程中更加稳定,并且它们生成数据的方式更加符合数据的内在分布。

Diffusion 模型在多种场景下都有应用,例如在图像生成领域,可以创造出不存在的逼真物体、场景和人物图像;在文本到图像的合成中,可以根据文本描述生成相应的图像;还可以用于音频合成,生成音乐和语音;或用于数据增强和图像超分辨率等领域。

Disco Diffusion

Disco Diffusion 是一个开源项目,它是一种结合了多种人工智能技术的扩散模型,旨在将文本描述转换为详细的图像。它通过理解语言提示,并将这些提示映射到丰富的视觉表现上,实现了从抽象概念到具体图像的创造性转换。该模型可以接受复杂的文本输入并生成与之相匹配的高质量图像,使用户能够直观地表达和实现他们的创意构想。

Disco Diffusion 的发展是建立在深度学习和生成模型领域的一系列创新之上的。最初的扩散模型在生成逼真图像方面已经取得了突破,但当结合了理解文本和图像关系的 CLIP 模型时,这些生成模型的能力得到了极大的扩展。Disco Diffusion 是这一进展的产物,它不仅继承了先前模型生成高质量图像的能力,还加入了对文本的理解,从而实现了更为直观和创造性的图像生成。

Disco Diffusion 的技术架构是基于扩散模型的,这是一种逐步引入并去除噪声以生成数据的方法。在这个基础上,Disco Diffusion 集成了 OpenAI 的 CLIP 模型,后者训练用于理解图像内容与自然语言描述之间的关联。该模型可能还结合了类似于生成对抗网络(GANs)的组件来提升最终图像的质量,以及变分自编码器(VAEs)来增强图像的多样性和创意表达。

Disco Diffusion 的主要特点是其能够将文本描述转化为高分辨率、高质量的图像。它通过灵活地理解和应用文本提示,结合了随机性和算法控制,生成独一无二的艺术作品。与传统的生成模型相比,Disco Diffusion 在保留图像真实感的同时,提供了更丰富的细节和更深层的创造性探索,使其成为 AIGC 领域中的一个创新和有影响力的工具。

Disco Diffusion 在艺术创作、媒体制作、设计和教育等多个领域都有广泛的应用。艺术家可以使用它来将他们的诗歌或故事变成视觉艺术作品;设计师可以通过它快速生成设计概念图;媒体制作者可以利用它为视频或游戏创造复杂的背景;教育者可以用它来激发学生的创造力并解释抽象概念。

Imagen 系列

Imagen 是 2022 年 5 月 Google Brain 团队研发的一个先进的文本到图像生成系统,它通过深度学习模型将文字描述转换为视觉图像。这种模型的核心功能是捕捉和解析人类语言中的复杂概念,并将这些概念以图像的形式表现出来,生成与文本描述高度一致且视觉上引人入胜的图像。

根据发布在 arXiv 的研究论文中,Imagen 使用了 Transformer 语言模型将文本转换成嵌入向量序列,三个连续的扩散模型将这些向量转换成高清图片。研究团队还开发了 U-Net 改进型扩散模型(Efficient U-Net)以及新的评估工具 DrawBench。Imagen 在 COCO 基准上取得了 7.27 的 FID 分数,优于 DALL-E 2。

与使用图像-文本数据集训练不同,Imagen 仅使用文本编码器(如T5)来处理输入文本。然后,扩散模型将嵌入向量转换为图像,通过迭代去噪过程生成高质量图片。

在 2023 年底 Google 发布 Imagen 2。Imagen 2 最与众不同之处在于,它能够以惊人的准确性,理解复杂抽象的概念,然后把这个概念可视化,细腻之程度令人惊叹!

Imagen 2 的核心,还是复杂的神经网络架构。经过微调的 Transformer 模型,在文本理解和图像合成上,都表现出了无与伦比的性能。

SDXL

SDXL,Stable Diffusion XL,该模型是在 2022 年 AIGC 元年后推出的。其开发历程包括从 0.9 测试版到基于用户反馈的1.0正式版的逐步迭代,不断优化以提高图像质量。

SDXL 是 Stable Diffusion 模型的进阶版,由 Stability AI 发布。这个模型通过双阶段扩散过程,即 Base 和 Refiner 模型,提供了高分辨率的图像生成和精细化处理。SDXL 特别适用于要求高细节图像的应用场景,如 AI 绘画和高级设计任务。

与原版 Stable Diffusion 相比,SDXL 引入了多项技术优化。其 U-Net 参数量显著增加,达到 2.6B,显著提高了模型的学习和图像细节处理能力。Refiner 模型的加入进一步提高了图像的精细度,而新的训练技巧,如多尺度训练,优化了整体模型性能。

当输入是图片时,Stable Diffusion XL 和 Stable Diffusion 一样,首先会使用 VAE 的 Encoder 结构将输入图像转换为Latent 特征,然后 U-Net 不断对 Latent 特征进行优化,最后使用 VAE 的 Decoder 结构将 Latent 特征重建出像素级图像。除了提取 Latent 特征和图像的像素级重建外,VAE 还可以改进生成图像中的高频细节,小物体特征和整体图像色彩。

当 Stable Diffusion XL 的输入是文字时,这时我们不需要 VAE 的 Encoder 结构,只需要 Decoder 进行图像重建。

Stable Diffusion XL 使用了和之前 Stable Diffusion 系列一样的 VAE 结构(KL-f8),但在训练中选择了更大的 Batch-Size(256 vs 9),并且对模型进行指数滑动平均操作(EMA,exponential moving average),EMA 对模型的参数做平均,从而提高性能并增加模型鲁棒性。