Repository: huggingface/diffusers
Issue category: Feature Request

Issue:
Allow configuring `shift=` for SD3 dynamically
**Is your feature request related to a problem? Please describe.**
Allow passing `shift=` per inference call (like timesteps) on the pipeline, for flow matching scheduler, or allow `set_shift()` etc. on the scheduler. This seems to be the key to getting good results with SD3 https://x.com/bfitzgerald242/status/1801018438120341911


Hints:
Hi, you can do it like this:

```python
from diffusers import  FlowMatchEulerDiscreteScheduler

pipe.scheduler = FlowMatchEulerDiscreteScheduler.from_config(pipe.scheduler.config, shift=3.0)
```
yep! but the same format is applicable for timesteps and was wondering if we can get around without re-instating the scheduler again and again?
Not for the moment, but I can see the potential in adding it as an argument if people change it a lot for each inference. 

In my experience it didn't fix the anatomy problems and sometimes it made the quality worse but I tested it with the T5, still need to test it without it and do some more generations.

Can you share some examples where changing the shift helped with the generation? That would help a lot.
This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the [contributing guidelines](https://github.com/huggingface/diffusers/blob/main/CONTRIBUTING.md) are likely to be ignored.
This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the [contributing guidelines](https://github.com/huggingface/diffusers/blob/main/CONTRIBUTING.md) are likely to be ignored.
Useful to have, changing `shift` is popular with HunyuanVideo and SD3/Flux.
does it really help though? examples requested never were shared.
Documented benefit for HunyuanVideo.

https://github.com/huggingface/diffusers/blob/1524781b88ac1a082e755a030ba9d73cd6948e84/docs/source/en/api/pipelines/hunyuan_video.md?plain=1#L32

I'll run some tests for SD3/Flux to confirm.
but SD3 already has resolution-dependent shift using the `mu` calculations, right?
Actually this won't do anything for Flux because of dynamic shifting. We recently added support for dynamic shifting in SD3, it's not used by default though. Either way, it's a simple change that has at least some benefit to HunyuanVideo and it won't do any harm to add a function to change `shift` without creating the scheduler each time for those that want it.
well not to be argumentative but the schedulers are stateful, yes?  doesn't this mean recreating it has to be done anyway? 

Patch:
diff --git a/src/diffusers/schedulers/scheduling_flow_match_euler_discrete.py b/src/diffusers/schedulers/scheduling_flow_match_euler_discrete.py
index 6ddd9ac23009..c7474d56c708 100644
--- a/src/diffusers/schedulers/scheduling_flow_match_euler_discrete.py
+++ b/src/diffusers/schedulers/scheduling_flow_match_euler_discrete.py
@@ -99,10 +99,19 @@ def __init__(
         self._step_index = None
         self._begin_index = None
 
+        self._shift = shift
+
         self.sigmas = sigmas.to("cpu")  # to avoid too much CPU/GPU communication
         self.sigma_min = self.sigmas[-1].item()
         self.sigma_max = self.sigmas[0].item()
 
+    @property
+    def shift(self):
+        """
+        The value used for shifting.
+        """
+        return self._shift
+
     @property
     def step_index(self):
         """
@@ -128,6 +137,9 @@ def set_begin_index(self, begin_index: int = 0):
         """
         self._begin_index = begin_index
 
+    def set_shift(self, shift: float):
+        self._shift = shift
+
     def scale_noise(
         self,
         sample: torch.FloatTensor,
@@ -236,7 +248,7 @@ def set_timesteps(
         if self.config.use_dynamic_shifting:
             sigmas = self.time_shift(mu, 1.0, sigmas)
         else:
-            sigmas = self.config.shift * sigmas / (1 + (self.config.shift - 1) * sigmas)
+            sigmas = self.shift * sigmas / (1 + (self.shift - 1) * sigmas)
 
         if self.config.shift_terminal:
             sigmas = self.stretch_shift_to_terminal(sigmas)


Test patch: