“Datawhale X 魔搭 AI夏令营”——AI生图学习笔记

一、赛题任务

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

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

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

二、文生图的历史

 

想深入了解文生图的相关技术和发展过程,推荐看一下:1.1文生图的历程与基石-历史沿革与基础理论_哔哩哔哩_bilibili

三、文生图基础知识

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

 接下来,我们简单了解下提示词、lora、ComfyUI和参考图控制这些知识点。

提示词

提示词很重要,一般写法:主体描述,细节描述,修饰词,艺术风格,艺术家

举个例子

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 fingers

 Lora

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

ComfyUI

ComfyUI 是一个工作流工具,主要用于简化和优化 AI 模型的配置和训练过程。通过直观的界面和集成的功能,用户可以轻松地进行模型微调、数据预处理、图像生成等任务,从而提高工作效率和生成效果。在ComfyUI平台的前端页面上,用户可以基于节点/流程图的界面设计并执行AIGC文生图或者文生视频的pipeline。

想对ComfyUI了解更多,推荐看一下:2.2ComfyUI应用场景探索_哔哩哔哩_bilibili

参考图控制

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

四、Baseline实践

1.环境安装

!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

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

 3.处理数据集,保存数据处理结果

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

 4.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)

 5.加载微调好的模型

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

 6.图片生成

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

可以通过改变prompt中的内容 ,改变生成的图像。在修改prompt的过程中,比如第一张图我想生成的是一个四五岁的扎着双马尾的小女孩和爷爷在院子里玩耍,生成的图片里就会只有一个小女孩,后面我又在爷爷前面加了一个形容词爷爷才出现在图片里。由此可见,提示词表达准确还是很重要的,于是我又搜索了相关资料,对主体描述、‌细节描述、‌修饰词、‌艺术风格等又作了进一步详细的了解。

主体描述:‌这部分主要描述图像的主体内容,‌如人物、‌场景等。‌例如,‌如果主题是人物肖像,‌提示词可能会包括人物的年龄、‌性别、‌表情、‌姿态等。‌

细节描述:‌这部分详细描述主体的具体特征,‌如服装、‌背景、‌环境等。‌例如,‌如果人物穿着特定的服装,‌提示词中会包含服装的描述。‌

修饰词:‌用于修饰主体和细节,‌增加描述的生动性和准确性。‌例如,‌使用形容词来描述人物的年龄(‌年轻、‌成熟)‌或背景的环境(‌宁静的夜晚)‌。‌

艺术风格:‌这部分指定了图像的艺术风格或画风,‌如写实、‌卡通、‌抽象等。‌这有助于AI根据特定的艺术风格生成图像。‌

五、生成的故事图片展示

故事主题:成长是不断分离的过程

1.女孩小时候经常和爷爷一块玩耍,非常开心幸福

2.小女孩慢慢长大,上了小学。

3.这时候,爷爷还可以每天接小女孩放学,每天见到小女孩。

4.小女孩慢慢长大,转眼间上了初中。

5.初中只能每周回一次家了,女孩每次回到家爷爷就给她做很多她爱吃的饭。

6.又过了三年,女孩上了高中,繁重的学业使她和爷爷见面次数更少了。

7.女孩努力的学习,取得了不错的成绩,拿着录取通知书高兴的和爷爷见面。

8. 短暂的团圆后,女孩又要去向更远的地方并且以后见爷爷的次数会更少,爷爷不舍得送她离开。

六、问题思考 

我的想法是可以使用魔搭社区图像模型训练工具,上传其他风格类型的图片,训练出专属的lora风格模型。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值