Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Reproducible pipelines","local":"reproducible-pipelines","sections":[{"title":"Control randomness","local":"control-randomness","sections":[],"depth":2},{"title":"Deterministic algorithms","local":"deterministic-algorithms","sections":[],"depth":2}],"depth":1}"> | |
| <link href="/docs/diffusers/pr_11986/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/entry/start.e4c568fa.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/scheduler.8c3d61f6.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/singletons.59c211be.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/index.0997d446.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/paths.38f9cd8e.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/entry/app.29bdf47f.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/index.da70eac4.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/nodes/0.f8d125de.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/each.e59479a4.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/nodes/303.b27a7d94.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/Tip.1d9b8c37.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/CodeBlock.a9c4becf.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/getInferenceSnippets.366c2c95.js"> | |
| <link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/HfOption.6ab18950.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{"title":"Reproducible pipelines","local":"reproducible-pipelines","sections":[{"title":"Control randomness","local":"control-randomness","sections":[],"depth":2},{"title":"Deterministic algorithms","local":"deterministic-algorithms","sections":[],"depth":2}],"depth":1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <h1 class="relative group"><a id="reproducible-pipelines" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#reproducible-pipelines"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Reproducible pipelines</span></h1> <p data-svelte-h="svelte-13kjkmn">Diffusion models are inherently random which is what allows it to generate different outputs every time it is run. But there are certain times when you want to generate the same output every time, like when you’re testing, replicating results, and even <a href="#deterministic-batch-generation">improving image quality</a>. While you can’t expect to get identical results across platforms, you can expect reproducible results across releases and platforms within a certain tolerance range (though even this may vary).</p> <p data-svelte-h="svelte-117kc42">This guide will show you how to control randomness for deterministic generation on a CPU and GPU.</p> <div class="course-tip bg-gradient-to-br dark:bg-gradient-to-r before:border-green-500 dark:before:border-green-800 from-green-50 dark:from-gray-900 to-white dark:to-gray-950 border border-green-50 text-green-700 dark:text-gray-400"><p data-svelte-h="svelte-ccpr3c">We strongly recommend reading PyTorch’s <a href="https://pytorch.org/docs/stable/notes/randomness.html" rel="nofollow">statement about reproducibility</a>:</p> <p data-svelte-h="svelte-1ci17z2">“Completely reproducible results are not guaranteed across PyTorch releases, individual commits, or different platforms. Furthermore, results may not be reproducible between CPU and GPU executions, even when using identical seeds.”</p></div> <h2 class="relative group"><a id="control-randomness" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#control-randomness"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Control randomness</span></h2> <p data-svelte-h="svelte-1tn5oba">During inference, pipelines rely heavily on random sampling operations which include creating the | |
| Gaussian noise tensors to denoise and adding noise to the scheduling step.</p> <p data-svelte-h="svelte-1iss7fm">Take a look at the tensor values in the <a href="/docs/diffusers/pr_11986/en/api/pipelines/ddim#diffusers.DDIMPipeline">DDIMPipeline</a> after two inference steps.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> DDIMPipeline | |
| <span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np | |
| ddim = DDIMPipeline.from_pretrained( <span class="hljs-string">"google/ddpm-cifar10-32"</span>, use_safetensors=<span class="hljs-literal">True</span>) | |
| image = ddim(num_inference_steps=<span class="hljs-number">2</span>, output_type=<span class="hljs-string">"np"</span>).images | |
| <span class="hljs-built_in">print</span>(np.<span class="hljs-built_in">abs</span>(image).<span class="hljs-built_in">sum</span>())<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1oqpaak">Running the code above prints one value, but if you run it again you get a different value.</p> <p data-svelte-h="svelte-ppvtm">Each time the pipeline is run, <a href="https://pytorch.org/docs/stable/generated/torch.randn.html" rel="nofollow">torch.randn</a> uses a different random seed to create the Gaussian noise tensors. This leads to a different result each time it is run and enables the diffusion pipeline to generate a different random image each time.</p> <p data-svelte-h="svelte-uamouh">But if you need to reliably generate the same image, that depends on whether you’re running the pipeline on a CPU or GPU.</p> <div class="course-tip bg-gradient-to-br dark:bg-gradient-to-r before:border-green-500 dark:before:border-green-800 from-green-50 dark:from-gray-900 to-white dark:to-gray-950 border border-green-50 text-green-700 dark:text-gray-400"><p data-svelte-h="svelte-1jpg0yb">It might seem unintuitive to pass <code>Generator</code> objects to a pipeline instead of the integer value representing the seed. However, this is the recommended design when working with probabilistic models in PyTorch because a <code>Generator</code> is a <em>random state</em> that can be passed to multiple pipelines in a sequence. As soon as the <code>Generator</code> is consumed, the <em>state</em> is changed in place which means even if you passed the same <code>Generator</code> to a different pipeline, it won’t produce the same result because the state is already changed.</p></div> <div class="flex space-x-2 items-center my-1.5 mr-8 h-7 !pl-0 -mx-3 md:mx-0"><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd border-gray-800 bg-black dark:bg-gray-700 text-white">CPU </div><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd text-gray-500 cursor-pointer opacity-90 hover:text-gray-700 dark:hover:text-gray-200 hover:shadow-sm">GPU </div></div> <div class="language-select"><p data-svelte-h="svelte-mi9bj0">To generate reproducible results on a CPU, you’ll need to use a PyTorch <a href="https://pytorch.org/docs/stable/generated/torch.Generator.html" rel="nofollow">Generator</a> and set a seed. Now when you run the code, it always prints a value of <code>1491.1711</code> because the <code>Generator</code> object with the seed is passed to all the random functions in the pipeline. You should get a similar, if not the same, result on whatever hardware and PyTorch version you’re using.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np | |
| <span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> DDIMPipeline | |
| ddim = DDIMPipeline.from_pretrained(<span class="hljs-string">"google/ddpm-cifar10-32"</span>, use_safetensors=<span class="hljs-literal">True</span>) | |
| generator = torch.Generator(device=<span class="hljs-string">"cpu"</span>).manual_seed(<span class="hljs-number">0</span>) | |
| image = ddim(num_inference_steps=<span class="hljs-number">2</span>, output_type=<span class="hljs-string">"np"</span>, generator=generator).images | |
| <span class="hljs-built_in">print</span>(np.<span class="hljs-built_in">abs</span>(image).<span class="hljs-built_in">sum</span>())<!-- HTML_TAG_END --></pre></div> </div> <h2 class="relative group"><a id="deterministic-algorithms" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#deterministic-algorithms"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Deterministic algorithms</span></h2> <p data-svelte-h="svelte-gypex5">You can also configure PyTorch to use deterministic algorithms to create a reproducible pipeline. The downside is that deterministic algorithms may be slower than non-deterministic ones and you may observe a decrease in performance.</p> <p data-svelte-h="svelte-dxdx5v">Non-deterministic behavior occurs when operations are launched in more than one CUDA stream. To avoid this, set the environment variable <a href="https://docs.nvidia.com/cuda/cublas/index.html#results-reproducibility" rel="nofollow">CUBLAS_WORKSPACE_CONFIG</a> to <code>:16:8</code> to only use one buffer size during runtime.</p> <p data-svelte-h="svelte-180x72j">PyTorch typically benchmarks multiple algorithms to select the fastest one, but if you want reproducibility, you should disable this feature because the benchmark may select different algorithms each time. Set Diffusers <a href="https://github.com/huggingface/diffusers/blob/142f353e1c638ff1d20bd798402b68f72c1ebbdd/src/diffusers/utils/testing_utils.py#L861" rel="nofollow">enable_full_determinism</a> to enable deterministic algorithms.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->enable_full_determinism()<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-b9yuf0">Now when you run the same pipeline twice, you’ll get identical results.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> DDIMScheduler, StableDiffusionPipeline | |
| pipe = StableDiffusionPipeline.from_pretrained(<span class="hljs-string">"stable-diffusion-v1-5/stable-diffusion-v1-5"</span>, use_safetensors=<span class="hljs-literal">True</span>).to(<span class="hljs-string">"cuda"</span>) | |
| pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config) | |
| g = torch.Generator(device=<span class="hljs-string">"cuda"</span>) | |
| prompt = <span class="hljs-string">"A bear is playing a guitar on Times Square"</span> | |
| g.manual_seed(<span class="hljs-number">0</span>) | |
| result1 = pipe(prompt=prompt, num_inference_steps=<span class="hljs-number">50</span>, generator=g, output_type=<span class="hljs-string">"latent"</span>).images | |
| g.manual_seed(<span class="hljs-number">0</span>) | |
| result2 = pipe(prompt=prompt, num_inference_steps=<span class="hljs-number">50</span>, generator=g, output_type=<span class="hljs-string">"latent"</span>).images | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"L_inf dist ="</span>, <span class="hljs-built_in">abs</span>(result1 - result2).<span class="hljs-built_in">max</span>()) | |
| <span class="hljs-string">"L_inf dist = tensor(0., device='cuda:0')"</span><!-- HTML_TAG_END --></pre></div> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/diffusers/blob/main/docs/source/en/using-diffusers/reusing_seeds.md" target="_blank"><span data-svelte-h="svelte-1kd6by1"><</span> <span data-svelte-h="svelte-x0xyl0">></span> <span data-svelte-h="svelte-1dajgef"><span class="underline ml-1.5">Update</span> on GitHub</span></a> <p></p> | |
| <script> | |
| { | |
| __sveltekit_u238jf = { | |
| assets: "/docs/diffusers/pr_11986/en", | |
| base: "/docs/diffusers/pr_11986/en", | |
| env: {} | |
| }; | |
| const element = document.currentScript.parentElement; | |
| const data = [null,null]; | |
| Promise.all([ | |
| import("/docs/diffusers/pr_11986/en/_app/immutable/entry/start.e4c568fa.js"), | |
| import("/docs/diffusers/pr_11986/en/_app/immutable/entry/app.29bdf47f.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 303], | |
| data, | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 20.3 kB
- Xet hash:
- 125456d7ade642306309d3393d1e545b2aaeb10a760f0bcc5d7292edac28c267
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.