使用 Stable Diffusion 生成图像

登录 Hugging Face

可以使用 huggingface_hub 库中的 login() 函数进行登录。需要提供你的 Hugging Face 令牌。代码如下:

  1. from huggingface_hub import login
  2.  
  3. login(token="XXXXXXX")

登录之后,可以使用 snapshot_download 下载指定模型到指定目录,方便后续加载。

  1. from huggingface_hub import snapshot_download
  2.  
  3. # 指定模型和保存路径
  4. model_id = "stabilityai/stable-diffusion-3.5-large"
  5. save_path = "/content/drive/MyDrive/stable-diffusion-3.5-large"
  6.  
  7. # 下载模型
  8. snapshot_download(
  9.     repo_id=model_id,
  10.     local_dir=save_path,
  11.     resume_download=True,   # 开启断点续传
  12.     force_download=False,   # 不强制下载已存在文件
  13. )
  14.  
  15. print(f"模型已下载到: {save_path}")

接着可以使用 from_pretrained() 加载模型。

  1. import torch
  2. from diffusers import StableDiffusion3Pipeline
  3.  
  4. text2img_pipe = StableDiffusion3Pipeline.from_pretrained(
  5.     "/content/drive/MyDrive/stable-diffusion-3.5-large",
  6.     torch_dtype=torch.bfloat16
  7. ).to("cuda:0")

生成图片

现在我们已经将 Stable Diffusion 模型加载到 GPU 上,可以开始生成图片了。text2img_pipe 是一个管道对象,我们只需要提供一个提示语,描述我们想要生成的图像。如以下代码所示:

  1. prompt = "high resolution, a photograph of an astronaut riding a horse"
  2. image = text2img_pipe(
  3.     prompt = prompt
  4. ).images[0]
  5. image

运行上面的代码,可能会看到如下生成的图像:

说“可能”是因为每次生成的结果是不一致的。为了使生成的结果保持一致,我们需要使用另一个参数,称为 generator

生成种子

和其他场景一样,在 Stable Diffusion 中,种子也是用于初始化随机数。种子用于创建一个噪声张量,Stable Diffusion 根据这个噪声张量生成图像。

以下是演示代码:

  1. my_seed = 1234
  2. generator = torch.Generator("cuda:0").manual_seed(my_seed)
  3. prompt = "high resolution, a photograph of an astronaut riding a horse"
  4. image = text2img_pipe(
  5.     prompt = prompt,
  6.     generator = generator
  7. ).images[0]
  8. image

我们使用 torch 创建一个带有手动种子的 torch.Generator 对象,并使用它来生成图像。这样,我们多次执行可以生成相同的图像。

采样调度器

采样调度器可以缩短图像生成的过程。目前我们还不了解其原理,不过可以运行以下代码查看当前模型使用的调度器:

  1. text2img_pipe.scheduler

运行代码后,会返回如下对象:

  • FlowMatchEulerDiscreteScheduler {
  •   "_class_name": "FlowMatchEulerDiscreteScheduler",
  •   "_diffusers_version": "0.31.0",
  •   "base_image_seq_len": 256,
  •   "base_shift": 0.5,
  •   "max_image_seq_len": 4096,
  •   "max_shift": 1.15,
  •   "num_train_timesteps": 1000,
  •   "shift": 3.0,
  •   "use_dynamic_shifting": false
  • }

引导因子

引导因子是一个控制生成图像和文本提示匹配程度的参数。较高的引导因子会使图像更加符合提示词的描述,而较低的引导因子则会给予 Stable Diffusion 更大的自由度。

以下示例展示了其他参数一样,引导因子不同所生成的效果:

  1. generator = torch.Generator("cuda:0").manual_seed(1234)
  2.  
  3. prompt = "high resolution, a photograph of an astronaut riding a horse"
  4.  
  5. # 使用引导因子为 3 生成图像
  6. image_3_gs = text2img_pipe(
  7.     prompt = prompt,
  8.     num_inference_steps = 30,
  9.     guidance_scale = 3,
  10.     generator = generator,
  11. ).images[0]
  12.  
  13. # 使用引导因子为 7 生成图像
  14. image_7_gs = text2img_pipe(
  15.     prompt = prompt,
  16.     num_inference_steps = 30,
  17.     guidance_scale = 7,
  18.     generator = generator,
  19. ).images[0]
  20.  
  21. # 使用引导因子为 3 生成图像
  22. image_10_gs = text2img_pipe(
  23.     prompt = prompt,
  24.     num_inference_steps = 30,
  25.     guidance_scale = 10,
  26.     generator = generator,
  27. ).images[0]
  28.  
  29. from diffusers.utils import make_image_grid
  30. images = [image_3_gs, image_7_gs, image_10_gs]
  31. make_image_grid(images, rows=1, cols=3)

查看输出图片,提示词的匹配度此处差异不太明显。不过除了提示词的匹配度,我们还可以发现,过高的引导因子可能会导致图像模糊。