Skip to content

Conversation

@patrickvonplaten
Copy link
Contributor

@patrickvonplaten patrickvonplaten commented Jan 3, 2023

This PR adds a new helper function torch_randn that has three purposes:

  • Allow fully deterministic generation by creating the tensors on CPU as also demanded here: Use consistent random number generation across hardware #1514
  • Avoids lots of duplicated code, as the same 5,6 lines are implemented in 10,20+ pipeline files.
  • Helps us to better tests models by always creating tensors on CPU

This is the first PR of a two PR series to see if this helps to make UnCLIP deterministic across different CUDA, GPUs. In a follow-up PR, I'd then like to replace all existing torch.randn functions with this function as well as add a reproducibility.md guide.

@HuggingFaceDocBuilderDev
Copy link

HuggingFaceDocBuilderDev commented Jan 3, 2023

The documentation is not available anymore as the PR was closed or merged.

Comment on lines 566 to 568


# <original>.time_embed -> <diffusers>.time_embedding
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New black? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, updated my black and then re-updated back to 22.8. We should maybe soon blackify the complete codebase once :-)

Copy link
Member

@pcuenca pcuenca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't tested it yet but it looks great!

My only small concern is about the name, wrote a comment below.

latents = torch.randn(shape, generator=generator, device="cpu", dtype=dtype).to(device)
else:
latents = torch.randn(shape, generator=generator, device=device, dtype=dtype)
latents = torch_randn(shape, generator=generator, device=device, dtype=dtype)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice

Comment on lines +57 to +60
latents = [
torch.randn(shape, generator=generator[i], device=rand_device, dtype=dtype) for i in range(batch_size)
]
latents = torch.cat(latents, dim=0).to(device)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool to include per-item reproducibility too

logger = logging.get_logger(__name__) # pylint: disable=invalid-name


def torch_randn(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern here is that torch_randn is easy to confuse (both visually and inadvertently while typing) with torch.randn. Would it make sense to make the name slightly more different? Can't think of anything great though, diffusers_randn feels kind of ugly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just randn_tensor?

f" Tensors will be created on 'cpu' and then moved to {device}. Note that one can probably"
f" slighly speed up this function by passing a generator that was created on the {device} device."
)
elif generator.device.type != device.type and generator.device.type == "cuda":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a comment here that we only allow cpu->cuda generation for reproducibility reasons, which is why the other way around is not supported / doesn't make sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll make a whole doc page about this in the follow-up PR :-)

@patrickvonplaten patrickvonplaten merged commit 8ed08e4 into main Jan 3, 2023
@patrickvonplaten patrickvonplaten deleted the add_torch_randn branch January 3, 2023 17:26
@patrickvonplaten patrickvonplaten changed the title [Deterministic torch randn] Allow tensors to be generated on CPU [Reproduceability 1/3] Allow tensors to be generated on CPU Jan 5, 2023
yoonseokjin pushed a commit to yoonseokjin/diffusers that referenced this pull request Dec 25, 2023
…gingface#1902)

* [Deterministic torch randn] Allow tensors to be generated on CPU

* fix more

* up

* fix more

* up

* Update src/diffusers/utils/torch_utils.py

Co-authored-by: Anton Lozhkov <[email protected]>

* Apply suggestions from code review

* up

* up

* Apply suggestions from code review

Co-authored-by: Pedro Cuenca <[email protected]>

Co-authored-by: Anton Lozhkov <[email protected]>
Co-authored-by: Pedro Cuenca <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants