在零售业不断发展的格局中,Stable Diffusion 等生成式人工智能技术的出现已成为行业变革的标志。通过利用先进的机器学习算法生成多样化和动态的内容,Stable Diffusion 为零售商面临的长期痛点提供了变革性解决方案。从彻底改变虚拟试穿体验到制作个性化广告,Stable Diffusion 的影响深远,以前所未有的方式改变了零售业。
为了有效利用 Stable Diffusion,零售商必须首先确定其具体用例并评估潜在投资回报率 (ROI)。这涉及评估这些技术如何提高客户参与度并促进销售。分配正确的角色和职责至关重要,需要聘请数据科学家、快速工程师、项目经理和艺术家。最后,零售商必须实施风险缓解策略,以最大限度地降低使用受版权保护或受限制内容的潜在许可风险。通过仔细考虑这些因素,零售商可以利用 Stable Diffusion 的力量在竞争激烈的零售领域保持领先地位。
对于希望在零售行业利用生成式 AI 的用户来说,Amazon SageMaker 是一项出色的服务。凭借其完整的机器学习功能和用户友好的界面,SageMaker 使零售商能够利用生成式 AI 技术,而无需复杂的基础设施配置或广泛的数据科学专业知识。
让我们探索使用 SageMaker 的 3 种解决方案:
-
SageMaker 快速入门
-
一键将预先训练的稳定扩散模型部署到 SageMaker Endpoint,无需配置。
-
您可以立即将代码从快速启动获取到推理端点,或者根据您的场景修改代码。
-
-
SageMaker 笔记本实例
-
只需几个步骤即可在您的 AWS 账户中通过 CloudFormation 快速部署用于 AI 生成图像生成的 Web 应用程序环境,实现一键部署。
-
Amazon SageMaker Notebook 实例托管的 Jupyter 笔记本实例负责底层 IT 开发环境(如存储、网络等)和基础设施维护。
-
该解决方案基于 Stable Diffusion 1.5 版,通过可用源项目使用提供了出色的用户体验,并支持基于您需求的扩展,例如 ControlNet。
-
用户可以使用自己的图像数据对模型进行微调,并使用自动化管道工具快速部署进行推理。
-
-
一体式
-
只需几个步骤即可在您的 AWS 账户中通过 CloudFormation 快速部署用于 AI 生成图像生成的 Web 应用程序环境,实现一键部署。
-
在具有自动扩展功能的 SageMaker Endpoint 上托管模型,以根据请求队列大小调整资源基础。
-
一体化解决方案可以与您自己的模型无缝集成。您只需将模型上传到 S3 存储桶,它就会自动将模型部署到 SageMaker Endpoint,无需手动配置。
-
现在我们已经了解了三种用于生成 AI 的 SageMaker 解决方案,让我们深入探讨一些引人注目的用例,重点介绍零售商如何从这项变革性技术中受益。
根据市场调查,聘请模特拍摄产品的价格约为每小时 200 美元以上,并且会根据您需要拍摄的产品数量而上涨。除了场地、设备和化妆的成本外,它还会给小型零售商带来压力。Stable Diffusion 可以在几秒钟内帮助打破产品图片位置和模特的限制。
-
从菜单选项中选择“img2img”选项卡。
-
您将看到两个字段:“Positive Prompt”和“Negative Prompt”。在这些字段中,您可以指定最终图像所需的属性。
-
为了生成高质量的图像,提供包含三个基本要素的详细提示至关重要。
-
物体:物体的种类、物体的样子、颜色等。
-
场景:背景、室内、室外、氛围等。
-
风格:摄影、素描、绘画、装置等。
-
现在,让我们将上述说明付诸实践并开始输入您的提示。
-
在‘积极提示’字段中,输入“客厅,侘寂风格,灯光,窗帘,室内,温暖,室内设计照片,杰作,高分辨率,高品质”
-
在‘负面提示’中,你可以输入你不希望在图像中出现的属性,如“低分辨率、低质量、水印、黑暗、脏、混乱”
-
选择“inpaint upload”上传原始照片和被遮罩的照片,这样就可以让模型只对被遮罩的区域进行修复。
-
点击“生成”,然后你就会看到结果

您可以对不同的蒙版(如模型、衣服等)执行相同的步骤,然后可以在几秒钟内获得产品照片的色调。

随着节日季的临近,营销团队总是忙于设计促销和特别活动的广告活动。制作多样化的广告材料需要付出巨大的努力。稳定传播是一种很好的工具,可以在几秒钟内生成材料来制作您独特的广告。
以风衣广告为例,我们需要森林场景、模特、产品照片和引人注目的文字等素材。除了上例中提到的提示元素外,还有一些有价值的技巧可以进一步提高提示的质量。
-
提示与开头的接近程度对图像生成过程的影响更大。
-
括号 ( ) 表示为所附提示分配 1.1 的权重,而方括号 [ ] 表示为所附提示分配 0.91 的权重。
-
可以使用“+”或“and”运算符链接多个提示。例如,要生成一张海滩图片,其中有人戴着太阳镜,只需在提示中输入“海滩+太阳镜”即可。
-
要组合多个提示,请使用“|”或“或”运算符。例如,通过在提示中输入“(绿色头发:1.1) | (黑色头发:1.4)”,即可生成染成绿色头发的人的图像。
现在,掌握了上述技巧,您可以利用它们在几秒钟内轻松生成材料并制作自己独特的广告。
-
选择模型并在 WebUI 上选择 txt2img 选项卡
-
单独生成带有提示的材料。
-
令人惊叹的森林场景照片,雨水多雾,山中茂密的森林,泥泞的小路,雄伟而令人惊叹的森林场景,杰作,高分辨率,高品质,hdr,富士 xt4、50mm、f/1.6、清晰对焦、高细节
-
黄色风衣的产品照片,杰作,(全身),(黄色风衣:1.3),运动裤,登山靴,英俊的年轻男子,正常的眼睛,高细节脸部,高细节,清晰对焦,轻轻一笑,自然皮肤,逼真,复杂,景深,富士 xt4,中景,hdr,8k,高分辨率,模特拍摄风格
-
雨水溅在(黄色风衣)上的照片,(防水),杰作,高细节,高分辨率,8k,hdr,(微距拍摄),
-
然后轻松地将材料组装成广告
很多时候,用户需要的不仅仅是稳定扩散模型生成图片的功能,他们往往需要利用模型生成特定产品或模型的图片。例如,假设某零售商与关键意见领袖 (KOL) 合作,让他们能够在线挑选代言,然后使用稳定扩散模型快速生成产品照片用于销售。因此,用户需要一种简化的流程,使用自己的图像数据自动微调模型。架构如下:

当用户将自己的图像数据上传到 S3 输入存储桶时,S3 会发送事件以触发 Lambda 启动 SageMaker Notebook 实例进行训练。该实例将使用预构建的生命周期配置来运行训练脚本,然后将模型导出到 S3 输出存储桶。然后,S3 会发送事件以触发 Lambda 关闭实例以避免不必要的成本。您可以按照以下步骤构建管道。
准备一个带有 GPU 的笔记本实例用于微调。我选择
ml.g4dn.xlarge
作为示例。

准备三个 S3 bucket 用于微调
-
一个用于训练数据
-
一个用于生成的图像输出
-
一个用于模型输出
准备好自己的产品或人物图片,以及每张图片的说明。例如,我想和某人一起制作代言照,所以我准备了6张照片(512*704)和6个同名的txt文件。在每个txt文件中写下提示。然后将文件夹压缩为training_data.zip以供以后使用。
使用您自己的图像构建用于 LoRA 模型训练的训练脚本。我将遵循从kohya-ss/sd-scripts修改的此示例代码来构建训练脚本。
!pip install torch==2.0.0+cu118 torchvision==0.15.1+cu118 --extra-index-url https://download.pytorch.org/whl/cu118
!pip install xformers==0.0.18
!git clone https://github.com/kohya-ss/sd-scripts
%cd sd-scripts/
!pip install -U -r requirements.txt
!pip install --upgrade lion-pytorch lycoris-lora
# fix some warnings and bugs poping up from notebook
!pip install tensorflow==2.11.0
!sudo rm -rf /lib64/libstdc++.so.6 /lib64/libstdc++.so.6
!sudo ln -s /home/ec2-user/anaconda3/envs/python3/lib/libstdc++.so.6 /lib64/libstdc++.so.6
import os
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1'
from accelerate.utils import write_basic_config
write_basic_config()
%%writefile dataset.toml
[general]
enable_bucket = true
shuffle_caption = true
caption_extension = '.txt'
keep_tokens = 0
# DreamBooth caption based character datasets
[[datasets]]
resolution = 512
batch_size = 2
[[datasets.subsets]]
image_dir = './images/sample'
num_repeats = 10
MODEL_NAME = "runwayml/stable-diffusion-v1-5"
DATASET_CONFIG = "./dataset.toml"
TRAIN_DATA_DIR = "./images/sample"
IMAGES_OUTPTS = "./images/outputs"
!mkdir -p $IMAGES_OUTPTS
!rm -rf sample training_data.zip $TRAIN_DATA_DIR
#REMEMBER TO CHANGE YOUR OWN BUCKET NAME FOR DATA INPUT
!aws s3 cp s3://<your s3 bucket for data input>/training_data.zip .
!unzip training_data.zip
!mv sample $TRAIN_DATA_DIR
!rm -rf training_data.zip
!accelerate launch train_network.py \
--pretrained_model_name_or_path=$MODEL_NAME \
--dataset_config=$DATASET_CONFIG \
--output_dir="./output" \
--logging_dir="./logs" \
--network_module="networks.lora" \
--max_train_epochs=10 \
--learning_rate="1e-4" \
--unet_lr="1e-4" \
--text_encoder_lr="1e-5" \
--lr_scheduler="cosine_with_restarts" \
--lr_scheduler_num_cycles=1 \
--network_dim=64 \
--network_alpha=32 \
--output_name="lora_wta" \
--save_every_n_epochs=2 \
--mixed_precision="fp16" \
--cache_latents \
--gradient_checkpointing \
--clip_skip=2 \
--prior_loss_weight=1 \
--max_token_length=225 \
--save_model_as="safetensors" \
--noise_offset=0.1 \
--xformers --use_8bit_adam
import torch
import datetime
from diffusers import StableDiffusionPipeline, EulerAncestralDiscreteScheduler
from networks.lora import LoRAModule, create_network_from_weights
from safetensors.torch import load_file
import boto3
model_id_or_dir = r"runwayml/stable-diffusion-v1-5"
# create pipe
print(f"creating pipe from {model_id_or_dir}...")
scheduler = EulerAncestralDiscreteScheduler.from_pretrained(model_id_or_dir, subfolder="scheduler")
generator = torch.Generator(device="cuda")
pipe = StableDiffusionPipeline.from_pretrained(model_id_or_dir, scheduler=scheduler, torch_dtype=torch.float16)
# pipe = StableDiffusionPipeline.from_pretrained(model_id_or_dir, custom_pipeline="lpw_stable_diffusion", scheduler=scheduler, torch_dtype=torch.float16)
pipe = pipe.to("cuda")
vae = pipe.vae
text_encoder = pipe.text_encoder
unet = pipe.unet
# load lora networks
print(f"loading lora networks...")
lora_path = r"./output/lora_wta.safetensors"
sd = load_file(lora_path) # If the file is .ckpt, use torch.load instead.
network, sd = create_network_from_weights(0.8, None, vae, text_encoder,unet, sd)
network.apply_to(text_encoder, unet)
network.load_state_dict(sd)
network.to("cuda", dtype=torch.float16)
# Uncomment below codes, if you don't want to enable NFSW
def dummy(images, **kwargs):
return images, False
pipe.safety_checker = dummy
# prompts
prompt = "zwxman, solo,"
negative_prompt = "lowres, worst quality, ugly, extra limbs, deformed legs, disfigured legs, (disfigured), ((mutated hands, misshapen hands, mutated fingers, fused fingers):1.2), text, logo, watermark"
# exec pipe
print("generating image...")
num_images = 1
seeds = []
s3upload_client = boto3.client("s3")
for _ in range(num_images):
seed = generator.seed()
seeds.append(seed)
generator = generator.manual_seed(seed)
with torch.autocast("cuda"):
image = pipe(
prompt,
negative_prompt=negative_prompt,
height=512,
width=512,
num_images_per_prompt=1,
num_inference_steps=20,
guidance_scale=7,
generator = generator
).images[0]
display(image)
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
file_path = IMAGES_OUTPTS + "/" + str(seed) + "_" + str(now) + ".png"
print(file_path + "\n")
image.save(file_path)
#REMEMBER TO CHANGE YOUR OWN BUCKET NAME FOR IMAGE OUTPUT
s3upload_client.upload_file(file_path, "<your s3 bucket for image output >", str(seed) + "_" + str(now) + ".png")
# print(seeds)
print(f"\nSeeds for generating images: {seeds}\n")
#REMEMBER TO CHANGE YOUR OWN BUCKET NAME FOR MODEL OUTPUT
!aws s3 cp ./output/lora_wta.safetensors s3://<your s3 bucket for model output>/
由于我们需要在实例启动时自动运行训练脚本,因此我们需要为笔记本实例构建一个生命周期配置。
-
导航到 SageMaker,单击左侧菜单中的生命周期配置
-
选择“笔记本实例”选项卡,然后单击“创建配置”

-
输入名称并选择“启动笔记本”选项卡,然后粘贴以下代码,记得替换你的训练脚本名称
ENVIRONMENT=python3
NOTEBOOK_FILE=/home/ec2-user/SageMaker/<your training script name>.ipynb
source /home/ec2-user/anaconda3/bin/activate "$ENVIRONMENT"
nohup jupyter nbconvert --ExecutePreprocessor.timeout=-1 --ExecutePreprocessor.kernel_name=python3 --to notebook --execute "$NOTEBOOK_FILE" >output.log 2>&1 < /dev/null &

-
点击“创建配置”
创建两个 Lambda:
-
一个用于在训练数据上传到 S3 时启动笔记本实例
-
一个用于停止笔记本实例,并将微调后的模型上传到 S3
请按照以下步骤操作
-
导航到 Lambda
-
点击“创建函数”并选择Python
-
输入以下代码,记得替换你的笔记本实例名称
import json
import boto3
import logging
notebook_name='<your notebook instance name>'
# starts customer segmentation notebook instance on S3 file put
def lambda_handler(event, context):
client = boto3.client('sagemaker')
notebook_description = client.describe_notebook_instance(NotebookInstanceName=notebook_name)
# keep this line
if notebook_description['NotebookInstanceStatus'] in ['Stopped', 'Failed']:
client.start_notebook_instance(NotebookInstanceName= notebook_name)
return 0
-
使用事件类型将输入数据的 S3 存储桶设置为触发器:
s3:ObjectCreated:*
-
部署函数

-
再次点击“创建函数”,选择Python
-
输入以下代码,记得替换你的笔记本实例名称
import json
import boto3
import logging
notebook_name='<your notebook instance name>'
# starts customer segmentation notebook instance on S3 file put
def lambda_handler(event, context):
client = boto3.client('sagemaker')
notebook_description = client.describe_notebook_instance(NotebookInstanceName=notebook_name)
# keep this line
if notebook_description['NotebookInstanceStatus'] in ['InService']:
client.stop_notebook_instance(NotebookInstanceName= notebook_name)
return 0
-
使用事件类型将模型输出的 S3 存储桶设置为触发器:
s3:ObjectCreated:*
-
部署函数

现在,您已全部设置完毕。您可以尝试上传 training_data.zip以启动自动微调管道。您可以在 下看到您的模型
s3://<your s3 bucket of model output>
,并在 下看到生成的图像s3://<your s3 bucket of image output>
。您也可以从 s3 下载模型并直接在 WebUI 中使用。
