#Datawhale X 魔搭 AI夏令营 #AI生图

具体步骤就不再跟大家赘述了(本人也是根据手册来运行的)这里放一份手册链接,有需要的大家可以按照步骤来https://linklearner.com/activity/14/10/24

我们直接进入赛题说明和相关知识包括代码部分:

赛题内容:

  • 参赛者需在可图Kolors 模型的基础上训练LoRA 模型,生成无限风格,如水墨画风格、水彩风格、赛博朋克风格、日漫风格......

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

赛前须知 :

文生图基础知识介绍:

文生图主要以SD系列基础模型为主,以及在其基础上微调的lora模型和人物基础模型等

提示词(Prompt):

提示词是输入到生成模型中的一段文本,用于指导模型产生特定的输出。在自然语言处理(NLP)中,提示词尤其重要,尤其是在以下场景:

  • 文本生成:例如,生成故事、诗歌、对话等。
  • 问答系统:提示词是用户提出的问题。
  • 语言模型:提示词用于引导模型完成句子或生成相关内容。

提示词的设计对模型输出有显著影响,以下是一些设计提示词时考虑的因素:

  • 相关性:提示词应与期望的输出紧密相关。
  • 明确性:提示词应清晰、具体,避免歧义。
  • 上下文:提供足够的上下文信息,帮助模型理解期望的输出风格或内容。

 举个例子

promts】Beautiful and cute girl, smiling, 16 years old, denim jacket, gradient background, soft colors, soft lighting, cinematic edge lighting, light and dark contrast, anime, super detail, 8k

负向prompts】(lowres, low quality, worst quality:1.2), (text:1.2), deformed, black and white,disfigured, low contrast, cropped, missing finge

LoRA(Low-Rank Adaptation):

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

以下是LoRA的主要特点和原理:

  • 低秩分解:LoRA通过将预训练模型的参数调整分解为两个低秩矩阵的乘积,从而减少需要调整的参数数量。
  • 参数效率:由于只需微调少量参数,LoRA大大减少了适应新任务所需的数据量和计算资源。
  • 实用性:LoRA可以应用于多种模型,包括变换器(Transformer)模型,且不会影响原始模型的结构和性能。

LoRA的工作流程通常包括以下步骤:

  • 在预训练模型的基础上,识别出需要微调的层。
  • 对这些层的参数进行低秩分解,并冻结原始参数。
  • 使用新任务的数据来训练低秩矩阵。
  • 将训练好的低秩矩阵与原始参数相乘,得到新的参数。

ComfyUI:

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

ComfyUI是一个深度学习实验和模型构建的图形界面,它具有以下特点:

  • 可视化操作:用户可以通过拖放组件来构建模型,无需编写代码。
  • 灵活性:支持多种深度学习框架,如TensorFlow、PyTorch等。
  • 易用性:即使是深度学习初学者也能快速上手,进行模型实验。
  • 扩展性:用户可以自定义组件,或导入新的模型和算法。

ComfyUI的使用场景包括:

  • 图像生成:如使用GANs生成艺术作品。
  • 图像处理:如图像风格转换、超分辨率等。
  • 数据可视化:帮助用户更好地理解数据和模型。

 

参考图控制(Reference Image Control):

参考图控制是一种在图像生成任务中使用的技巧,其目的是让生成的图像在特定方面(如风格、颜色、纹理)与提供的参考图像相似。以下是实现参考图控制的方法:

  • 特征匹配:在生成图像和参考图像之间匹配高级特征表示,通常通过使用预训练的卷积神经网络(CNN)来实现。
  • 损失函数:在训练过程中,将参考图像相关的损失加入到总的损失函数中,例如,风格损失、内容损失等。
  • 优化过程:在生成图像的过程中,不断调整生成器的参数,以最小化与参考图像的差异。

参考图控制广泛应用于图像风格迁移、图像编辑和图像生成等领域,它为用户提供了更多控制生成图像外观的能力。

参考图控制类型

简介

示例

OpenPose姿势控制

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

Canny精准绘制

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

Hed绘制

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

深度图Midas

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

颜色color控制

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

代码部分:

!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: '<__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())

!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

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 \
  --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")

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

结果图:

代码理解:

!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: '<__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())

!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
  • 导入必要的库

    • MsDataset:ModelScope的数据集加载类。
    • json:用于处理JSON数据。
    • os:用于操作系统级别的操作,如创建目录。
    • SpecialTokens:可能用于处理特殊标记,但在当前代码段中未使用。
    • tqdm:用于在循环中显示进度条。
  • 下载数据集 
  • 创建目录
  • 处理数据集并保存元数据 
# 下载模型
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)

  • 导入download_models函数

    • diffsynth库中导入download_models函数,用于下载预训练模型。
  • 下载模型

    • 使用download_models函数下载两个模型:KolorsSDXL-vae-fp16-fix。这些模型可能用于图像生成或其他计算机视觉任务。
  • 模型训练

    • 定义了一个命令字符串cmd,其中包含了用于训练新模型的参数。
    • 参数包括:
      • pretrained_unet_path:指定预训练的UNET模型路径。
      • pretrained_text_encoder_path:指定预训练的文本编码器模型路径。
      • pretrained_fp16_vae_path:指定预训练的浮点VAE模型路径。
      • lora_rank:指定LoRA适配器的秩。
      • lora_alpha:指定LoRA适配器的alpha值。
      • dataset_path:指定训练数据集的路径。
      • output_path:指定模型输出的路径。
      • max_epochs:指定训练的最大epoch数。
      • center_crop:是否使用中心裁剪。
      • use_gradient_checkpointing:是否使用梯度检查点。
      • precision:指定训练的精度,如"16-mixed"。
  • 执行命令

    • 使用os.system(cmd)执行命令字符串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"
)

  • 导入库

    • ModelManager:用于管理模型加载和初始化的类。
    • SDXLImagePipeline:用于图像处理的流水线。
    • LoraConfig:用于定义LoRA(低秩适配器)配置。
    • inject_adapter_in_model:用于将LoRA适配器注入模型。
    • torch:PyTorch库,用于深度学习和计算图。
  • 定义load_lora函数

    • 这个函数用于加载LoRA适配器,它是用于模型微调的一种技术,可以减少模型参数的数量,提高模型效率。
    • lora_config对象定义了LoRA适配器的秩(r)、alpha值(lora_alpha)、初始权重(init_lora_weights)和目标模块(target_modules)。
    • inject_adapter_in_model函数将LoRA适配器注入到给定的模型中。
    • 加载预训练模型的状态字典(state_dict)并将其加载到模型中。
  • 加载模型

    • 使用ModelManager创建一个模型管理器,指定模型的类型、设备('cuda’表示使用GPU)和文件路径列表。
    • 从模型管理器创建一个SDXLImagePipeline实例,用于处理图像。
  • 加载LoRA适配器

    • 将LoRA适配器加载到pipe.unet模型中。
    • lora_ranklora_alpha参数用于配置LoRA适配器。
    • lora_path指定LoRA适配器的权重文件路径。

torch.manual_seed(0)
image = pipe(
    prompt="二次元,一个黑色头发的小女孩,在家中阳台上站着,双手打开,感受阳光,全身,白色公主裙",
    negative_prompt="丑陋、变形、嘈杂、模糊、低对比度",
    cfg_scale=4,
    num_inference_steps=50, height=1024, width=1024,
)
image.save("1.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
  • 导入库

    • numpy:用于数组操作。
    • PIL(Pillow):用于图像处理。
  • 加载图像

    • 使用列表推导式和Image.open函数,从指定目录加载8个图像。
    • 每个图像都被转换为numpy数组。
  • 拼接图像

    • 使用np.concatenate函数,按照列方向(axis=1)将前两个图像拼接在一起,形成一个新的图像数组。
    • 重复这个过程,将剩下的图像依次拼接。
    • 最后,将所有拼接好的图像数组按照行方向(axis=0)合并成一个大的图像数组。
  • 转换回图像

    • 使用Image.fromarray函数将数组转换回图像。
  • 调整图像大小

    • 使用resize方法将图像调整为指定的大小(1024x2048)。

代码部分就到这里啦,此时task1的内容也接近尾声,期待task2的优化吧hhh~ 

魔搭社区提供的学习参考内容以及相关工具:

  • 15
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值