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

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

    正在检查是否收录...

AI工具使用

1. baseline 代码 2. 使用通义千问理解代码 2.1 工作流程 2.2 逐行释意 3. 使用通义千问生成 Prompt 3.1 生成的 Prompt 3.1 根据 Prompt 生成的图片

1. 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 

2. 使用通义千问理解代码

2.1 工作流程

这段代码主要涉及了以下几个部分的工作流程:

环境设置与依赖安装 使用!pip install命令安装一系列Python包,包括simple-aesthetics-predictor, data-juicer, peft, lightning, pandas, torchvision, 和 DiffSynth-Studio。 卸载并重新安装pytorch-lightning。 数据集加载与预处理 加载名为AI-ModelScope/lowres_anime的数据集,并指定子集和拆分类型为训练集。 创建必要的目录结构用于存储图像和元数据。 遍历数据集,将图像转换为RGB格式并保存到指定目录,同时构建包含文本描述和图像路径的元数据JSONL文件。 数据过滤与处理配置 编写YAML配置文件,定义数据处理流程,包括过滤图像大小和长宽比,以及输出路径等参数。 使用data_juicer工具根据配置文件处理数据集,生成处理后的结果文件。 数据整理与模型预测 将处理后的数据整理成DataFrame,并将其保存为CSV文件。 加载CLIP模型和处理器,对图像和文本进行编码,计算图像与文本之间的相似性分数。 创建自定义PyTorch数据集和数据加载器,使用CLIP模型进行批量预测。 图像生成 利用StableDiffusionPipeline生成基于给定提示(prompt)的二次元图像。 指定不同的种子以生成不同的图像实例,同时设定负面提示(negative prompt)来避免某些不希望出现的特征。 保存生成的图像,并组合多个图像成一个大图以便展示。

整个流程从数据集的加载开始,经过数据预处理、数据过滤、特征提取和相似性计算,最后通过文本到图像的生成模型产生新的图像。每一部分都紧密相连,共同完成了从数据到生成图像的完整工作流。

2.2 逐行释意

以下是逐行代码及对应的中文注释:

# 安装simple-aesthetics-predictor库 !pip install simple-aesthetics-predictor # 以可编辑模式安装data-juicer库,-v参数表示详细模式 !pip install -v -e data-juicer # 卸载pytorch-lightning库,-y参数表示自动确认卸载 !pip uninstall pytorch-lightning -y # 安装peft, lightning, pandas 和 torchvision库 !pip install peft lightning pandas torchvision # 以可编辑模式安装DiffSynth-Studio库 !pip install -e DiffSynth-Studio # 从modelscope导入MsDataset类 from modelscope.msdatasets import MsDataset # 加载ModelScope上的lowres_anime数据集,subset_name指定子集,split指定数据集划分,cache_dir指定缓存目录 ds = MsDataset.load( 'AI-ModelScope/lowres_anime', subset_name='default', split='train', cache_dir="/mnt/workspace/kolors/data" ) # 导入json和os模块 import json, os # 导入SpecialTokens类(未在后续代码中使用) from data_juicer.utils.mm_utils import SpecialTokens # 导入tqdm模块,用于显示进度条 from tqdm import tqdm # 创建目录用于存放训练图像,exist_ok参数设为True表示如果目录已存在则不抛出异常 os.makedirs("./data/lora_dataset/train", exist_ok=True) # 创建目录用于存放data-juicer的输入文件 os.makedirs("./data/data-juicer/input", exist_ok=True) # 打开metadata.jsonl文件用于写入,"w"表示写模式 with open("./data/data-juicer/input/metadata.jsonl", "w") as f: # 遍历数据集ds中的每一项,使用tqdm显示进度 for data_id, data in enumerate(tqdm(ds)): # 将图像转换为RGB模式 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的配置字符串,包含了数据处理的参数 data_juicer_config = """ # 全局参数 project_name: 'data-process' dataset_path: './data/data-juicer/input/metadata.jsonl' # 数据集目录或文件的路径 np: 4 # 处理数据集时使用的子进程数量 text_keys: 'text' image_key: 'image' image_special_token: '<__dj__image>' export_path: './data/data-juicer/output/result.jsonl' # 处理计划,一系列的数据处理操作及其参数 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 """ # 写入data_juicer配置到文件 with open("data/data-juicer/data_juicer_config.yaml", "w") as file: file.write(data_juicer_config.strip()) # 调用dj-process命令,--config参数指定配置文件路径 !dj-process --config data/data-juicer/data_juicer_config.yaml # 导入pandas库 import pandas as pd # 再次导入os和json模块(已经导入过,此处重复) import os, json # 导入Image模块,用于图像处理 from PIL import Image # 创建目录用于存放处理后的图像 os.makedirs("./data/data-juicer/output/images", exist_ok=True) # 打开result.jsonl文件,读取处理后的数据 with open("./data/data-juicer/output/result.jsonl", "r") as f: # 初始化两个空列表,用于存储文本和图像文件名 texts, file_names = [], [] # 遍历文件中的每一行 for line in tqdm(f): # 解析每一行的JSON数据 metadata = json.loads(line) # 提取文本和图像路径,添加到列表中 texts.append(metadata["text"]) file_names.append(metadata["image"][0]) # 创建一个DataFrame,列名为"text"和"file_name" df = pd.DataFrame({"text": texts, "file_name": file_names}) # 将DataFrame保存为CSV文件,index=False表示不保存索引 df.to_csv("./data/data-juicer/output/result.csv", index=False) # 显示DataFrame的内容 df # 从transformers导入CLIPProcessor和CLIPModel类 from transformers import CLIPProcessor, CLIPModel # 导入torch库 import torch # 从预训练模型加载CLIP模型 model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32") # 从预训练模型加载CLIP处理器 processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32") # 加载图像并使用processor预处理图像和文本 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 # 计算概率分布 probs = logits_per_image.softmax(dim=1) # 查看概率分布 probs # 从torch.utils.data导入Dataset和DataLoader类 from torch.utils.data import Dataset, DataLoader # 定义一个自定义数据集类CustomDataset 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 # 使用CustomDataset和DataLoader创建数据集和数据加载器 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库(已经导入过,此处重复) import torch # 从diffusers导入StableDiffusionPipeline类 from diffusers import StableDiffusionPipeline # 设置随机种子,确保生成过程的一致性 torch.manual_seed(1) # 从预训练模型加载StableDiffusionPipeline模型 pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v-1-4", torch_dtype=torch.float16) # 将模型移动到CUDA设备上 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 # 导入numpy和Image模块(numpy已经导入过,此处重复) import numpy as np 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") # 加载多个图像,使用numpy转换为数组 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) # 使用PIL从数组创建图像,并调整尺寸 image = Image.fromarray(image).resize((1024, 2048)) # 显示最终拼接的图像 image 

这段代码涵盖了从数据集的加载、图像预处理、模型预测、数据集封装、图像生成到图像拼接的整个工作流程。

3. 使用通义千问生成 Prompt

3.1 生成的 Prompt

基于你的要求,这里是每张图片的生图提示词:

仙侠,水墨画,一个黑发飘逸的少女,全身着装白色仙门弟子服,手持长剑,在清晨的山巅,朝阳映照下,正对着东方初升的太阳练习剑法,全身,背景是雾气缭绕的山峰和松柏。

仙侠,动态描绘,少女脚踏飞剑,衣袂飘飘,凌空飞翔于云海之上,全身,背景是辽阔的天空和下方连绵起伏的山脉。

仙侠,细腻描绘,少女站在山门之前,背着行囊,准备下山,目光坚定,上半身特写,背景是宏伟的山门和远方的村落。

仙侠,紧张氛围,一群狰狞的妖怪在村庄中肆虐,房屋倒塌,火光冲天,全身,背景是混乱的村庄和村民们四散奔逃的景象。

仙侠,英勇战斗,少女挥舞长剑,与妖怪激战,剑光闪烁,全身,背景是被破坏的村庄一角,妖怪的尸体散落周围。

仙侠,温馨场景,少女被一群感激的村民围绕,接受他们的鲜花和食物,上半身,背景是重建中的村庄和欢乐的村民。

仙侠,归来时刻,少女身着尘土飞扬的旅装,重新踏上通往山门的道路,全身,背景是夕阳下的山路和逐渐消失在视线中的村庄。

仙侠,循环不息,少女回到山顶,再次拿起长剑,对着同一棵木桩,开始新的一轮剑术练习,全身,背景是熟悉的院子和远处的山峦。

这些描述结合了仙侠元素、动作、人物和环境,可以作为生成图像的依据。如果需要调整任何细节,请随时告知!

3.1 根据 Prompt 生成的图片

相关链接

Datawhale活动页面 通义千问 魔搭体验网址 Scepter与WebUI,一站式生成编辑工具箱 《AIGC未来已来》 AI绘画的发展历史(GAN、diffusion、VAE…)

总结

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

Midjourney连夜发布v6.1版本 | Midjourney API v6.1

上一篇

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

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