Datawhale X 魔搭 AI夏令营 第四期-AIGC方向Task2笔记

Datawhale X 魔搭 AI夏令营 第四期-AIGC方向Task2笔记

    正在检查是否收录...

baseline的流程图

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 

主体框架工作流

环境准备和依赖安装: 使用pip命令安装所需的Python库,包括simple-aesthetics-predictordata-juicerpytorch-lightningpeftlightningpandastorchvisionDiffSynth-Studio。 数据集加载: 从modelscope.msdatasets加载名为AI-ModelScope/lowres_anime的数据集,并指定子集和分割类型。 数据预处理: 创建保存图片和元数据的目录。 遍历数据集,将图片保存为JPEG格式,并生成包含文本和图片路径的元数据文件。 配置数据处理: 定义data_juicer的配置文件,包括项目名称、数据集路径、进程数、文本和图片键、特殊标记以及导出路径。 写入配置文件并使用dj-process命令行工具处理数据。 数据处理结果分析: 读取处理后的数据,提取文本和文件名,并将它们保存到CSV文件中。 模型加载和推理: 加载CLIP模型和处理器,对图片和文本进行编码,获取图像-文本相似度得分。 自定义数据集和数据加载器: 定义自定义数据集类CustomDataset,用于封装处理后的图片和文本数据。 创建数据加载器DataLoader,用于批量加载数据。 模型训练/推理循环: 遍历数据加载器中的批次,进行模型推理,获取每个批次的图像-文本相似度得分。 生成图像: 使用Stable Diffusion模型根据给定的提示生成图像,并保存到文件。 图像拼接: 将生成的多张图像拼接成一张长图,并调整大小。

逐行代码解释

安装所需的Python包
!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 
simple-aesthetics-predictor:安装一个简单的美学预测器。 data-juicer:安装数据处理工具包,使用可编辑模式安装(-e)。 卸载已有的pytorch-lightning版本。 安装peft(参数高效微调)、lightning(新的PyTorch Lightning库)、pandas(数据处理)和torchvision(计算机视觉工具包)。 安装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" ) 
modelscope.msdatasets导入MsDataset类。 使用MsDataset.load方法加载名为'AI-ModelScope/lowres_anime'的数据集,指定使用默认子集('default'),数据划分为训练集('train'),并将数据缓存到指定目录。 准备数据处理
import json, os from data_juicer.utils.mm_utils import SpecialTokens from tqdm import tqdm 
导入必要的库:json(处理JSON数据)、os(文件系统操作)、tqdm(进度条显示)。 从data_juicer的工具模块中导入SpecialTokens(用于处理特殊标记)。 创建必要的目录
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") 
打开一个名为metadata.jsonl的文件,用于写入每个图像的元数据。 遍历数据集中的每一条数据: 将图像转换为RGB格式。 将图像保存到指定目录,文件名为数据的索引。 创建元数据字典,包含文本描述"二次元"和图像路径。 将元数据以JSON格式写入文件,每条记录占一行。 配置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的配置,内容包括: 全局参数,如项目名称、数据集路径、并行处理的子进程数量等。 指定文本和图像的键,以及特殊的图像标记。 输出路径。 处理流程,包括图像尺寸过滤(最小宽度和高度为1024)和图像长宽比过滤(比例在0.5到2.0之间)。 将配置写入data_juicer_config.yaml文件。 运行data_juicer处理数据
!dj-process --config data/data-juicer/data_juicer_config.yaml 
使用data_juicer的命令行工具,根据配置文件处理数据集。 读取处理后的数据并创建DataFrame
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 
导入必要的库:pandas(数据处理)、osjsonPIL.Image(图像处理)和tqdm。 创建用于存储图像的输出目录。 打开处理后的结果文件result.jsonl,逐行读取: 解析每行的JSON数据,提取文本和图像路径,分别存储到列表中。 使用pandas创建一个包含文本和图像文件名的DataFrame。 将DataFrame保存为CSV文件。 显示DataFrame的内容。 使用CLIP模型计算图像和文本的相似度
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 
transformers库中导入CLIPProcessorCLIPModel,以及torch。 加载预训练的CLIP模型和处理器。 打开DataFrame中所有的图像文件。 使用处理器将文本和图像进行预处理,返回PyTorch张量,并进行适当的填充。 将预处理后的数据输入模型,获得输出。 提取每个图像与文本的相似度分数(logits_per_image)。 对相似度分数应用softmax,得到概率分布。 显示计算得到的概率。 定义自定义数据集和数据加载器
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) 
torch.utils.data中导入DatasetDataLoader。 定义CustomDataset类: 在初始化时,存储文本列表、打开的图像列表和处理器。 实现__len__方法,返回数据集的大小。 实现__getitem__方法,对指定索引的数据进行处理,并返回处理后的输入。 创建数据集和数据加载器,设置批次大小为8。 遍历数据加载器中的每个批次: 将批次数据输入模型,计算相似度分数和概率,并打印结果。 使用Stable Diffusion生成图像
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 
导入torchStableDiffusionPipeline。 设置随机种子为1,确保生成的图像可重复。 加载预训练的Stable Diffusion模型,并将其移动到GPU上,设置为半精度浮点数以节省显存。 定义正向和负向提示词,以及指导尺度和推理步数。 使用提示词生成图像,指定图像的高度和宽度为1024像素。 保存生成的图像为example_image.png,并显示图像。 生成更多图像并保存
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") 
使用不同的随机种子和提示词,生成多张图像,并分别保存为1.jpg8.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 
导入numpyPIL.Image。 打开之前生成的8张图像,将其转换为numpy数组。 将图像按照行和列拼接,形成一个大的图像网格: 每行拼接两张图像,共四行。 将拼接后的图像调整大小为1024x2048像素。 显示最终的拼接图像。

利用AI生成剧本(以kimi为例)

提示词1:你是一个古风漫画家,我们现在要做一个古风仙侠漫,现在要写一个故事简介
提示词2:根据故事简介,写一个故事大纲
提示词3:展开第四章:修仙大会,并把漫画具体的场景描绘出来
提示词4:

你是一个文生图专家,我们现在要做一个实战项目,就是要根据刚才展开的修仙大会内容编排一个文生图, 由8张场景图片生成,你需要输出每张图片的生图提示词 生图提示词要求 1、风格为古风 2、根据场景确定是使用全身还是上半身 3、人物描述 4、场景描述 5、做啥事情 例子: 古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙 修仙大会的提示词(AI生成) 

AI生成的提示词微调后整理如下:

编号 场景 正向提示词 负向提示词 结果 1 大会前夕 古风,水墨画,市集繁华,一个笑容甜美的少女(笑笑),背影转头,穿梭在人群中,好奇地打量着各种摊位,全身,身着简单朴素的布衣。 丑陋,变形,嘈杂,模糊,低对比度 2 报名处的混乱 古风,水墨画,报名处人潮汹涌,一个表情轻松的少女(笑笑)站在人群中,用幽默化解紧张气氛,上半身,身着带有些许修仙特色的服饰。 丑陋,变形,嘈杂,模糊,低对比度 3 大会开幕式 古风,水墨画,宏伟的主会场,一个少女(笑笑)和其他修仙者一起,仰头观看开幕式,全身,身着节日盛装。 丑陋,变形,嘈杂,模糊,低对比度 4 比武大会 古风,水墨画,比武台上,一个少女(笑笑)正在进行灵力控制比赛,全身,身着便于活动的修仙服饰,脸上带着自信的微笑。 丑陋,变形,嘈杂,模糊,低对比度 5 夜晚的庆祝 古风,水墨画,夜市灯火通明,一个少女(笑笑)和她的队友们围坐一桌,品尝美食,享受烟火表演,上半身,身着轻便的夜行衣。 丑陋,变形,嘈杂,模糊,低对比度 6 意外的挑战 古风,水墨画,夜市角落,一个少女(笑笑)面对神秘人物,准备接受挑战,全身,身着带有一些神秘符号的服饰,表情认真。 丑陋,变形,嘈杂,模糊,低对比度 7 智慧的较量 古风,水墨画,僻静角落,一个少女(笑笑)和神秘人物进行灵力与智慧的较量,上半身,身着代表智慧的服饰,手中拿着棋子或类似道具。 丑陋,变形,嘈杂,模糊,低对比度 8 大会的落幕 古风,水墨画,主会场,一个少女(笑笑)和她的队友们站在领奖台上,接受“最具潜力新人奖”,全身,身着带有荣誉象征的服饰,脸上洋溢着喜悦和自豪。 丑陋,变形,嘈杂,模糊,低对比度

总结

promptjson二次元clipclitpu数据集提示词gitdiffusion演唱会pandas元数据kolguicsvcto数据处理pytorchstablediffusion
  • 本文作者:李琛
  • 本文链接: https://wapzz.net/post-21207.html
  • 版权声明:本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。
本站部分内容来源于网络转载,仅供学习交流使用。如涉及版权问题,请及时联系我们,我们将第一时间处理。
文章很赞!支持一下吧 还没有人为TA充电
为TA充电
还没有人为TA充电
0
  • 支付宝打赏
    支付宝扫一扫
  • 微信打赏
    微信扫一扫
感谢支持
文章很赞!支持一下吧
关于作者
2.3W+
5
0
1
WAP站长官方

“免费的AI绘画软件推荐:开启你的创作之旅“

上一篇

【拥抱AIGC】通义灵码策略配置

下一篇
  • 复制图片
按住ctrl可打开默认菜单