AI大模型教程
一起来学习

Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task02笔记

目录

了解AI生图技术

1.AI生图前言

 2.AI生图历史

3.通过魔搭社区探索AI生图前沿

 Part1:磨刀准备一一认识通义千问(AI智能助手)

Part2:精读baseline——从零入门AI生图

1.分析代码的主体框架

安装和卸载依赖包(!pip命令)

加载数据集

3.数据预处理

4. 使用 Data-Juicer 进行数据处理

 5.数据整理与训练

6.图像生成

7.合并图像

Part3:实战演练

成果展示

了解AI生图技术

1.AI生图前言

AIGC(AI-Generated Content)是通过人工智能技术自动生成内容的生产方式,很早就有专家指出,AIGC将是未来人工智能的重点方向,也将改造相关行业和领域生产内容的方式。

小常识:警惕Deepfake技术

Deepfake技术是一种使用人工智能技术生成的伪造媒体,特别是视频和音频。它们能够学习真实数据的特征,并生成新的、逼真的数据。

Deepfake技术虽然在多个领域展现出其创新潜力,但其滥用也带来了一系列严重的危害。在政治领域,Deepfake可能被用来制造假新闻或操纵舆论,影响选举结果和政治稳定。经济上,它可能破坏企业形象,引发市场恐慌,甚至操纵股市。法律体系也面临挑战,因为伪造的证据可能误导司法判断。此外,深度伪造技术还可能加剧身份盗窃的风险,成为恐怖分子的新工具,煽动暴力和社会动荡,威胁国家安全。

由此衍生的Deepfake攻防技术 从零入门CV图像竞赛(Deepfake攻防)

 2.AI生图历史

20世纪70年代,艺术家哈罗德·科恩(Harold Cohen)发明AARON,可通过机械臂输出作画。

现代的AI生图模型大多基于深度神经网络基础上训练,最早可追溯到2012年吴恩达训练出的能生成“猫脸”的模型。使用卷积神经网络(CNN)训练,证明了深度学习模型能够学习到图像的复杂特征。

2015年,谷歌推出了“深梦”(Deep Dream)图像生成工具,类似一个高级滤镜,可以基于给定的图片生成梦幻版图片

2021 年 1 月 OpenAI 推出DALL-E模型(一个深度学习算法模型,是GPT-3 语言处理模型的一个衍生版本),能直接从文本提示“按需创造”风格多样的图形设计

一般来说,AI生图模型属于多模态机器学习模型,通过海量的图库和文本描述的深度神经网络学习,最终的目标是可以根据输入的指示(不管是文本还是图片还是任何)生成符合语义的图片

AI生图模型 往往可以照猫画虎绘制出类似的画作,在2022年8月AI生图真正走进了大众的视野,让各个领域无法忽视

3.通过魔搭社区探索AI生图前沿

Kolors(可图)模型(点击即可跳转魔搭模型介绍页) 是快手开源的文本到图像生成模型,该模型具有对英语和汉语的深刻理解,并能够生成高质量、逼真的图像。

Kolors(可图)模型(点击即可跳转魔搭模型介绍页)代码开源链接:https://github.com/Kwai-Kolors/Kolors

模型开源链接:https://modelscope.cn/models/Kwai-Kolors/Kolors

技术报告链接:https://github.com/Kwai-Kolors/Kolors/blob/master/imgs/Kolors_paper.pdf

魔搭研习社最佳实践说明:https://www.modelscope.cn/learn/575?pid=543

 Part1:磨刀准备一一认识通义千问(AI智能助手)

Part2:精读baseline——从零入门AI生图

文生图代码的框架结构:

baseline中的所有代码整理出来,代码结构如下: 

!pip install simple-aesthetics-predictor

!pip install -v -e data-juicer

!pip uninstall pytorch-lightning -y
!pip install peft lightning pandas torchvision

!pip install -e DiffSynth-Studio

from modelscope.msdatasets import MsDataset

ds = MsDataset.load(
    'AI-ModelScope/lowres_anime',
    subset_name='default',
    split='train',
    cache_dir="/mnt/workspace/kolors/data"
)

import json, os
from data_juicer.utils.mm_utils import SpecialTokens
from tqdm import tqdm


os.makedirs("./data/lora_dataset/train", exist_ok=True)
os.makedirs("./data/data-juicer/input", exist_ok=True)
with open("./data/data-juicer/input/metadata.jsonl", "w") as f:
    for data_id, data in enumerate(tqdm(ds)):
        image = data["image"].convert("RGB")
        image.save(f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg")
        metadata = {"text": "二次元", "image": [f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg"]}
        f.write(json.dumps(metadata))
        f.write("n")

data_juicer_config = """
# global parameters
project_name: 'data-process'
dataset_path: './data/data-juicer/input/metadata.jsonl'  # path to your dataset directory or file
np: 4  # number of subprocess to process your dataset

text_keys: 'text'
image_key: 'image'
image_special_token: ''

export_path: './data/data-juicer/output/result.jsonl'

# process schedule
# a list of several process operators with their arguments
process:
    - image_shape_filter:
        min_width: 1024
        min_height: 1024
        any_or_all: any
    - image_aspect_ratio_filter:
        min_ratio: 0.5
        max_ratio: 2.0
        any_or_all: any
"""
with open("data/data-juicer/data_juicer_config.yaml", "w") as file:
    file.write(data_juicer_config.strip())

!dj-process --config data/data-juicer/data_juicer_config.yaml

import pandas as pd
import os, json
from PIL import Image
from tqdm import tqdm


texts, file_names = [], []
os.makedirs("./data/data-juicer/output/images", exist_ok=True)
with open("./data/data-juicer/output/result.jsonl", "r") as f:
    for line in tqdm(f):
        metadata = json.loads(line)
        texts.append(metadata["text"])
        file_names.append(metadata["image"][0])

df = pd.DataFrame({"text": texts, "file_name": file_names})
df.to_csv("./data/data-juicer/output/result.csv", index=False)

df

from transformers import CLIPProcessor, CLIPModel
import torch

model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

images = [Image.open(img_path) for img_path in df["file_name"]]
inputs = processor(text=df["text"].tolist(), images=images, return_tensors="pt", padding=True)

outputs = model(**inputs)
logits_per_image = outputs.logits_per_image  # this is the image-text similarity score
probs = logits_per_image.softmax(dim=1)  # we can take the softmax to get the probabilities

probs

from torch.utils.data import Dataset, DataLoader

class CustomDataset(Dataset):
    def __init__(self, df, processor):
        self.texts = df["text"].tolist()
        self.images = [Image.open(img_path) for img_path in df["file_name"]]
        self.processor = processor

    def __len__(self):
        return len(self.texts)

    def __getitem__(self, idx):
        inputs = self.processor(text=self.texts[idx], images=self.images[idx], return_tensors="pt", padding=True)
        return inputs

dataset = CustomDataset(df, processor)
dataloader = DataLoader(dataset, batch_size=8)

for batch in dataloader:
    outputs = model(**batch)
    logits_per_image = outputs.logits_per_image
    probs = logits_per_image.softmax(dim=1)
    print(probs)

import torch
from diffusers import StableDiffusionPipeline

torch.manual_seed(1)
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v-1-4", torch_dtype=torch.float16)
pipe = pipe.to("cuda")

prompt = "二次元,一个紫色长发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌,手持话筒"
negative_prompt = "丑陋、变形、嘈杂、模糊、低对比度"
guidance_scale = 4
num_inference_steps = 50

image = pipe(
    prompt=prompt,
    negative_prompt=negative_prompt,
    guidance_scale=guidance_scale,
    num_inference_steps=num_inference_steps,
    height=1024,
    width=1024,
).images[0]

image.save("example_image.png")
image

from PIL import Image

torch.manual_seed(1)
image = pipe(
    prompt="二次元,日系动漫,演唱会的观众席,人山人海,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙坐在演唱会的观众席,舞台上衣着华丽的歌星们在唱歌",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("1.jpg")

torch.manual_seed(1)
image = pipe(
    prompt="二次元,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙坐在演唱会的观众席,露出憧憬的神情",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度,色情擦边",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("2.jpg")

torch.manual_seed(2)
image = pipe(
    prompt="二次元,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙坐在演唱会的观众席,露出憧憬的神情",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度,色情擦边",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("3.jpg")

torch.manual_seed(5)
image = pipe(
    prompt="二次元,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙,对着流星许愿,闭着眼睛,十指交叉,侧面",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度,扭曲的手指,多余的手指",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("4.jpg")

torch.manual_seed(0)
image = pipe(
    prompt="二次元,一个紫色中等长度头发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("5.jpg")

torch.manual_seed(1)
image = pipe(
    prompt="二次元,一个紫色长发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌,手持话筒",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("6.jpg")

torch.manual_seed(7)
image = pipe(
    prompt="二次元,紫色长发少女,穿着黑色连衣裙,试衣间,心情忐忑",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("7.jpg")

torch.manual_seed(0)
image = pipe(
    prompt="二次元,紫色长发少女,穿着黑色礼服,连衣裙,在台上唱歌",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("8.jpg")

import numpy as np
from PIL import Image


images = [np.array(Image.open(f"{i}.jpg")) for i in range(1, 9)]
image = np.concatenate([
    np.concatenate(images[0:2], axis=1),
    np.concatenate(images[2:4], axis=1),
    np.concatenate(images[4:6], axis=1),
    np.concatenate(images[6:8], axis=1),
], axis=0)
image = Image.fromarray(image).resize((1024, 2048))
image

1.分析代码的主体框架

  1. 安装和卸载依赖包(!pip命令)

    使用 !pip 命令来安装或卸载 Python 包。包括:

    1. 卸载 pytorch-lightning(使用 -y 自动确认卸载)。

    2. simple-aesthetics-predictor, data-juicer, peft, lightning, pandas, torchvision, 和 DiffSynth-Studio 的安装。

  2. 加载数据集

    使用 ModelScope 的 MsDataset 类加载名为 AI-ModelScope/lowres_anime 的数据集,并指定子集名称为 default 和分割为 train,缓存目录设置为 /mnt/workspace/kolors/data

  • PIL.Image: 用于图像处理。

  • torch: 深度学习库PyTorch的核心模块。

  • torchvision.models, torchvision.transforms, torchvision.datasets: 用于处理图像数据和构建模型。

  • torch.nn, torch.nn.functional: 用于构建神经网络。

  • torch.optim: 用于优化算法。

  • torch.autograd.Variable: 用于自动求导。

  • Dataset: 用于自定义数据集。

  • timm: 用于加载预训练模型。

  • time: 用于计时。

  • pandas, numpy: 用于数据处理。

  • cv2: 用于图像处理。

  • tqdm_notebook: 用于显示进度条。

3.数据预处理

        将数据集中的图像转换为 RGB 模式,并保存到指定目录。

        创建包含图像路径和文本描述的元数据文件 metadata.jsonl

        编写并保存 data_juicer_config.yaml 配置文件,用于后续的数据过滤和处理。

  • torch.manual_seed(0): 设置随机种子,确保结果可复现。

  • torch.backends.cudnn.deterministic = False: 关闭确定性,提高训练速度。

  • torch.backends.cudnn.benchmark = True: 启用基准测试,自动选择最优算法。

4. 使用 Data-Juicer 进行数据处理

  • AverageMeter: 用于计算和存储平均值和当前值,方便在训练和验证过程中跟踪损失和准确率。

  • ProgressMeter: 用于打印训练和验证过程中的进度,显示当前批次和总批次数。

  • validate: 验证函数,计算模型在验证集上的准确率和损失。使用torch.no_grad()确保在验证过程中不计算梯度。

  • predict: 预测函数,计算模型在测试集上的预测结果。使用torch.no_grad()确保在预测过程中不计算梯度。

  • train: 训练函数,计算模型在训练集上的损失和准确率,并进行梯度更新。使用model.train()确保模型处于训练模式。

 5.数据整理与训练

        1.读取 result.jsonl 文件中的数据,并将其转换为 Pandas DataFrame,然后保存为 CSV 文件,并且将图片保存到./data/lora_dataset_processed/train文件夹下。

        2.下载模型download_models([“Kolors”, “SDXL-vae-fp16-fix”])

        3.在前面模型的基础上,执行Lora微调训练

        4.加载微调后的模型

6.图像生成

  • 设置正向提示词,反向提示词,执行次数,图片尺寸

  • 设置随机种子,控制图片是否可以重复生成,并将图像保存为 .jpg 文件。

7.合并图像

        最后,将生成的多个图像合并成一个大图像,并调整大小。

 执行过程(通义千问):

# 安装 Data-Juicer 和 DiffSynth-Studio
!pip install simple-aesthetics-predictor # 安装simple-aesthetics-predictor
!pip install -v -e data-juicer # 安装data-juicer
!pip uninstall pytorch-lightning -y # 卸载pytorch-lightning
!pip install peft lightning pandas torchvision # 安装 peft lightning pandas torchvision
!pip install -e DiffSynth-Studio # 安装DiffSynth-Studio

# 从魔搭数据集中下载数据集AI-ModelScope/lowres_anime
from modelscope.msdatasets import MsDataset  #引入数据集模块msdatasets
ds = MsDataset.load(
    'AI-ModelScope/lowres_anime',
    subset_name='default',
    split='train',
    cache_dir="/mnt/workspace/kolors/data" # 指定缓存目录
) # 从魔搭数据集中下载数据集AI-ModelScope/lowres_anime,赋值给参数ds

# 生成数据集
import json, os # 导入json和os模块
from data_juicer.utils.mm_utils import SpecialTokens # 导入SpecialTokens
from tqdm import tqdm # 导入tqdm进度条管理
os.makedirs("./data/lora_dataset/train", exist_ok=True) # 创建文件夹./data/lora_dataset/train
os.makedirs("./data/data-juicer/input", exist_ok=True) # 创建文件夹./data/data-juicer/input
with open("./data/data-juicer/input/metadata.jsonl", "w") as f:
    for data_id, data in enumerate(tqdm(ds)): # 遍历数据集ds
        image = data["image"].convert("RGB") # 将数据集的图片转换为RGB
        image.save(f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg") # 保存数据集的图片
        metadata = {"text": "二次元", "image": [f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg"]} # 生成当前图片的索引数据
        f.write(json.dumps(metadata)) # 将索引数据写入文件./data/data-juicer/input/metadata.jsonl
        f.write("n")

# 配置data-juicer,并进行数据筛选过滤
# 配置过滤的规则
data_juicer_config = """
# global parameters
project_name: 'data-process' # 名称
dataset_path: './data/data-juicer/input/metadata.jsonl'  # 你前面生成的数据的索引文件
np: 4  # 线程数

text_keys: 'text' # 文件./data/data-juicer/input/metadata.jsonl的描述的字段名
image_key: 'image' # 文件./data/data-juicer/input/metadata.jsonl的图片字段名
image_special_token: ''

export_path: './data/data-juicer/output/result.jsonl' # 筛选通过的图片结果保存的的索引文件

# process schedule
# a list of several process operators with their arguments
# 过滤的规则
process:
    - image_shape_filter: # 图片尺寸过滤
        min_width: 1024 # 最小宽度1024
        min_height: 1024 # 最小高度1024
        any_or_all: any # 符合前面条件的图片才会被保留
    - image_aspect_ratio_filter: # 图片长宽比过滤
        min_ratio: 0.5 # 最小长宽比0.5
        max_ratio: 2.0 # 最大长宽比2.0
        any_or_all: any # 符合前面条件的图片才会被保留
"""

# 保存data-juicer配置到data/data-juicer/data_juicer_config.yaml
with open("data/data-juicer/data_juicer_config.yaml", "w") as file:
    file.write(data_juicer_config.strip())
# data-juicer开始执行数据筛选
!dj-process --config data/data-juicer/data_juicer_config.yaml


# 通过前面通过data-juicer筛选的图片索引信息./data/data-juicer/output/result.jsonl,生成数据集
import pandas as pd # 导入pandas
import os, json # 导入os和json
from PIL import Image # 导入Image
from tqdm import tqdm # 导入tqdm进度条管理
texts, file_names = [], [] # 定义两个空列表,分别存储图片描述和图片名称
os.makedirs("./data/lora_dataset_processed/train", exist_ok=True) # 创建文件夹./data/lora_dataset_processed/train
with open("./data/data-juicer/output/result.jsonl", "r") as file: # 打开前面data-juicer筛选的图片索引文件./data/data-juicer/output/result.jsonl
    for data_id, data in enumerate(tqdm(file.readlines())): # 遍历文件./data/data-juicer/output/result.jsonl
        data = json.loads(data) # 将json字符串转换为对象
        text = data["text"] # 获取对象中的text属性,也就是图片的描述信息
        texts.append(text) # 将图片的描述信息添加到texts列表中
        image = Image.open(data["image"][0]) # 获取对象中的image属性,也就是图片的路径,然后用这个路径打开图片
        image_path = f"./data/lora_dataset_processed/train/{data_id}.jpg" # 生成保存图片的路径
        image.save(image_path) # 将图片保存到./data/lora_dataset_processed/train文件夹中
        file_names.append(f"{data_id}.jpg") # 将图片名称添加到file_names列表中
data_frame = pd.DataFrame() # 创建空的DataFrame
data_frame["file_name"] = file_names # 将图片名称添加到data_frame中
data_frame["text"] = texts # 将图片描述添加到data_frame中
data_frame.to_csv("./data/lora_dataset_processed/train/metadata.csv", index=False, encoding="utf-8-sig") # 将data_frame保存到./data/lora_dataset_processed/train/metadata.csv
data_frame # 查看data_frame


# 下载可图模型
from diffsynth import download_models # 导入download_models
download_models(["Kolors", "SDXL-vae-fp16-fix"]) # 下载可图模型
# DiffSynth-Studio提供了可图的Lora训练脚本,查看脚本信息
!python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py -h


# 执行可图Lora训练
import os
cmd = """
python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py  # 选择使用可图的Lora训练脚本DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py
  --pretrained_unet_path models/kolors/Kolors/unet/diffusion_pytorch_model.safetensors  # 选择unet模型
  --pretrained_text_encoder_path models/kolors/Kolors/text_encoder  # 选择text_encoder
  --pretrained_fp16_vae_path models/sdxl-vae-fp16-fix/diffusion_pytorch_model.safetensors  # 选择vae模型
  --lora_rank 16  # lora_rank 16 表示在权衡模型表达能力和训练效率时,选择了使用 16 作为秩,适合在不显著降低模型性能的前提下,通过 LoRA 减少计算和内存的需求
  --lora_alpha 4.0  # 设置 LoRA 的 alpha 值,影响调整的强度
  --dataset_path data/lora_dataset_processed  # 指定数据集路径,用于训练模型
  --output_path ./models  # 指定输出路径,用于保存模型
  --max_epochs 1  # 设置最大训练轮数为 1
  --center_crop  # 启用中心裁剪,这通常用于图像预处理
  --use_gradient_checkpointing  # 启用梯度检查点技术,以节省内存
  --precision "16-mixed" # 指定训练时的精度为混合 16 位精度(half precision),这可以加速训练并减少显存使用
""".strip()
os.system(cmd) # 执行可图Lora训练


# 加载lora微调后的模型
from diffsynth import ModelManager, SDXLImagePipeline # 导入ModelManager和SDXLImagePipeline
from peft import LoraConfig, inject_adapter_in_model # 导入LoraConfig和inject_adapter_in_model
import torch # 导入torch
# 加载LoRA配置并注入模型
def load_lora(model, lora_rank, lora_alpha, lora_path):
    lora_config = LoraConfig(
        r=lora_rank, # 设置LoRA的秩(rank)
        lora_alpha=lora_alpha, # 设置LoRA的alpha值,控制LoRA的影响权重
        init_lora_weights="gaussian", # 初始化LoRA权重为高斯分布
        target_modules=["to_q", "to_k", "to_v", "to_out"], # 指定要应用LoRA的模块
    )
    model = inject_adapter_in_model(lora_config, model) # 将LoRA配置注入到模型中
    state_dict = torch.load(lora_path, map_location="cpu") # 加载LoRA微调后的权重
    model.load_state_dict(state_dict, strict=False) # 将权重加载到模型中,允许部分权重不匹配
    return model # 返回注入LoRA后的模型
# 加载预训练模型
model_manager = ModelManager(
    torch_dtype=torch.float16, # 设置模型的数据类型为float16,减少显存占用
    device="cuda", # 指定使用GPU进行计算
    file_path_list=[
        "models/kolors/Kolors/text_encoder", # 文本编码器的路径
        "models/kolors/Kolors/unet/diffusion_pytorch_model.safetensors", # UNet模型的路径
        "models/kolors/Kolors/vae/diffusion_pytorch_model.safetensors" # VAE模型的路径
    ]
)
# 初始化图像生成管道
pipe = SDXLImagePipeline.from_model_manager(model_manager) # 从模型管理器中加载模型并初始化管道
# 加载并应用LoRA权重到UNet模型
pipe.unet = load_lora(
    pipe.unet, 
    lora_rank=16, # 设置LoRA的秩(rank),与训练脚本中的参数保持一致
    lora_alpha=2.0, # 设置LoRA的alpha值,控制LoRA对模型的影响权重
    lora_path="models/lightning_logs/version_0/checkpoints/epoch=0-step=500.ckpt" # 指定LoRA权重的文件路径
)


# 生成图像
torch.manual_seed(0) # 设置随机种子,确保生成的图像具有可重复性。如果想要每次生成不同的图像,可以将种子值改为随机值。
image = pipe(
    prompt="二次元,一个紫色短发小女孩,在家中沙发上坐着,双手托着腮,很无聊,全身,粉色连衣裙", # 设置正向提示词,用于指导模型生成图像的内容
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度", # 设置负向提示词,模型会避免生成包含这些特征的图像
    cfg_scale=4, # 设置分类自由度 (Classifier-Free Guidance) 的比例,数值越高,模型越严格地遵循提示词
    num_inference_steps=50, # 设置推理步数,步数越多,生成的图像细节越丰富,但生成时间也更长
    height=1024, width=1024, # 设置生成图像的高度和宽度,这里生成 1024x1024 像素的图像
)
image.save("1.jpg") # 将生成的图像保存为 "1.jpg" 文件


# 图像拼接,展示总体拼接大图
import numpy as np  # 导入numpy库,用于处理数组和数值计算
from PIL import Image  # 导入PIL库中的Image模块,用于图像处理
images = [np.array(Image.open(f"{i}.jpg")) for i in range(1, 9)]  # 读取1.jpg到8.jpg的图像,转换为numpy数组,并存储在列表images中
image = np.concatenate([  # 将四组图像在垂直方向上拼接
    np.concatenate(images[0:2], axis=1),  # 将第1组(images[0:2])的两张图像在水平方向上拼接
    np.concatenate(images[2:4], axis=1),  # 将第2组(images[2:4])的两张图像在水平方向上拼接
    np.concatenate(images[4:6], axis=1),  # 将第3组(images[4:6])的两张图像在水平方向上拼接
    np.concatenate(images[6:8], axis=1),  # 将第4组(images[6:8])的两张图像在水平方向上拼接
], axis=0)  # 将四组拼接后的图像在垂直方向上拼接
image = Image.fromarray(image).resize((1024, 2048))  # 将拼接后的numpy数组转换为图像对象,并调整大小为1024x2048像素
image  # 输出最终生成的图像对象,用于显示图像

Part3:实战演练

你是一个文生图专家,我们现在要做一个实战项目,就是要编排一个文生图话剧
话剧由8张场景图片生成,你需要输出每张图片的生图提示词

具体的场景图片
1、女主正在上课
2、开始睡着了
3、进入梦乡,梦到自己站在路旁
4、王子骑马而来
5、两人相谈甚欢
6、一起坐在马背上
7、下课了,梦醒了
8、又回到了学习生活中

生图提示词要求
1、风格为古风
2、根据场景确定是使用全身还是上半身
3、人物描述
4、场景描述
5、做啥事情

例子:
古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙

 询问通义,结合AI内容进行微调

成果展示

文章来源于互联网:Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task02笔记

赞(0)
未经允许不得转载:5bei.cn大模型教程网 » Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task02笔记

Datawhale AI夏令营第四期 魔搭-AIGC方向 task01笔记

文生图的历史

文生图(Text-to-Image Generation)是一种通过文本生成图像的技术,其发展历程可以追溯到早期的计算机视觉和自然语言处理研究。这一技术的历史可以分为几个关键阶段:

发展阶段

发展介绍

早期探索

(20世纪60年代-20世纪90年代)

文生图的概念最早出现于计算机视觉和图像处理的早期研究中。

早期的图像生成技术主要依赖于规则和模板匹配,通过预定义的规则将文本转换为简单的图形。

然而,由于计算能力和算法的限制,这一阶段的技术能力非常有限,生成的图像质量较低,应用场景也非常有限。

基于统计模型的方法

(2000年代)

进入2000年代,随着统计模型和机器学习技术的发展,文生图技术开始得到更多关注。

研究者们开始利用概率图模型和统计语言模型来生成图像。尽管这一阶段的技术在生成图像的多样性和质量上有了一定提升,但由于模型的复杂性和计算资源的限制,生成的图像仍然较为粗糙,不够逼真。

深度学习的崛起

(2010年代)

2010年代是文生图技术发展的一个重要转折点。随着深度学习,尤其是卷积神经网络(CNN)和生成对抗网络(GAN)的发展,文生图技术取得了突破性进展。2014年,Goodfellow等人提出的GAN模型通过生成器和判别器的对抗训练,极大地提升了图像生成的质量。随后,各类变种GAN模型被提出,如DCGAN、Pix2Pix等,使得文生图技术在生成逼真图像方面达到了前所未有的高度。

大规模预训练模型

(2020年代)

进入2020年代,大规模预训练模型如OpenAI的CLIP、DALL-E以及Stable Diffusion等的出现,标志着文生图技术进入了一个新的时代。

CLIP通过大规模的文本和图像配对数据训练,能够理解和生成高度一致的文本和图像;DALL-E和Stable Diffusion进一步提升了生成图像的创意和细节表现能力,使得通过简单的文本描述生成高质量、复杂图像成为可能。

这些技术的应用范围从艺术创作、广告设计到辅助医疗诊断,展现了广泛的商业价值和社会影响力。

文生图基础知识介绍

提示词:为图片的生成提供信息,一般需要,主要描述,细节和风格。

模型:这次task主要使用stable diffusion中的lora模型,来对预训练好的模型进行优化。

参考图:使用参考图可以对图片进行一些设置,生成更令人满意的图片,可以预先给要生成的图片限定姿势,颜色等框架,也可以使用底稿作为参考图,让AI完成上色工作。

task0 跑通baseline

step 0  开通试用,报名,授权等准备工作

链接:阿里云免费试用 – 阿里云

赛事链接:https://tianchi.aliyun.com/competition/entrance/532254

在魔塔社区创建PAI实例

链接:魔搭社区

step 1 体验一站式 baseline!

下载baseline文件(大约需要2分钟)

git lfs install
git clone https://www.modelscope.cn/datasets/maochase/kolors.git

进入文件夹,打开baseline文件

然后按照notebook中的步骤运行就可以啦!

想要以自己的想法生成图片的话,需要调整prompt

step 2 上传结果

链接:https://www.modelscope.cn/models/create

移动结果文件

终端中运行

mkdir /mnt/workspace/kolors/output & cd 
cp /mnt/workspace/kolors/models/lightning_logs/version_0/checkpoints/epoch=0-step=500.ckpt /mnt/workspace/kolors/output/
cp /mnt/workspace/kolors/1.jpg /mnt/workspace/kolors/output/

下载结果文件

创建并上传模型所需内容

  点击魔搭链接,创建模型,中文名称建议格式:队伍名称-可图Kolors训练-xxxxxx

然后就可以在创空间中查看自己的模型了。

进阶知识

无代码生成图像界面

魔搭平台现推出的零代码图像模型训练工具,您只需提供几张图片,即可训练出专属的lora风格模型,并直接使用该模型生成新的图片。让我们一键开始使用魔搭的图像模型训练工具(点击跳转工具)

baseline代码解释

环境安装

!pip install simple-aesthetics-predictor

!pip install -v -e data-juicer

!pip uninstall pytorch-lightning -y
!pip install peft lightning pandas torchvision

!pip install -e DiffSynth-Studio

下载数据集

#下载数据集
from modelscope.msdatasets import MsDataset

ds = MsDataset.load(
    'AI-ModelScope/lowres_anime',
    subset_name='default',
    split='train',
    cache_dir="/mnt/workspace/kolors/data"
)

import json, os
from data_juicer.utils.mm_utils import SpecialTokens
from tqdm import tqdm

os.makedirs("./data/lora_dataset/train", exist_ok=True)
os.makedirs("./data/data-juicer/input", exist_ok=True)
with open("./data/data-juicer/input/metadata.jsonl", "w") as f:
    for data_id, data in enumerate(tqdm(ds)):
        image = data["image"].convert("RGB")
        image.save(f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg")
        metadata = {"text": "二次元", "image": [f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg"]}
        f.write(json.dumps(metadata))
        f.write("n")
处理数据集,保存数据集处理结果
data_juicer_config = """
# global parameters
project_name: 'data-process'
dataset_path: './data/data-juicer/input/metadata.jsonl'  # path to your dataset directory or file
np: 4  # number of subprocess to process your dataset

text_keys: 'text'
image_key: 'image'
image_special_token: ''

export_path: './data/data-juicer/output/result.jsonl'

# process schedule
# a list of several process operators with their arguments
process:
    - image_shape_filter:
        min_width: 1024
        min_height: 1024
        any_or_all: any
    - image_aspect_ratio_filter:
        min_ratio: 0.5
        max_ratio: 2.0
        any_or_all: any
"""
with open("data/data-juicer/data_juicer_config.yaml", "w") as file:
    file.write(data_juicer_config.strip())

!dj-process --config data/data-juicer/data_juicer_config.yaml


import pandas as pd
import os, json
from PIL import Image
from tqdm import tqdm


texts, file_names = [], []
os.makedirs("./data/lora_dataset_processed/train", exist_ok=True)
with open("./data/data-juicer/output/result.jsonl", "r") as file:
    for data_id, data in enumerate(tqdm(file.readlines())):
        data = json.loads(data)
        text = data["text"]
        texts.append(text)
        image = Image.open(data["image"][0])
        image_path = f"./data/lora_dataset_processed/train/{data_id}.jpg"
        image.save(image_path)
        file_names.append(f"{data_id}.jpg")
data_frame = pd.DataFrame()
data_frame["file_name"] = file_names
data_frame["text"] = texts
data_frame.to_csv("./data/lora_dataset_processed/train/metadata.csv", index=False, encoding="utf-8-sig")
data_frame

lora微调

# 下载模型
from diffsynth import download_models
download_models(["Kolors", "SDXL-vae-fp16-fix"])

#模型训练
import os

cmd = """
python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py 
  --pretrained_unet_path models/kolors/Kolors/unet/diffusion_pytorch_model.safetensors 
  --pretrained_text_encoder_path models/kolors/Kolors/text_encoder 
  --pretrained_fp16_vae_path models/sdxl-vae-fp16-fix/diffusion_pytorch_model.safetensors 
  --lora_rank 16 
  --lora_alpha 4.0 
  --dataset_path data/lora_dataset_processed 
  --output_path ./models 
  --max_epochs 1 
  --center_crop 
  --use_gradient_checkpointing 
  --precision "16-mixed"
""".strip()

os.system(cmd)

加载微调好的模型

from diffsynth import ModelManager, SDXLImagePipeline
from peft import LoraConfig, inject_adapter_in_model
import torch


def load_lora(model, lora_rank, lora_alpha, lora_path):
    lora_config = LoraConfig(
        r=lora_rank,
        lora_alpha=lora_alpha,
        init_lora_weights="gaussian",
        target_modules=["to_q", "to_k", "to_v", "to_out"],
    )
    model = inject_adapter_in_model(lora_config, model)
    state_dict = torch.load(lora_path, map_location="cpu")
    model.load_state_dict(state_dict, strict=False)
    return model


# Load models
model_manager = ModelManager(torch_dtype=torch.float16, device="cuda",
                             file_path_list=[
                                 "models/kolors/Kolors/text_encoder",
                                 "models/kolors/Kolors/unet/diffusion_pytorch_model.safetensors",
                                 "models/kolors/Kolors/vae/diffusion_pytorch_model.safetensors"
                             ])
pipe = SDXLImagePipeline.from_model_manager(model_manager)

# Load LoRA
pipe.unet = load_lora(
    pipe.unet,
    lora_rank=16, # This parameter should be consistent with that in your training script.
    lora_alpha=2.0, # lora_alpha can control the weight of LoRA.
    lora_path="models/lightning_logs/version_0/checkpoints/epoch=0-step=500.ckpt"
)

生成图片

torch.manual_seed(0)
image = pipe(
    prompt="二次元,一个紫色短发小女孩,在家中沙发上坐着,双手托着腮,很无聊,全身,粉色连衣裙",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("1.jpg")

文章来源于互联网:Datawhale AI夏令营第四期 魔搭-AIGC方向 task01笔记

相关推荐: 课程论文太难?AI写作神器一键搞定

论文——一个让大学生闻风丧胆的词语 而且,现在不仅是毕业生要写的毕业论文 很多老师还会布置课程论文 现在临近期末,想必一定有不少同学正在为此发愁 不过别担心,小编整理了几个适合大学生用来辅助课程论文写作的ai神器 【笔灵ai】 笔灵是我使用频率比较高的一款ai…

赞(0)
未经允许不得转载:5bei.cn大模型教程网 » Datawhale AI夏令营第四期 魔搭-AIGC方向 task01笔记

Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task03笔记

目录

一、认识ComfyUI

1.1 主流GUI

1.2 Comfy UI的基础逻辑

1.3 ComfyUI的优势

二、下载Comfy UI

2.1 Comfy UI的使用

三、拓展知识

四、LoRA微调

4.1 LoRA微调的本质

4.2 LoRA微调的代码展示

4.3  UNet、VAE和文本编码器的协作关系

4.4  图文数据


 本篇文章是在task01和task02的基础上,对模型进行微调,了解其中的原理,并作出更高级别的模型从而方便使用。这个Task中会给大家介绍一下文生图的工作流平台工具ComfyUI,来实现一个更加高度定制的文生图。


一、认识ComfyUI

1.1 主流GUI

  本部分部分参考b站up主(点击即可跳转)。

     图形用户界面(Graphical User Interface,简称 GUI):是计算机图形学技术的一种,它一般由窗口、下拉菜单或者对话框等图形化的控件组成。用户通过点击菜单栏、按钮或者弹出对话框的形式来实现与机器的交互,GUI 的存在拉近了人与计算机的的距离,让人机交互的过程变得简单舒适、有温度。

     三种主流GUI:第一种是使用范围最广的以窗口为特征的Web UI。第二种是节点式工作流为特征的并且方便作为后端使用的Comfy UI。第三种就是只需关注提示词无需在乎各种复杂参数就可以获得极高质量生成效果的Fooocus。

     那么开始介绍我们今天的主角Comfy UI:ComfyUI 是GUI的一种,是基于节点工作的用户界面,主要用于操作图像的生成技术,ComfyUI 的特别之处在于它采用了一种模块化的设计,把图像生成的过程分解成了许多小的步骤,每个步骤都是一个节点。这些节点可以连接起来形成一个工作流程,这样用户就可以根据需要定制自己的图像生成过程。Comfy UI本身不仅仅可以作为后端来使用,而且还可以作为插件加入其他GUI中。Comfy UI更加接近于一种SD的原理,也更像是一个通用的可视化代码平台。

      对于它本身来说,是以节点搭建工作流,类似一种乐高搭建积木的感觉适用于长线工作。与此同时他的速度也很快,不限于GPU或者CPU,方便工作者的使用。 作为插件来说,一种是作为Web UI的插件,一种是作为Blender的插件。作为后端来说,一种是作为Comfy Box的后端,另一种就是官方推荐的一款前端界面的Swarm UI。还有一个以Comfy UI作为后端的项目,主流之一的fooocus。

       对于这三种主流的GUI来说他们的使用场景不同:如果只想简单的通过提示词获得高质量图像那就选择fooocus简单省时省力,如果需要丰富好用的插件或者更习惯图文框式的操作界面那就选择Web UI。如果需要长线,定制化,自动化的专业使用那就选择Comfy UI。如果即想要Comfy UI的灵活性又想要图文框式的操作界面那就选择以Comfy UI作为后端的几种前端页面。

1.2 Comfy UI的基础逻辑

      Comfy UI的核心模块由模型加载器(核心模块由模型加载器、提示词管理器、采样器、解码器。)、提示词管理器(核心模块由模型加载器、提示词管理器、采样器、解码器。)、采样器 (核心模块由模型加载器、提示词管理器、采样器、解码器。)、解码器(核心模块由模型加载器、提示词管理器、采样器、解码器。)。

      首先我们围绕Comfy UI的基础逻辑展开认识,他的构建类似于一个搭建积木,第一先需要组件,然后构造,再接下来成为结构,便可以实现功能。也就是从模块到模组再到功能组成为工作流最后实现目标一样。而实现就是这个逆过程。

      那么我们开始从下到上介绍各个区域,首先就是模块也可以叫节点英文名nodes,把模块和模组放在一起来介绍,其核心包括采样器,加载器,条件,潜空间,图像,蒙版,通用等七大组,除了核心之外,还有客制等部分。

       说完模块和模组,接下来来到功能组,来到两大提示词输入,文本提示词由CLIP模型+正负提示词输入组成。图像提示词由图像编码器接入条件编码器模型以及图像组成,这两种功能组最终都已经条件作为输出。然后就是初始噪声和controlnet,初始噪声有三种模式,第一种是最常用到的潜空间噪声,也就是平时看到的emptylatentimage模块另外就是像素噪声图,可以通过刚刚提到的第三方模组生成然后经过VAE编码器进入潜空间,还有就是将图像经过VAE编码进入潜空间的方式(就是图生图的方式)。对于CN,则是通过一个处理器接入CN模型,条件以及预处理的特定图像通过选择与CN模型相匹配的预处理器完成控制最终以条件输出。来到最核心的采样器部分,分别以主模型,正负条件和潜空间噪声图作为输入最后以潜空间作为输出,其他还有很多不再一一说明。

    将需要的功能组组合在一起便生成了工作流基本的原理图如下图所示

1.3 ComfyUI的优势

模块化和灵活性:ComfyUI 提供了一个模块化的系统,用户可以通过拖放不同的模块来构建复杂的工作流程。这种灵活性允许用户根据自己的需求自由组合和调整模型、输入、输出、和其他处理步骤。

可视化界面:ComfyUI 提供了直观的图形界面,使得用户能够更清晰地理解和操作复杂的 AI 模型和数据流。这对没有编程背景的用户特别有帮助,使他们能够轻松构建和管理工作流程。

多模型支持:ComfyUI 支持多个不同的生成模型,用户可以在同一平台上集成和切换使用不同的模型,从而实现更广泛的应用场景。

调试和优化:通过其可视化界面,ComfyUI 使得调试生成过程变得更简单。用户可以轻松地追踪数据流,识别并解决问题,从而优化生成结果。

开放和可扩展:ComfyUI 是一个开源项目,具有高度的可扩展性。开发者可以根据需要编写新的模块或插件,扩展系统功能,并根据项目需求进行定制。

用户友好性:尽管其功能强大,但 ComfyUI 仍然保持了用户友好性,即使对于复杂任务,也能以相对简单的方式完成,使其成为生成式 AI 工作流程管理的有力工具。

二、下载Comfy UI

   回到我们的魔搭社区(点击跳转),利用免费算力来下载

  开启之后点击左上角的file,点击新建,然后点击Terminal,把下面的代码粘贴进去。

git lfs install
git clone https://www.modelscope.cn/datasets/maochase/kolors_test_comfyui.git
mv kolors_test_comfyui/* ./
rm -rf kolors_test_comfyui/
mkdir -p /mnt/workspace/models/lightning_logs/version_0/checkpoints/
mv epoch=0-step=500.ckpt /mnt/workspace/models/lightning_logs/version_0/checkpoints/   

  下一步点击运行,也就是上面一筐倒数第三个按键开始运行的图如下所示。

     运行时间较长,耐心等待。

    运行结束之后会出现一个访问链接,点击链接This is the URL to access Comfy UI,(我这里出现一个时间超了的问题asyncio.exceptions.TimeoutError,可以重启再试试)

2.1 Comfy UI的使用

    进入Comfy UI,但进入之后还需要上传文件,在这里我补充一个名词,你们知道的跳过就行。(PS:如果链接访问白屏,或者报错,就等一会再访问重试,程序可能没有正常启动完毕

      LORA是Low-Rank Adaptation的缩写,最早在2021年论文《LoRA: Low-Rank Adaptation of Large Language Models》中提出。是一种大语言模型低秩适配器,简单来说就是它可以降低模型可训练参数,使其尽量不损失模型表现的大模型微调方法,
     在此之前,StableDiffusion只能通过使用Dreambooth的方法训练大模型,如果对大模型的效果不满意,那么就只能从头开始,重新训练,但是大模型的训练要求高,算力要求大,速度慢。自从LORA被引入StableDiffusion后,大大降低了训练门槛,并扩宽了产出模型的适用范围。这就使得我们这些对AI绘画感兴趣的非专业人员,也可以在家用电脑上尝试训练自己的LORA模型。

    LoRA现在已经广泛应用于商业场景中,将IP形象训练成LORA就大大节省了运营去根据不同活动不同场景结合IP绘制的时间;在电商领域,可以将衣服训练成LORA,就不需要请模特,或者拍摄,直接用AI生成模特,使用LORA给AI模特穿上特定的服饰;很多需要真人出镜拍摄的场景,也可以使用LoRA模型,让一切变的简单可操作。

   接下来需要下载工作流脚本(我网盘空间不知道为啥不够了,太麻烦了我就把文件放在文章最开头了,需要的自己拿)在文章最上面,打开之后是这个界面,点击load(那个负荷),选择下载的json文件,一个是带有Lora的一个是不带的,然后等待生成图片,生成图片的时间可能有点长,需要耐心等待。

三、拓展知识

在魔搭使用ComfyUI,玩转AIGC!:https://modelscope.cn/headlines/article/429

ComfyUI的官方地址:https://github.com/comfyanonymous/ComfyUI

ComfyUI官方示范:https://comfyanonymous.github.io/ComfyUI_examples/

别人的基础工作流示范:https://github.com/cubiq/ComfyUI_Workflows                                        https://github.com/wyrde/wyrde-comfyui-workflows

工作流分享网站:https://comfyworkflows.com/

推荐一个比较好的comfyui的github仓库网站:https://github.com/ZHO-ZHO-ZHO/ComfyUI-Workflows-ZHO?tab=readme-ov-file

四、LoRA微调

4.1 LoRA微调的本质

    LoRA (Low-Rank Adaptation) 微调是一种用于在预训练模型上进行高效微调的技术。它可以通过高效且灵活的方式实现模型的个性化调整,使其能够适应特定的任务或领域,同时保持良好的泛化能力和较低的资源消耗。这对于推动大规模预训练模型的实际应用至关重要。

     微调的本质:把模型通过数据训练成另外一个新的模型,而模型的本质又是有一群参数构成的,那么新的模型就是通过原来的参数经过某种修改从而形成新的模型,所以本质就是修改模型的参数,保留原模型的部分功能,放大模型的部分能力。

   区别:这里面的参数全都通过学习的方法得出便是全量微调。

              用更少量的资源进行得出参数的方法就叫PEFT,LoRA便是其中一种。

   因为有的数据可能是多余的,也就是利用了大量的资源,而得出多余的重复的参数,得到有价值的数据,扩大想要的模型功能,所以为了高效的学习,我们引入一个矩阵进行说明。

    W是一个100*100的矩阵,他包含1w条数据,但是他可以拆分成A和B两个矩阵,而他们含有的参数为=100*k*2,大大的降低了参数的含量,从而使得更少的资源得到了充分的利用,这就是LoRA微调的基本思想

   

 LoRA微调的原理: LoRA通过在预训练模型的关键层中添加低秩矩阵来实现。这些低秩矩阵通常被设计成具有较低维度的参数空间,这样它们就可以在不改变模型整体结构的情况下进行微调。在训练过程中,只有这些新增的低秩矩阵被更新,而原始模型的大部分权重保持不变。

LoRA的优势

     快速适应新任务:在特定领域有少量标注数据的情况下,也可以有效地对模型进行个性化调整,可以迅速适应新的领域或特定任务。

     保持泛化能力:LoRA通过微调模型的一部分,有助于保持模型在未见过的数据上的泛化能力,同时还能学习到特定任务的知识。

     资源效率:LoRA旨在通过仅微调模型的部分权重,而不是整个模型,从而减少所需的计算资源和存储空间。

4.2 LoRA微调的代码展示

     在task02中的微调代码。

import os
cmd = """
python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py  # 选择使用可图的Lora训练脚本DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py
  --pretrained_unet_path models/kolors/Kolors/unet/diffusion_pytorch_model.safetensors  # 选择unet模型
  --pretrained_text_encoder_path models/kolors/Kolors/text_encoder  # 选择text_encoder
  --pretrained_fp16_vae_path models/sdxl-vae-fp16-fix/diffusion_pytorch_model.safetensors  # 选择vae模型
  --lora_rank 16  # lora_rank 16 表示在权衡模型表达能力和训练效率时,选择了使用 16 作为秩,适合在不显著降低模型性能的前提下,通过 LoRA 减少计算和内存的需求
  --lora_alpha 4.0  # 设置 LoRA 的 alpha 值,影响调整的强度
  --dataset_path data/lora_dataset_processed  # 指定数据集路径,用于训练模型
  --output_path ./models  # 指定输出路径,用于保存模型
  --max_epochs 1  # 设置最大训练轮数为 1
  --center_crop  # 启用中心裁剪,这通常用于图像预处理
  --use_gradient_checkpointing  # 启用梯度检查点技术,以节省内存
  --precision "16-mixed" # 指定训练时的精度为混合 16 位精度(half precision),这可以加速训练并减少显存使用
""".strip()
os.system(cmd) # 执行可图Lora训练    

这是部分参数对应相关解释。

4.3  UNet、VAE和文本编码器的协作关系

  • UNet:负责根据输入的噪声和文本条件生成图像。在Stable Diffusion模型中,UNet接收由VAE编码器产生的噪声和文本编码器转换的文本向量作为输入,并预测去噪后的噪声,从而生成与文本描述相符的图像

  • VAE:生成模型,用于将输入数据映射到潜在空间,并从中采样以生成新图像。在Stable Diffusion中,VAE编码器首先生成带有噪声的潜在表示,这些表示随后与文本条件一起输入到UNet中

  • 文本编码器:将文本输入转换为模型可以理解的向量表示。在Stable Diffusion模型中,文本编码器使用CLIP模型将文本提示转换为向量,这些向量与VAE生成的噪声一起输入到UNet中,指导图像的生成过程

4.4  图文数据

首先明确需求目的

  • 关注应用场景:确定你的模型将被应用到什么样的场景中(例如,艺术风格转换、产品图像生成、医疗影像合成等)。

  • 关注数据类型:你需要什么样的图片?比如是真实世界的照片还是合成图像?是黑白的还是彩色的?是高分辨率还是低分辨率?

  • 关注数据量:考虑你的任务应该需要多少图片来支持训练和验证。

数据集来源整理

数据类型 推荐
公开数据平台
  • ImageNet:包含数百万张图片,广泛用于分类任务,也可以用于生成任务。

  • Open Images:由Google维护,包含数千万张带有标签的图片。

  • Flickr:特别是Flickr30kK和Flickr8K数据集,常用于图像描述任务。

  • CelebA:专注于人脸图像的数据集。

  • LSUN (Large-scale Scene Understanding):包含各种场景类别的大规模数据集。

利用API或者爬虫获取
  1. 如果需要特定类型的内容,可以利用API从图库网站抓取图片,如Unsplash、Pexels等。

  2. 使用网络爬虫技术从互联网上抓取图片,但需要注意版权问题。

数据合成

利用现有的图形引擎(如Unity、Unreal Engine)或特定软件生成合成数据,这在训练某些类型的模型时非常有用。

最近Datawhale联合阿里云天池,做了一整套多模态大模型数据合成的学习,欢迎大家一起交流。从零入门多模态大模型数据合成

数据增强

对于较小的数据集,可以通过旋转、翻转、缩放、颜色变换等方式进行数据增强

购买或定制

如果你的应用是特定领域的,比如医学影像、卫星图像等,建议从靠谱的渠道购买一些数据集。

补充:之前task01那个美学评分我现在才看到,在官网上面我复制过来。

import torch, os
from PIL import Image
from transformers import CLIPProcessor
from aesthetics_predictor import AestheticsPredictorV2Linear
from modelscope import snapshot_download


model_id = snapshot_download('AI-ModelScope/aesthetics-predictor-v2-sac-logos-ava1-l14-linearMSE', cache_dir="models/")
predictor = AestheticsPredictorV2Linear.from_pretrained(model_id)
processor = CLIPProcessor.from_pretrained(model_id)
device = "cuda"
predictor = predictor.to(device)


def get_aesthetics_score(image):
    inputs = processor(images=image, return_tensors="pt")
    inputs = {k: v.to(device) for k, v in inputs.items()}
    with torch.no_grad():
        outputs = predictor(**inputs)
    prediction = outputs.logits
    return prediction.tolist()[0][0]


def evaluate(folder):
    scores = []
    for file_name in os.listdir(folder):
        if os.path.isfile(os.path.join(folder, file_name)):
            image = Image.open(os.path.join(folder, file_name))
            scores.append(get_aesthetics_score(image))
    if len(scores) == 0:
        return 0
    else:
        return sum(scores) / len(scores)


score = evaluate("./images")
print(score)

文章来源于互联网:Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task03笔记

相关推荐: 提升写作效率:DeepSeek智能写作助手全解析

在当今信息爆炸的时代,内容创作的需求日益增加,如何高效地生成高质量文章成为许多写作者面临的挑战。DeepSeek智能写作助手应运而生,凭借其强大的功能,帮助用户在短时间内批量生成优质内容。本文将对DeepSeek的主要功能进行深入解析,探讨其如何提升写作效率。…

赞(0)
未经允许不得转载:5bei.cn大模型教程网 » Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task03笔记

Datawhale AI夏令营第四期魔搭- AIGC方向 task02笔记

1,代码拆析部分:http://t.csdnimg.cn/UHvD2
2,运行样例提示词

3,修改提示词,借用ai工具辅助,以下为我的提示词表格

场景编号 场景描述 生图提示词
1 女主在古亭中抚琴 幽静古亭,晨光微露,身着淡紫罗裙的少女端坐于石凳之上,轻抚古琴,指尖跳跃间,音符如泉水般流淌而出,上半身特写,周围是郁郁葱葱的竹林,清风徐来,竹叶沙沙作响,增添一份宁静与雅致。
2 琴声引来了林间小鹿 古风林间,少女琴声悠扬,吸引了一只小鹿悄悄靠近,它好奇地望着少女,眼中闪烁着灵动的光芒,全身镜头,小鹿与少女之间仿佛建立了一种微妙的联系,周围是盛开的野花和轻舞的蝴蝶,营造出一幅和谐共生的画面。
3 小鹿引领少女进入秘境 神秘秘境,小鹿在前引领,少女紧随其后,穿过一片迷雾缭绕的竹林,眼前豁然开朗,一片未被尘世污染的仙境展现在眼前,全身照,少女眼中闪烁着惊奇与喜悦,四周是奇花异草,瀑布飞泻,宛如世外桃源。
4 秘境中偶遇仙人 仙风道骨,一位白发苍苍的仙人悠然自得地坐在秘境中央的巨石之上,闭目养神,少女无意间闯入,两人目光交汇,仙人微微一笑,仿佛看穿了世间万物,全身视角,周围云雾缭绕,仙气飘飘,营造出一种超凡脱俗的氛围。
5 仙人传授秘籍 古老秘籍,仙人缓缓展开一卷泛黄的古籍,向少女传授修炼之法,少女虔诚聆听,眼中闪烁着求知的光芒,半身至全身照,古籍上的符文闪烁着神秘的光芒,周围是静谧的竹林和潺潺的流水声,让人感受到一股强大的力量正在汇聚。
6 少女修炼有成,与仙人共舞云端 云端之上,少女修炼有成,身姿轻盈如燕,与仙人一同在云端翩翩起舞,两人衣袂飘飘,仿佛与天地融为一体,全身照,周围是绚烂的云霞和缥缈的雾气,展现出一种超脱世俗的美感和力量。
7 梦境破碎,少女回到现实 现实回归,少女猛然从梦中惊醒,发现自己仍坐在古亭之中,古琴依旧在旁,但周围却没有了秘境与仙人的踪迹,上半身特写,少女眼中闪烁着失落与不舍,但更多的是对未来的憧憬与决心。
8 少女决心将所学用于造福苍生 决心已定,少女站起身来,目光坚定地望着远方,心中已有了明确的目标——将所学用于造福苍生,全身照,她轻轻抚摸着古琴,仿佛在与它告别,同时也是在向自己的过去告别,迎接一个全新的开始。

4,出图如下,

5,总结部分:在本次文生图的实践中,我深刻体会到了文字与图像之间奇妙的转化力量。通过精心构思的提示词,我能够引导AI生成出既符合古风韵味又充满创意的场景图片。这一过程不仅锻炼了我的文字表达能力和想象力,还让我对图像创作的艺术性和技术性有了更深入的理解。我学会了如何运用细腻的笔触和丰富的色彩来营造氛围,如何通过构图和细节来讲述故事。更重要的是,我意识到文生图不仅仅是技术的展现,更是情感与创意的传递。在这个过程中,我学会了如何将内心的想法和情感转化为视觉语言,与观众产生共鸣。总之,本次文生图的实践让我收获颇丰,不仅提升了我的创作技能,还激发了我对艺术创作的无限热爱和追求。

文章来源于互联网:Datawhale AI夏令营第四期魔搭- AIGC方向 task02笔记

相关推荐: 五大AI写作神器,助力论文写作一路畅通

一、ailisipaper:文理工科论文写作的智囊团 ailisipaper这款专为文理工科学生打造的智能论文写作辅助工具。它基于先进的自然语言处理(NLP)技术和深度学习算法,研发出了学术之星4.0学术模型,能够精准理解用户需求,提供高质量的写作支持。ail…

赞(0)
未经允许不得转载:5bei.cn大模型教程网 » Datawhale AI夏令营第四期魔搭- AIGC方向 task02笔记

Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task02笔记

一、精读baseline——从零入门AI生图

1.baseline代码

我把baseline中的所有代码整理出来,代码结构如下:

!pip install simple-aesthetics-predictor

!pip install -v -e data-juicer

!pip uninstall pytorch-lightning -y
!pip install peft lightning pandas torchvision

!pip install -e DiffSynth-Studio

from modelscope.msdatasets import MsDataset

ds = MsDataset.load(
    'AI-ModelScope/lowres_anime',
    subset_name='default',
    split='train',
    cache_dir="/mnt/workspace/kolors/data"
)

import json, os
from data_juicer.utils.mm_utils import SpecialTokens
from tqdm import tqdm


os.makedirs("./data/lora_dataset/train", exist_ok=True)
os.makedirs("./data/data-juicer/input", exist_ok=True)
with open("./data/data-juicer/input/metadata.jsonl", "w") as f:
    for data_id, data in enumerate(tqdm(ds)):
        image = data["image"].convert("RGB")
        image.save(f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg")
        metadata = {"text": "二次元", "image": [f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg"]}
        f.write(json.dumps(metadata))
        f.write("n")

data_juicer_config = """
# global parameters
project_name: 'data-process'
dataset_path: './data/data-juicer/input/metadata.jsonl'  # path to your dataset directory or file
np: 4  # number of subprocess to process your dataset

text_keys: 'text'
image_key: 'image'
image_special_token: ''

export_path: './data/data-juicer/output/result.jsonl'

# process schedule
# a list of several process operators with their arguments
process:
    - image_shape_filter:
        min_width: 1024
        min_height: 1024
        any_or_all: any
    - image_aspect_ratio_filter:
        min_ratio: 0.5
        max_ratio: 2.0
        any_or_all: any
"""
with open("data/data-juicer/data_juicer_config.yaml", "w") as file:
    file.write(data_juicer_config.strip())

!dj-process --config data/data-juicer/data_juicer_config.yaml

import pandas as pd
import os, json
from PIL import Image
from tqdm import tqdm


texts, file_names = [], []
os.makedirs("./data/data-juicer/output/images", exist_ok=True)
with open("./data/data-juicer/output/result.jsonl", "r") as f:
    for line in tqdm(f):
        metadata = json.loads(line)
        texts.append(metadata["text"])
        file_names.append(metadata["image"][0])

df = pd.DataFrame({"text": texts, "file_name": file_names})
df.to_csv("./data/data-juicer/output/result.csv", index=False)

df

from transformers import CLIPProcessor, CLIPModel
import torch

model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

images = [Image.open(img_path) for img_path in df["file_name"]]
inputs = processor(text=df["text"].tolist(), images=images, return_tensors="pt", padding=True)

outputs = model(**inputs)
logits_per_image = outputs.logits_per_image  # this is the image-text similarity score
probs = logits_per_image.softmax(dim=1)  # we can take the softmax to get the probabilities

probs

from torch.utils.data import Dataset, DataLoader

class CustomDataset(Dataset):
    def __init__(self, df, processor):
        self.texts = df["text"].tolist()
        self.images = [Image.open(img_path) for img_path in df["file_name"]]
        self.processor = processor

    def __len__(self):
        return len(self.texts)

    def __getitem__(self, idx):
        inputs = self.processor(text=self.texts[idx], images=self.images[idx], return_tensors="pt", padding=True)
        return inputs

dataset = CustomDataset(df, processor)
dataloader = DataLoader(dataset, batch_size=8)

for batch in dataloader:
    outputs = model(**batch)
    logits_per_image = outputs.logits_per_image
    probs = logits_per_image.softmax(dim=1)
    print(probs)

import torch
from diffusers import StableDiffusionPipeline

torch.manual_seed(1)
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v-1-4", torch_dtype=torch.float16)
pipe = pipe.to("cuda")

prompt = "二次元,一个紫色长发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌,手持话筒"
negative_prompt = "丑陋、变形、嘈杂、模糊、低对比度"
guidance_scale = 4
num_inference_steps = 50

image = pipe(
    prompt=prompt,
    negative_prompt=negative_prompt,
    guidance_scale=guidance_scale,
    num_inference_steps=num_inference_steps,
    height=1024,
    width=1024,
).images[0]

image.save("example_image.png")
image

from PIL import Image

torch.manual_seed(1)
image = pipe(
    prompt="二次元,日系动漫,演唱会的观众席,人山人海,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙坐在演唱会的观众席,舞台上衣着华丽的歌星们在唱歌",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("1.jpg")

torch.manual_seed(1)
image = pipe(
    prompt="二次元,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙坐在演唱会的观众席,露出憧憬的神情",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度,色情擦边",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("2.jpg")

torch.manual_seed(2)
image = pipe(
    prompt="二次元,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙坐在演唱会的观众席,露出憧憬的神情",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度,色情擦边",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("3.jpg")

torch.manual_seed(5)
image = pipe(
    prompt="二次元,一个紫色短发小女孩穿着粉色吊带漏肩连衣裙,对着流星许愿,闭着眼睛,十指交叉,侧面",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度,扭曲的手指,多余的手指",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("4.jpg")

torch.manual_seed(0)
image = pipe(
    prompt="二次元,一个紫色中等长度头发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("5.jpg")

torch.manual_seed(1)
image = pipe(
    prompt="二次元,一个紫色长发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌,手持话筒",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("6.jpg")

torch.manual_seed(7)
image = pipe(
    prompt="二次元,紫色长发少女,穿着黑色连衣裙,试衣间,心情忐忑",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("7.jpg")

torch.manual_seed(0)
image = pipe(
    prompt="二次元,紫色长发少女,穿着黑色礼服,连衣裙,在台上唱歌",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("8.jpg")

import numpy as np
from PIL import Image


images = [np.array(Image.open(f"{i}.jpg")) for i in range(1, 9)]
image = np.concatenate([
    np.concatenate(images[0:2], axis=1),
    np.concatenate(images[2:4], axis=1),
    np.concatenate(images[4:6], axis=1),
    np.concatenate(images[6:8], axis=1),
], axis=0)
image = Image.fromarray(image).resize((1024, 2048))
image

2.分析代码

(1)输入给通义千问的Prompt

通义千问链接:

通义官网通义官网,致力于实现类人智慧的通用智能https://tongyi.aliyun.com/Prompt:

你是一个优秀的python开发工程师,现在我们需要你帮我们分析这个代码的主体框架,你需要把代码按照工作流分成几部分,用中文回答我的问题。{此处替换前面的代码}

 (2)AI的回答

这段代码可以分为以下几个主要部分,每一部分执行不同的功能:

第一部分:环境设置与依赖安装
这部分代码使用!pip install命令来安装项目所需的Python包,包括simple-aesthetics-predictor, data-juicer, peft, lightning, pandas, torchvision, 和 DiffSynth-Studio。同时,它也卸载了pytorch-lightning并重新安装了lightning,可能是因为版本控制或特定依赖关系的需要。

第二部分:数据集加载与预处理
这里从modelscope加载了一个名为lowres_anime的数据集,并将数据集中的图片和相关元数据保存到本地目录。每张图片被转换为RGB格式并保存,同时创建了一个JSONL文件存储每张图片对应的元数据。

第三部分:数据过滤与处理
通过data_juicer对数据进行进一步的处理,包括应用图像尺寸和宽高比的过滤器。这些操作是通过配置文件data_juicer_config.yaml指定的,并使用dj-process命令行工具执行。

第四部分:数据整理与特征提取
这部分读取处理后的数据,将其转换为Pandas DataFrame,并保存为CSV文件。然后使用CLIP模型(Contrastive Language-Image Pre-training)来计算图像和文本描述之间的相似性分数。

第五部分:数据加载与模型评估
创建了一个自定义的PyTorch数据集类CustomDataset,用于从DataFrame中加载数据,并使用DataLoader进行批处理。然后使用CLIP模型对每个批次的数据进行评估,得到图像与文本匹配的概率。

第六部分:生成图像
这部分使用StableDiffusionPipeline模型根据给定的提示(prompts)生成二次元风格的图像。通过调整guidance_scale和num_inference_steps参数,以及不同的随机种子,生成了一系列具有不同场景和细节的图像。

第七部分:图像拼接与展示
最后,将生成的多个图像拼接在一起形成一个大的图像,并进行了尺寸调整,以便于展示或进一步的处理。

整个流程涉及数据集的加载、预处理、特征提取、模型训练和评估,以及最终的图像生成与后处理,覆盖了从数据准备到模型应用的完整机器学习工作流。

 (3)执行过程

图1: 输入问题

图2:返回答案

二、实战演练

 1.数据准备

(1)提示词

你是一个文生图专家,我们现在要做一个实战项目,就是要编排一个文生图话剧 话剧由8张场景图片生成,你需要输出每张图片的生图提示词

具体的场景图片

1、女主正在上课

2、开始睡着了

3、进入梦乡,梦到自己站在路旁

4、王子骑马而来

5、两人相谈甚欢

6、一起坐在马背上

7、下课了,梦醒了

8、又回到了学习生活中

生图提示词要求

1、风格为古风

2、根据场景确定是使用全身还是上半身

3、人物描述

4、场景描述

5、做啥事情

例子: 古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙

 (2)话剧场景

图片编号

场景描述

正向提示词

反向提示词

图片1

女主正在上课

古风,工笔画,一个着汉服的女子,束起的黑色长发,头戴玉簪,上半身,坐在书案前,手握毛笔,凝视着摊开的卷轴,背景是古色古香的书房,窗外竹影摇曳

丑陋,变形,嘈杂,模糊,低对比度

图片2

开始睡着了

古风,淡墨渲染,同一个女子,头微垂,双手轻轻搭在桌上,嘴角挂着一丝笑意,似乎正陷入梦境,上半身,身着青花瓷图案的汉服,背景是一幅朦胧的山水画卷,书案上散落着几页未完成的诗词

丑陋,变形,嘈杂,模糊,低对比度

图片3

进入梦乡,梦到自己站在路旁 古风,梦幻色彩,全身像,女子穿着飘逸的白纱衣,站在一条蜿蜒的石径上,四周环绕着轻烟薄雾,远处有山峦叠嶂,她抬头望向远方,仿佛期待着什么 丑陋,变形,嘈杂,模糊,低对比度

图片4

王子骑马而来 古风,浓墨重彩,全身像,一位英俊的男子骑着一匹白马缓缓而来,身穿金丝镶边的战袍,头戴冠冕,目光坚定地望向前方,背景是开阔的草原,阳光洒在大地上 丑陋,变形,嘈杂,模糊,低对比度

图片5

两人相谈甚欢 古风,细腻笔触,上半身,女子与王子并肩而立,他们面带微笑,似乎在分享着彼此的秘密,女子穿着精致的绣花衣裳,王子则身着简洁的贵族服饰,背后是精致的凉亭和盛开的牡丹花 丑陋,变形,嘈杂,模糊,低对比度

图片6

一起坐在马背上 古风,动感描绘,全身像,王子和女子共乘一骑,王子稳稳驾驭着马匹,女子依偎在他的臂弯里,两人脸上洋溢着幸福的笑容,背景是夕阳下的壮丽山河 丑陋,变形,嘈杂,模糊,低对比度

图片7

下课了,梦醒了 古风,渐变色彩,上半身,女子坐在书案前,突然睁开眼睛,脸上带着惊异的表情,似乎刚从美梦中醒来,身着朴素的学子服饰,周围是熟悉的教室环境,同窗们正陆续离开 丑陋,变形,嘈杂,模糊,低对比度

图片8

又回到了学习生活中 古风,和谐色调,全身像,女子与其他学子一起,或读书或写字,有的在探讨学问,有的在练习书法,背景是充满书香气息的学院场景,每个人都在专心致志地学习 丑陋,变形,嘈杂,模糊,低对比度

(3)修改提示词

  1. 双击进入baseline文件

  2. 找到生成图像的板块

  3. 依次替换8张图片的正向提示词和反向提示词

(4)结果展示 

文章来源于互联网:Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task02笔记

赞(0)
未经允许不得转载:5bei.cn大模型教程网 » Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task02笔记

Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task01笔记

目录

分任务1:跑通baseline

第一步——搭建代码环境

第二步——报名赛事

第三步——在魔搭社区创建PAI实例

分任务2:相关知识学习以及赛题理解

赛题理解:

文生图基本认识:

1. Diffusion  Model(扩散模型)

2. LDMs(潜空间扩散模型)

3.基础文生图模型优化的三大方向

4.LORA(Low-Rank Adaptation) ——轻量级大模型微调方法


附:

DataWhale开源组织网站主页:Datawhale

DataWhaleAI夏令营第四期AIGC方向学习手册:Doc

赛事链接:可图Kolors-LoRA风格故事挑战赛_创新应用大赛_天池大赛-阿里云天池的赛制

分任务1:跑通baseline

第一步——搭建代码环境

1. 进入阿里云免费试用区,免费使用算力时:

阿里云社区https://free.aliyun.com/?spm=5176.14066474.J_4683019720.1.8646754cugXKWo&scm=20140722.M_988563._.V_1&productCode=learn

2. 登录or注册自己的阿里云账号:

3. 点击立即试用

领取成功之后关闭页面即可

4 .进入魔搭社区授权

魔搭社区https://www.modelscope.cn/my/mynotebook/authorization

第二步——报名赛事

可图Kolors-LoRA风格故事挑战赛https://tianchi.aliyun.com/competition/entrance/532254

第三步——在魔搭社区创建PAI实例

创建完成之后返回魔搭社区,如下图所示,就已经绑定好实例了:

点击打开,因为我这里点击打开没有反应,索性就使用了第二种方法——魔搭的免费notebook

那么实际上,可能是因为魔搭社区的流量限制,使得访问速度很慢,那么我们也可以通过阿里云官网进入实例,

step1:进入阿里云官网

Step2:进入控制台

step3:左侧栏中有DSW这个选择

step4:在这里点击打开,进入实例,速度比魔搭社区要快

总之,无论是从A,B还是C进入,都是为了进入我们的notebook实例中。

进入notebook之后,要先git下来我们的baseline文件,在哪git呢??

需要进入我们的终端Terminal

git lfs install
git clone https://www.modelscope.cn/datasets/maochase/kolors.git

然后就可以跟着教程一步一步进行baseline的运行了,注意,如果出现运行不成功的情况,可以restart一下。

至于运行,有两种方式,可以选中一个代码块,同时按下ctrl+enter,或者是点击左边的运行键。

运行成功之后左边会出现绿色的小对号,即代表我们运行成功了这个代码块。

这是我运行完全部代码块后,最终的部分效果:

在赛事官网提交相关信息:

魔搭社区-创建模型

分任务2:相关知识学习以及赛题理解

赛题理解:

事实上,我们的赛题作出了以下几点要求:

1

要求基于LoRA模型生成 8 张图片组成连贯故事,故事内容可自定义;基于8图故事,评估LoRA风格的美感度及连贯性

2 参赛者可以根据自己审美,任意选择自己喜欢的文生图风格,例如水墨风、国风、日漫风等。
3

要求参赛者在赛事官网提交微调后的LoRA 模型文件、LORA 模型的介绍、以及使用该模型生成的至少8张图片和对应 prompt

4 美学分数仅作评价提交是否有效的标准,其中美学分数小于6(阈值可能根据比赛的实际情况调整,解释权归主办方所有)的提交被视为无效提交,无法参与主观评分。

 我们需要注意的是,必须保证我们的美学分数高于6,这样我们的作品才能视为有效作品,可以使用以下代码进行美学评分。


import torch, os
from PIL import Image
from transformers import CLIPProcessor
from aesthetics_predictor import AestheticsPredictorV2Linear
from modelscope import snapshot_download


model_id = snapshot_download('AI-ModelScope/aesthetics-predictor-v2-sac-logos-ava1-l14-linearMSE', cache_dir="models/")
predictor = AestheticsPredictorV2Linear.from_pretrained(model_id)
processor = CLIPProcessor.from_pretrained(model_id)
device = "cuda"
predictor = predictor.to(device)


def get_aesthetics_score(image):
    inputs = processor(images=image, return_tensors="pt")
    inputs = {k: v.to(device) for k, v in inputs.items()}
    with torch.no_grad():
        outputs = predictor(**inputs)
    prediction = outputs.logits
    return prediction.tolist()[0][0]


def evaluate(folder):
    scores = []
    for file_name in os.listdir(folder):
        if os.path.isfile(os.path.join(folder, file_name)):
            image = Image.open(os.path.join(folder, file_name))
            scores.append(get_aesthetics_score(image))
    if len(scores) == 0:
        return 0
    else:
        return sum(scores) / len(scores)


score = evaluate("./images")
print(score)

文生图基本认识:

提到文生图,我脑海中蹦出的第一个词就是Stable Diffusion(稳定扩散)

Stable Diffusion是文生图技术的一种实现,它是一种基于Latent Diffusion Models(LDMs)实现的文生图(text-to-image)算法模型,通过模拟物理世界中的扩散过程,将噪声逐渐转化为具有特定结构和纹理的图像。

这里的LDMs,则是在DM(Diffusion Model,扩散模型)基础上发展起来的。

与传统的图像生成方法相比,Stable Diffusion具有更高的灵活性和可扩展性,能够生成更加真实、细腻的图像。在训练过程中,Stable Diffusion使用深度学习技术,通过大量的图像数据来优化模型的参数,利用卷积神经网络(CNN)提取图像特征,并通过扩散模型生成具有这些特征的图像。

相信大家应该捕捉到了一些关键字眼:比如DM,LDMs ,这是SD的基本原理。

1. Diffusion  Model(扩散模型)

从技术角度来看,AI绘画热潮的兴起要归功于扩散模型的引入。然而,作为一项早在2015年于国际机器学习会议(ICML)上提出的理论构想,其初现并未引起广泛的关注。

直至2020年6月,来自加州大学伯克利分校的一篇题为DDPM(去噪扩散概率模型)的论文,在更加庞大的数据集上展现出与当时最优的生成对抗网络(GAN)模型相媲美的性能,研究人员方才逐渐领悟到扩散模型在内容创作领域所蕴藏的威力与前景。

此后,不同国家的研究人员一直在进行着不断地探索,而他的真正出圈,是由于OpenAI 2022年发布的DALLE-2,其呈现出的前所未有的理解和创造能力,加之OpenAI 公司的开放API,使得文生图技术彻底走向大众视野。

  • DM扩散模型』工作原理:通过向原始图像中,连续添加高斯噪声来破坏训练数据,然后通过反转这个噪声过程,来学习恢复数据。简单来说,包含两个过程:「前向扩散」和「逆向扩散」。

  • 1)前向扩散:前向扩散过程是不断往输入图片中添加高斯噪声,直到原图像模糊;

  • 2)逆向扩散;反向(逆向)扩散过程是将噪声不断还原为原始图片,这一举措会得到一个【模型】(令为模型A),这个模型训练并稳定下来,就能实现在线预测了,即给模型一个 文本提示或原始图像,它就能基于这个模型生成另一幅图像。

2. LDMs(潜空间扩散模型)

笔者认为提出LDMs的主要原因是,我们需要对训练图片进行像素级的处理,而图像的像素空间是巨大的,对于512×512大小RBG三通道的彩色图片,这将是一个768,432(512x512x3)维度的空间。(意味着为了生成一张图,你需要确定768,432个值)

可想而知,这会消耗大量的时间和资源,因此提出了潜空间扩散模型(LDMs)何为潜空间??

由于图像像素之间的信息是大量冗余的,我们训练一个自编码器将图片进行压缩。

大概可以理解成是和像素空间对应的空间,但是容积比像素空间小,即,通过潜空间,我们实现了对原本像素数据的压缩。

然后我们在潜空间中进行扩散操作。

因此S-D处理的并不是直接的像素图像,而是潜空间中的张量(即4*64*64的噪声图),在训练中,我们在潜空间的图像添加潜空间的噪声,而不是像素图添加像素噪声,这样就使得执行速度有了大幅提升。

与此同时,随着隐空间编码带来的速度提升,它的缺点也暴露出来,就是对于图像信息的压缩,会产生一定的损失,那么,对于图像精度要求比较高的场景(高清的街景),解码器输出的图片可能会出现比例失真,肢体扭曲等问题。

3.基础文生图模型优化的三大方向

1. 更大的模型容量

2. 更强的prompt following ability

3. 模型架构选择?

更大的模型容量:通过对比SD 1.4/1.5 —> SD 2.0/2.1—->SDXL,我们可以发现,参数量的提升确实带来的生成质量的提高。

更强的prompt following ability—–指令遵循能力

啥意思呢??就是(模型生成图片所描述的内容)——【实际得到的】 与(你所给出的文本引导提示)——【你所期望的】的匹配程度。

怎么提高prompt following ability 呢?

方法有二:

其一,使用更长更详细的image caption ,在open AI 官网中关于DELL-E-3的pdf介绍中,建立了一个可以对图像进行精准描述的打标器,我们使用打标器对于训练数据重新生成图像的caption,并进行训练,从而提高模型的prompt following ability 。下图是DELE-E-3论文中对于图像的更加精细的描述。

其二,使用更大更多的text encoder ,可以看到SD 3已经使用三个文本编码器,且嵌入维度也成倍增加。

模型架构的选择——Transformer?or Unet?

对于NLP任务,Transformer 架构具有一骑绝尘的地位,但是在图像领域,SD系列模型采用的是Unet架构。

而对于今年推出的视频生成模型Sora ,则是采用了DIT架构,即 Diffusion transformer 架构

4.LORA(Low-Rank Adaptation) ——轻量级大模型微调方法

大模型的研发是昂贵的,对于小公司或者个人而言,如何调整大模型为自己所用,是我们专注的问题所在。

lora ,顾名思义,就是一种低秩微调的方式,也就意味着我们可以使用少量的权重,进行大模型的微调,对于下图而言,r的维度始终是小于d和k的,在实际训练中,lora可以直接和Transformer中的FFN层对接,也就是下图的左半部分是FFN层,右半部分就是我们训练的Lora,这样的话,不会对原来的权重造成影响,直接加到模型中即可。

基于大模型的内在低秩特性,增加旁路矩阵来模拟全参数微调,LoRA 通过简单有效的方案来达成轻量微调的目的,可以将现在的各种大模型通过轻量微调变成各个不同领域的专业模型。这里推荐阅读http://t.csdnimg.cn/bqbGd,里面有更加通俗详细的lora技术原理。

目前 LORA 已经被 HuggingFace 集成在了 PEFT(Parameter-Efficient Fine-Tuning) 代码库里。

在AI绘画领域,我们可以使用SD模型+LoRA模型的组合微调训练方式,只训练参数量很小的LoRA模型,就能在一些细分任务中取得不错的效果。

接下来就实现一下lora:

#导入需要的模块
import torch
import torch.nn as nn
import torch.nn.functional as F
import math

class LoRALinear(nn.Module):
    #merge:使用预训练层的时候,要不要把预训练层的参数合并到lora层中,相当于一个开关
    #rank:lora层的rank,要降到多少位
    #lora_alpha:lora层的缩放系数,即究竟使用怎样的比例和原始的权重进行相加,如果太大的话,可能会对原始权重造成影响


    def __init__(self, in_features, out_features, merge,rank=16, lora_alpha=1, dropout=0.5):
        super(LoRALinear, self).__init__()
        self.in_features = in_features
        self.out_features = out_features
        self.merge = merge
        self.rank = rank
        self.lora_alpha = lora_alpha
        self.dropout_rate = dropout
        
        #构建一个线性映射的层
        self.linear = nn.Linear(in_features, out_features)
        if rank >0:
            #使用zero初始化参数
            self.lora_B = nn.Parameter(torch.zeros(rank, out_features))
            self.lora_A = nn.Parameter(torch.zeros(in_features, rank))
            self.scale = self.lora_alpha / self.rank   #究竟以什么样的权重系数放缩之后加入原始权重中
            self.linear.weight.requires_grad = False  #不需要更新原始权重
        
        # 如果dropout大于0,则构建一个dropout层
        if self.dropout_rate > 0:
            self.dropout = nn.Dropout(self.dropout_rate)
        else:
            self.dropout = None
        self.intial_weight()
    #对lora_A的权重进行初始化
    def intial_weight(self):
        #海明窗初始化
        nn.init.kaiming_uniform_(self.lora_A, a=math.sqrt(5))
        nn.init.zeros_(self.lora_B)
    #前向传播
    def forward(self, x):
        if self.merge and self.rank > 0:
            #如果merge为True,则使用原始权重和lora权重相加
            #lora_a 矩阵乘法 lora_b ,所以说我们的原始权重是 wx+b  w是out_features*in_features,,x 是in_features*batch_size(几维)
            output=F.linear(x,self.linear.weight + self.lora_B @ self.lora_A*self.scale,self.linear.bias) 
            output=self.dropout(output)
            return output
        else:
            #如果merge为False,则使用原始权重
            return self.linear(x)
    



参考资料:

【翻译】How Stable Diffusion Work – 给小白看的StableDiffusion原理介绍

Stable Diffusion一周年:这份扩散模型编年简史值得拥有

什么是 GAN?

深入浅出完整解析LoRA(Low-Rank Adaptation)模型核心基础知

文章来源于互联网:Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task01笔记

相关推荐: whisper-large-v3:速度快的令人翻译模型三种实用的调用方法

1、whisper-large-v3 是openai公司的模型,可使用Python代码调用; 2、whisper-large-v3基础上chenxwh 制作了开源库insanely-fast-whisper ,可本地指令运行,或 Google Colab T4…

赞(0)
未经允许不得转载:5bei.cn大模型教程网 » Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task01笔记
分享到: 更多 (0)

AI大模型,我们的未来

小欢软考联系我们