继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