DataWhale夏令营第四期魔搭- AIGC方向task02笔记

Part1:磨刀准备一一认识通义千问

Part2: 精读baseline——从零入门AI生图

  • 关于代码阅读和理解,我们今天尝试让AI助手从两个角度帮助我们:
  1. 分析代码的主题架构;

  2. 逐行代码解析

  • 首先我们来直观 感知下这个文生图代码的框架结构:

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑 

  •  baseline中的所有代码整理码结构如下:
!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/data-juicer/output/images", exist_ok=True)
with open("./data/data-juicer/output/result.jsonl", "r") as f:
    for line in tqdm(f):
        metadata = json.loads(line)
        texts.append(metadata["text"])
        file_names.append(metadata["image"][0])

df = pd.DataFrame({"text": texts, "file_name": file_names})
df.to_csv("./data/data-juicer/output/result.csv", index=False)

df

from transformers import CLIPProcessor, CLIPModel
import torch

model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

images = [Image.open(img_path) for img_path in df["file_name"]]
inputs = processor(text=df["text"].tolist(), images=images, return_tensors="pt", padding=True)

outputs = model(**inputs)
logits_per_image = outputs.logits_per_image  # this is the image-text similarity score
probs = logits_per_image.softmax(dim=1)  # we can take the softmax to get the probabilities

probs

from torch.utils.data import Dataset, DataLoader

class CustomDataset(Dataset):
    def __init__(self, df, processor):
        self.texts = df["text"].tolist()
        self.images = [Image.open(img_path) for img_path in df["file_name"]]
        self.processor = processor

    def __len__(self):
        return len(self.texts)

    def __getitem__(self, idx):
        inputs = self.processor(text=self.texts[idx], images=self.images[idx], return_tensors="pt", padding=True)
        return inputs

dataset = CustomDataset(df, processor)
dataloader = DataLoader(dataset, batch_size=8)

for batch in dataloader:
    outputs = model(**batch)
    logits_per_image = outputs.logits_per_image
    probs = logits_per_image.softmax(dim=1)
    print(probs)

import torch
from diffusers import StableDiffusionPipeline

torch.manual_seed(1)
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v-1-4", torch_dtype=torch.float16)
pipe = pipe.to("cuda")

prompt = "二次元,一个紫色长发小女孩穿着粉色吊带漏肩连衣裙,在练习室练习唱歌,手持话筒"
negative_prompt = "丑陋、变形、嘈杂、模糊、低对比度"
guidance_scale = 4
num_inference_steps = 50

image = pipe(
    prompt=prompt,
    negative_prompt=negative_prompt,
    guidance_scale=guidance_scale,
    num_inference_steps=num_inference_steps,
    height=1024,
    width=1024,
).images[0]

image.save("example_image.png")
image

from PIL import Image

torch.manual_seed(1)
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)]
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
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
  1. 分析代码的主体架构

  1. 输入的Prompt

你是一个优秀的python开发工程师,现在我们需要你帮我们分析这个代码的主体框架,你需要把代码按照工作流分成几部分,用中文回答我的问题。{此处替换前面的代码}
  1. 返回的结果

这段代码可以大致分为以下几个主要的工作流程:
1. 环境准备与依赖安装
使用pip命令安装所需的Python库,包括simple-aesthetics-predictor、data-juicer(使用editable模式)、移除并重新安装pytorch-lightning及其替代库peft、lightning、pandas、torchvision,以及DiffSynth-Studio。
2. 数据预处理与整理
加载数据集:通过MsDataset从ModelScope加载名为lowres_anime的数据集,并指定子集、分割方式和缓存目录。
转换并保存图像:遍历数据集,将图像转换为RGB格式并保存到指定路径,同时生成包含文本和图像路径的元数据文件,用于后续处理。
配置数据处理:创建一个data_juicer_config.yaml配置文件,设定数据处理的规则,如图像尺寸、长宽比过滤条件等。
执行数据处理:使用data-juicer工具根据配置文件对数据进行过滤和处理,输出处理后的结果。
3. 数据分析与准备
读取处理后的数据:读取处理后的JSONL文件,提取文本和对应的图像路径,构建Pandas DataFrame,并保存为CSV文件。
CLIP模型应用:利用Hugging Face的CLIPModel和CLIPProcessor计算文本与图像的相似性分数,展示概率分布。
4. 自定义数据集与模型加载
创建自定义数据集类:定义了一个继承自torch.utils.data.Dataset的CustomDataset类,用于封装处理好的文本和图像数据,配合CLIPProcessor进行数据处理。
数据加载器:使用DataLoader加载自定义数据集,以批量形式迭代处理数据。
5. 图像生成与处理
Stable Diffusion Pipeline:利用Hugging Face的StableDiffusionPipeline生成二次元风格的图像,通过不同的种子值和提示生成多张变体图片,同时加入负面提示以排除不希望出现的特征。
图像拼接:最后,将生成的多张图片横向和纵向拼接成一张大图,展示生成结果。
整体来看,这段代码实现了一个从数据准备、处理、分析、模型应用到最终图像生成的完整工作流程,涵盖了数据预处理、机器学习模型应用、自定义数据集构建、深度学习模型调用等多个技术环节。

  • 执行过程 

  • 逐行 解释代码

  1. 输入的问题

你是一个优秀的python开发工程师,现在我们需要你帮我们逐行分析这个代码,用中文回答我的问题。{此处替换前面的代码}
  1. 返回的结果

这段代码主要分为以下几个部分:
环境准备和依赖安装:
安装所需的库,如simple-aesthetics-predictor、data-juicer、pytorch-lightning、peft、lightning、pandas和torchvision。
卸载旧版本的pytorch-lightning并重新安装。
克隆并安装DiffSynth-Studio项目。
数据加载与预处理:
使用MsDataset从AI-ModelScope加载'lowres_anime'数据集,并指定训练集、子集名和缓存目录。
将数据集中的图像保存到特定文件夹,并为每个图像创建对应的JSON格式的metadata文件,包含文本描述和图片路径。
使用DataJuicer进行数据清洗:
配置DataJuicer参数,包括项目名称、数据集路径、进程数以及数据过滤条件(如最小宽度、高度和纵横比)。
写入配置文件。
运行DataJuicer脚本对数据进行清洗和筛选。
将预处理后的数据转换为CSV:
读取清洗后的结果,提取文本和文件名,并将其存储为DataFrame。
将DataFrame写入CSV文件。
使用CLIP模型计算相似性得分:
加载CLIP预训练模型和处理器。
对清洗后的数据集中的文本和图像应用处理器以生成输入张量。
通过模型获取图像与文本的相似性得分(概率)。
定义自定义数据集类并构建Dataloader:
创建CustomDataset类,用于处理数据加载和预处理。
实例化CustomDataset和Dataloader对象。
运行CLIP模型并打印输出:
在定义好的Dataloader上迭代,每次循环调用CLIP模型并打印图像与文本的相似性得分(概率)。
使用StableDiffusionPipeline生成图像:
初始化StableDiffusionPipeline,设置随机种子和模型参数。
使用不同的提示和负向提示生成多幅图像,并保存它们。
拼接生成的图像:
将生成的图像数组沿着水平方向拼接成一个大图,然后调整大小并保存。
整个代码的工作流程是:首先下载和预处理数据,接着利用DataJuicer进行数据清洗,之后使用CLIP模型计算图像与文本的相关性,最后使用StableDiffusionPipeline根据给定的提示生成新的图像,并将它们拼接在一起。

  • 执行过程 

  

Part3:实战演练一一基于话剧的连环画制作 

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

具体的场景图片
1、女主正在上课
2、开始睡着了
3、进入梦乡,梦到自己站在路旁
4、王子骑马而来
5、两人相谈甚欢
6、一起坐在马背上
7、下课了,梦醒了
8、又回到了学习生活中

生图提示词要求
1、风格为古风
2、根据场景确定是使用全身还是上半身
3、人物描述
4、场景描述
5、做啥事情

例子:
古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙

  

   

  •  结果展示

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑 

 

  •  方定义

🪄SCEPTER is an open-source code repository dedicated to generative training, fine-tuning, and inference, encompassing a suite of downstream tasks such as image generation, transfer, editing. SCEPTER integrates popular community-driven implementations as well as proprietary methods by Tongyi Lab of Alibaba Group, offering a comprehensive toolkit for researchers and practitioners in the field of AIGC. This versatile library is designed to facilitate innovation and accelerate development in the rapidly evolving domain of generative models.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值