Datawhale X 魔搭 AI夏令营--文生图原理&实践Task02学习笔记

1.学习目标

使用AI助手精读baseline,对Task01中的实践结果进行调整。

2.精读baseline

使用到的AI助手:通义千问通义tongyi.ai_你的全能AI助手

Task01中baseline基本框架为:

1.环境准备:

  • 安装或卸载所需的Python包

2.数据集加载与预处理:

  • 加载动漫图像数据集
  • 遍历数据集,保存图像并记录元数据

3.数据清洗与过滤:

  • 使用DataJuicer配置文件定义数据处理规则
  • 应用过滤规则处理数据集

4.模型微调:

  • 使用DiffSynth-Studio进行模型微调

5.加载微调后的模型

  • 加载微调后的Lora模型

6.图像生成

  • 设置正负提示词
  • 设置图片尺寸、执行轮数
  • 合并生成的图像

代码精读:

第一步:安装

# 安装 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: 这里可能是指 pytorch-lightning 的另一个版本或者是其他同名的库。
pandas: 一个非常流行的用于数据分析的库。
torchvision: PyTorch 的扩展库,提供了对计算机视觉模型的支持

!pip install -e DiffSynth-Studio # 安装 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"
) # 加载数据集,使用 MsDataset.load() 方法加载名为 AI-ModelScope/lowres_anime 的数据集
指定了 subset_name 为 'default',这通常是数据集中的一种子集名称,用于指定要使用的具体数据子集
指定了 split 为 'train',这表示加载的是训练集部分
设置了 cache_dir 为 "/mnt/workspace/kolors/data",这指定了数据集缓存的目录位置,ModelScope会尝试从该目录中读取已缓存的数据集,如果没有找到则会下载并缓存数据集到此目录

# 保存数据集中的图片及元数据

# 导入必要的模块
import json, os # json: 用于处理JSON数据,os: 提供与操作系统交互的功能,如创建目录
from data_juicer.utils.mm_utils import SpecialTokens # SpecialTokens (from data_juicer.utils.mm_utils): 假设这是一个自定义模块,用于处理特殊标记
from tqdm import tqdm # tqdm: 一个进度条库,用于显示迭代过程中的进度

# 创建输出目录
os.makedirs("./data/lora_dataset/train", exist_ok=True) # 创建目录:./data/lora_dataset/train: 用于存储处理后的图像,exist_ok=True 参数确保如果目录已经存在,则不会引发错误
os.makedirs("./data/data-juicer/input", exist_ok=True) # 创建目录:./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)): #遍历数据集 ds 中的每个数据项,并为每个数据项创建一个进度条
        image = data["image"].convert("RGB") # 获取其中的图像,并将其转换为 RGB 格式
        image.save(f"/mnt/workspace/kolors/data/lora_dataset/train/{data_id}.jpg") # 将图像保存到 ./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 格式,并写入到 metadata.jsonl 文件中
        f.write("\n") # 每条记录后跟一个换行符

第三步:数据处理

# 使用 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 的文件中。文件路径为 data/data-juicer/data_juicer_config.yaml

#  执行数据处理命令
!dj-process --config data/data-juicer/data_juicer_config.yaml # 这一部分使用 dj-process 命令执行数据处理流程,其中 --config 参数指定了配置文件的路径

# 保存处理好的数据

# 导入必要的模块
import pandas as pd
import os, json
from PIL import Image # Image (from PIL): 用于处理图像
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: # 读取处理后的数据集 result.jsonl 文件
    for data_id, data in enumerate(tqdm(file.readlines())): # 遍历数据集中的每一条记录,并为每个数据项创建一个进度条
        data = json.loads(data) # 解析JSON格式的数据
        text = data["text"] # 提取文本描述,并将其添加到 texts 列表中
        texts.append(text)
        image = Image.open(data["image"][0]) # 打开图像文件,并将其保存到 ./data/lora_dataset_processed/train 目录下,文件名为 {data_id}.jpg
        image_path = f"./data/lora_dataset_processed/train/{data_id}.jpg"
        image.save(image_path)
        file_names.append(f"{data_id}.jpg") # 记录图像文件名到 file_names 列表中
# 创建DataFrame并保存到CSV文件
data_frame = pd.DataFrame() # 创建一个空的 pandas DataFrame
data_frame["file_name"] = file_names # 将图像文件名和文本描述分别添加到DataFrame的两列中
data_frame["text"] = texts
data_frame.to_csv("./data/lora_dataset_processed/train/metadata.csv", index=False, encoding="utf-8-sig") # 将DataFrame保存到CSV文件 metadata.csv 中,文件路径为 ./data/lora_dataset_processed/train/metadata.csv
data_frame

第四步:训练模型

# 下载模型

#导入模块
from diffsynth import download_models # 导入了 diffsynth 库中的 download_models 函数,这个函数用于下载模型文件

# 下载模型
download_models(["Kolors", "SDXL-vae-fp16-fix"]) # 调用了 download_models 函数,并传入了一个列表,列表中包含了需要下载的模型名称:

"Kolors": 第一个需要下载的模型名称。
"SDXL-vae-fp16-fix": 第二个需要下载的模型名称

# 查看训练脚本的输入参数

!python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py -h # 执行了一个名为 train_kolors_lora.py 的Python脚本,该脚本位于 DiffSynth-Studio/examples/train/kolors 目录下

# 开始训练

# 导入必要的模块
import os

# 构建训练命令
cmd = """
python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py \ # 指定了要执行的 Python 脚本
  --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 的秩
  --lora_alpha 4.0 \ # 指定了 LoRA 的 alpha 参数
  --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 # ModelManager (from diffsynth): 用于管理模型加载,SDXLImagePipeline (from diffsynth): 用于创建图像生成管道
from peft import LoraConfig, inject_adapter_in_model # LoraConfig 和 inject_adapter_in_model (from peft): 用于配置和注入LoRA适配器
import torch # torch: PyTorch库,用于处理张量和模型

# 定义LoRA加载函数
def load_lora(model, lora_rank, lora_alpha, lora_path): # 定义了一个名为 load_lora 的函数,用于加载LoRA适配器并将其注入到模型中。函数接收以下参数:
model: 需要注入LoRA的模型
lora_rank: LoRA的秩
lora_alpha: 控制LoRA权重的参数
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"],
    )
    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",# 创建一个 ModelManager 实例,用于管理模型加载,指定模型的浮点类型为 float16,设备为 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) # 从 ModelManager 实例创建一个 SDXLImagePipeline 管道

# Load LoRA,加载LoRA适配器
pipe.unet = load_lora( # 调用 load_lora 函数,将LoRA适配器加载到 SDXLImagePipeline 的 unet 层中
    pipe.unet,
    lora_rank=16, # This parameter should be consistent with that in your training script. # 指定LoRA的秩、alpha值以及LoRA模型文件的路径
    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) # 设置随机种子,设置PyTorch的随机种子为0,确保每次运行代码时生成的结果相同,这对于实验的可复现性非常重要
image = pipe( # 使用 SDXLImagePipeline 的实例 pipe 生成一张图像
    prompt="二次元风格,漫画表现手法,一位金色长发的小美人鱼,穿着淡蓝色的裙子,全身展现于巨大玻璃缸内,双手轻触缸壁,眼神流露出悲伤与渴望自由的情绪", # 提供了一个正面提示 (prompt) 描述所期望的图像内容
    negative_prompt="丑陋、变形、嘈杂、模糊、高对比度", # 提供了一个负面提示 (negative_prompt) 来排除不想要的特征
    cfg_scale=4, # 设置了配置参数 cfg_scale 用于控制条件生成过程中的指导力度
    num_inference_steps=50, height=1024, width=1024, # 设置了 num_inference_steps 参数来定义生成过程中的步数,设置了输出图像的尺寸为 height=1024 和 width=1024
)
image.save("1.jpg") # 将生成的图像 image 保存为文件 "1.jpg"

AI助手的代码解析非常详细,不明白的地方可进行追问。

3.AI助手生成文生图提示词

问:

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

1、一条小美人鱼被关在海洋博物馆

2、一个人类女孩参加学校的春游来到海洋博物馆

3、人类女孩看到小美人鱼的困境,想帮助她逃离海洋馆

4、人类女孩有魔法,让小美人鱼回到了大海

5、小美人鱼回到大海很开心

6、人类女孩经常去海边眺望

7、小美人鱼也一直在寻找帮助她回到大海的人

8、很多年以后她们两个在海边相遇

生图提示词要求 1、风格为二次元 2、根据场景确定是使用全身还是上半身 3、人物描述 4、场景描述 5、做啥事情 例子: 二次元,漫画,一个金色长发小美人鱼,在海洋馆内,悲伤,全身,白色衣服

答:

明白了,以下是根据您提供的要求和场景所设计的生图提示词:

1. 一条小美人鱼被关在海洋博物馆
风格: 二次元,漫画
人物描述: 一位金色长发的小美人鱼,身穿淡蓝色的裙子
场景描述: 海洋博物馆内,巨大的玻璃缸中
做啥事情: 小美人鱼双手放在玻璃缸上,眼神忧郁
提示词: "二次元风格,漫画表现手法,一位金色长发的小美人鱼,穿着淡蓝色的裙子,全身展现于巨大玻璃缸内,双手轻触缸壁,眼神流露出悲伤与渴望自由的情绪。"

2. 一个人类女孩参加学校的春游来到海洋博物馆
风格: 二次元,漫画
人物描述: 一位棕色短发的人类女孩,穿着校服,手拿学生手册
场景描述: 海洋博物馆的入口处,背景是博物馆标志性的建筑
做啥事情: 女孩正在查看手册上的地图
提示词: "二次元风格,漫画手法描绘,一位棕色短发的女孩穿着校服,手持学生手册,站在海洋博物馆的入口处,认真查看手中的地图,准备进入博物馆探索。"

3. 人类女孩看到小美人鱼的困境,想帮助她逃离海洋馆
风格: 二次元,漫画
人物描述: 同上
场景描述: 海洋博物馆内的玻璃缸前
做啥事情: 女孩与小美人鱼对视,女孩露出同情的表情
提示词: "二次元风格,漫画手法,棕色短发的女孩站在玻璃缸前,与缸中的金色长发小美人鱼对视,女孩脸上露出同情与决心的表情,似乎在思考如何帮助小美人鱼逃脱。"

4. 人类女孩有魔法,让小美人鱼回到了大海
风格: 二次元,漫画
人物描述: 同上
场景描述: 博物馆外面的大海边
做啥事情: 女孩施展魔法,小美人鱼缓缓上升,准备回归大海
提示词: "二次元风格,漫画手法,女孩施展魔法,金色长发的小美人鱼从博物馆中缓缓升起,准备回归广阔的大海,女孩的手中散发着柔和的光芒。"

5. 小美人鱼回到大海很开心
风格: 二次元,漫画
人物描述: 金色长发的小美人鱼
场景描述: 大海中,阳光照耀下
做啥事情: 小美人鱼在水中欢快地游泳
提示词: "二次元风格,漫画手法,金色长发的小美人鱼在清澈的海水中欢快地游泳,阳光穿透水面,小美人鱼满脸喜悦,尽情享受自由的快乐。"

6. 人类女孩经常去海边眺望
风格: 二次元,漫画
人物描述: 棕色短发的人类女孩
场景描述: 海滩边,黄昏时分
做啥事情: 女孩独自站在海滩上,眺望着远方的大海
提示词: "二次元风格,漫画手法,女孩独自站在海滩上,穿着休闲服装,手搭凉棚眺望着远方的大海,表情充满思念。"

7. 小美人鱼也一直在寻找帮助她回到大海的人
风格: 二次元,漫画
人物描述: 金色长发的小美人鱼
场景描述: 海中,远处有人类居住的城市轮廓
做啥事情: 小美人鱼在海面上四处寻找,眼神坚定
提示词: "二次元风格,漫画手法,金色长发的小美人鱼在海面上游弋,眼神坚定地四处寻找,远处可见人类城市的轮廓,似乎在寻找曾经帮助她的那位女孩。"

8. 很多年以后她们两个在海边相遇
风格: 二次元,漫画
人物描述: 两人皆长大成熟
场景描述: 海滩边,夕阳西下
做啥事情: 女孩和小美人鱼重逢,相视而笑
提示词: "二次元风格,漫画手法,长大成熟的女孩和小美人鱼在海滩边相遇,夕阳映照下,两人相视而笑,仿佛多年前的约定终于得以实现。"

很满意,后续还能用它做优化调整。

4.调整结果

总结:

AI助手生成的提示词不能完全识别,还需要做细致调节,不过故事人物形象能大致统一

未完待续...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值