01_stable_diffusion_introduction_CN

stable_diffusion

配置

!pip install -Uq diffusers ftfy accelerate
# Installing transformers from source for now since we need the latest version for Depth2Img:
!pip install -Uq git+https://github.com/huggingface/transformers 
import torch
import requests
from PIL import Image
from io import BytesIO
from matplotlib import pyplot as plt

# We'll be exploring a number of pipelines today!
from diffusers import (
    StableDiffusionPipeline, 
    StableDiffusionImg2ImgPipeline,
    StableDiffusionInpaintPipeline, 
    StableDiffusionDepth2ImgPipeline
    )       

# We'll use a couple of demo images later in the notebook
def download_image(url):
    response = requests.get(url)
    return Image.open(BytesIO(response.content)).convert("RGB")

# Download images for inpainting example
img_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo.png"
mask_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo_mask.png"

init_image = download_image(img_url).resize((512, 512))
mask_image = download_image(mask_url).resize((512, 512))
# Set device
device = (
    "mps"
    if torch.backends.mps.is_available()
    else "cuda"
    if torch.cuda.is_available()
    else "cpu"
)

从文本生成图像

我们先载入 Stable Diffusion 的管线,看看我们能做点什么。现有的 Stable Diffusion 模型有好多不同版本,截至本文书写时的最新版本是第2.1版。如果你想探究更旧的版本,只需要在 model_id 处修改即可(比如你可以试试将其改成 CompVis/stable-diffusion-v1-4 或从dreambooth concepts library选一个模型)。

# Load the pipeline
model_id = "stabilityai/stable-diffusion-2-1-base"
pipe = StableDiffusionPipeline.from_pretrained(model_id).to(device)
pipe.enable_attention_slicing()
unet\diffusion_pytorch_model.safetensors not found



Loading pipeline components...:   0%|          | 0/6 [00:00<?, ?it/s]

如果你的GPU内存不够用,这里有些办法也许可以减少内存使用:

  • 载入 FP16 精度的版本(但并不是所有的系统上都支持)。与此同时,在你对管线的某个特定部分实验时,你也需要把所有的张量换成 torch.float16 精度:

    pipe = StableDiffusionPipeline.from_pretrained(model_id, revision="fp16", torch_dtype=torch.float16).to(device)

  • 开启注意力机制切分(attention slicing)。这会牺牲一点点速度来减少GPU内存的使用:

pipe.enable_attention_slicing()

  • 降低要生成的图片的尺寸

当管线加载好了以后,我们可以用以下代码去使用文字提示生成图片:

# Set up a generator for reproducibility
generator = torch.Generator(device=device).manual_seed(42)

# Run the pipeline, showing some of the available arguments
pipe_output = pipe(
    prompt="What to generate Palette knife painting of an autumn cityscape",
    negative_prompt="Oversaturated, blurry, low quality", # What NOT to generate
    height=480, width=640,     # Specify the image size
    guidance_scale=8,          # How strongly to follow the prompt
    num_inference_steps=35,    # How many steps to take
    generator=generator        # Fixed random seed
)

# View the resulting image:
pipe_output.images[0]
  0%|          | 0/35 [00:00<?, ?it/s]

在这里插入图片描述

练习: 花点时间去用上面的代码块实验,使用你自己的文字提示,反复调整各项设置看看这些设置如何影响生成效果。使用不同的随机种子或者移除掉 generator 这个输入参数,看看能获取什么不同的效果。

主要的要调节参数介绍:

  • widthheight 指定了生成图片的尺寸。它们必须是可被 8 整除的数字,只有这样我们的可变分自编码器(VAE)才能正常工作(我们在将来的章节会了解到)。
  • 步数 num_inference_steps 也会影响生成的质量。默认设成 50 已经很好了,但有些时候你也可以用少到像 20 步这样,这对做实验就方便多了。
  • 使用 negative_prompt 来强调不希望生成的内容,一般会在无分类器引导(classifier-free guidance)的过程中用到,这可以是个非常有用的添加额外控制的方式。你可以留空这个地方不管,但很多用户觉得列出一些不想要的特性对更好的生成很有帮助。
  • guidance_scale 这个参数决定了无分类器引导(CFG)的影响强度有多大。增大这个值会使得生成的内容更接近文字提示;但这个值如果过大,可能会使得结果变得过饱和、不好看。

如果你想为文字提示找点灵感,你也可以从这里开始:Stable Diffusion Prompt Book

你可在下面看到增大guidance_scale 这个参数所带来的作用:

#@markdown comparing guidance scales:
cfg_scales = [1.1, 8, 12] #@param
prompt = "A collie with a pink hat" #@param
fig, axs = plt.subplots(1, len(cfg_scales), figsize=(16, 5))
for i, ax in enumerate(axs):
  im = pipe(prompt, height=480, width=480,
    guidance_scale=cfg_scales[i], num_inference_steps=35,
    generator=torch.Generator(device=device).manual_seed(42)).images[0]
  ax.imshow(im); ax.set_title(f'CFG Scale {cfg_scales[i]}');
  0%|          | 0/35 [00:00<?, ?it/s]



  0%|          | 0/35 [00:00<?, ?it/s]



  0%|          | 0/35 [00:00<?, ?it/s]

在这里插入图片描述

调一调上面的值,尝试不同的幅度和提示。当然了,如何解读这些参数是个很主观的事情,但对我来说,我觉得 8 到 12 这个值区间比其它情况产出的结果都好。

管线的组成部分

这里我们用的 StableDiffusionPipeline 比前面几个单元的 DDPMPipeline 要复杂一点。除了 UNet 和调度器之外,管线内还有很多其它的组成部分:

print(list(pipe.components.keys())) # List components
['vae', 'text_encoder', 'tokenizer', 'unet', 'scheduler', 'safety_checker', 'feature_extractor']

为了更好地理解管线如何工作,我们简要地一个一个看看各个组成部分,然后我们自己动手,把它们组合在一起,以此复现出整个管线功能。

可变分自编码器(VAE)

可变分自编码器(VAE)是一种模型,它可以将输入编码成一种被压缩过的表示形式,再把这个“隐式的”表示形式解码成某种接近输入的输出。当我们使用 Stable Diffusion 生成图片时,我们先在VAE的“隐空间”应用扩散过程生成隐编码,然后在结尾对它们解码来查看结果图片。

这里就是一个例子,使用VAE把输入图片编码成隐式的表示形式,再对它解码:

# Create some fake data (a random image, range (-1, 1))
images = torch.rand(1, 3, 512, 512).to(device) * 2 - 1 
print("Input images shape:", images.shape)

# Encode to latent space
with torch.no_grad():
  latents = 0.18215 * pipe.vae.encode(images).latent_dist.mean
print("Encoded latents shape:", latents.shape)

# Decode again
with torch.no_grad():
  decoded_images = pipe.vae.decode(latents / 0.18215).sample
print("Decoded images shape:", decoded_images.shape)
Input images shape: torch.Size([1, 3, 512, 512])
Encoded latents shape: torch.Size([1, 4, 64, 64])
Decoded images shape: torch.Size([1, 3, 512, 512])

如你所见,原本 512x512 尺寸的图片被压缩到 64x64的隐式表示形式(有四个通道)中。每一空间维度上都被压缩到了原有的八分之一,这也是为什么我们设定 widthheight 时需要它们是 8 的倍数。

使用这些信息量充裕的 4x64x64 隐编码可比使用 512px 大小的图片要高效多了,可以让我们的扩散模型更快,并使用更少的资源来训练和使用。VAE的解码过程并不是完美的,但即使损失了一点点质量,总的来说也足够好了。

注意:上面的代码例子包含了一个值为 0.18215 的缩放因子,以此来适配stable diffusion训练时的处理流程。

分词器(Tokenizer)和文本编码器(Text Encoder)

文本编码器的作用是将输入的字符串(文本提示)转化成数值表示形式,这样才能输入进 UNet 作为条件。文本首先要被管线中的分词器(tokenizer)转换成一系列的分词(token)。文本编码器有大约五万分词的词汇量 —— 任何不存在于这些词汇量中的词语都会被细分成多个更小的词语。这些分词然后就被送入文本编码器模型中 —— 文本编码器是一个transformer模型,最初被训练作为CLIP的文本编码器。这里我们希望这个经过了预训练的transformer模型学习到了足够好的文本表示能力,可以对我们这里的扩散任务一样有用。

我们这里通过对一个文字提示进行编码,验证一下这个过程。首先,我们手动进行分词,并将它输入到文本编码器中,再使用管线的 _encode_prompt 方法,观察一下完成的过程,这包括补全或截断分词串的长度,使得分词串的长度等于最大长度 77 :

# Tokenizing and encoding an example prompt manualy:

# Tokenize
input_ids = pipe.tokenizer(["A painting of a flooble"])['input_ids']
print("Input ID -> decoded token")
for input_id in input_ids[0]:
  print(f"{input_id} -> {pipe.tokenizer.decode(input_id)}")

# Feed through CLIP text encoder
input_ids = torch.tensor(input_ids).to(device)
with torch.no_grad():
  text_embeddings = pipe.text_encoder(input_ids)['last_hidden_state']
print("Text embeddings shape:", text_embeddings.shape)
Input ID -> decoded token
49406 -> <|startoftext|>
320 -> a
3086 -> painting
539 -> of
320 -> a
4062 -> floo
1059 -> ble
49407 -> <|endoftext|>
Text embeddings shape: torch.Size([1, 8, 1024])
# Get the final text embeddings using the pipeline's _encode_prompt function:
text_embeddings = pipe._encode_prompt("A painting of a flooble", device, 1, False, '')
text_embeddings.shape
F:\software\Anaconda\envs\test\lib\site-packages\diffusers\pipelines\stable_diffusion\pipeline_stable_diffusion.py:237: FutureWarning: `_encode_prompt()` is deprecated and it will be removed in a future version. Use `encode_prompt()` instead. Also, be aware that the output format changed from a concatenated tensor to a tuple.
  deprecate("_encode_prompt()", "1.0.0", deprecation_message, standard_warn=False)



---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

Cell In[6], line 2
      1 # Get the final text embeddings using the pipeline's _encode_prompt function:
----> 2 text_embeddings = pipe._encode_prompt("A painting of a flooble", device, 1, False, '')
      3 text_embeddings.shape


File F:\software\Anaconda\envs\test\lib\site-packages\diffusers\pipelines\stable_diffusion\pipeline_stable_diffusion.py:251, in StableDiffusionPipeline._encode_prompt(self, prompt, device, num_images_per_prompt, do_classifier_free_guidance, negative_prompt, prompt_embeds, negative_prompt_embeds, lora_scale)
    239 prompt_embeds_tuple = self.encode_prompt(
    240     prompt=prompt,
    241     device=device,
   (...)
    247     lora_scale=lora_scale,
    248 )
    250 # concatenate for backwards comp
--> 251 prompt_embeds = torch.cat([prompt_embeds_tuple[1], prompt_embeds_tuple[0]])
    253 return prompt_embeds


TypeError: expected Tensor as element 0 in argument 0, but got NoneType

这些文本嵌入(text embedding),也即文本编码器中最后一个transformer模块的“隐状态(hidden state)”,将会被送入 UNet 中作为 forward 函数的一个额外输入,下面部分我们会详细看到。

UNet

UNet 模型接收一个带噪的输入,并预测噪声,和我们之前单元中看到的 UNet 一样。但与以往例子不同的是,这里的输入并不是图片了,而是图片的隐式表示形式(latent representation)。此外,除了把用于暗示带噪程度的timestep输入进 UNet 作为条件外,这里模型也把文字提示(prompt)的文本嵌入(text embeddings)作为了额外输入。这里我们假数据试着让它预测一下:

# Dummy inputs:
timestep = pipe.scheduler.timesteps[0]
latents = torch.randn(1, 4, 64, 64).to(device)
text_embeddings = torch.randn(1, 77, 1024).to(device)

# Model prediction:
with torch.no_grad():
  unet_output = pipe.unet(latents, timestep, text_embeddings).sample
print('UNet output shape:', unet_output.shape) # Same shape as the input latents

调度器(Scheduler)

调度器保存了如何加噪的计划安排,管理着如何基于模型的预测更新带噪样本。默认的调度器是 PNDMScheduler 调度器,但你也可以用其它的(比如 LMSDiscreteScheduler 调度器),只要它们用相同的配置初始化。

我们可以画出图像来观察随着timestep添加噪声的计划安排,看看不同时间的噪声水平(基于 α ˉ \bar{\alpha} αˉ这个参数)是什么样的:

plt.plot(pipe.scheduler.alphas_cumprod, label=r'$\bar{\alpha}$')
plt.xlabel('Timestep (high noise to low noise ->)');
plt.title('Noise schedule');plt.legend();

在这里插入图片描述

pip install scipy
Looking in indexes: http://mirrors.aliyun.com/pypi/simple/
Collecting scipy
  Downloading http://mirrors.aliyun.com/pypi/packages/32/8e/7f403535ddf826348c9b8417791e28712019962f7e90ff845896d6325d09/scipy-1.10.1-cp38-cp38-win_amd64.whl (42.2 MB)
Requirement already satisfied: numpy<1.27.0,>=1.19.5 in f:\software\anaconda\envs\test\lib\site-packages (from scipy) (1.23.0)
Installing collected packages: scipy
Successfully installed scipy-1.10.1
Note: you may need to restart the kernel to use updated packages.

如果你想尝试不同的调度器,你可以像下面代码中一样换一个新的:

from diffusers import LMSDiscreteScheduler

# Replace the scheduler
pipe.scheduler = LMSDiscreteScheduler.from_config(pipe.scheduler.config)

# Print the config
print('Scheduler config:', pipe.scheduler)

# Generate an image with this new scheduler
pipe(prompt="Palette knife painting of an winter cityscape", height=480, width=480,
     generator=torch.Generator(device=device).manual_seed(42)).images[0]
Scheduler config: LMSDiscreteScheduler {
  "_class_name": "LMSDiscreteScheduler",
  "_diffusers_version": "0.21.4",
  "beta_end": 0.012,
  "beta_schedule": "scaled_linear",
  "beta_start": 0.00085,
  "clip_sample": false,
  "num_train_timesteps": 1000,
  "prediction_type": "epsilon",
  "set_alpha_to_one": false,
  "skip_prk_steps": true,
  "steps_offset": 1,
  "timestep_spacing": "linspace",
  "trained_betas": null,
  "use_karras_sigmas": false
}




  0%|          | 0/50 [00:00<?, ?it/s]

在这里插入图片描述

在这里你可以了解更多使用不同调度器的信息。

DIY一个采样循环

现在我们已经一个个看过这些组成部分了,我们可以把它们拼装到一起,来复现一下整个管线的功能:

guidance_scale = 8 #@param
num_inference_steps=30 #@param
prompt = "Beautiful picture of a wave breaking" #@param
negative_prompt = "zoomed in, blurry, oversaturated, warped" #@param

# Encode the prompt
text_embeddings = pipe._encode_prompt(prompt, device, 1, True, negative_prompt)

# Create our random starting point
latents = torch.randn((1, 4, 64, 64), device=device, generator=generator)
latents *= pipe.scheduler.init_noise_sigma

# Prepare the scheduler
pipe.scheduler.set_timesteps(num_inference_steps, device=device)

# Loop through the sampling timesteps
for i, t in enumerate(pipe.scheduler.timesteps):

  # expand the latents if we are doing classifier free guidance
  latent_model_input = torch.cat([latents] * 2)

  # Apply any scaling required by the scheduler
  latent_model_input = pipe.scheduler.scale_model_input(latent_model_input, t)

  # predict the noise residual with the unet
  with torch.no_grad():
    noise_pred = pipe.unet(latent_model_input, t, encoder_hidden_states=text_embeddings).sample

  # perform guidance
  noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
  noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)

  # compute the previous noisy sample x_t -> x_t-1
  latents = pipe.scheduler.step(noise_pred, t, latents).prev_sample

# Decode the resulting latents into an image
with torch.no_grad():
  image = pipe.decode_latents(latents.detach())

# View
pipe.numpy_to_pil(image)[0]
F:\software\Anaconda\envs\test\lib\site-packages\diffusers\pipelines\stable_diffusion\pipeline_stable_diffusion.py:430: FutureWarning: The decode_latents method is deprecated and will be removed in 1.0.0. Please use VaeImageProcessor.postprocess(...) instead
  deprecate("decode_latents", "1.0.0", deprecation_message, standard_warn=False)

在这里插入图片描述

其它的一些管线

Img2Img

直到现在,我们生成的图片还都是完全从随机的隐变量来开始生成的,而且也都使用了完整的扩散模型采样循环。但其实我们不必从头开始。Img2Img 这个管线首先将一张已有的图片进行编码,编码成一系列的隐变量,然后在这些隐变量上随机加噪声,以这些作为起始点。噪声加多大量、去噪需要的步数决定了这个 img2img 过程的“强度”。只加一点点噪声(强度低)只会带来微小改变,而加入最大量的噪声并跑完完整的去噪过程又会生成出几乎完全不像原始图片的结果,即使可能在整体结构上还多少有点相似。

这个管线无需什么特殊模型,只要模型的 ID 和我们的文字到图像模型一样就行,没有新的需要下载的文件。

# Loading an Img2Img pipeline
model_id = "stabilityai/stable-diffusion-2-1-base"
img2img_pipe = StableDiffusionImg2ImgPipeline.from_pretrained(model_id).to(device)
unet\diffusion_pytorch_model.safetensors not found



Loading pipeline components...:   0%|          | 0/6 [00:00<?, ?it/s]

在本节的“配置”部分,我们加载了一个名为 init_image 的图片来用于这里的演示,当然你也可以用你自己的图片替换它。这里是使用该管线的代码:

# Apply Img2Img
result_image = img2img_pipe(
    prompt="An oil painting of a man on a bench",
    image = init_image, # The starting image
    strength = 0.6, # 0 for no change, 1.0 for max strength
).images[0]

# View the result
fig, axs = plt.subplots(1, 2, figsize=(12, 5))
axs[0].imshow(init_image);axs[0].set_title('Input Image')
axs[1].imshow(result_image);axs[1].set_title('Result');
---------------------------------------------------------------------------

RuntimeError                              Traceback (most recent call last)


RuntimeError: CUDA out of memory. Tried to allocate 128.00 MiB (GPU 0; 4.00 GiB total capacity; 9.90 GiB already allocated; 0 bytes free; 10.01 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

练习: 用这个管线做实验,试试你自己的图片,或者试试不同的强度和文字提示。你可以使用很多和文字到图片管线相同的输入参数。所以尽可能试试不同的图片尺寸、生成步数吧。

In-Painting

如果我们想在一张图中保留一部分不变而在其它部分生成新东西,那该怎么办呢?这种技术叫 inpainting 。虽然我们可以通过前面演示中的同一个模型(用 StableDiffusionInpaintPipelineLegacy 管线)来实现,但我们这里可以用一个自定义的微调版 Stable Diffusion 模型来得到更好的效果。这里的 Stable Diffusion 模型接收一个掩模(mask)作为额外条件性输入。这个掩模图片需要和输入图片尺寸一致,白色区域表示要被替换的部分,黑色区域表示要保留的部分。以下代码就展示了我们如何载入这个管线并如何应用到前面载入的示例图片和掩模上:

# Load the inpainting pipeline (requires a suitable inpainting model)
pipe = StableDiffusionInpaintPipeline.from_pretrained("runwayml/stable-diffusion-inpainting")
pipe = pipe.to(device)
Downloading (…)ain/model_index.json:   0%|          | 0.00/548 [00:00<?, ?B/s]


F:\software\Anaconda\envs\test\lib\site-packages\huggingface_hub\file_download.py:137: UserWarning: `huggingface_hub` cache-system uses symlinks by default to efficiently store duplicated files but your machine does not support them in C:\Users\11637\.cache\huggingface\hub. Caching files will still work but in a degraded version that might require more space on your disk. This warning can be disabled by setting the `HF_HUB_DISABLE_SYMLINKS_WARNING` environment variable. For more details, see https://huggingface.co/docs/huggingface_hub/how-to-cache#limitations.
To support symlinks on Windows, you either need to activate Developer Mode or to run Python as an administrator. In order to see activate developer mode, see this article: https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development
  warnings.warn(message)
unet\diffusion_pytorch_model.safetensors not found



Fetching 16 files:   0%|          | 0/16 [00:00<?, ?it/s]



Downloading pytorch_model.bin:   0%|          | 0.00/1.22G [00:00<?, ?B/s]



Downloading (…)_checker/config.json:   0%|          | 0.00/4.78k [00:00<?, ?B/s]



Downloading pytorch_model.bin:   0%|          | 0.00/492M [00:00<?, ?B/s]



Downloading (…)tokenizer/merges.txt:   0%|          | 0.00/525k [00:00<?, ?B/s]



Downloading (…)cial_tokens_map.json:   0%|          | 0.00/472 [00:00<?, ?B/s]



Downloading (…)cheduler_config.json:   0%|          | 0.00/313 [00:00<?, ?B/s]



Downloading (…)okenizer_config.json:   0%|          | 0.00/806 [00:00<?, ?B/s]



Downloading (…)tokenizer/vocab.json:   0%|          | 0.00/1.06M [00:00<?, ?B/s]



Downloading (…)rocessor_config.json:   0%|          | 0.00/342 [00:00<?, ?B/s]



Downloading (…)49d/unet/config.json:   0%|          | 0.00/748 [00:00<?, ?B/s]



Downloading (…)_encoder/config.json:   0%|          | 0.00/617 [00:00<?, ?B/s]



Downloading (…)b49d/vae/config.json:   0%|          | 0.00/552 [00:00<?, ?B/s]



Downloading (…)on_pytorch_model.bin:   0%|          | 0.00/335M [00:00<?, ?B/s]

ProxyError: (MaxRetryError("HTTPSConnectionPool(host='huggingface.co', port=443): Max retries exceeded with url: /runwayml/stable-diffusion-inpainting/resolve/51388a731f57604945fddd703ecb5c50e8e7b49d/config.json (Caused by ProxyError('Cannot connect to proxy.', timeout('_ssl.c:1114: The handshake operation timed out')))"), '(Request ID: fb3b77aa-4c46-4dd6-9245-5a2f602160e4)')
# Inpaint with a prompt for what we want the result to look like
prompt = "A small robot, high resolution, sitting on a park bench"
image = pipe(prompt=prompt, image=init_image, mask_image=mask_image).images[0]

# View the result
fig, axs = plt.subplots(1, 3, figsize=(16, 5))
axs[0].imshow(init_image);axs[0].set_title('Input Image')
axs[1].imshow(mask_image);axs[1].set_title('Mask')
axs[2].imshow(image);axs[2].set_title('Result');

当和其它可以自动生成掩模的模型结合起来的时候,这个模型将会相当强大。比如这个示例space就用了一个名为 CLIPSeg 的模型,它可以根据文字描述自动地用掩模去掉一个物体。

题外话:管理你的模型缓存

探索不同的管线和模型可能会占满你的硬盘空间。你可用这个指令看看你都下载了哪些模型到你的硬盘上:

!ls ~/.cache/huggingface/diffusers/ # List the contents of the cache directory
models--CompVis--stable-diffusion-v1-4
models--ddpm-bedroom-256
models--google--ddpm-bedroom-256
models--google--ddpm-celebahq-256
models--runwayml--stable-diffusion-inpainting
models--stabilityai--stable-diffusion-2-1-base

看看缓存相关文档来了解如何高效地查看和管理缓存。

Depth2Image

在这里插入图片描述

Input image, depth image and generated examples (image source: StabilityAI)

Img2Img 已经很厉害了,但有时我们还想用原始图片的组成成分但使用完全不同的颜色或纹理来生成新图片。通过调节 Img2Img 的“强度”来保留图片整体结构但却不保留原有颜色将会很困难。

所以这里就需要另一个微调的模型了!这个模型需要输入额外的深度信息作为生成条件。相关管线使用了一个深度预测模型来预测出一个深度图,然后这个深度图会被输入微调过的 UNet 中用以生成图片。我们这里希望生成的图片能够保留原始图片的深度信息和总体结构,同时又在相关部分填入全新的内容。

# Load the Depth2Img pipeline (requires a suitable model)
pipe = StableDiffusionDepth2ImgPipeline.from_pretrained("stabilityai/stable-diffusion-2-depth")
pipe = pipe.to(device)
# Inpaint with a prompt for what we want the result to look like
prompt = "An oil painting of a man on a bench"
image = pipe(prompt=prompt, image=init_image).images[0]

# View the result
fig, axs = plt.subplots(1, 2, figsize=(16, 5))
axs[0].imshow(init_image);axs[0].set_title('Input Image')
axs[1].imshow(image);axs[1].set_title('Result');
  0%|          | 0/40 [00:00<?, ?it/s]

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/114240.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Logstash学习

1、什么是logstash logstash是一个数据抽取工具&#xff0c;将数据从一个地方转移到另一个地方。如hadoop生态圈的sqoop等。下载地址: https://www.elastic.co/cn/downloads/logstash logstash之所以功能强大和流行&#xff0c;还与其丰富的过滤器插件是分不开的&#xff0c;过…

搭建个人hMailServer邮件服务实现远程发送邮件

文章目录 前言1. 安装hMailServer2. 设置hMailServer3. 客户端安装添加账号4. 测试发送邮件5. 安装cpolar6. 创建公网地址7. 测试远程发送邮件8. 固定连接公网地址9. 测试固定远程地址发送邮件 前言 hMailServer 是一个邮件服务器,通过它我们可以搭建自己的邮件服务,通过cpola…

python连接clickhouse (CK)

Author: tkhywang 2810248865qq.com Date: 2023-11-01 11:28:58 LastEditors: tkhywang 2810248865qq.com LastEditTime: 2023-11-01 11:36:25 FilePath: \PythonProject02\Python读取clickhouse2 数据库数据.py Description: 这是默认设置,请设置customMade, 打开koroFileHead…

tcp/ip该来的还是得来

1. TCP/IP、Http、Socket的区别 \qquad 区别是&#xff1a;TCP/IP即传输控制/网络协议&#xff0c;也叫作网络通讯协议&#xff0c;它是在网络的使用中的最基本的通信协议。Http是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。Socket是对网络中不同主机上的应用进…

react-hook-form。 useFieldArray Controller 必填,报错自动获取较多疑问记录

背景 动态多个数据Controller包裹时候&#xff0c;原生html标签input可以add时候自动获取焦点&#xff0c;聚焦到最近不符合要求的元素上面 matiral的TextField同样可以可是x-date-pickers/DatePicker不可以❌ 是什么原因呢&#xff0c;内部提供foucs&#xff1f;&#xff1f;属…

这才是当今生成式人工智能的根本性问题!

原创 | 文 BFT机器人 01 引言 近年来&#xff0c;生成式人工智能产品层出不穷&#xff0c;ChatGPT火爆出圈后&#xff0c;百度、谷歌等科技大佬争相研究生成式人工智能产品&#xff0c;将该技术的普及程度提升到了一个新的水平。然而&#xff0c;生成式人工智能的运营需要高昂…

【Redis】入门篇--安装以及常用命令

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Redis的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Redis是什么 二. Redis有什么优势 三…

谷歌浏览器解决跨域问题配置记录

在访问时出现has been blocked by CORS policy: Responspreflight request doesn’t pass access control checlAccess-Control-A1low-Origin" header is present onrequested resource. 出现跨域问题 1.先关闭浏览器 2.创建一个目录&#xff0c;文件夹记住路径 3.点击谷…

强化学习的动态规划

一、动态规划 动态规划&#xff08;DP&#xff09;一词指的是一系列算法&#xff0c;这些算法可用于在给定环境的完美模型作为马尔可夫决策过程&#xff08;MDP&#xff09;的情况下计算最优策略。经典的DP算法在强化学习中具有有限的实用性&#xff0c;既因为其对完美模型的假…

开源播放器GSYVideoPlayer的简单介绍及播放rtsp流的优化

开源播放器GSYVideoPlayer的简单介绍及播放rtsp流的优化 前言一、GSYVideoPlayer&#x1f525;&#x1f525;&#x1f525;是什么&#xff1f;二、简单使用1.First、在project下的build.gradle添加2.按需导入3. 常用代码 rtsp流的优化大功告成 总结 前言 本文介绍&#xff0c;…

Uni-App 快捷登录

uniapp 实现一键登录前置条件: 开通uniCloud, 开通一键登录功能参考的文档 : 官网 - 一键登录uniapp指南 : https://uniapp.dcloud.net.cn/univerify.html#%E6%A6%82%E8%BF%B0 官网 - 一键登录开通指南 : https://ask.dcloud.net.cn/article/37965 官网 - unicloud使用指南 htt…

Greenplum管理和监控工具-gpcc-web介绍

Greenplum管理和监控工具-gpcc-web介绍 1. gpcc-web简介 ​ gpcc&#xff08;Greenplum Command Center&#xff09;的Web用户界面是一个强大的工具&#xff0c;它可以帮助用户管理Greenplum数据库集群&#xff0c;提高效率&#xff0c;优化性能&#xff0c;并确保数据的安全…

应用场景由点及面,大模型在银行业落地的方法|案例研究

自2022年11月面世以来&#xff0c;ChatGPT已经吸引了全球范围内的广泛关注。其底层技术大模型&#xff0c;也获得了银行业自上而下所有人员前所未有的关注度。 01 相较于传统AI小模型&#xff0c;大模型具有以下三大核心优势&#xff1a;效率提升&#xff0c;个性化输出和交互…

二维码智慧门牌管理系统升级解决方案:让门牌安装任务更加智能化

文章目录 前言一、任务地图和任务领取二、贴牌作业和提交作业三、优势与效益四、自媒体平台的吸引力 前言 随着科技的不断发展&#xff0c;智能化管理在各个领域的应用越来越广泛。在门牌安装领域&#xff0c;二维码智慧门牌管理系统已经成为了一种新的升级解决方案&#xff0…

什么样的耳机适合跑步?适合跑步佩戴的无线耳机推荐

​无论是在烈日炎炎的夏天&#xff0c;还是在寒风刺骨的冬天里健身运动&#xff0c;只要打开音乐就能沉浸其中。运动耳机不仅佩戴稳固舒适&#xff0c;还能提供高品质音质表现。无论在哪里&#xff0c;无论何时&#xff0c;只要打开音乐&#xff0c;你就可以找到你的节奏&#…

日本移动支付Merpay QA团队的自动化现状

Merpay是日本最大的网购平台之一Mercari的无现金支付系统。Merpay 的主要功能是让用户在 Mercari的网站上购物&#xff0c;也可以在日本的许多实体店和餐厅使用它&#xff0c;也可以理解为日本的“支付宝”。以下为Merpay QA 团队在自动化方面的一些思考&#xff1a; 这几年&am…

AI、万圣节与聊斋;用AI写甜蜜恋爱小暖文;AGI新趋势与机会洞察;Meta官方Llama 2入门指南 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f440; 时代杂志评选2023年度最佳发明&#xff0c;AI赛道入选名单 https://time.com/collection/best-inventions-2023 10 月 24 日&#xff…

【排序算法】 计数排序(非比较排序)详解!了解哈希思想!

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; 算法—排序篇 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言&#x1f324;️计数排序的概念☁️什么是计数排序&#xff1f;☁️计数排序思想⭐绝对…

安全第一!速卖通测评补单稳定的系统注意事项大盘点

对新卖家而言&#xff0c;测评并非可耻之事&#xff0c;反而是无法起步、耗费自身时间才是真正的可耻。由于速卖通新店几乎无法获得任何活动的支持&#xff0c;流量也基本没有&#xff0c;因此要在90天内达成60单的业绩对于许多卖家来说都是一项挑战。因此&#xff0c;通过快速…

将一个Series序列转化为数据框Dataframe格式Series.to_frame()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将一个Series序列 转化为Dataframe格式 Series.to_frame() [太阳]选择题 关于以下代码的说法中正确的是? import pandas as pd s pd.Series([1,2],name"myValue") print("【显…