InvokeAI
InvokeAI copied to clipboard
increase random number seed space
Increased NUMPY_RAND_MAX, utilized by the ui to enforce random number seed maximum to 2^53 - 1 (9007199254740991).
This number was chosen as it is the largest integer that Javascript can represent.
Reduce minimum value for CfgScale from 1.01 to 1.0001. There are perceptual differences between 1.01 and 1.001 for most pipeline renders. Added an additional order of magnitude for safety.
This is the crux of the seed fix:
Refactored all use of the pytorch_lightning seed_everything() function to utilize the sane and predictable torch.manual_seed function.
https://pytorch.org/docs/stable/generated/torch.manual_seed.html
manual_seed will provide up to 63-bits of seed selection space.
seed_everything() inherits its behavior from a numpy function that conflates its single parameter with two independent functions:
- setting the random number seed to the passed parameter
- resetting the random number seed to a unspecified, function selected number, ignoring the passed parameter. The latter behavior occurs for seed values equal to or greater than 2^32 (
4294967296).
Tested successfully via the invokeai UI with some values up to 9007199254740991. Tested successfully via the invokeai CLI with some values in the range 9007199254740992 ... 9223372036854775807.
invoke> may I use your towel my car just hit a water buffalo -s 30 -C 7.5 -S 9007199254740992
...
invoke> may I use your towel my car just hit a water buffalo -s 30 -C 7.5 -S 9223372036854775807
Was able to use seeds > 2^32 in invokeai which I had previously rendered via a vanilla StableDiffusionPipeline implementation. Was able to obtain perceptually identical results via invokeai. What I set out to do!
:D

Code reads fine to me. I'll let @lstein or @keturn have a look at the seeding changes on the backend.
If they're good with it, you'll need to build the frontend before we merge.
Thanks for the PR.
Reduce minimum value for CfgScale from 1.01 to 1.0001. There are perceptual differences between 1.01 and 1.001 for most pipeline renders. Added an additional order of magnitude for safety.
This is tangential to the topic of random seeds, but is there interest in allowing CFG=1, i.e. disabling the classifier-free guidance entirely? We could certainly do that (and disabling it would let it use only half the resources), but given the way the models are trained I don't know if people find that useful.
If this eliminates the platform-to-platform differences in random seed generation that we see, then that's very much for the good. On the other hand, what effect does this have on reproducibility of images when users provide a previously-used prompt and seed? If it breaks reproducibility then we need a mechanism to revert to the legacy random number generator via an environment variable or (preferably) a command-line switch.
Because of the reorganization of the source tree, there are now multiple conflicts with this PR. I understand where things have gone and am happy to try to resolve the conflicts. I think this is something we want to have ultimately, as long as there's a backward compatibility flag.
If it breaks reproducibility then we need a mechanism to revert to the legacy random number generator via an environment variable or (preferably) a command-line switch.
I believe these changes only improve reproducibility. It only changes the behavior for seeds > 4294967295. The previous behavior, if given by the command-line for example, when given a seed greater than 4294967295 was to select a new and different random seed than the seed specified. The behavior came from the use of the torch seed_everything function. I think it is redundant to add a switch to restore such behavior.
Still waiting for a response to requests for changes from damian and myself. I will close this PR soon if no further activity.
I responded to your change request above:
I believe these changes only improve reproducibility. It only changes the behavior for seeds > 4294967295. The previous behavior, if given by the command-line for example, when given a seed greater than 4294967295 was to select a new and different random seed than the seed specified. The behavior came from the use of the torch seed_everything function. I think it is redundant to add a switch to restore such behavior.
I can make keturn's suggested changes if you agree with my assessment above. Otherwise I will let you close the pull request.
Status?
4294967295 is a bit low as an upper limit right now.
This is all fine by me, but this needs to be implemented in main, using the new nodes backend.
FWIW JS can deal with large numbers safely and across all browsers using https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt. Does require being careful in all maths operations (though choosing the random seed is better done in the backend) and JSON representation. Unclear wether input type number supports bigint but it's easy enough to just use a text input.
Superseded by #3933. The app now uses numpy in a number of places and so the max seed value is uint32 max. In the future we'd be happy for a PR that refactors seeding to allow for higher values.
Given that this PR is against v2.3, and we are on v3.0 (a full rewrite), I'm closing this. Thanks for making the PR anyways @waffletower .