Datawhale X 魔塔 AI夏令营 AIGC方向Task1

小白学习笔记,如有错误请各位大佬指正

一、跑通baseline教程

Datawhale 教程链接Datawhale

二、baseline代码分析

1.安装库
!pip install simple-aesthetics-predictor

!pip install -v -e data-juicer  #用于数据处理的工具包

!pip uninstall pytorch-lightning -y #移除之前安装的pytorch-lightning包
!pip install peft lightning pandas torchvision  #用于机器学习和数据处理

!pip install -e DiffSynth-Studio
2.下载数据集
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: #打开文件metadata.jsonl以写入模式,保存元数据
    for data_id, data in enumerate(tqdm(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)) #将元数据字典转换为JSON格式并写入文件
        f.write("\n") #在文件中写入换行符
3.使用 data-juicer 处理数据
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: '<__dj__image>' 关键字配置

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()) #写入data_juicer_config.yaml文件

!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())): #提取每条记录中的text和image路径,保存图像到指定目录,并记录图像文件名
        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() #创建一个pandas数据框,包含图像文件名和文本描述
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")  #将数据框保存为CSV文件
data_frame
4.训练模型
#下载模型
from diffsynth import download_models

download_models(["Kolors", "SDXL-vae-fp16-fix"]) #导入函数,调用模型
#查看训练脚本的输入参数
!python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py -h
#开始训练
import os

cmd = 
"""
python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py \
  --pretrained_unet_path models/kolors/Kolors/unet/diffusion_pytorch_model.safetensors \ 指定预训练的U-Net模型路径
  --pretrained_text_encoder_path  models/kolors/Kolors/text_encoder \指定预训练的文本编码器路径
  --pretrained_fp16_vae_path  models/sdxl-vae-fp16-fix/diffusion_pytorch_model.safetensors \ 指定预训练的VAE模型路径
  --lora_rank 16 \
  --lora_alpha 4.0 \ 配置lora模型的超参数
  --dataset_path data/lora_dataset_processed \ 指定数据集路径
  --output_path ./models \ 指定训练后的模型保存路径
  --max_epochs 1 \ 指定训练的最大轮次
  --center_crop \ 在图像预处理阶段应用中心裁剪
  --use_gradient_checkpointing \ 启用梯度检查点以减少内存使用
  --precision "16-mixed" 设置训练的精度为16-bit混合精度
""".strip() #定义了一个命令行字符串 cmd,用于启动训练脚本

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模型
    lora_config = LoraConfig(
        r=lora_rank,
        lora_alpha=lora_alpha,
        init_lora_weights="gaussian",
        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")
    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"
)  #应用模型
5.生成图像
torch.manual_seed(0)
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)] #读取生成的图像文件,并将它们转换为 NumPy 数组
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)) #将拼接后的图像数组转换回 PIL 图像对象,并调整图像大小
image

提示:

(1)在训练命令中填入 --modelscope_model_id xxxxx 以及 --modelscope_access_token xxxxx 后,训练程序会在结束时自动上传模型到 ModelScope

(2)部分参数可根据实际需求调整,例如 lora_rank 可以控制 LoRA 模型的参数量

(3)prompt为图像中包含的因素,negative_prompt为图像中不包含的内容。

6.图像展示

三、相关知识点补充

1.LoRA

       Stable Diffusion中的Lora(LoRA)模型是一种轻量级的微调方法,它代表了“Low-Rank Adaptation”,即低秩适应。Lora不是指单一的具体模型,而是指一类通过特定微调技术应用于基础模型的扩展应用。在Stable Diffusion这一文本到图像合成模型的框架下,Lora被用来对预训练好的大模型进行针对性优化,以实现对特定主题、风格或任务的精细化控制。

      LoRA(Low-Rank Adaptation)本质上是对特征矩阵进行低秩分解的一种近似数值分解技术,可以大幅降低特征矩阵的参数量,但是会伴随着一定的有损压缩。从传统深度学习时代走来的读者,可以发现其实LoRA本质上是基于Stable Diffusion的一种轻量化技术。

2.ComfyUI

       ComfyUI 是一个工作流工具,主要用于简化和优化 AI 模型的配置和训练过程。通过直观的界面和集成的功能,用户可以轻松地进行模型微调、数据预处理、图像生成等任务,从而提高工作效率和生成效果。

3.参考图控制

ControlNet是一种用于精确控制图像生成过程的技术组件。它是一个附加到预训练的扩散模型(如Stable Diffusion模型)上的可训练神经网络模块。扩散模型通常用于从随机噪声逐渐生成图像的过程,而ControlNet的作用在于引入额外的控制信号,使得用户能够更具体地指导图像生成的各个方面(如姿势关键点、分割图、深度图、颜色等)。

参考图控制类型

简介

OpenPose姿势控制

输入是一张姿势图片(或者使用真人图片提取姿势)作为AI绘画的参考图,输入prompt后,之后AI就可以依据此生成一副相同姿势的图片;

Canny精准绘制

输入是一张线稿图作为AI绘画的参考图,输入prompt后,之后AI就可以根据此生成一幅根据线稿的精准绘制。

Hed绘制

Hed是一种可以获取渐变线条的线稿图控制方式,相比canny更加的灵活。

深度图Midas

输入是一张深度图,输入prompt后,之后AI就可以根据此生成一幅根据深度图的绘制。

颜色color控制

通过参考图控制和颜色控制,实现更加精准和个性化的图像生成效果。

4.提示词

       写法:主体\(描述1, 描述2, 描述3\)

       有些教程中提到大括号 { } 表示增加 1.01 权重,ComfyUI 文档中说明大括号的作用为动态提示,并非增加权重。

        可以同时使用多个括号,用几个括号就代表几个基础权重值相乘:
 (keyword): 1.1
 ((keyword)): 1.21
(((keyword))): 1.331

5.文本到图像Stable Diffusion

       Stable Diffusion是一种潜在的扩散模型,可以从文本中生成AI图像。 它不是在高维图像空间中操作,而是首先将图像压缩到潜空间中。Stable Diffusion是一个文本到图像的生成模型。给它一个文本指令作为输入,它将返回给你一张与输入指令匹配的图像。

参考

1.Datawhale AI夏令营教程Datawhale

2.知乎文章https://zhuanlan.zhihu.com/p/639229126

3.知乎文章https://zhuanlan.zhihu.com/p/687923903

4.How does Stable Diffusion work?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值