Buckets:
| # 可复现性 | |
| Diffusion 是一个随机过程,每次都会生成不同的输出。对于测试和复现结果等用例,你希望在一定的容差范围内,跨版本和平台每次都能生成相同的结果。 | |
| 本指南将向您展示如何控制随机性来源并启用确定性算法。 | |
| ## 生成器 | |
| Pipelines 依赖 [torch.randn](https://pytorch.org/docs/stable/generated/torch.randn.html) 来创建初始噪声张量,而该函数每次都会使用不同的随机种子。若要在 CPU 或 GPU 上生成相同的输出,请使用 [Generator](https://docs.pytorch.org/docs/stable/generated/torch.Generator.html) 来管理随机值的生成方式。 | |
| > [!TIP] | |
| > 如果可复现性很重要,你应该使用 CPU 上的 `Generator`。性能损失通常可以忽略不计,并且你会生成更相似的数值。 | |
| 如果您关注可复现性,请使用 CPU `Generator`。CPU 随机数生成器在不同机器上更加稳定。 | |
| 当传入 CPU `Generator` 时,Diffusers 的 [randn_tensor()](/docs/diffusers/v0.43.0/zh/api/utilities#diffusers.utils.torch_utils.randn_tensor) 会在 CPU 上进行采样,并在流水线内部将张量移至 GPU。您无需自行调用 `randn_tensor` 或 `.to("cuda")`。GPU `Generator` 则直接在设备上采样,其结果可能与 CPU 上的结果存在差异。 | |
| 使用 [manual_seed](https://docs.pytorch.org/docs/stable/generated/torch.manual_seed.html) 来设置种子。 | |
| ```py | |
| import torch | |
| from diffusers import DiffusionPipeline | |
| pipeline = DiffusionPipeline.from_pretrained( | |
| "Qwen/Qwen-Image", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu" | |
| ) | |
| generator = torch.manual_seed(0) | |
| image = pipeline( | |
| prompt="a red apple on a wooden table", | |
| generator=generator, | |
| num_inference_steps=4, | |
| ).images[0] | |
| ``` | |
| 创建一个 CPU `Generator`,并使用 [Generator.manual_seed](https://docs.pytorch.org/docs/stable/generated/torch.Generator.html#torch.Generator.manual_seed) 设置种子。 | |
| ```py | |
| import torch | |
| from diffusers import DiffusionPipeline | |
| pipeline = DiffusionPipeline.from_pretrained( | |
| "Qwen/Qwen-Image", dtype=torch.bfloat16, device_map="cpu" | |
| ) | |
| generator = torch.Generator(device="cpu").manual_seed(0) | |
| image = pipeline( | |
| prompt="a red apple on a wooden table", | |
| generator=generator, | |
| num_inference_steps=4, | |
| ).images[0] | |
| ``` | |
| 向 pipeline 传入一个 `Generator` 对象,而不是整数种子。`Generator` 会维护一个随机状态,每次使用它时该状态都会被消耗并更新。因此,即使跨 pipeline,后续调用同一对象也会产生不同的结果,因为其状态已经改变。如果需要再次使用相同的种子,请在每次调用前重新设置种子或创建一个新的 `Generator`。 | |
| ```py | |
| import torch | |
| prompt = "a red apple on a wooden table" | |
| for _ in range(5): | |
| generator = torch.manual_seed(0) | |
| image = pipeline(prompt, generator=generator, num_inference_steps=4).images[0] | |
| ``` | |
| ## 确定性算法 | |
| PyTorch 支持针对某些操作使用[确定性算法](https://docs.pytorch.org/docs/stable/notes/randomness.html#avoiding-nondeterministic-algorithms)(在可用的情况下),以确保它们产生相同的结果。确定性算法可能会更慢并降低性能。 | |
| 使用 Diffusers 的 `enable_full_determinism()` 来启用确定性算法。 | |
| ```py | |
| from diffusers.utils.torch_utils import enable_full_determinism | |
| enable_full_determinism() | |
| ``` | |
| `enable_full_determinism` 的工作原理如下: | |
| - 将环境变量 `CUDA_LAUNCH_BLOCKING` 设置为 `1` | |
| - 将环境变量 [CUBLAS_WORKSPACE_CONFIG](https://docs.nvidia.com/cuda/cublas/index.html#results-reproducibility) 设置为 `:16:8`,以便 cuBLAS 在运行时使用固定的工作区布局 | |
| - 调用 `torch.use_deterministic_algorithms(True)` | |
| - 设置 `torch.backends.cudnn.deterministic = True` | |
| - 设置 `torch.backends.cudnn.benchmark = False`,使 cuDNN 不会在每次运行时选择不同的卷积算法 | |
| - 通过`torch.backends.cuda.matmul.allow_tf32 = False`禁用 TensorFloat32 (TF32),转而使用精度更高的全精度矩阵乘法 | |
| ## 后续步骤 | |
| 建议阅读 PyTorch 关于 [可复现性](https://docs.pytorch.org/docs/stable/notes/randomness.html) 的开发者说明。你可以尝试限制随机性,但即使使用相同的随机种子,也无法 *保证* 结果完全一致。 | |
Xet Storage Details
- Size:
- 4.31 kB
- Xet hash:
- 752b17a2af8181850d6b7ebe54305a95bb8e4dd67e00d7ba9f465222b8baf97f
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.