当前位置:AIGC资讯 > AIGC > 正文

DatawhaleX魔搭-AI夏令营AIGC-task2

一、了解AI生图技术

1,为什么了解生图技术

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

应用广泛:AI生成图像技术在广告、设计、影视制作、游戏开发等多个领域都有广泛应用。掌握这些技术可以帮助你在这些行业中更好地理解和利用图像生成工具。

创造性和设计:AI生成图像技术可以帮助设计师和艺术家快速生成创意图像,提供灵感,甚至自动化一些创作过程,从而提升生产力和创作效率。

技术发展趋势:图像生成技术正迅速发展,了解这些技术有助于跟上行业的最新趋势和技术进步,这对于从事相关工作的专业人士尤为重要。

伦理和责任:AI生成图像技术带来了许多伦理和法律问题,例如深度伪造技术(deepfakes)可能被用于恶意目的。了解这些技术有助于制定和遵守相关的伦理规范和法律法规。

用户体验:对于产品经理和开发者,了解AI生成图像技术可以帮助他们设计更符合用户需求和期望的产品,提升用户体验。

创新机会:掌握AI生成图像技术能够为创业者和创新者提供新机会,探索前沿的应用场景和商业模式,开辟新的市场和机会。

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

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

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

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

2,从工具角度了解历史

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

现代的AI生图模型大多基于深度神经网络基础上训练,最早可追溯到2012年吴恩达训练出的能生成“猫脸”的模型。它使用卷积神经网络(CNN)训练,证明了深度学习模型能够学习到图像的复杂特征。

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

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

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

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

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

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

3,AI生图的难点和挑战

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

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

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

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

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

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

4,AI生图技术探索前沿

下面kolors模型是快手开源的文本到图像生成模型,该模型具有对英语和汉语的深刻理解,并能够生成高质量、逼真的图像。

5,魔塔社区探索AI生图

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

一个步骤是AI生成背景,

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

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

二、认识通义千问

1,通义千问的自我介绍

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

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

2,抱走你的AI学习助教

三、零入门AI生图

文生图代码的框架结构:

!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.1输入的Prompt
1.2返回的结果

分为以下几个部分:

安装和卸载依赖包

使用 !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 文件。

合并图像

最后,将生成的多个图像合并成一个大图像,并调整大小。

整个流程涵盖了从数据加载、预处理、特征提取、模型预测到图像生成等多个方面。每一部分都有其特定的功能,共同构成了一个完整的二次元图像处理和生成的工作流。

1.3执行过程

2,逐行解释代码

2.1输入的问题
2.2返回的结果

这段代码主要完成以下功能:

安装和卸载一些Python包。

从ModelScope加载一个名为lowres_anime的数据集,并保存图像到指定目录。

创建并处理一个用于数据清洗的JSONL文件。

使用data-juicer工具过滤和处理数据集。

将处理后的数据集转换为CSV格式。

根据数据集通过DiffSynth做Lora微调

加载Lora微调后的模型

设置提示词,用微调后的模型生成图片

2.3执行的结果

四、实战演绎

1,数据准备

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

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

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

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

下面是每个场景的正向和负向提示词:

场景1: 女主正在上课

正向提示词: 古风, 工笔画, 黑色长发少女, 身穿蓝色绸缎长袍, 坐在书桌前, 专注地看着书卷, 上半身, 古色古香的书房, 墙上挂着山水画, 桌上摆满了竹简和毛笔。

负向提示词: 现代元素, 不清晰的脸部特征, 无关的背景人物, 非读书相关活动。

场景2: 开始睡着了

正向提示词: 古风, 淡墨渲染, 黑色长发少女, 穿着浅绿色长裙, 靠在书桌上, 头枕着手臂, 上半身, 空旷的书房, 窗外阳光斜照, 一只蝴蝶轻轻飞过。

负向提示词: 清醒状态, 多余的人物, 现代物品, 明亮光线。

场景3: 进入梦乡,梦到自己站在路旁

正向提示词: 古风, 水彩, 黑色长发少女, 身穿白色纱裙, 站在一条蜿蜒小径旁, 仰望着天空, 全身, 一片花海, 远处山峦叠翠, 天边晚霞映照。

负向提示词: 室内场景, 多余的人物, 现代服装, 没有花海背景。

场景4: 王子骑马而来

正向提示词: 古风, 浓墨重彩, 英俊少年, 身着金色铠甲, 骑着一匹黑色骏马, 向少女缓缓靠近, 全身, 古道边, 两侧树木葱郁, 远处有炊烟袅袅升起。

负向提示词: 缺少马匹, 现代背景, 少女不在画面中, 非古装元素。

场景5: 两人相谈甚欢

正向提示词: 古风, 工笔画, 黑色长发少女与英俊少年, 面对面坐着, 彼此微笑交谈, 上半身, 花园一角, 周围鲜花盛开, 石桌上摆放着茶具。

负向提示词: 单独的人物, 没有交流的表情, 室内场景, 缺少茶具。

场景6: 一起坐在马背上

正向提示词: 古风, 水墨, 少女与少年, 并肩坐在马背上, 眺望远方, 全身, 广阔的田野, 夕阳西下, 天际线处有几朵悠闲的云朵。

负向提示词: 室内场景, 没有马匹, 多余的人物, 现代服装。

场景7: 下课了,梦醒了

正向提示词: 古风, 淡墨渲染, 黑色长发少女, 身穿蓝色绸缎长袍, 猛然惊醒, 手扶额头, 上半身, 空荡荡的教室, 窗外夕阳余晖, 书桌上散落着书籍。

负向提示词: 睡着的状态, 多余的人物, 现代元素, 明亮光线。

场景8: 又回到了学习生活中

正向提示词: 古风, 工笔画, 黑色长发少女, 身着蓝色绸缎长袍, 手持书卷认真阅读, 上半身, 书房内, 桌上堆满书籍, 墙上挂有字画, 窗外夜幕降临。

负向提示词: 室外场景, 多余的人物, 缺少书籍, 明亮光线。

2,执行task1的baseline

3,替换

五,结果展示

总结

更新时间 2024-09-14