探探前沿:了解一下 AI生图技术 的能力&局限
下面是一些可以反思的图片:
- 开始探索AI生图前沿
AI生图自破圈以来,被科研界、业界广泛关注,且引发了各大厂商的模型之战,如我们这次学习活动所需要用到的Kolors(可图)模型(点击即可跳转魔搭模型介绍页),就是其中的一个产物——
Kolors(可图)模型(点击即可跳转魔搭模型介绍页) 是快手开源的文本到图像生成模型,该模型具有对英语和汉语的深刻理解,并能够生成高质量、逼真的图像。
代码开源链接:https://github.com/Kwai-Kolors/Kolors
模型开源链接:https://modelscope.cn/models/Kwai-Kolors/Kolors
技术报告链接:https://github.com/Kwai-Kolors/Kolors/blob/master/imgs/Kolors_paper.pdf
魔搭研习社最佳实践说明:https://www.modelscope.cn/learn/575?pid=543
这些都是非常实用的网站哦
过去文生图主要以 SD 系列基础模型为主,仅支持英文的prompt,但可图是支持中文的文生图模型,文生图的prompt格式较为固定,魔搭社区还开源了专门的各种风格的可图优质咒语书(点击即可跳转),可以针对600+种不同风格,完善prompt,生成各种风格图片,可以在我们的学习当中使用——
2.个人笔记:(大约没有什么用,可直接跳过看baseline)
直接生成,控制(可控生成和图形编辑)和对整个的速度()
去噪是什么意思?
"去噪"(Denoising)这个术语通常用于信号处理、图像处理、音频处理和其他相关领域,指的是从数据中移除噪声或干扰的过程。噪声可以理解为数据中不想要的或无关的信号,它们可能来源于多种原因,比如传感器的不完美、环境干扰、传输错误等。
像素空间去噪
输出(扩散模型)的两种模式:用两种方式输出为代表
共同:大尺寸都是先用扩散级联生成小分辨率图片再借助一个或者多个超分辨率的模型将小分辨率的图片到超分辨率使得图片更大
为什么不直接更大?会让收敛变慢而且会有硬件要求
隐空间去噪:
对一张大图片压缩提高效率,隐空间表达自编码进行还原。
推理速度更高,有损失(对小细节或者比例有一些问题,保真度问题)
但是还是主流办法
Stable cascade:结合
可以再更小的潜空间工作
(比如42倍压缩比)
图片的布局色彩
模型优化:
Sd模型框架变化没有那么大,但是提高生成质量,模型大为主流
更准确:1.更准确的表述(打标器)和训练2.更大的文本编码器(第一个只有1个,现在已经已经有3个编码器了),提高模型性能3.Unet->transformer.(dit)
更大的模型容量,prompt,模型的架构选择
Diffusion transformer:架构:"Diffusion transformer"是一种基于transformer架构的新型扩散模型,它利用transformer来处理图像数据的潜在表示,而不是传统的基于U-Net的架构。这种模型通过替换通常使用的U-Net骨干网络,采用transformer来操作潜在的图像块,从而实现图像生成的扩散过程 。
Cross attension:
三阶段的训练模式
Stable diffusion:
可控生成和图形编辑
- 模型得分预测
- 微调扩散模型(不引入额外模型参数)
- 无需训练的条件得分预测(中间结果,attension map)
- 条件引导的得分估计(不影响模型,而是输出)
空间控制条件:比如pose(三种统一建构)
Controlnet
T2i adapter(多个控制条件)。。。
2.Baseline举例说明
(巨无敌有用,吐血整修)
# 安装 Data-Juicer 和 DiffSynth-Studio
!pip install simple-aesthetics-predictor # 安装simple-aesthetics-predictor
!pip install -v -e data-juicer # 安装data-juicer
!pip uninstall pytorch-lightning -y # 卸载pytorch-lightning
!pip install peft lightning pandas torchvision # 安装 peft lightning pandas torchvision
!pip install -e DiffSynth-Studio # 安装DiffSynth-Studio
# 从魔搭数据集中下载数据集AI-ModelScope/lowres_anime
from modelscope.msdatasets import MsDataset #引入数据集模块msdatasets
ds = MsDataset.load(
'AI-ModelScope/lowres_anime',
subset_name='default',
这指定了数据集中的一个子集名称,这里使用的是默认子集。子集名称='默认
split='train',
cache_dir="/mnt/workspace/kolors/data" 目录
# 指定缓存目录
) # 从魔搭数据集中下载数据集AI-ModelScope/lowres_anime,赋值给参数ds
# 生成数据集
import json, os # 导入json和os模块
from data_juicer.utils.mm_utils import SpecialTokens # 导入SpecialTokens
from tqdm import tqdm # 导入tqdm进度条管理
os.makedirs("./data/lora_dataset/train", exist_ok=True) # 创建文件夹./data/lora_dataset/train这是os模块中的一个函数,用于递归地创建目录。如果中间的目录不存在,makedirs会创建它们。
- exist_ok=True: 这个参数告诉makedirs函数,如果指定的目录已经存在,不要抛出异常。默认情况下,如果目录已经存在,makedirs会抛出一个OSError。
os.makedirs("./data/data-juicer/input", exist_ok=True) # 创建文件夹./data/data-juicer/input
with open("./data/data-juicer/input/metadata.jsonl", "w") as f:
for data_id, data in enumerate(tqdm(ds)): # 遍历数据集ds
image = data["image"].convert("RGB") # 将数据集的图片转换为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)) # 将索引数据写入文件./data/data-juicer/input/metadata.jsonl
- json.dumps(metadata):
- 这是json模块的dumps()函数,它将Python对象转换成JSON格式的字符串。这里的metadata是一个Python对象,可能是一个字典、列表或其他类型,它将被转换成JSON格式。
f.write("\n")
# 配置data-juicer,并进行数据筛选过滤
# 配置过滤的规则
data_juicer_config = """
# global parameters
project_name: 'data-process' # 名称
dataset_path: './data/data-juicer/input/metadata.jsonl' # 你前面生成的数据的索引文件
np: 4 # 线程数
text_keys: 'text' # 文件./data/data-juicer/input/metadata.jsonl的描述的字段名
image_key: 'image' # 文件./data/data-juicer/input/metadata.jsonl的图片字段名
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 # 最小宽度1024
min_height: 1024 # 最小高度1024
any_or_all: any # 符合前面条件的图片才会被保留
- image_aspect_ratio_filter: # 图片长宽比过滤
min_ratio: 0.5 # 最小长宽比0.5
max_ratio: 2.0 # 最大长宽比2.0
any_or_all: any # 符合前面条件的图片才会被保留
"""
# 保存data-juicer配置到data/data-juicer/data_juicer_config.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
- dj-process: 这是Data-Juicer提供的一个命令行工具,用于处理数据集。
- --config: 这是一个参数,用来指定配置文件的位置。这个配置文件应该包含了数据处理所需的所有设置和参数。
- data/data-juicer/data_juicer_config.yaml: 这是配置文件的路径。注意,这里的路径是相对路径,根据你的当前工作目录而定。
# 通过前面通过data-juicer筛选的图片索引信息./data/data-juicer/output/result.jsonl,生成数据集
import pandas as pd # 导入pandas
import os, json # 导入os和json
from PIL import Image # 导入Image
from tqdm import tqdm # 导入tqdm进度条管理
texts, file_names = [], [] # 定义两个空列表,分别存储图片描述和图片名称
os.makedirs("./data/lora_dataset_processed/train", exist_ok=True) # 创建文件夹./data/lora_dataset_processed/train
# 使用 makedirs 创建目录,如果目录已存在则不抛出异常
with open("./data/data-juicer/output/result.jsonl", "r") as file: # 打开前面data-juicer筛选的图片索引文件./data/data-juicer/output/result.jsonl
for data_id, data in enumerate(tqdm(file.readlines())): # 遍历文件./data/data-juicer/output/result.jsonl
data = json.loads(data) # 将json字符串转换为对象
text = data["text"] # 获取对象中的text属性,也就是图片的描述信息
texts.append(text) # 将图片的描述信息添加到texts列表中
image = Image.open(data["image"][0]) # 获取对象中的image属性,也就是图片的路径,然后用这个路径打开图片
image_path = f"./data/lora_dataset_processed/train/{data_id}.jpg" # 生成保存图片的路径
image.save(image_path) # 将图片保存到./data/lora_dataset_processed/train文件夹中
file_names.append(f"{data_id}.jpg") # 将图片名称添加到file_names列表中
data_frame = pd.DataFrame() # 创建空的DataFrame
data_frame["file_name"] = file_names # 将图片名称添加到data_frame中
data_frame["text"] = texts # 将图片描述添加到data_frame中
data_frame.to_csv("./data/lora_dataset_processed/train/metadata.csv", index=False, encoding="utf-8-sig") # 将data_frame保存到./data/lora_dataset_processed/train/metadata.csv
data_frame # 查看data_frame
# 下载可图模型
from diffsynth import download_models # 导入download_models
download_models(["Kolors", "SDXL-vae-fp16-fix"]) # 下载可图模型
# DiffSynth-Studio提供了可图的Lora训练脚本,查看脚本信息
!python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py -h
# 执行可图Lora训练
import os
cmd = """
python DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py \ # 选择使用可图的Lora训练脚本DiffSynth-Studio/examples/train/kolors/train_kolors_lora.py
--pretrained_unet_path models/kolors/Kolors/unet/diffusion_pytorch_model.safetensors \ # 选择unet模型
--pretrained_text_encoder_path models/kolors/Kolors/text_encoder \ # 选择text_encoder
--pretrained_fp16_vae_path models/sdxl-vae-fp16-fix/diffusion_pytorch_model.safetensors \ # 选择vae模型
--lora_rank 16 \ # lora_rank 16 表示在权衡模型表达能力和训练效率时,选择了使用 16 作为秩,适合在不显著降低模型性能的前提下,通过 LoRA 减少计算和内存的需求
--lora_alpha 4.0 \ # 设置 LoRA 的 alpha 值,影响调整的强度
--dataset_path data/lora_dataset_processed \ # 指定数据集路径,用于训练模型
--output_path ./models \ # 指定输出路径,用于保存模型
--max_epochs 1 \ # 设置最大训练轮数为 1
--center_crop \ # 启用中心裁剪,这通常用于图像预处理
--use_gradient_checkpointing \ # 启用梯度检查点技术,以节省内存
--precision "16-mixed" # 指定训练时的精度为混合 16 位精度(half precision),这可以加速训练并减少显存使用
""".strip()
os.system(cmd) # 执行可图Lora训练
# 加载lora微调后的模型
from diffsynth import ModelManager, SDXLImagePipeline # 导入ModelManager和SDXLImagePipeline
from peft import LoraConfig, inject_adapter_in_model # 导入LoraConfig和inject_adapter_in_model
import torch # 导入torch
# 加载LoRA配置并注入模型
def load_lora(model, lora_rank, lora_alpha, lora_path):
lora_config = LoraConfig(
r=lora_rank, # 设置LoRA的秩(rank)
lora_alpha=lora_alpha, # 设置LoRA的alpha值,控制LoRA的影响权重
init_lora_weights="gaussian", # 初始化LoRA权重为高斯分布
target_modules=["to_q", "to_k", "to_v", "to_out"], # 指定要应用LoRA的模块
)
model = inject_adapter_in_model(lora_config, model) # 将LoRA配置注入到模型中
state_dict = torch.load(lora_path, map_location="cpu") # 加载LoRA微调后的权重
model.load_state_dict(state_dict, strict=False) # 将权重加载到模型中,允许部分权重不匹配
return model # 返回注入LoRA后的模型
# 加载预训练模型
model_manager = ModelManager(
torch_dtype=torch.float16, # 设置模型的数据类型为float16,减少显存占用
device="cuda", # 指定使用GPU进行计算
file_path_list=[
"models/kolors/Kolors/text_encoder", # 文本编码器的路径
"models/kolors/Kolors/unet/diffusion_pytorch_model.safetensors", # UNet模型的路径
"models/kolors/Kolors/vae/diffusion_pytorch_model.safetensors" # VAE模型的路径
]
)
# 初始化图像生成管道
pipe = SDXLImagePipeline.from_model_manager(model_manager) # 从模型管理器中加载模型并初始化管道
# 加载并应用LoRA权重到UNet模型
pipe.unet = load_lora(
pipe.unet,
lora_rank=16, # 设置LoRA的秩(rank),与训练脚本中的参数保持一致
lora_alpha=2.0, # 设置LoRA的alpha值,控制LoRA对模型的影响权重
lora_path="models/lightning_logs/version_0/checkpoints/epoch=0-step=500.ckpt" # 指定LoRA权重的文件路径
) LoRA的秩(rank),与 LoRA的alpha值,控制LoRA对模型的影响权重
# 生成图像
torch.manual_seed(0) # 设置随机种子,确保生成的图像具有可重复性。如果想要每次生成不同的图像,可以将种子值改为随机值。
image = pipe(
prompt="二次元,一个紫色短发小女孩,在家中沙发上坐着,双手托着腮,很无聊,全身,粉色连衣裙", # 设置正向提示词,用于指导模型生成图像的内容
negative_prompt="丑陋、变形、嘈杂、模糊、低对比度", # 设置负向提示词,模型会避免生成包含这些特征的图像
cfg_scale=4, # 设置分类自由度 (Classifier-Free Guidance) 的比例,数值越高,模型越严格地遵循提示词
num_inference_steps=50, # 设置推理步数,步数越多,生成的图像细节越丰富,但生成时间也更长
height=1024, width=1024, # 设置生成图像的高度和宽度,这里生成 1024x1024 像素的图像
)
image.save("1.jpg") # 将生成的图像保存为 "1.jpg" 文件
# 图像拼接,展示总体拼接大图
import numpy as np # 导入numpy库,用于处理数组和数值计算
from PIL import Image # 导入PIL库中的Image模块,用于图像处理
images = [np.array(Image.open(f"{i}.jpg")) for i in range(1, 9)] # 读取1.jpg到8.jpg的图像,转换为numpy数组,并存储在列表images中
image = np.concatenate([ # 将四组图像在垂直方向上拼接
np.concatenate(images[0:2], axis=1), # 将第1组(images[0:2])的两张图像在水平方向上拼接
np.concatenate(images[2:4], axis=1), # 将第2组(images[2:4])的两张图像在水平方向上拼接
np.concatenate(images[4:6], axis=1), # 将第3组(images[4:6])的两张图像在水平方向上拼接
np.concatenate(images[6:8], axis=1), # 将第4组(images[6:8])的两张图像在水平方向上拼接
], axis=0) # 将四组拼接后的图像在垂直方向上拼接
image = Image.fromarray(image).resize((1024, 2048)) # 将拼接后的numpy数组转换为图像对象,并调整大小为1024x2048像素
image # 输出最终生成的图像对象,用于显示图像
3.通过ai获取提示词:
For example:
你是一个文生图专家,我们现在要做一个实战项目,就是要编排一个文生图话剧
话剧由8张场景图片生成,你需要输出每张图片的生图提示词
具体的场景图片
1、女主正在上课
2、开始睡着了
3、进入梦乡,梦到自己站在路旁
4、王子骑马而来
5、两人相谈甚欢
6、一起坐在马背上
7、下课了,梦醒了
8、又回到了学习生活中
生图提示词要求
1、风格为古风
2、根据场景确定是使用全身还是上半身
3、人物描述
4、场景描述
5、做啥事情
例子:
古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙
结合AI内容,自己在AI结果上做一些调整,可以结合我上一条笔记来重新自己制作修改个性化baseline
下面是千问,我个人用kimi比较多,效果也不错,几乎是一样的
(小声:可以少花钱请画手哦)
概括一下就是,
- 返回的结果
这段代码主要分为以下几个部分:
- 安装和卸载依赖包
- 使用 !pip 命令来安装或卸载 Python 包。包括:
- simple-aesthetics-predictor, data-juicer, peft, lightning, pandas, torchvision, 和 DiffSynth-Studio 的安装。
- 卸载 pytorch-lightning(使用 -y 自动确认卸载)。
- 加载数据集
- 使用 ModelScope 的 MsDataset 类加载名为 AI-ModelScope/lowres_anime 的数据集,并指定子集名称为 default 和分割为 train,缓存目录设置为 /mnt/workspace/kolors/data。
- 数据预处理
- 将数据集中的图像转换为 RGB 模式,并保存到指定目录。
- 创建包含图像路径和文本描述的元数据文件 metadata.jsonl。
- 编写并保存 data_juicer_config.yaml 配置文件,用于后续的数据过滤和处理。
- 使用 Data-Juicer 进行数据处理
- 使用 dj-process 命令根据配置文件对数据进行过滤和处理,生成 result.jsonl 文件。
- 数据整理与训练
- 读取 result.jsonl 文件中的数据,并将其转换为 Pandas DataFrame,然后保存为 CSV 文件,并且将图片保存到./data/lora_dataset_processed/train文件夹下。
- 下载模型download_models(["Kolors", "SDXL-vae-fp16-fix"])
- 在前面模型的基础上,执行Lora微调训练
- 加载微调后的模型
- 图像生成
- 设置正向提示词,反向提示词,执行次数,图片尺寸
- 设置随机种子,控制图片是否可以重复生成,并将图像保存为 .jpg 文件。
- 合并图像
- 最后,将生成的多个图像合并成一个大图像,并调整大小。
整个流程涵盖了从数据加载、预处理、特征提取、模型预测到图像生成等多个方面。每一部分都有其特定的功能,共同构成了一个完整的二次元图像处理和生成的工作流。
3.浅尝scepter webui:Quickstart
官方定义
🪄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.
4.知识拓展网页
github地址:https://github.com/modelscope/scepter
https://github.com/Kwai-Kolors
视频拓展:2.1Scepter与WebUI,一站式生成编辑工具箱_哔哩哔哩_bilibili
5.tip
我个人不喜欢模模糊糊的学知识,所以我个人比较建议先仔细看一遍注解理解一下baseline,后面可以用自己喜欢的方式运行一下,拓展知识由于难度大刚接触的话看会比较辛苦,可以用自己的学习方式,比如我是喜欢做笔记防止自己睡着。
今天也是学到知识的一天呐~~