AI作画:在AI人工智能领域绽放光彩

关键词:AI绘画、生成式AI、扩散模型、Stable Diffusion、文本到图像、神经网络、prompt工程

摘要:你是否想过,只需输入一句"一只穿着西装的企鹅在月球上喝咖啡",电脑就能立刻画出一幅栩栩如生的画?这不是科幻电影,而是当下火热的"AI作画"技术!本文将带你走进AI绘画的奇妙世界,从"AI如何学会画画"的基本原理,到"如何让AI画出你心中所想"的实战技巧,再到"AI绘画如何改变艺术与设计"的深度思考。我们会用"照片修复"类比扩散模型,用"翻译官+画家"比喻核心技术架构,用简单代码带你亲手生成第一幅AI画作。无论你是艺术爱好者、设计师,还是对AI好奇的小白,都能在这篇文章中找到属于你的"AI绘画入门钥匙"。

背景介绍

目的和范围

AI作画(AI绘画)是生成式人工智能(Generative AI)的明星应用,它能让计算机根据文字描述(甚至草图、图片)自动生成图像。本文的目的是:

  • 用"小学生能听懂"的语言解释AI作画的核心原理(不用复杂公式也能懂扩散模型!);
  • 手把手教你用代码实现AI绘画(5分钟生成你的第一幅作品);
  • 分析AI绘画的实际应用场景和未来趋势(不只是画画,它正在改变100+行业)。

范围:我们聚焦"文本到图像"(Text-to-Image)生成技术,重点讲解目前最主流的"扩散模型"(Diffusion Models),并以Stable Diffusion为例展开实战。

预期读者

  • 艺术/设计从业者:想了解如何用AI提升创作效率的设计师、插画师;
  • AI技术爱好者:想搞懂"AI为什么能画画"的技术小白;
  • 学生/职场人:想快速掌握AI绘画工具的普通人(不需要编程基础也能学会!);
  • 创业者/研究者:关注AI绘画商业价值和技术趋势的从业者。

文档结构概述

本文就像一本"AI绘画说明书",共分为7个核心部分:

  1. 背景介绍:带你认识AI绘画的"前世今生";
  2. 核心概念与联系:用生活例子解释"扩散模型""文本编码"等关键技术;
  3. 核心算法原理:拆解AI绘画的"工作步骤",附简化代码示例;
  4. 项目实战:手把手教你用Stable Diffusion生成图像(含环境搭建+代码解读);
  5. 实际应用场景:看看AI绘画已经在哪些领域"大显身手";
  6. 未来发展趋势与挑战:AI绘画会取代人类艺术家吗?它面临哪些问题?
  7. 总结与思考题:回顾核心知识点,带你深入思考AI与艺术的关系。

术语表

核心术语定义
术语 通俗解释 类比例子
生成式AI 能"创造新内容"的AI(不是简单识别或分类) 像会写小说的机器人(而不是只会读书的机器人)
文本到图像(Text-to-Image) 输入文字描述,输出图像的技术 你说"红色的猫",AI画一只红色的猫
扩散模型(Diffusion Model) AI绘画的"核心引擎",通过"加噪声-去噪声"过程生成图像 像从模糊的照片一步步修复成清晰照片
Prompt 输入给AI的文字描述(“提示词”) 你给画家的"需求清单"(比如"画一只戴帽子的狗")
Latent Space( latent空间) AI内部"理解图像"的"数学世界",图像在这里被表示为数字向量 像画家的"脑海",里面用抽象的想法(而非具体画笔)构思画面
UNet 扩散模型中的"去噪工具",负责从噪声中还原图像 像照片修复师的"放大镜+画笔",能看清模糊图像的细节
相关概念解释
  • GAN(生成对抗网络):早期AI绘画技术,通过"生成器"和"判别器"对抗学习(生成器画假图,判别器分辨真假,两者互相竞争进步)。但生成的图像质量不如扩散模型稳定。
  • VAE(变分自编码器):将图像压缩到latent space的工具,就像"图像压缩机",能把高清图像变成紧凑的数字向量(方便AI处理)。
  • CLIP模型:负责"理解文字和图像关系"的AI,能判断"文字描述"和"图像内容"是否匹配,帮助AI生成更贴合prompt的图像。
缩略词列表
  • AI:人工智能(Artificial Intelligence)
  • GAN:生成对抗网络(Generative Adversarial Networks)
  • VAE:变分自编码器(Variational Autoencoder)
  • DDPM:去噪扩散概率模型(Denoising Diffusion Probabilistic Models,扩散模型的"祖师爷")
  • SD:Stable Diffusion(目前最流行的开源AI绘画模型)

核心概念与联系

故事引入:小明的"太空猫宇航员"画作

小明是个10岁的小学生,他特别喜欢画画,但有个烦恼:他脑海里有个超酷的画面——“一只穿着蓝色宇航服的胖橘猫,戴着透明头盔,坐在月球表面的咖啡杯里,背景是旋转的地球和闪烁的星星”,但他手笨,画不出来。

爸爸告诉他:"我们可以请AI帮忙!“只见爸爸打开电脑,输入了一长串文字,点击"生成”,10秒后,屏幕上出现了一幅和小明想象中几乎一样的画!小明惊呆了:“AI怎么知道我想画什么?它难道会读心术?”

核心概念解释(像给小学生讲故事一样)

其实AI不会读心术,它画画靠的是"四大法宝"。我们一个个认识它们:

核心概念一:生成式AI——会"创造"的AI魔法师

什么是生成式AI?
普通AI(比如人脸识别)是"识别型"的,像个"图书管理员",只能告诉你"这本书叫什么名字";而生成式AI是"创造型"的,像个"魔法师",能凭空变出一本"全新的书"。

AI绘画就是生成式AI的一种——它能创造出以前从未存在过的图像,而不是从已有图片库里找一张给你。

生活例子
识别型AI:你给它一张猫的照片,它说"这是猫"(分类);
生成式AI:你说"画一只长翅膀的猫",它画一张全新的"带翅膀的猫"(创造)。

核心概念二:扩散模型——从"模糊到清晰"的照片修复师

什么是扩散模型?
扩散模型是AI绘画的"核心引擎",它的工作原理像"照片修复":

  1. 前向扩散(加噪声):想象你有一张清晰的照片(比如小明想要的"太空猫"),你一步步往上面撒"灰尘"(加噪声),直到照片变得完全模糊(像电视没信号的雪花屏)。
  2. 反向扩散(去噪声):AI通过学习"加噪声的过程",反过来从"雪花屏"(纯噪声)开始,一步步擦掉"灰尘"(去噪声),最终还原出清晰的照片(太空猫)。

生活例子
就像你在黑板上画画:

  • 前向扩散:你先在黑板上用粉笔乱涂一通(变成模糊的噪声);
  • 反向扩散:然后你拿着黑板擦,从模糊的乱涂中慢慢擦出一只猫的形状(去噪声生成图像)。

AI学的就是"怎么从乱涂中擦出猫"的本事!

核心概念三:文本编码器——AI的"翻译官"

什么是文本编码器?
小明输入的"太空猫宇航员"是中文,但AI只懂"数字语言"(数学向量)。文本编码器的作用就是"翻译":把人类的文字描述(prompt)翻译成AI能理解的数字向量(就像把中文翻译成英文)。

生活例子
你去国外餐厅吃饭,菜单是外文(文字描述),你看不懂,这时来了个翻译官(文本编码器),把菜单翻译成中文(数字向量),你就能告诉厨师(AI)你想吃什么了。

目前最常用的文本编码器是CLIP模型,它不仅能翻译文字,还能"理解"文字和图像的关系(比如知道"蓝色宇航服"对应图像中的蓝色区域)。

核心概念四:图像解码器——AI的"画家之手"

什么是图像解码器?
扩散模型在"latent space"(AI的"脑海")里生成的是"抽象的数字向量"(像画家的"构思草稿"),而不是直接的图像。图像解码器的作用就是把这些"抽象草稿"变成我们能看懂的像素图像(就像画家把草稿画成最终作品)。

生活例子
latent space里的数字向量像"乐谱",图像解码器像"钢琴家",把乐谱(数字)演奏成我们能听懂的音乐(图像)。

核心概念之间的关系(用小学生能理解的比喻)

这四个概念就像一个"AI绘画工厂",分工合作完成画画任务:

  • 生成式AI:工厂的"老板",负责统筹全局,目标是"创造新图像";
  • 文本编码器:工厂的"翻译官",把客户(你)的需求(prompt)翻译成工厂内部能看懂的"工作单"(数字向量);
  • 扩散模型:工厂的"设计师",根据"工作单"在"草稿本"(latent space)上一步步画出"设计图"(去噪声生成latent向量);
  • 图像解码器:工厂的"生产员",把"设计图"(latent向量)变成最终的"产品"(像素图像)。

合作流程
你(客户)→ 告诉翻译官(文本编码器)"我要太空猫"→ 翻译官写工作单→ 设计师(扩散模型)看工作单画草稿→ 生产员(图像解码器)把草稿变成成品画→ 你拿到画。

核心概念原理和架构的文本示意图(专业定义)

以目前最流行的Stable Diffusion模型为例,其核心架构分为3个部分:

1. 文本编码器(Text Encoder)
  • 输入:用户的文本prompt(如"a cat astronaut on the moon");
  • 功能:将文本转换为固定长度的 latent向量(通常是768维或1024维);
  • 实现:基于CLIP模型的文本编码器(如CLIP ViT-L/14),通过Transformer结构学习文本的语义表示。
2. 扩散模型(Diffusion Model)
  • 核心组件:UNet网络(带注意力机制)+ 噪声调度器(Noise Scheduler);
  • 输入:文本编码器生成的 latent向量 + 随机噪声(纯噪声图像的 latent表示);
  • 功能:在噪声调度器的控制下,通过UNet逐步预测并去除噪声,生成与文本匹配的 latent图像表示;
  • 关键过程
    • 噪声调度:预先定义一系列噪声系数β₁, β₂, …, βₜ,控制每个时间步的噪声强度;
    • 反向扩散:从纯噪声(xₜ)开始,对t个时间步迭代:用UNet预测当前噪声,根据噪声调度器公式去除部分噪声,得到更清晰的xₜ₋₁,直到t=0得到最终的 latent图像。
3. 图像解码器(Image Decoder)
  • 输入:扩散模型生成的 latent图像表示(通常尺寸为64×64×4,远小于最终图像);
  • 功能:将低维 latent向量上采样为高分辨率图像(如512×512或1024×1024像素);
  • 实现:基于VAE(变分自编码器)的解码器,通过反卷积层逐步放大图像尺寸,恢复细节。

Mermaid 流程图:Stable Diffusion生成图像的完整流程

输入文本提示词 Prompt
文本编码器 CLIP
生成文本 latent向量
生成随机噪声
扩散模型 UNet
反向扩散去噪 t步
生成图像 latent向量
图像解码器 VAE
输出最终图像

流程图解读

  1. 用户输入文本prompt(如"太空猫宇航员");
  2. 文本编码器(CLIP)将prompt转为文本 latent向量;
  3. 系统生成随机噪声(纯噪声的 latent表示);
  4. 扩散模型(UNet)结合文本 latent向量和随机噪声,通过t步反向扩散去噪,生成图像 latent向量;
  5. 图像解码器(VAE)将图像 latent向量解码为最终的像素图像;
  6. 输出图像到用户界面。

核心算法原理 & 具体操作步骤

扩散模型的核心算法:从"噪声"到"图像"的魔法步骤

扩散模型的灵魂是"反向扩散"过程——如何从纯噪声一步步生成图像。我们用"数学+生活例子"结合的方式拆解步骤:

步骤1:前向扩散——给清晰图像"加噪声"(AI的"学习阶段")

AI在训练时,首先要学习"如何把清晰图像变成噪声"。就像你练习"如何把一幅画涂乱",练熟了才能反过来"从乱涂中画出画"。

数学描述
假设原始清晰图像为x₀,我们定义T个时间步(比如T=1000),每个时间步t(从1到T)给图像加一点噪声。加噪声的公式为:
q ( x t ∣ x t − 1 ) = N ( x t ; 1 − β t x t − 1 , β t I ) q(x_t | x_{t-1}) = \mathcal{N}(x_t; \sqrt{1-\beta_t}x_{t-1}, \beta_t \mathbf{I}) q(xtxt1)=N(xt;1βt xt1,βtI)

  • x t x_t xt:t时刻的含噪声图像;
  • β t \beta_t βt:t时刻的噪声系数(提前设定,随t增大,β_t也增大,加的噪声更多);
  • N ( μ , σ 2 ) \mathcal{N}(\mu, \sigma^2) N(μ,σ2):高斯分布,均值为 1 − β t x t − 1 \sqrt{1-\beta_t}x_{t-1} 1βt xt1,方差为 β t \beta_t βt

生活例子
x₀是一张清晰的猫照片,t=1时加一点噪声(β₁=0.0001),x₁有点模糊但还能看出是猫;t=500时加很多噪声(β₅₀₀=0.01),x₅₀₀已经很模糊;t=1000时加最大噪声(β₁₀₀₀=0.02),x₁₀₀₀变成纯噪声(雪花屏)。

步骤2:反向扩散——从噪声中"去噪声"(AI的"创作阶段")

训练完成后,AI就可以开始"创作"了:从纯噪声x_T开始,一步步去除噪声,还原出清晰图像x₀。

核心思想
AI无法直接从x_T跳到x₀,而是通过UNet网络预测"当前图像x_t中的噪声",然后根据预测的噪声"减去"一部分噪声,得到xₜ₋₁。重复T次,就得到了x₀。

数学描述
反向扩散的概率分布近似为:
p ( x t − 1 ∣ x t ) ≈ N ( x t − 1 ; μ θ ( x t , t ) , σ t 2 I ) p(x_{t-1} | x_t) \approx \mathcal{N}(x_{t-1}; \mu_\theta(x_t, t), \sigma_t^2 \mathbf{I}) p(xt1xt)N(xt1;μθ(xt,t),σt2I)

  • μ θ ( x t , t ) \mu_\theta(x_t, t) μθ(xt,t):AI(UNet)预测的均值(去噪后的图像中心);
  • σ t 2 \sigma_t^2 σt2:固定的方差(噪声调度器提前设定)。

其中, μ θ ( x t , t ) \mu_\theta(x_t, t) μθ(xt,t)的计算公式为:
μ θ ( x t , t ) = 1 1 − β t ( x t − β t 1 − α ˉ t ϵ θ ( x t , t ) ) \mu_\theta(x_t, t) = \frac{1}{\sqrt{1-\beta_t}} \left( x_t - \frac{\beta_t}{\sqrt{1-\bar{\alpha}_t}} \epsilon_\theta(x_t, t) \right) μθ(xt,t)=1βt 1(xt1αˉt βtϵθ(xt,t))

  • α ˉ t = ∏ s = 1 t ( 1 − β s ) \bar{\alpha}_t = \prod_{s=1}^t (1-\beta_s) αˉt=s=1t(1βs):累计的"清晰系数"(随t增大而减小);
  • ϵ θ ( x t , t ) \epsilon_\theta(x_t, t) ϵθ(xt,t):UNet预测的噪声(核心!AI的主要任务就是预测这个噪声)。

生活例子
你看到一张模糊的图(x_t),UNet告诉你:“这张图里的噪声长这样( ϵ θ \epsilon_\theta ϵθ)”,然后你根据公式"擦掉"这部分噪声,得到稍微清晰一点的图(xₜ₋₁)。重复1000次,模糊图就变成了清晰的猫照片。

步骤3:文本引导——让AI画"你想要的"(而不是随便画)

如果只有扩散模型,AI会生成"随机好看的图像",但不一定符合你的prompt。文本引导(Text Guidance)就是让AI"盯着prompt画"的关键。

核心方法:Classifier-Free Guidance(CFG)
简单说,就是让AI同时做两件事:

  1. 不看prompt,生成一张"随便的图像"(无引导图像);
  2. 看prompt,生成一张"符合prompt的图像"(有引导图像);
  3. 把两张图像的差异"放大",让最终图像更贴合prompt。

数学描述
最终预测的噪声为:
ϵ guided = ϵ uncond + w ( ϵ cond − ϵ uncond ) \epsilon_\text{guided} = \epsilon_\text{uncond} + w (\epsilon_\text{cond} - \epsilon_\text{uncond}) ϵguided=ϵuncond+w(ϵcondϵuncond)

  • ϵ uncond \epsilon_\text{uncond} ϵuncond:无引导时预测的噪声(不输入prompt);
  • ϵ cond \epsilon_\text{cond} ϵcond:有引导时预测的噪声(输入prompt);
  • w w w:引导权重(guidance scale,通常设为7-15,w越大,图像越贴合prompt,但可能越不自然)。

生活例子
你让画家画"猫",画家先随便画了一只狗(无引导),再画了一只像猫的动物(有引导),你说:“把像猫的地方再放大10倍!”(w=10),画家就画出了更像猫的图像。

简化代码实现:用PyTorch搭建迷你扩散模型

为了让你更直观理解,我们用PyTorch实现一个"迷你扩散模型",生成简单的28×28手写数字(MNIST数据集)。

步骤1:导入库和设置参数
import torch
import torch.nn as nn
import numpy as np
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt

# 超参数
T = 1000  # 时间步数
beta_start, beta_end = 0.0001, 0.02  # 噪声系数范围
img_size = 28  # MNIST图像尺寸28×28
channels = 1  # 灰度图像,通道数1
batch_size = 128
epochs = 100
步骤2:定义噪声调度器(前向扩散参数)
# 生成β_t、α_t、ᾱ_t数组
beta = torch.linspace(beta_start, beta_end, T)
alpha = 1. - beta
alpha_bar = torch.cumprod(alpha, dim=0)  # ᾱ_t = α₁×α₂×...×α_t
步骤3:定义UNet模型(预测噪声)
class UNet(nn.Module):
    def __init__(self, img_size, channels):
        super().__init__()
        self.img_size = img_size
        self.channels = channels
        
        # 简单的UNet(仅做演示,实际模型更复杂)
        self.down = nn.Sequential(
            nn.Conv2d(channels, 64, 3, padding=1),
            nn.ReLU(),
            nn.Conv2d(64, 128, 3, padding=1, stride=2),  # 下采样
            nn.ReLU()
        )
        
        self.mid = nn.Sequential(
            nn.Conv2d(128, 128, 3, padding=1),
            nn.ReLU()
        )
        
        self.up = nn.Sequential(
            nn.ConvTranspose2d(128, 64, 3, padding=1, stride=2, output_padding=1),  # 上采样
            nn.ReLU(),
            nn.Conv2d(64, channels, 3, padding=1)  # 输出噪声(和输入图像同尺寸)
        )
        
        # 时间步嵌入(将t转换为特征向量)
        self.time_mlp = nn.Sequential(
            nn.Linear(1, 128),
            nn.ReLU(),
            nn.Linear(128, 128)
        )
    
    def forward(self, x, t):
        # x: [batch, channels, img_size, img_size]
        # t: [batch](时间步)
        
        # 时间步嵌入
        t_emb = self.time_mlp(t.unsqueeze(1).float())  # [batch, 128]
        t_emb = t_emb.view(-1, 128, 1, 1)  # 适配卷积维度
        
        # 下采样
        x = self.down(x)  # [batch, 128, 14, 14]
        x = x + t_emb  # 加入时间信息
        
        # 中间层
        x = self.mid(x)  # [batch, 128, 14, 14]
        
        # 上采样
        x = self.up(x)  # [batch, channels, 28, 28]
        return x  # 预测的噪声
步骤4:前向扩散采样(生成含噪声图像)
def forward_diffusion_sample(x0, t, device="cpu"):
    """从x0生成x_t(加噪声)"""
    # 生成均值为0、方差为1的噪声
    noise = torch.randn_like(x0)
    # 计算ᾱ_t(取t时刻的累计α)
    alpha_bar_t = alpha_bar[t].unsqueeze(1).unsqueeze(2).unsqueeze(3)  # 适配图像维度
    # 生成x_t = sqrt(ᾱ_t)x0 + sqrt(1-ᾱ_t)noise
    xt = torch.sqrt(alpha_bar_t) * x0 + torch.sqrt(1 - alpha_bar_t) * noise
    return xt, noise
步骤5:训练模型(学习预测噪声)
device = "cuda" if torch.cuda.is_available() else "cpu"
model = UNet(img_size, channels).to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
criterion = nn.MSELoss()  # 损失函数:预测噪声与真实噪声的均方误差

# 加载MNIST数据集
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
dataset = datasets.MNIST("./data", train=True, download=True, transform=transform)
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

# 训练循环
for epoch in range(epochs):
    model.train()
    total_loss = 0
    for batch in dataloader:
        x0, _ = batch  # x0是清晰图像(手写数字)
        x0 = x0.to(device)
        
        # 随机采样时间步t
        t = torch.randint(0, T, (x0.shape[0],), device=device).long()
        
        # 生成x_t和真实噪声
        xt, noise = forward_diffusion_sample(x0, t, device)
        
        # 模型预测噪声
        noise_pred = model(xt, t)
        
        # 计算损失(预测噪声 vs 真实噪声)
        loss = criterion(noise_pred, noise)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        total_loss += loss.item()
    
    avg_loss = total_loss / len(dataloader)
    if (epoch+1) % 10 == 0:
        print(f"Epoch {epoch+1}, Loss: {avg_loss:.4f}")
步骤6:反向扩散采样(生成图像)
def sample(model, img_size, channels, T, device="cpu"):
    """从纯噪声生成图像"""
    model.eval()
    with torch.no_grad():
        # 初始噪声x_T
        x = torch.randn(16, channels, img_size, img_size, device=device)  # 生成16张图像
        
        for t in reversed(range(0, T)):
            # 生成时间步t的张量
            t_tensor = torch.full((x.shape[0],), t, device=device).long()
            
            # 预测噪声
            noise_pred = model(x, t_tensor)
            
            # 计算α_t、ᾱ_t
            alpha_t = alpha[t]
            alpha_bar_t = alpha_bar[t]
            alpha_bar_t_prev = alpha_bar[t-1] if t > 0 else torch.tensor(1.0, device=device)
            
            # 计算均值μ
            sqrt_reciprocal_alpha_t = 1.0 / torch.sqrt(alpha_t)
            beta_t = beta[t]
            sqrt_one_minus_alpha_bar_t = torch.sqrt(1.0 - alpha_bar_t)
            # 公式:μ = (x_t - (beta_t / sqrt_one_minus_alpha_bar_t) * noise_pred) / sqrt_reciprocal_alpha_t
            mu = sqrt_reciprocal_alpha_t * (x - (beta_t / sqrt_one_minus_alpha_bar_t) * noise_pred)
            
            # 计算方差σ_t
            if t > 0:
                sigma_t = torch.sqrt(beta[t])
            else:
                sigma_t = torch.tensor(0.0, device=device)
            
            # 生成噪声(t=0时不加噪声,确保图像清晰)
            if t > 0:
                noise = torch.randn_like(x)
                x = mu + sigma_t * noise
            else:
                x = mu  # t=0时直接用均值
        
        # 归一化到[0, 1]
        x = (x.clamp(-1, 1) + 1) / 2.0
        return x

# 生成图像
samples = sample(model, img_size, channels, T, device)

# 显示结果
plt.figure(figsize=(10, 10))
for i in range(16):
    plt.subplot(4, 4, i+1)
    plt.imshow(samples[i].cpu().squeeze(), cmap="gray")
    plt.axis("off")
plt.show()

代码说明
这段代码实现了一个简化的扩散模型,通过训练让AI学会从噪声生成MNIST手写数字。实际的Stable Diffusion模型更复杂(如加入文本编码器、更大的UNet、latent space优化等),但核心原理相同——通过"加噪声-学去噪-反向扩散"生成图像。

数学模型和公式 & 详细讲解 & 举例说明

扩散模型的核心数学基础

扩散模型的数学本质是"随机过程"——用一系列高斯分布描述图像从清晰到噪声、再从噪声到清晰的过程。我们重点讲解3个核心公式:

1. 前向扩散的边缘分布:一步到位生成x_t

前面提到,前向扩散是"逐步加噪",但数学上可以证明,x_t可以直接从x0生成,无需一步步计算x1→x2→…→x_t。

公式
q ( x t ∣ x 0 ) = N ( x t ; α ˉ t x 0 , ( 1 − α ˉ t ) I ) q(x_t | x_0) = \mathcal{N}(x_t; \sqrt{\bar{\alpha}_t}x_0, (1-\bar{\alpha}_t)\mathbf{I}) q(xtx0)=N(xt;αˉt x0,(1αˉt)I)

  • α ˉ t = ∏ s = 1 t ( 1 − β s ) \bar{\alpha}_t = \prod_{s=1}^t (1-\beta_s) αˉt=s=1t(1βs):累计的"清晰系数"(t越大, α ˉ t \bar{\alpha}_t αˉt越小,x_t越接近噪声);
  • 含义:已知x0,x_t服从均值为 α ˉ t x 0 \sqrt{\bar{\alpha}_t}x0 αˉt x0、方差为 ( 1 − α ˉ t ) (1-\bar{\alpha}_t) (1αˉt)的高斯分布。

举例
当t=0时, α ˉ 0 = 1 \bar{\alpha}_0=1 αˉ0=1,所以 q ( x 0 ∣ x 0 ) = N ( x 0 ; x 0 , 0 ) q(x_0|x_0)=\mathcal{N}(x_0; x_0, 0) q(x0x0)=N(x0;x0,0)(确定分布,x0就是自身);
当t=T(如T=1000)时, α ˉ T \bar{\alpha}_T αˉT接近0,所以 q ( x T ∣ x 0 ) ≈ N ( x T ; 0 , I ) q(x_T|x_0)\approx\mathcal{N}(x_T; 0, \mathbf{I}) q(xTx0)N(xT;0,I)(纯噪声)。

2. 反向扩散的后验分布:从x_t到x_{t-1}

反向扩散需要计算"已知x_t,x_{t-1}的分布",即 q ( x t − 1 ∣ x t , x 0 ) q(x_{t-1}|x_t, x_0) q(xt1xt,x0)

公式
q ( x t − 1 ∣ x t , x 0 ) = N ( x t − 1 ; μ ~ ( x t , x 0 ) , β ~ t I ) q(x_{t-1}|x_t, x_0) = \mathcal{N}(x_{t-1}; \tilde{\mu}(x_t, x_0), \tilde{\beta}_t \mathbf{I}) q(xt1xt,x0)=N(xt1;μ~(xt,x0),β~tI)
其中,均值 μ ~ ( x t , x 0 ) \tilde{\mu}(x_t, x_0) μ~(xt,x0)为:
μ ~ ( x t , x 0 ) = α ˉ t − 1 β t 1 − α ˉ t x 0 + α t ( 1 − α ˉ t − 1 ) 1 − α ˉ t x t \tilde{\mu}(x_t, x_0) = \frac{\sqrt{\bar{\alpha}_{t-1}}\beta_t}{1-\bar{\alpha}_t}x_0 + \frac{\sqrt{\alpha_t}(1-\bar{\alpha}_{t-1})}{1-\bar{\alpha}_t}x_t μ~(xt,x0)=1αˉtαˉt1 βtx0+1αˉtαt (1αˉt1)xt
方差 β ~ t \tilde{\beta}_t β~t为:
β ~ t = 1 − α ˉ t − 1 1 − α ˉ t β t \tilde{\beta}_t = \frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t}\beta_t β~t=1αˉt1αˉt1βt

含义:这个公式告诉我们,在已知x_t和x0的情况下,x_{t-1}的分布是高斯分布,均值和方差都可以通过x_t、x0和预设的β_t计算。

为什么重要?
AI在训练时,就是通过最小化"预测噪声"和"真实噪声"的差距来学习这个分布。因为x0未知,AI用预测的噪声 ϵ θ ( x t , t ) \epsilon_\theta(x_t, t) ϵθ(xt,t)来近似 μ ~ ( x t , x 0 ) \tilde{\mu}(x_t, x_0) μ~(xt,x0)(见前面的 μ θ \mu_\theta μθ公式)。

3. 损失函数:扩散模型的"学习目标"

扩散模型的训练目标是最小化"预测噪声"和"真实噪声"的均方误差(MSE)。

公式
L = E t , x 0 , ϵ [ ∥ ϵ − ϵ θ ( x t , t ) ∥ 2 ] L = \mathbb{E}_{t, x_0, \epsilon} \left[ \|\epsilon - \epsilon_\theta(x_t, t)\|^2 \right] L=Et,x0,ϵ[ϵϵθ(xt,t)2]

  • ϵ \epsilon ϵ:真实噪声(前向扩散时加入的噪声);
  • ϵ θ ( x t , t ) \epsilon_\theta(x_t, t) ϵθ(xt,t):UNet预测的噪声;
  • E \mathbb{E} E:对t(随机时间步)、x0(随机训练图像)、 ϵ \epsilon ϵ(随机噪声)的期望。

含义:AI的目标是让预测的噪声尽可能接近真实噪声。为什么能通过预测噪声生成图像?因为有了 ϵ θ \epsilon_\theta ϵθ,就能用前面的 μ θ \mu_\theta μθ公式计算去噪后的均值,从而一步步还原图像。

文本引导(CFG)的数学原理

前面提到CFG能让图像更贴合prompt,其数学本质是"放大条件分布和无条件分布的差异"。

公式回顾
ϵ guided = ϵ uncond + w ( ϵ cond − ϵ uncond ) \epsilon_\text{guided} = \epsilon_\text{uncond} + w (\epsilon_\text{cond} - \epsilon_\text{uncond}) ϵguided=ϵuncond+w(ϵcondϵuncond)

举例
假设prompt是"猫",则:

  • ϵ uncond \epsilon_\text{uncond} ϵuncond:不输入prompt时,UNet预测的噪声(生成"随便图像"的噪声);
  • ϵ cond \epsilon_\text{cond} ϵcond:输入"猫"时,UNet预测的噪声(生成"猫图像"的噪声);
  • 差异项 ( ϵ cond − ϵ uncond ) (\epsilon_\text{cond} - \epsilon_\text{uncond}) (ϵcondϵuncond):代表"为了生成猫,需要额外调整的噪声";
  • w=7:将差异放大7倍,让生成的图像更像"猫"。

w的影响

  • w太小(如w=1):图像可能不像猫(引导不足);
  • w太大(如w=20):图像可能过于生硬、细节扭曲(引导过度);
  • 通常最佳w为7-15(Stable Diffusion默认w=7.5)。

项目实战:用Stable Diffusion生成你的第一幅AI画作

开发环境搭建

我们使用Hugging Face的diffusers库(Stable Diffusion官方推荐),无需自己训练模型,直接调用预训练好的SD模型生成图像。

步骤1:安装必要的库

打开终端,输入以下命令:

# 创建虚拟环境(可选但推荐)
conda create -n ai-drawing python=3.10 -y
conda activate ai-drawing

# 安装核心库
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118  # 安装PyTorch(GPU版,CPU版去掉--index-url...)
pip install diffusers transformers accelerate safetensors  # diffusers:SD模型库;transformers:CLIP等模型;accelerate:加速推理
pip install matplotlib pillow  # 显示和保存图像
步骤2:获取Hugging Face访问令牌

Stable Diffusion模型需要从Hugging Face下载,需注册账号并获取访问令牌:

  1. 访问Hugging Face官网,注册账号;
  2. 登录后,进入个人设置→Access Tokens,创建新令牌(权限选"read");
  3. 复制令牌(形如hf_xxxxxx),保存好备用。
步骤3:接受模型协议

SD模型受版权保护,需先接受协议才能下载:

  1. 访问Stable Diffusion v1.5模型页面
  2. 点击"Access repository",阅读并接受协议(需绑定手机号)。

源代码详细实现和代码解读

完整代码:生成"太空猫宇航员"图像
# 导入库
from diffusers import StableDiffusionPipeline
import torch
import matplotlib.pyplot as plt

# 1. 加载Stable Diffusion模型
model_id = "runwayml/stable-diffusion-v1-5"  # 模型名称
pipe = StableDiffusionPipeline.from_pretrained(
    model_id,
    torch_dtype=torch.float16  # 使用float16节省显存(需GPU支持)
)

# 2. 设置设备(优先GPU,没有则用CPU)
pipe = pipe.to("cuda" if torch.cuda.is_available() else "cpu")

# 3. 定义prompt(文本提示词)
prompt = "A fat orange cat wearing a blue spacesuit, sitting in a coffee cup on the moon, with the earth rotating in the background and stars twinkling, ultra detailed, 8k, photorealistic"
# 中文prompt需要用翻译工具转为英文(SD v1.5对中文支持较差,可用DeepL翻译)

# 4. 生成图像(核心参数)
image = pipe(
    prompt=prompt,
    num_inference_steps=50,  # 去噪步数:50步(越多越清晰,耗时越长)
    guidance_scale=7.5,      # 引导权重:7.5(越大越贴合prompt)
    width=512,               # 图像宽度:512(SD v1.5默认支持512×512)
    height=512,              # 图像高度:512
    num_images_per_prompt=1  # 每次生成1张图像
).images[0]  # 获取生成的第一张图像

# 5. 显示和保存图像
plt.figure(figsize=(10, 10))
plt.imshow(image)
plt.axis("off")
plt.show()
image.save("space_cat_astronaut.png")  # 保存为PNG文件
代码解读:核心参数详解
  1. model_id:模型名称

    • “runwayml/stable-diffusion-v1-5”:最经典的开源SD模型,适合入门;
    • 其他模型:“stabilityai/stable-diffusion-2-1”(更高分辨率)、“dreamlike-art/dreamlike-diffusion-1.0”(艺术风格)等。
  2. torch_dtype=torch.float16:数据类型

    • float16(半精度)比float32(单精度)节省50%显存,生成速度更快(需NVIDIA GPU支持,AMD或CPU用float32)。
  3. prompt:文本提示词(最重要的参数!)

    • 技巧:越详细越好,可加入风格词("photorealistic"写实、"cartoon"卡通)、质量词(“8k”、“ultra detailed”)、构图词("close-up"特写、"wide shot"广角)。
    • 反面例子:只写"猫在月球"→ AI可能生成模糊、不贴合想象的图像;
    • 正面例子:加入颜色(“blue spacesuit”)、动作(“sitting in a coffee cup”)、背景(“earth rotating”)→ 生成更精准的图像。
  4. num_inference_steps:去噪步数

    • 含义:反向扩散的迭代次数(t的取值,如50步即从t=50扩散到t=0);
    • 建议值:20-100步(步数太少→图像模糊;太多→耗时增加,收益递减,50步是平衡选择)。
  5. guidance_scale:引导权重(CFG系数)

    • 建议值:7-15(7.5是SD默认值);
    • 调整技巧:生成抽象艺术可降低(w=3-5),生成写实图像可提高(w=10-12)。
常见问题解决
  • 问题1:显存不足(Out of Memory)
    解决:使用float16、减小图像尺寸(如512→256)、安装bitsandbytes库启用8位量化(pipe = StableDiffusionPipeline.from_pretrained(model_id, load_in_8bit=True))。

  • 问题2:生成图像有瑕疵(如多只手、模糊)
    解决:增加去噪步数(如50→100)、优化prompt(更详细描述)、使用"negative prompt"(负面提示词,如negative_prompt="ugly, malformed, blurry")排除不想要的特征。

  • 问题3:中文prompt效果差
    解决:用DeepL翻译成英文;或使用支持中文的模型(如"bigscience/bloom"文本编码器+SD模型,需额外配置)。

进阶技巧:用ControlNet控制图像姿态

如果你想让AI画"特定姿势的人物"(如跳舞的女孩),普通SD可能生成随机姿态。ControlNet可以解决这个问题——通过"条件控制"(如草图、姿态关键点)引导图像生成。

示例代码(使用ControlNet生成指定姿态的人物)

from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from PIL import Image

# 加载ControlNet模型(姿态控制)
controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/sd-controlnet-openpose",
    torch_dtype=torch.float16
)

# 加载带ControlNet的SD管道
pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    controlnet=controlnet,
    torch_dtype=torch.float16
).to("cuda")

# 加载姿态图(可从OpenPose工具生成,或手绘草图)
control_image = Image.open("pose.png").convert("RGB")  # pose.png是包含人体姿态关键点的图像

# 生成图像
prompt = "A girl in a red dress dancing, photorealistic, 8k"
image = pipe(
    prompt=prompt,
    image=control_image,  # 输入姿态控制图
    num_inference_steps=50,
    guidance_scale=7.5
).images[0]

image.save("dancing_girl.png")

效果:AI会严格按照pose.png中的姿态生成跳舞的女孩,解决了"姿态不可控"的问题。

实际应用场景

AI绘画不仅是"玩具",更是能提升效率、创造价值的工具。以下是它在各行各业的真实应用:

1. 艺术创作:让"创意落地"更简单

  • 插画师/设计师:快速生成灵感草图(输入"赛博朋克风格的城市夜景",AI生成10种方案,设计师在此基础上修改);
  • 独立艺术家:创作NFT作品(如用AI生成系列画作《人工智能的梦境》,在OpenSea上售卖);
  • 普通人:零基础创作个性化艺术(给家人画"穿越到侏罗纪的全家福",无需绘画基础)。

案例:游戏公司Niantic(《精灵宝可梦GO》开发商)用AI绘画快速生成游戏场景草图,将原本2周的设计周期缩短到2天。

2. 设计行业:从"需求"到"方案"的加速器

  • 广告设计:生成产品宣传图(输入"一瓶绿色的有机洗发水,放在竹林背景中,阳光照射",AI生成广告图初稿);
  • UI/UX设计:生成APP界面原型(输入"简约风格的天气APP界面,蓝色主题,显示温度和天气图标",AI生成多个UI方案);
  • 服装设计:生成服装款式图(输入"未来科技感的连衣裙,银色材质,带有LED灯带装饰",AI生成设计图)。

数据:据Adobe 2023年报告,使用AI绘画的设计师平均工作效率提升了40%,客户满意度提升了25%。

3. 教育领域:让知识"可视化"更生动

  • 教材插图:生成抽象概念的图像(讲"光合作用"时,用AI画"阳光+树叶+叶绿体"的示意图);
  • 历史教学:还原历史场景(输入"唐朝长安城的街景,有骆驼商队和穿汉服的行人",帮助学生理解历史);
  • 特殊教育:为残障学生生成辅助图像(给视力障碍学生生成"盲文+触觉图像"的教材)。

案例:北京某小学用AI绘画制作科学课教材,将"太阳系行星"的抽象知识转化为生动图像,学生课堂参与度提升了60%。

4. 娱乐产业:内容生产的"超级引擎"

  • 游戏美术:生成角色、场景、道具(如《逆水寒》手游用AI生成NPC头像和场景素材,节省
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐