Datawhale X 魔搭 AI夏令营 ‣AIGC文生图方向-task01笔记

目录

一、文生图

‣文生图基础知识介绍:

 提示词(prompts)(后面有详细笔记)

Lora

参考图控制

二、跑通Baseline

小白零基础——30min速通指南👇(2d人物)

模型训练参考资料

三、调整prompts

‣风格类型

‣以下是笔者跑baseline时,调整prompts风格类型后的效果:

‣以下是生成的图片:

‣下面是笔者创作的小故事,以文生图的形式展现(代码格式与上组图一致):

◍调试发现: 

‣prompts举例 

四、代码详情

1.环境安装

2.下载数据集

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

4.lora微调

5.加载微调好的模型

6.图片生成


附:DataWhale开源组织网站主页:Datawhale

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

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


一、文生图

文生图技术演变,参考内容如下:文生图的历程与基石.pptx · 语雀 (yuque.com)icon-default.png?t=N7T8https://www.yuque.com/office/yuque/0/2024/pptx/1169882/1720431794935-a1a33ec5-e784-4b6e-9664-8f459e2c7413.pptx?from=https%3A%2F%2Fwww.yuque.com%2F2ai%2Fmodel%2Fgutsk9ezeymuebq9

‣文生图基础知识介绍:

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


  •  提示词(prompts)(后面有详细笔记)

 正向提示词公式——风格+主体细节+环境背景+构图视角+画质等

                                               ↪‣人物+角色+年龄+五官+表情+发型+服装+动作+其它

 反向提示词(用于避免生成不适合特定环境或不符合用户意图的内容) 

                     常见:“丑陋、变形、嘈杂、模糊、低对比度、色情擦边、扭曲/多余的手指”等

常见prompts如下:

正向提示词

 

       后面有详细prompts笔记 


  • Lora

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

  • 参考图控制

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


二、跑通Baseline

  • 小白零基础——30min速通指南👇(2d人物)

※详细操作教程:Datawhale (linklearner.com)icon-default.png?t=N7T8https://linklearner.com/activity/14/10/24

※在魔搭社区创建PAI实例:魔搭社区汇聚各领域最先进的机器学习模型,提供模型探索体验、推理、训练、部署和应用的一站式服务。icon-default.png?t=N7T8https://www.modelscope.cn/my/mynotebook/authorization ↪৹注册后,再次创建实例或查看之前的实例,可直接进第二个链接-魔搭社区

  • 若另创建实例,则点击 [ 创建实例 ] ⇒ (GPU规格的第二个选项)[ 支持资源包抵扣ecs.gn7i-c8g1.2xlarge ] ⇒ [ 下一步 ] ⇒ [ 创建实例 ] ⇒ [ 打开 ] ⇒ [ 打开terminal ] ⇒ [ 粘贴代码(如下)] ⇒ [ kolors ] ⇒ [ baseline.ipynb ] ⇒ 详见下图
    git lfs install
    git clone https://www.modelscope.cn/datasets/maochase/kolors.git
  • 若查看之前的实例,点击 [了解更多产品详情] ⇒[ 管理控制台 ] ⇒ [ 启动 ] ⇒详见下图    ⇒ 查看完后 [ 停止 ]

  • 模型训练参考资料

  1. AIGC专题视频课程:ModelScope官方账号的个人空间-ModelScope官方账号个人主页-哔哩哔哩视频

  2. AIGC专题品牌馆:魔搭社区

  3. 模型训练入口:魔搭社区

  4. 赛事提交界面:魔搭社区


三、调整prompts

‣风格类型

prompts——列举部分风格类型

‣以下是笔者跑baseline时,调整prompts风格类型后的效果:

torch.manual_seed(0)
image = pipe(
    prompt="水彩画风格,一个黑色长发的18岁女孩,头发是大波浪卷,戴着时尚墨镜,带着卡其色的渔夫帽,微笑,水嫩肌肤,脸颊白里透红,鹅黄色连衣裙,站在樱花树下,可爱,精力充沛,微微抬头,侧面,半身,立体像",
    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")

‣以下是生成的图片:

第一行风格依次为:水彩画风格,动漫美学风格,赛博朋格风格,吉卜力风格;
第二行风格依次为:油画艺术风格,水墨画风格,迪士尼皮克斯风格,哥特式风格

‣下面是笔者创作的小故事,以文生图的形式展现(代码格式与上组图一致)

@Cx330_Aurora   女将&权谋

↪‣代码格式与上组文生图代码格式一致,具体提示词如下(均为动漫美学风格): 

  1. 一个五岁的中国小女孩,穿着浅粉色的汉服,可爱漂亮的圆脸,水汪汪的大眼睛,手里拿着书和毛笔,坐在书桌前,光线柔和,立体像 
  2. 夜晚,一个18岁的中国女孩,挽着玉簪,五官精致,皮肤纹理清晰,穿着白色汉服,左手拿着书卷,右手拿着燃烧的蜡烛,低头看书,全身镜头,立体像
  3. 在中式建筑前,一个20岁的这个女孩,穿着墨绿色汉服,手中挥剑,五官精致,皮肤纹理清晰,动态图像,立体风格,侧视全身像,全景图,光线柔和,高清
  4. 18岁的中国古代女孩,五官精致,皮肤纹理清晰,穿着黑色汉服,腰间佩剑,长发飘扬,骑着白马,马背上还装着一些布包,动态图像,背景是树林,全身像,光线柔和,立体风格
  5. 闪闪发光的动态角度,一个穿着红色汉服和黑色铠甲的中国女战士,手中拿着长剑,五官精致,皮肤纹理清晰,背景是火光,立体像
  6. 中国女战士骑着战马,穿着金色盔甲,金属质感,手中持长缨枪,从红光中飞出,侧视图,闪闪发光的动态角度,全景图
  7. 中国古代,一个头发盘起的女孩,穿着深紫色汉服和黑色铠甲,腰间佩剑,手中拿着竖着的白色令牌,背景是白色的台阶,全身像,全景图,立体风格
  8. 中国古代,一个穿着紫色汉服的朝堂女官,站在高高的阁楼上,五官精致,皮肤纹理清晰,立体风格,受万臣朝拜,全景图(预期与成图有所差别

◍调试发现: 

  • 描述“五官精致,皮肤纹理清晰”相关提示词,人物类型偏向于真人;反之,偏向卡通类型。(在动漫美学风格下)
  • 提示词细致些,文生图美感效果更好,尤其是人物面部、服饰形象塑造方面。
  • AI对部分中国传统服饰、配饰、动作用语无法理解,有特别需要,需详细描述。
  • 提示词需简洁,若过于冗长,则部分细节达不到预想要求。
  • 光效部分特殊强调一下,效果更好,常见prompts如下 

‣prompts举例 

常见正向prompts 如下(常见反向prompts在文章开始,根据具体情况而定) 

本次baseline不涉及3d图像

四、代码详情

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

如果您对本文有任何疑问、建议或想分享自己的经验,请在评论区留言,期待与大家的互动!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值