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

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

    正在检查是否收录...

        继task01跑通baseline之后,有时候回想起实例中那些自己摸不着头脑的代码片段,确实有些好奇,task2正好用借助通用大语言模型工具精读了一下这些代码片段,并进行了实战演练一一基于话剧的连环画制作。

(这里学习文档给出的大语言模型是国内的通义千问,但是个人更喜欢用chatgpt-4o,感觉又快又准)

1.精读baseline代码

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

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

Answer:

这个代码的主体框架可以按照工作流分为几个主要部分,每个部分的功能和作用如下:

### 1. **环境准备和依赖安装**
   - **代码片段:**
     ```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
     ```
   - **说明:**
     这一部分是进行必要的库和依赖项的安装,为后续的代码运行做好准备。这些库包括图像处理、数据集处理、模型推理等所需的工具。

### 2. **数据集加载与预处理**
   - **代码片段:**
     ```python
     from modelscope.msdatasets import MsDataset
     ds = MsDataset.load(
         'AI-ModelScope/lowres_anime',
         subset_name='default',
         split='train',
         cache_dir="/mnt/workspace/kolors/data"
     )
     ```
   - **说明:**
     这一部分代码从指定的来源加载数据集,并存储到本地缓存目录中,供后续使用。

### 3. **数据保存与配置文件生成**
   - **代码片段:**
     ```python
     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")
     ```
   - **说明:**
     这部分代码将数据集中的图像保存到指定目录,并生成相应的元数据文件,用于后续的数据处理工作。

### 4. **数据处理和过滤**
   - **代码片段:**
     ```python
     data_juicer_config = """
     # global parameters
     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
     """
     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
     ```
   - **说明:**
     这一部分代码通过 `data-juicer` 工具对数据集进行预处理和过滤,保留符合要求的图像数据。

### 5. **数据处理后的结果保存**
   - **代码片段:**
     ```python
     import pandas as pd
     import os, json
     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)
     ```
   - **说明:**
     这部分代码将经过处理的图像和文本数据保存为 CSV 文件,便于后续分析和使用。

### 6. **模型推理与概率计算**
   - **代码片段:**
     ```python
     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
     probs = logits_per_image.softmax(dim=1)

     probs
     ```
   - **说明:**
     这一部分代码使用 CLIP 模型进行推理计算,计算图像和文本之间的相似性得分,并通过 softmax 得到概率分布。

### 7. **自定义数据集与数据加载**
   - **代码片段:**
     ```python
     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)
     ```
   - **说明:**
     这部分代码定义了一个自定义数据集,并创建数据加载器,以批量处理数据进行模型推理。

### 8. **生成图片**
   - **代码片段:**
     ```python
     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")
     ```
   - **说明:**
     这一部分使用 `StableDiffusionPipeline` 生成图像,基于提供的 prompt 和 negative prompt,生成不同内容的二次元风格图片。

### 9. **图片拼接与最终图像生成**
   - **代码片段:**
     ```python
     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
     ```
   - **说明:**
     最后,这部分代码将之前生成的多张图片进行拼接,生成一个大图,用于展示多个结果。

通过以上工作流的分析,这段代码的主要工作流程涵盖了环境准备、数据加载与预处理、模型推理、图片生成和最终的结果展示,能够很好地完成数据处理和图像生成的任务。

1.2 逐行解释代码

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

Answer:

以下是对给定代码的逐行中文分析:

### 1. **安装依赖库**
   ```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
   ```
   - **说明**:这一部分代码使用 `pip` 安装了一些需要的 Python 包和库。这些库包括 `simple-aesthetics-predictor`(用于美学评分的预测器)、`data-juicer`(数据处理工具包)、`pytorch-lightning`(一种轻量级的 PyTorch 封装,已卸载并替换为 `lightning`)、`peft`、`pandas`(数据处理库)、`torchvision`(用于计算机视觉的库)以及 `DiffSynth-Studio`(用于图像生成的工具包)。

### 2. **加载数据集**
   ```python
   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` 方法加载一个名为 `lowres_anime` 的低分辨率动漫图像数据集。这个数据集被存储在本地缓存目录 `/mnt/workspace/kolors/data` 中。

### 3. **导入必要的模块**
   ```python
   import json, os
   from data_juicer.utils.mm_utils import SpecialTokens
   from tqdm import tqdm
   ```
   - **说明**:导入 Python 标准库的 `json` 和 `os` 模块,分别用于处理 JSON 数据和操作系统功能。`SpecialTokens` 是从 `data_juicer` 的 `mm_utils` 中导入的工具类,而 `tqdm` 则用于显示循环进度条。

### 4. **创建文件夹并处理数据集**
   ```python
   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/lora_dataset/train` 和 `./data/data-juicer/input`。然后,遍历数据集 `ds`,将图像转换为 RGB 格式并保存到 `train` 文件夹中。对于每个图像,生成相应的元数据(包括文本标签“二次元”和图像路径),并将这些元数据写入 `metadata.jsonl` 文件中。

### 5. **生成数据处理配置文件**
   ```python
   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` 数据处理的 YAML 配置文件。该配置文件定义了全局参数(如项目名称、数据集路径、并行处理子进程数)、文本和图像键,以及图像过滤器(基于图像的最小宽度、高度和宽高比)。

### 6. **执行数据处理任务**
   ```python
   !dj-process --config data/data-juicer/data_juicer_config.yaml
   ```
   - **说明**:使用 `data-juicer` 命令行工具根据上一步生成的配置文件 `data_juicer_config.yaml` 来处理数据集。处理后的结果将被保存到 `data/data-juicer/output/result.jsonl`。

### 7. **加载处理后的数据并保存为 CSV 文件**
   ```python
   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)
   ```
   - **说明**:从 `result.jsonl` 文件中读取处理后的数据,并提取文本和图像文件名,存储在 `texts` 和 `file_names` 列表中。然后将这些数据保存为 Pandas DataFrame,并导出为 CSV 文件 `result.csv`。

### 8. **使用 CLIP 模型计算图像与文本的相似性**
   ```python
   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` 库中的 CLIP 模型和处理器,并使用 `CLIPModel` 加载预训练的 CLIP 模型。随后,处理图像和文本数据,将其输入模型,计算每张图像与文本之间的相似性得分,并通过 softmax 函数计算得分的概率分布。

### 9. **定义自定义数据集类并使用 DataLoader**
   ```python
   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)
   ```
   - **说明**:定义一个 `CustomDataset` 类,用于将文本和图像数据包装成一个 PyTorch 数据集。`__getitem__` 方法返回处理后的图像和文本张量。然后使用 `DataLoader` 进行批量加载,并在每个批次中进行模型推理,计算图像与文本的相似性得分。

### 10. **使用 Stable Diffusion 生成图像**
   ```python
   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
   ```
   - **说明**:使用 `StableDiffusionPipeline` 从预训练的 `stable-diffusion-v-1-4` 模型生成图像。设置随机种子、加载模型到 GPU,并根据提供的 prompt 和 negative prompt 生成图像,最终将图像保存为 `example_image.png`。

### 11. **使用不同的提示词生成更多图像**
   ```python
   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")
   ```
   - **说明**:这段代码生成一系列图像,使用不同的 prompt 和随机种子。每个图像使用相应的 prompt 生成并保存为不同的文件(如 `1.jpg`, `2.jpg` 等等)。每个 prompt 描述了不同的场景或动作。

### 12. **拼接多个图像生成最终结果**
   ```python
   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
   ```
   - **说明**:导入 `numpy` 和 `PIL`,并将生成的八张图像拼接成一个大图。首先,将图像按行拼接,然后将所有行拼接成一个最终的图像,最后将其调整为目标尺寸 `1024x2048`。

这段代码整体上展示了从数据处理、模型推理、图像生成到结果展示的完整流程。

 1.3  理解之后加上逐行注释

# 安装简单美学预测器包 !pip install simple-aesthetics-predictor # 以可编辑模式安装 data-juicer 包,方便进行调试和开发 !pip install -v -e data-juicer # 卸载 pytorch-lightning 包,并安装特定的库:peft, lightning, pandas, torchvision !pip uninstall pytorch-lightning -y !pip install peft lightning pandas torchvision # 以可编辑模式安装 DiffSynth-Studio 包 !pip install -e DiffSynth-Studio # 从 ModelScope 加载 MsDataset 数据集类 from modelscope.msdatasets import MsDataset # 加载 'lowres_anime' 数据集,指定训练集部分,并缓存到指定目录 ds = MsDataset.load( 'AI-ModelScope/lowres_anime', subset_name='default', split='train', cache_dir="/mnt/workspace/kolors/data" ) # 导入所需的库,包括 JSON 处理、操作系统接口、tqdm 进度条工具,以及 data_juicer 的实用工具 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) # 打开 metadata.jsonl 文件,以写入模式保存图像的元数据 with open("./data/data-juicer/input/metadata.jsonl", "w") as f: # 遍历数据集中的每一条数据 for data_id, data in enumerate(tqdm(ds)): # 将图像转换为 RGB 格式 image = data["image"].convert("RGB") # 保存图像到指定路径,并以数据ID命名 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"]} # 将元数据写入 metadata.jsonl 文件中 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 # 任意一个条件满足即可 """ # 将配置文件写入到指定的 YAML 文件中 with open("data/data-juicer/data_juicer_config.yaml", "w") as file: file.write(data_juicer_config.strip()) # 使用 data-juicer 进行数据处理,依据刚才生成的配置文件 !dj-process --config data/data-juicer/data_juicer_config.yaml # 导入所需的库,包括 pandas、操作系统接口、JSON 处理、图像处理工具 PIL,以及 tqdm 进度条工具 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) # 打开结果文件 result.jsonl,读取处理后的元数据 with open("./data/data-juicer/output/result.jsonl", "r") as f: for line in tqdm(f): # 遍历每一行数据 metadata = json.loads(line) # 将 JSON 字符串解析为字典 texts.append(metadata["text"]) # 将文本添加到文本列表中 file_names.append(metadata["image"][0]) # 将图像路径添加到文件名列表中 # 创建 DataFrame 存储文本和文件名,并保存为 CSV 文件 df = pd.DataFrame({"text": texts, "file_name": file_names}) df.to_csv("./data/data-juicer/output/result.csv", index=False) # 显示 DataFrame 内容 df # 从 transformers 库中导入 CLIP 模型和处理器 from transformers import CLIPProcessor, CLIPModel import torch # 加载预训练的 CLIP 模型和处理器 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 # 图像-文本相似度得分 probs = logits_per_image.softmax(dim=1) # 对相似度得分进行 softmax 处理,获得概率分布 # 显示概率分布 probs # 从 PyTorch 中导入数据集和数据加载器模块 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 # CLIP 处理器 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 # 创建自定义数据集实例,并使用 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) # 导入 PyTorch 和 Stable Diffusion 管道 import torch from diffusers import StableDiffusionPipeline # 设置随机种子以保证生成结果的可重复性 torch.manual_seed(1) # 加载预训练的 Stable Diffusion 模型,并将其设置为 float16 类型以提高性能 pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v-1-4", torch_dtype=torch.float16) pipe = pipe.to("cuda") # 将模型加载到 GPU 上 # 定义生成图像的文本提示和负面提示 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 # 导入 PIL 图像处理库 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 和 PIL 库,用于图像处理 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 数据准备

Prompt: 

   你是一个文生图专家,我们现在要做一个实战项目,就是要编排一个文生图话剧 话剧由8张场景图片生成,你需要输出每张图片的生图提示词 具体的场景图片 1、女主正在上课 2、开始睡着了 3、进入梦乡,梦到自己站在路旁 4、王子骑马而来 5、两人相谈甚欢 6、一起坐在马背上 7、下课了,梦醒了 8、又回到了学习生活中 生图提示词要求 1、风格为古风 2、根据场景确定是使用全身还是上半身 3、人物描述 4、场景描述 5、做啥事情 例子: 古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙

Answer:

1. 女主正在上课

提示词:
古风,水墨画,一个黑色长发少女,坐在古色古香的课堂里,面前是一本展开的书,正在认真听课,上半身,穿着浅绿色古代长袍。

2. 开始睡着了

提示词:
古风,水墨画,一个黑色长发少女,坐在古色古香的课堂里,眼神逐渐迷离,头微微低下,手轻轻撑着脸颊,睡意渐浓,上半身,浅绿色古代长袍。

3. 进入梦乡,梦到自己站在路旁

提示词:
古风,水墨画,一个黑色长发少女,站在铺满落叶的古道旁,身边是寂静的竹林,神情恍惚,仿佛置身梦境,全身,淡紫色古代长裙。

4. 王子骑马而来

提示词:
古风,水墨画,一个英俊的王子,身穿深蓝色长袍,骑着一匹白色骏马,从远处的山道缓缓而来,手握缰绳,目光温柔,全身,背景是苍翠的群山。

5. 两人相谈甚欢

提示词:
古风,水墨画,一个黑色长发少女,和英俊的王子并肩站在古道旁,两人神情愉悦,正在交谈,背景是青翠的竹林和古道,全身,少女穿着淡紫色古代长裙,王子身穿深蓝色长袍。

6. 一起坐在马背上

提示词:
古风,水墨画,一个黑色长发少女与英俊的王子同乘一匹白马,王子在前,少女轻轻扶着他的肩膀,马儿缓缓前行,背景是夕阳映照下的古道,全身,少女穿着淡紫色古代长裙,王子身穿深蓝色长袍。

7. 下课了,梦醒了

提示词:
古风,水墨画,一个黑色长发少女,突然惊醒,发现自己仍然坐在古色古香的课堂里,双眼睁大,神情微带迷茫,上半身,浅绿色古代长袍,面前是展开的书。

8. 又回到了学习生活中

提示词:
古风,水墨画,一个黑色长发少女,重新专心于书本,手中握着毛笔,正在古色古香的课堂里奋笔疾书,背景是古代书桌和书籍,上半身,浅绿色古代长袍。

 2.2 执行Task1的30分钟速通Baseline

中途遇到显存不足的问题,清理缓存之后解决

2.3 提示词修改 生成图片

总结

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

AI绘画工具Stable Diffusion+ComfyUI的配置

上一篇

AIGC绘画设计基础——SD人物写实图像高质量生成和手部修复

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