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

探探前沿:了解一下 AI生图技术 的能力&局限

有些同学可能对于AI可以生成什么样的图片、AI生图有哪些风险和挑战并不是很了解。

在这里我们想先给大家再补充一点背景知识,让大家了解其中的风险和难点。

另外,也将从技术视角拆解AI生图相关工具,让大家更清楚自己的预期场景,能否使用AI生图解决,或部分解决,以及追踪更多AI生图前沿的信息。

 

  1. 为什么要了解AI生图前沿?

 

AIGC(AI-Generated Content)是通过人工智能技术自动生成内容的生产方式,很早就有专家指出,AIGC将是未来人工智能的重点方向,也将改造相关行业和领域生产内容的方式。

 

AI生图则是其中最早被大众所熟知并广泛被认可的AIGC领域,首先我们来看一个新闻

62e4385da1634933ad19a173ca0955e1.png

AI生成图片的快速发展,使诸多领域措手不及,如:摄影、美术等艺术领域正在面临前所未有的颠覆。我们所认为的“有图有真相”,甚至理解的现实也将不断被挑战...

e0fcfa7560e74e5f87f37fb32d0bcac3.png

插入一段小常识,提醒大家警惕Deepfake技术

Deepfake是一种使用人工智能技术生成的伪造媒体,特别是视频和音频,它们看起来或听起来非常真实,但实际上是由计算机生成的。这种技术通常涉及到深度学习算法,特别是生成对抗网络(GANs),它们能够学习真实数据的特征,并生成新的、逼真的数据。

插入一段小常识,提醒大家警惕Deepfake技术

Deepfake是一种使用人工智能技术生成的伪造媒体,特别是视频和音频,它们看起来或听起来非常真实,但实际上是由计算机生成的。这种技术通常涉及到深度学习算法,特别是生成对抗网络(GANs),它们能够学习真实数据的特征,并生成新的、逼真的数据。1d25b7d1bb6a46aaa213840b9f1fe988.png

Deepfake技术虽然在多个领域展现出其创新潜力,但其滥用也带来了一系列严重的危害。在政治领域,Deepfake可能被用来制造假新闻或操纵舆论,影响选举结果和政治稳定。经济上,它可能破坏企业形象,引发市场恐慌,甚至操纵股市。法律体系也面临挑战,因为伪造的证据可能误导司法判断。此外,深度伪造技术还可能加剧身份盗窃的风险,成为恐怖分子的新工具,煽动暴力和社会动荡,威胁国家安全。

 

对所有人来说,定期关注AI生图的最新能力情况都十分重要:

  • 对于普通人来说,可以避免被常见的AI生图场景欺骗,偶尔也可以通过相关工具绘图

  • 对于创作者来说,通过AI生图的工具可以快速提效,制作自己所需要的内容

  • 对于技术人来说,了解AI生图的能力的玩法,可以更好地针对自己的业务进行开发和使用,甚至攻克难题开发更实用的工具

  1. 再来从工具视角回顾一下AI生图的历史

最早的AI生图可追溯到20世纪70年代,当时由艺术家哈罗德·科恩(Harold Cohen)发明AARON,可通过机械臂输出作画。

5deab20c00a94db38286b36f0c60f93d.png

9cd1ae8edb83415cbf25ea1b9ea6e6d5.png

现代的AI生图模型大多基于深度神经网络基础上训练,最早可追溯到2012年吴恩达训练出的能生成“猫脸”的模型。

63b65c3ad9b84c6f9be7abea7c6a8f79.png

它使用卷积神经网络(CNN)训练,证明了深度学习模型能够学习到图像的复杂特征。

 

2015年,谷歌推出了“深梦”(Deep Dream)图像生成工具,类似一个高级滤镜,可以基于给定的图片生成梦幻版图片——

c417838e50b14ddfbcd935ee4ac22668.png

2021 年 1 月 OpenAI 推出DALL-E模型(一个深度学习算法模型,是GPT-3 语言处理模型的一个衍生版本),能直接从文本提示“按需创造”风格多样的图形设计——

728d3028e8834ac6ab6c70a9a8a654ed.png

在当时,就已经被一些媒体评价为:“ 秒杀50%的设计行业打工人应该是没有问题的,而且是质量和速度双重意义上的“秒杀” ”。

 

一般来说,AI生图模型属于多模态机器学习模型,通过海量的图库和文本描述的深度神经网络学习,最终的目标是可以根据输入的指示(不管是文本还是图片还是任何)生成符合语义的图片

插入一个小八卦

AI生图在很长一段时间很难被人们所广泛接纳,一方面是生成的内容没有可用的生产场景,还有很大程度可能是由于“恐怖谷效应”——

3651c31be44546a88f1244742e5853a1.png

 

其核心观点是:随着仿真物(如机器人、玩偶等)模拟真实性程度的变化,人们对其亲和力也会产生变化,一般规律是亲和力随着仿真程度增高而增高,但当仿真程度达到一个临界点时,人的亲和反应会陡然跌入谷底,突然产生排斥、恐惧、困惑等负面心理。

通过学习大量画家的作品,AI生图模型 往往可以照猫画虎绘制出类似的画作,在2022年8月AI生图真正走进了大众的视野,让各个领域无法忽视

当时让AI生图破圈的是AI绘画作品《太空歌剧院》,该作品在美国科罗拉多州举办的新兴数字艺术家竞赛中获得了比赛“数字艺术/数字修饰照片”类别一等奖,引起了当时“艺术家们 Not Happy”的社会舆论。

97dd9fadfe264cadaad6d4e788e65c11.png

  1. AI生图的难点和挑战有哪些?

 

往前一年,AI绘画还不会画“手”——

ac41b8fae1d64ee3957b709c879bf883.png

也因为当时这个情况,产生了很多解决这个问题的相关技术,如:给图片里的人手打上标记,像把手掌、拇指、食指啥的,都给清楚地标出来;

fb2933af5d8042f38e199873fe97faa5.png

我们现在还可以经常在各类自媒体的文章中看到“AI翻车”的案例,那些往往也是需要解决的难点,某些“翻车”现象,也许在业界已有相关的解决方案。

 

通俗来说,AI生图模型获得图片生成能力主要是通过 学习 图片描述 以及 图片特征,尝试将这两者进行一一对应,存储在自己的记忆里。

在我们需要的时候,通过输入的文字,复现出来对应的图片特征,从而生成了我们需要的图片。

 

关于AI是否真正理解了图片背后所代表的世界的特征,是否理解了图片的含义,这个一直是科研界和产业界存在争议的话题,我们唯一可以确定的是——

 

由于每个模型用于训练的数据是有限的且不一定相同的,它们能匹配的描述和特征也是有限的,所以在风格、具体事物上,不同的模型会有很大的生成差异,且可能存在诸多与现实不符的情况。

 

而这些问题,就是业界和科研界持续在想办法解决的问题。

 

在大部分生图场景下,我们可能经常会觉得图片存在“AI味”,这很长一段时间也是科研界和相关从业人员非常头大的问题。

*AI味:AI生成的图片和实际生活场景/艺术家创作的绘画/摄影/三维作品 相比,存在强烈的违和感,或是细节处理,或是画面逻辑性存在问题,一言就能被看出是“AI出品”

 

目前大部分的模型,已经具备了去除 “AI味” 的能力,且可能存在容易误导他人的情况,这时候我们想辨别可能需要非常仔细地——

  • 观察图片的细节。仔细检查人物的面部特征,尤其是眼睛和嘴巴

  • 检查光线和阴影。分析图片中的光源是否一致,阴影的方向是否与光源相符,是否存在不自然的光线或阴影

  • 分析像素。放大图片,寻找是否有模糊或像素化的部分。

  • 注意背景。检查背景中是否有不协调的元素,比如物体边缘是否平滑,背景中是否有不自然的重复模式。

而这些细节上的AI特性,也许就是我们在某些特定场景下需要解决的挑战。

 

  1. 开始探索AI生图前沿

 

回到主题,我们要探索AI生图的前沿,就必须有一个持续更新,且我们持续愿意跟进和投入时间的“主线”引导,例如,可以从这次学习活动可图Kolors-LoRA风格故事挑战赛魔搭社区的各类AIGC工具 开始,持续探索、尝试、思考总结、实践,甚至开始持续创作自己的作品/工具

6d6ba537d5934321beb399be2c7d8b5b.png

AI生图自破圈以来,被科研界、业界广泛关注,且引发了各大厂商的模型之战,如我们这次学习活动所需要用到的Kolors(可图)模型(点击即可跳转魔搭模型介绍页),就是其中的一个产物——

b49247b43cf945c48bc2360681929500.png

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,生成各种风格图片,可以在我们的学习当中使用——

7fbee7ffbe5f4faebd72ea4c4ecf6ca2.png

  1. 通过魔搭社区持续探索AI生图前沿

 

在某些设计的场景中,我们还希望AI能为我们将特定的文字生成在图片当中,如下图所示

954aea6ed4f74fbc8197749e215639ac.png

但实际上,这种固定文字生成,往往难度较大,一是具体生成在哪些位置,往往需要人为设定,为了更方便地制作类似这样的海报还产生了PS等图片编辑工具,才能实现相应的效果,想要让AI稳定生成相似效果的图片可想而知难度之大。

 

像我们Task1中介绍的 创意海报生成 工具,早已在代码中固定了相应的文字位置和对应的字体,才能进行相应的生成,且大概率是进行了两个步骤——

  • 一个步骤是AI生成背景,

  • 另一个步骤是通过代码将对应的文字显示到对应位置,

  • 然后渲染,合成图片,给到我们。

7963a2949e9c416aa1f2cb9934d11930.png

事实上,我们可以通过魔搭社区上感兴趣的工具,尝试思考——

  • 可以用在哪些业务里?有哪些行业在使用?

  • 用的是哪个 AI 模型?

  • 是自己部署的AI模型,还是用的API?

  • 使用到了哪些 AI 能力?

  • 如果要复现,需要做哪些额外的设置和开发?

  • 还可以有哪些优化点?

最方便的是,我们还可以直接点到空间文件,进行相关代码的查看甚至下载在 本地/云服务器 复现,以验证思考 & 学习相关的设计开发:

86b531d4699d42d59002926a4b087adf.png

199cc586e18940fe9b3f9f090cffd74c.png

魔搭社区还有各种资料,可以供我们学习&探索AI生图的前沿——

7765a682ef26414c9861d502fe4da0ef.png

比如图像生成的技术的前沿你还可以查看魔搭社区出品这个视频:

1.2最新图像生成技术研究方向-介绍与分析_哔哩哔哩_bilibili

Part1:磨刀准备一一认识通义千问

学习说明:

我们计划使用通义千问大语言模型来告诉大家如何借助AI智能助手帮我们阅读代码。工欲善其事必先利其器,现在让我们请出今天的主角,通义千问(点击直达)。

 

📢:注意

  1. 使用大语言模型比较频繁的学习者可跳过这部分内容。

  2. 也可以自行选择其他的大语言模型使用,学习过程中不做限制。

  3. 通义系列产品也有文生图的工具:通义万相,大家感兴趣可以自己体验。

 

  1. 通义千问的自我介绍

首先,我们来看下它的自我介绍。通义千问是具有信息查询、语言理解、文本创作等多能力的AI助手。我们可以看到,编程与技术支持能力是它的强项之一。(P1:通义千问自我介绍)

 

接下来我们把场景聚焦到编程与技术支持这个方向,让他详细介绍下自己可以如何帮助大家编程。(P2:编程能力介绍)。

5479daf619fd47f09dbe87295122094e.png

1ea7703c263b40939a692df71925df75.png

  1. 抱走你的AI学习助教

作为一个AI助手,通义千问就是你专属的、可随时触达的、24小时随时待命的贴心助教,可以帮助你解决很多学习中遇到的问题。

 

所以当你遇到学习问题的时候,问问千问吧。在这里请接收一下通义千问的邀请函!👉

851e18566ad946ac8eca162bd428a097.png

  1. 使用操作指南

官方链接:https://tongyi.aliyun.com/qianwen/

step1 注册账号

2df6f3a26e104ad0a70d638316037265.png

c83e4ac430774f7a8221d2d87ff09094.png

step2 通义主要功能模块

主要功能模块:

  1. 对话,支持文字输入,文件上传等模式,我们本次课程主要使用当前模块;

  2. 效率,各种学习办公小工具;

  3. 智能体,通义的智能体应用市场,大家可以根据自己的需求找到很多有意思的小应用。

90bfe0a8cf804aea9c5f74414bd3463e.png

473c29444a4841c2a9d6776a0639f946.png

Part2:精读baseline——从零入门AI生图

学习说明:

关于代码阅读和理解,我们今天尝试让AI助手从两个角度帮助我们:

  1. 分析代码的主题架构;

  2. 逐行代码解析。

 

📢:注意

  1. 以下代码为方便大家阅读理解,故放在了一起。但不能一键运行跑通,如何跑通代码,请直接参考task1中的内容。

 

在task1的任务中, 我们拿到baseline文件后, 根据教程指示顺畅通关, 似乎没有什么问题。但是可能有些同学看到这个baseline的代码会一脸懵,就很想知道某一个模块、某一行究竟是干啥的,下面我们就借助前面讲到的通义千问来精读这个代码。

 

首先我们来直观感知下这个文生图代码的框架结构:

9d8e8a1a6c8c40fd9b02efb644fb77b2.png

现在我们先把我们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
  1. 分析代码的主体架构

  1. 输入的Prompt

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

这段代码主要分为以下几个部分:

1. 环境准备
安装依赖包:
安装 simple-aesthetics-predictor、data-juicer、peft、lightning、pandas、torchvision 和 DiffSynth-Studio 等依赖包。
卸载并重新安装 pytorch-lightning。

2. 数据加载与预处理
加载数据集:
使用 ModelScope 加载 lowres_anime 数据集,并指定子集名称为 default 和数据集切分为 train。
将数据集缓存到 /mnt/workspace/kolors/data 目录下。
数据转换与存储:
遍历数据集中的每条记录,将图像转换为 RGB 模式并保存到本地目录。
创建 JSONL 文件,每一行包含一条记录的文本描述和对应的图像路径。
保存到 ./data/data-juicer/input/metadata.jsonl。

3. 数据过滤与处理
编写配置文件:
创建一个 YAML 配置文件 data/data-juicer/data_juicer_config.yaml,定义数据处理的参数和规则,包括最小尺寸、宽高比等。
执行数据处理:
使用 data-juicer 对数据进行过滤,生成过滤后的数据集,并保存到 ./data/data-juicer/output/result.jsonl。

4. 数据整理与分析
整理过滤后的数据:
读取过滤后的 JSONL 文件,并将文本和图像文件名提取出来,存储到 DataFrame 中。
将 DataFrame 内容保存为 CSV 文件。

5. 图像-文本相似度计算
加载模型与处理器:
加载 CLIP 模型及其处理器。
创建数据集与数据加载器:
定义 CustomDataset 类,用于加载图像和文本数据。
创建 PyTorch 的 DataLoader 实例。
计算相似度:
使用 CLIP 模型对图像和文本进行编码,并计算它们之间的相似度。

6. 图像生成
加载图像生成模型:
加载 StableDiffusionPipeline 模型。
生成图像:
使用不同的提示和负向提示生成一系列图像,并保存到本地。

7. 图像拼接
合并图像:
将生成的图像按顺序拼接成一张大图,并调整大小。
  1. 执行过程

9fc4f16e58ba45e49e3b88b42827ba02.png

758971bc42fa4e92842f8858844973ca.png

  1. 逐行解释代码

  1. 输入的问题

你是一个优秀的python开发工程师,现在我们需要你帮我们逐行分析这个代码,用中文回答我的问题。{此处替换前面的代码}
  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
  • 第一行安装 simple-aesthetics-predictor 包。
  • 第二行安装 data-juicer 包,并通过 -e 选项使其可编辑安装(即可以实时修改源码)。
  • 第四行卸载 pytorch-lightning,第五行安装 peftlightningpandastorchvision
  • 第六行以可编辑方式安装 DiffSynth-Studio

2. 数据加载与预处理

加载数据集

from modelscope.msdatasets import MsDataset

ds = MsDataset.load(
    'AI-ModelScope/lowres_anime',
    subset_name='default',
    split='train',
    cache_dir="/mnt/workspace/kolors/data"
)
  • 导入 ModelScope 的数据集加载模块。
  • 加载 lowres_anime 数据集,选择 default 子集,使用 train 分割,并缓存在 /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")
  • 创建两个目录用于存储图像和元数据文件。
  • 遍历数据集,将每个图像转换为 RGB 模式并保存,同时构建元数据字典并写入 metadata.jsonl 文件。

3. 数据过滤与处理

编写配置文件

data_juicer_config = """
...
"""
with open("data/data-juicer/data_juicer_config.yaml", "w") as file:
    file.write(data_juicer_config.strip())
  • 定义一个 YAML 配置字符串,其中包含了数据处理的各种参数。
  • 将配置字符串写入 data_juicer_config.yaml 文件。

执行数据处理

!dj-process --config data/data-juicer/data_juicer_config.yaml
  • 调用 dj-process 命令行工具,使用之前定义的配置文件来处理数据。

4. 数据整理与分析

整理过滤后的数据

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
  • 读取过滤后的 JSONL 文件,提取文本和图像文件名,并将其存储在 Pandas DataFrame 中。
  • 将 DataFrame 保存为 CSV 文件,并显示 DataFrame。

5. 图像-文本相似度计算

加载模型与处理器

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")
  • 加载 CLIP 模型和处理器。

创建数据集与数据加载器

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
  • 从 DataFrame 中加载图像和文本数据。
  • 使用 CLIP 处理器处理数据,并通过 CLIP 模型计算图像与文本之间的相似度。

创建自定义数据集类

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 类继承自 torch.utils.data.Dataset
  • 创建一个 DataLoader 实例来批量加载数据,并通过 CLIP 模型计算每个批次的图像与文本之间的相似度。

6. 图像生成

加载图像生成模型

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")
  • 加载 StableDiffusionPipeline 模型,并将其移动到 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
  • 使用不同的提示和负向提示生成一系列图像,并保存到本地。

7. 图像拼接

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
  • 将生成的图像按顺序拼接成一张大图,并调整大小。

执行过程

8ae4338b05504da38132e9f1840991a0.png

fdbbaa7423b34d139b1cfb33dd1f0347.png

  1. 代码还有疑问?

  1. 向AI追问

在刚刚逐行解析结果页后面继续追问,如图,通义给了我们更加细致的问题解释,大家可以举一反三,多操作一下

我对其中{替换成你的问题}还是不太理解,给我再详细介绍一下

28808ba296d74148ac618df48ce191fb.png

最后,希望大家养成使用AI的习惯,擅用AI,帮你的工作和学习事半功倍。

 

Part3:实战演练一一基于话剧的连环画制作

  1. 数据准备(哈哈哈,还得是通义)

  1. 提示词

你是一个文生图专家,我们现在要做一个实战项目,就是要编排一个文生图话剧
话剧由8张场景图片生成,你需要输出每张图片的生图提示词

具体的场景图片
1、女主正在上课
2、开始睡着了
3、进入梦乡,梦到自己站在路旁
4、王子骑马而来
5、两人相谈甚欢
6、一起坐在马背上
7、下课了,梦醒了
8、又回到了学习生活中

生图提示词要求
1、风格为古风
2、根据场景确定是使用全身还是上半身
3、人物描述
4、场景描述
5、做啥事情

例子:
古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙
  1. 询问通义

自己在通义的返回的基础上,多多调整,争取打磨出一个最佳的提示词

fb458b3414534014be72c16e0419f5b6.png

  1. 最后的话剧场景

结合AI内容,自己在AI结果上做一些调整,最终整理出来场景表格

图片编号

场景描述

正向提示词

反向提示词

图片1

女主正在上课

古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,深思,上半身,红色长裙

丑陋,变形,嘈杂,模糊,低对比度

图片2

开始睡着了

古风,水墨画,一个黑色长发少女,坐在教室里,趴在桌子上睡着了,上半身,红色长裙

丑陋,变形,嘈杂,模糊,低对比度

图片3

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

古风,水墨画,一个黑色长发少女,站在路边,上半身,红色长裙

丑陋,变形,嘈杂,模糊,低对比度

图片4

王子骑马而来

古风,水墨画,一个英俊少年,骑着白马,上半身,白色衬衫

丑陋,变形,嘈杂,模糊,低对比度

图片5

两人相谈甚欢

古风,水墨画,一个英俊少年,白色衬衫,一个黑色长发少女,红色长裙,两个人一起聊天,开心,上半身

丑陋,变形,嘈杂,模糊,低对比度

图片6

一起坐在马背上

古风,水墨画,一个英俊少年,白色衬衫,一个黑色长发少女,红色长裙,两个人一起骑着马,全身

丑陋,变形,嘈杂,模糊,低对比度

图片7

下课了,梦醒了

古风,水墨画,一个黑色长发少女,坐在教室里,下课铃声响了,同学们开始走动,从睡梦中醒来,深思,上半身,红色长裙

丑陋,变形,嘈杂,模糊,低对比度

图片8

又回到了学习生活中

古风,水墨画,一个黑色长发少女,坐在教室里,盯着黑板,认真上课,上半身,红色长裙

丑陋,变形,嘈杂,模糊,低对比度

  1. 执行Task1的30分钟速通Baseline

从零入门AI生图原理&实践

  1. 提示词修改

  1. 双击进入baseline文件

  2. 找到生成图像的板块

  3. 依次替换8张图片的正向提示词和反向提示词

4f040654fed340918d9b6661c49866a6.png

e11cd67983074fb9bdab3d6b7f71741e.png

  1. 结果展示

c92dcae301704343a8196ecbdcd92986.jpeg

e768b5f4e73e4bfea13bc81bca981a30.jpeg

bb56b73ad86c43f781200235da050fec.jpeg

4d6642c300504b9fad8c1bc7aa7efa97.jpeg

2467ceb378904b5c892f21be310a0de5.jpeg

6c7b63595bbd4518900ab9eced4a104b.jpeg

75b1ca6e80584c178de079129d62343a.jpeg

ad5102db1b9b424daade69b2c18b9056.jpeg

Part4:更多的选择一一浅尝scepter webui

 

  1. 浅尝功能

魔搭体验网址:https://www.modelscope.cn/studios/iic/scepter_studio

270e01400dba463e9b96c99775db464a.png

0df5a4f2202747c997a5173f1ee6b059.png

  1.  

  1. 核心组件

  1. 私有部署(挑战型

魔搭社区提供的体验地址里面缺失了微调模型的功能,如果大家希望能使用secpter完整的功能,我们可以将其私有部署到我们自己的服务器。

github地址:https://github.com/modelscope/scepter

可以通过官方readme文件中的教程进行操作,该模块对基础有一定的要求,适合学有余力的同学

PS:如果在安装中遇到各种问题,别忘了这节课的老朋友,尽管向通义等AI工具提问~~~~~

45b3d94b0d4e41549f6dea3ce6c51f77.png

28158d4a28f04058b5d1eac214302f4b.png

更多内容可见:

2.1Scepter与WebUI,一站式生成编辑工具箱_哔哩哔哩_bilibili

 

参考链接:Datawhale (linklearner.com)

 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值