From e1a6d9781a042371c861bd7acd10962462537ddf Mon Sep 17 00:00:00 2001 From: David El Malih Date: Wed, 29 Jul 2026 23:44:14 +0200 Subject: [PATCH 1/2] Improve docstring scheduling - last batch --- .../scheduling_ltx_euler_ancestral_rf.py | 70 ++++++++-- src/diffusers/schedulers/scheduling_utils.py | 52 +++---- .../schedulers/scheduling_vq_diffusion.py | 130 ++++++++++++------ 3 files changed, 169 insertions(+), 83 deletions(-) diff --git a/src/diffusers/schedulers/scheduling_ltx_euler_ancestral_rf.py b/src/diffusers/schedulers/scheduling_ltx_euler_ancestral_rf.py index 453c8515c301..6b12c5ef96b2 100644 --- a/src/diffusers/schedulers/scheduling_ltx_euler_ancestral_rf.py +++ b/src/diffusers/schedulers/scheduling_ltx_euler_ancestral_rf.py @@ -81,30 +81,37 @@ def __init__( num_train_timesteps: int = 1000, eta: float = 1.0, s_noise: float = 1.0, - ): + ) -> None: # Note: num_train_timesteps is kept only for config compatibility. - self.num_inference_steps: int = None + self.num_inference_steps: int | None = None self.sigmas: torch.Tensor | None = None self.timesteps: torch.Tensor | None = None - self._step_index: int = None - self._begin_index: int = None + self._step_index: int | None = None + self._begin_index: int | None = None @property - def step_index(self) -> int: + def step_index(self) -> int | None: + """ + The index counter for the current timestep. It increases by one after each scheduler step. + """ return self._step_index @property - def begin_index(self) -> int: + def begin_index(self) -> int | None: """ The index for the first timestep. It can be set from a pipeline with `set_begin_index` to support image-to-image like workflows that start denoising part-way through the schedule. """ return self._begin_index - def set_begin_index(self, begin_index: int = 0): + def set_begin_index(self, begin_index: int = 0) -> None: """ Included for API compatibility; not strictly needed here but kept to allow pipelines that call `set_begin_index`. + + Args: + begin_index (`int`, defaults to `0`): + The index of the first timestep in the denoising schedule. """ self._begin_index = begin_index @@ -117,6 +124,16 @@ def index_for_timestep( This follows the convention used in other discrete schedulers: if the same timestep value appears multiple times in the schedule (which can happen when starting in the middle of the schedule), the *second* occurrence is used for the first `step` call so that no sigma is accidentally skipped. + + Args: + timestep (`float` or `torch.Tensor`): + The timestep value to find in the schedule. + schedule_timesteps (`torch.Tensor`, *optional*): + The timestep schedule to search. If `None`, `self.timesteps` is used. + + Returns: + `int`: + The index of the timestep in the schedule. """ if schedule_timesteps is None: if self.timesteps is None: @@ -141,9 +158,13 @@ def index_for_timestep( return indices[pos].item() - def _init_step_index(self, timestep: float | torch.Tensor): + def _init_step_index(self, timestep: float | torch.Tensor) -> None: """ Initialize the internal step index based on a given timestep. + + Args: + timestep (`float` or `torch.Tensor`): + The current timestep used to initialize the step index. """ if self.timesteps is None: raise ValueError("Timesteps have not been set. Call `set_timesteps` first.") @@ -162,8 +183,8 @@ def set_timesteps( sigmas: list[float] | torch.Tensor | None = None, timesteps: list[float] | torch.Tensor | None = None, mu: float | None = None, - **kwargs, - ): + **kwargs: object, + ) -> None: """ Set the sigma / timestep schedule for sampling. @@ -186,6 +207,8 @@ def set_timesteps( mu (`float`, *optional*): Optional shift parameter used when delegating to [`FlowMatchEulerDiscreteScheduler.set_timesteps`] and `config.use_dynamic_shifting` is `True`. + kwargs (`object`): + Additional keyword arguments accepted for API compatibility. """ # 1. Auto-generate schedule (FlowMatch-style) when no explicit sigmas/timesteps are given if sigmas is None and timesteps is None: @@ -269,6 +292,16 @@ def set_timesteps( def _sigma_broadcast(self, sigma: torch.Tensor, sample: torch.Tensor) -> torch.Tensor: """ Helper to broadcast a scalar sigma to the shape of `sample`. + + Args: + sigma (`torch.Tensor`): + The scalar sigma tensor to broadcast. + sample (`torch.Tensor`): + The sample tensor whose number of dimensions determines the broadcast shape. + + Returns: + `torch.Tensor`: + The sigma tensor reshaped for broadcasting with `sample`. """ while sigma.ndim < sample.ndim: sigma = sigma.view(*sigma.shape, 1) @@ -295,9 +328,15 @@ def step( Current latent sample `x_t`. generator (`torch.Generator`, *optional*): Optional generator for reproducible noise. - return_dict (`bool`): + return_dict (`bool`, defaults to `True`): If `True`, return a `LTXEulerAncestralRFSchedulerOutput`; otherwise return a tuple where the first element is the updated sample. + + Returns: + [`~schedulers.scheduling_ltx_euler_ancestral_rf.LTXEulerAncestralRFSchedulerOutput`] or `tuple`: + If `return_dict` is `True`, + [`~schedulers.scheduling_ltx_euler_ancestral_rf.LTXEulerAncestralRFSchedulerOutput`] is returned. + Otherwise, a tuple is returned where the first element is the updated sample. """ if isinstance(timestep, (int, torch.IntTensor, torch.LongTensor)): @@ -380,6 +419,11 @@ def step( return LTXEulerAncestralRFSchedulerOutput(prev_sample=prev_sample) def __len__(self) -> int: - # For compatibility with other schedulers; used e.g. in some training - # utilities to infer the maximum number of training timesteps. + """ + Return the number of training timesteps for compatibility with scheduler utilities. + + Returns: + `int`: + The configured number of training timesteps. + """ return int(getattr(self.config, "num_train_timesteps", 1000)) diff --git a/src/diffusers/schedulers/scheduling_utils.py b/src/diffusers/schedulers/scheduling_utils.py index 417ecf26a704..d50c7e54dff3 100644 --- a/src/diffusers/schedulers/scheduling_utils.py +++ b/src/diffusers/schedulers/scheduling_utils.py @@ -15,6 +15,7 @@ import os from dataclasses import dataclass from enum import Enum +from typing import Any import torch from huggingface_hub.utils import validate_hf_hub_args @@ -31,6 +32,10 @@ # When it's used as a type in pipelines, it really is a Union because the actual # scheduler instance is passed in. class KarrasDiffusionSchedulers(Enum): + """ + Enumeration of schedulers compatible with Karras diffusion pipelines. + """ + DDIMScheduler = 1 DDPMScheduler = 2 PNDMScheduler = 3 @@ -97,13 +102,13 @@ def from_pretrained( cls, pretrained_model_name_or_path: str | os.PathLike | None = None, subfolder: str | None = None, - return_unused_kwargs=False, - **kwargs, - ) -> Self: + return_unused_kwargs: bool = False, + **kwargs: Any, + ) -> Self | tuple[Self, dict[str, Any]]: r""" Instantiate a scheduler from a pre-defined JSON configuration file in a local directory or Hub repository. - Parameters: + Args: pretrained_model_name_or_path (`str` or `os.PathLike`, *optional*): Can be either: @@ -115,27 +120,13 @@ def from_pretrained( The subfolder location of a model file within a larger model repository on the Hub or locally. return_unused_kwargs (`bool`, *optional*, defaults to `False`): Whether kwargs that are not consumed by the Python class should be returned or not. - cache_dir (`str | os.PathLike`, *optional*): - Path to a directory where a downloaded pretrained model configuration is cached if the standard cache - is not used. - force_download (`bool`, *optional*, defaults to `False`): - Whether or not to force the (re-)download of the model weights and configuration files, overriding the - cached versions if they exist. - - proxies (`dict[str, str]`, *optional*): - A dictionary of proxy servers to use by protocol or endpoint, for example, `{'http': 'foo.bar:3128', - 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. - output_loading_info(`bool`, *optional*, defaults to `False`): - Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages. - local_files_only(`bool`, *optional*, defaults to `False`): - Whether to only load local model weights and configuration files or not. If set to `True`, the model - won't be downloaded from the Hub. - token (`str` or *bool*, *optional*): - The token to use as HTTP bearer authorization for remote files. If `True`, the token generated from - `diffusers-cli login` (stored in `~/.huggingface`) is used. - revision (`str`, *optional*, defaults to `"main"`): - The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier - allowed by Git. + kwargs (`dict[str, Any]`, *optional*): + Additional keyword arguments passed to [`~ConfigMixin.load_config`] and [`~ConfigMixin.from_config`]. + + Returns: + [`~schedulers.scheduling_utils.SchedulerMixin`] or `tuple[SchedulerMixin, dict[str, Any]]`: + The scheduler instantiated from the configuration. If `return_unused_kwargs` is `True`, a tuple is + returned where the second element is a dictionary of unused keyword arguments. > [!TIP] > To use private or [gated models](https://huggingface.co/docs/hub/models-gated#gated-models), log-in with `hf > auth login`. You can also activate the special > @@ -152,7 +143,7 @@ def from_pretrained( ) return cls.from_config(config, return_unused_kwargs=return_unused_kwargs, **kwargs) - def save_pretrained(self, save_directory: str | os.PathLike, push_to_hub: bool = False, **kwargs): + def save_pretrained(self, save_directory: str | os.PathLike, push_to_hub: bool = False, **kwargs: Any) -> None: """ Save a scheduler configuration object to a directory so that it can be reloaded using the [`~SchedulerMixin.from_pretrained`] class method. @@ -170,17 +161,18 @@ def save_pretrained(self, save_directory: str | os.PathLike, push_to_hub: bool = self.save_config(save_directory=save_directory, push_to_hub=push_to_hub, **kwargs) @property - def compatibles(self): + def compatibles(self) -> list[type[Self]]: """ - Returns all schedulers that are compatible with this scheduler + Return all scheduler classes that are compatible with this scheduler. Returns: - `list[SchedulerMixin]`: list of compatible schedulers + `list[type[SchedulerMixin]]`: + A list of compatible scheduler classes. """ return self._get_compatibles() @classmethod - def _get_compatibles(cls): + def _get_compatibles(cls) -> list[type[Self]]: compatible_classes_str = list(set([cls.__name__] + cls._compatibles)) diffusers_library = importlib.import_module(__name__.split(".")[0]) compatible_classes = [ diff --git a/src/diffusers/schedulers/scheduling_vq_diffusion.py b/src/diffusers/schedulers/scheduling_vq_diffusion.py index 7ba3a8e6f5c4..bb3f0fc6f697 100644 --- a/src/diffusers/schedulers/scheduling_vq_diffusion.py +++ b/src/diffusers/schedulers/scheduling_vq_diffusion.py @@ -30,7 +30,7 @@ class VQDiffusionSchedulerOutput(BaseOutput): Args: prev_sample (`torch.LongTensor` of shape `(batch size, num latent pixels)`): - Computed sample x_{t-1} of previous timestep. `prev_sample` should be used as next model input in the + The computed sample at the previous timestep. `prev_sample` should be used as the next model input in the denoising loop. """ @@ -39,18 +39,17 @@ class VQDiffusionSchedulerOutput(BaseOutput): def index_to_log_onehot(x: torch.LongTensor, num_classes: int) -> torch.Tensor: """ - Convert batch of vector of class indices into batch of log onehot vectors + Convert a batch of class index vectors into a batch of log one-hot vectors. Args: x (`torch.LongTensor` of shape `(batch size, vector length)`): - Batch of class indices - + The batch of class indices. num_classes (`int`): - number of classes to be used for the onehot vectors + The number of classes used for the one-hot vectors. Returns: `torch.Tensor` of shape `(batch size, num classes, vector length)`: - Log onehot vectors + The log one-hot vectors. """ x_onehot = F.one_hot(x, num_classes) x_onehot = x_onehot.permute(0, 2, 1) @@ -60,7 +59,17 @@ def index_to_log_onehot(x: torch.LongTensor, num_classes: int) -> torch.Tensor: def gumbel_noised(logits: torch.Tensor, generator: torch.Generator | None) -> torch.Tensor: """ - Apply gumbel noise to `logits` + Apply Gumbel noise to the input logits. + + Args: + logits (`torch.Tensor`): + The logits to which Gumbel noise is added. + generator (`torch.Generator` or `None`): + A random number generator for reproducible noise generation, or `None` to use the default generator. + + Returns: + `torch.Tensor`: + The logits with Gumbel noise added. """ uniform = torch.rand(logits.shape, device=logits.device, generator=generator) gumbel_noise = -torch.log(-torch.log(uniform + 1e-30) + 1e-30) @@ -68,11 +77,25 @@ def gumbel_noised(logits: torch.Tensor, generator: torch.Generator | None) -> to return noised -def alpha_schedules(num_diffusion_timesteps: int, alpha_cum_start=0.99999, alpha_cum_end=0.000009): +def alpha_schedules( + num_diffusion_timesteps: int, alpha_cum_start: float = 0.99999, alpha_cum_end: float = 0.000009 +) -> tuple[np.ndarray, np.ndarray]: """ - Cumulative and non-cumulative alpha schedules. + Create cumulative and non-cumulative alpha schedules for the diffusion process. + + The schedules follow the formulation in section 4.1 of the VQ-Diffusion paper. - See section 4.1. + Args: + num_diffusion_timesteps (`int`): + The number of diffusion timesteps. + alpha_cum_start (`float`, defaults to `0.99999`): + The starting cumulative alpha value. + alpha_cum_end (`float`, defaults to `0.000009`): + The ending cumulative alpha value. + + Returns: + `tuple[np.ndarray, np.ndarray]`: + A tuple containing the non-cumulative and cumulative alpha schedules, respectively. """ att = ( np.arange(0, num_diffusion_timesteps) / (num_diffusion_timesteps - 1) * (alpha_cum_end - alpha_cum_start) @@ -84,11 +107,25 @@ def alpha_schedules(num_diffusion_timesteps: int, alpha_cum_start=0.99999, alpha return at, att -def gamma_schedules(num_diffusion_timesteps: int, gamma_cum_start=0.000009, gamma_cum_end=0.99999): +def gamma_schedules( + num_diffusion_timesteps: int, gamma_cum_start: float = 0.000009, gamma_cum_end: float = 0.99999 +) -> tuple[np.ndarray, np.ndarray]: """ - Cumulative and non-cumulative gamma schedules. + Create cumulative and non-cumulative gamma schedules for the diffusion process. + + The schedules follow the formulation in section 4.1 of the VQ-Diffusion paper. + + Args: + num_diffusion_timesteps (`int`): + The number of diffusion timesteps. + gamma_cum_start (`float`, defaults to `0.000009`): + The starting cumulative gamma value. + gamma_cum_end (`float`, defaults to `0.99999`): + The ending cumulative gamma value. - See section 4.1. + Returns: + `tuple[np.ndarray, np.ndarray]`: + A tuple containing the non-cumulative and cumulative gamma schedules, respectively. """ ctt = ( np.arange(0, num_diffusion_timesteps) / (num_diffusion_timesteps - 1) * (gamma_cum_end - gamma_cum_start) @@ -113,15 +150,15 @@ class VQDiffusionScheduler(SchedulerMixin, ConfigMixin): num_vec_classes (`int`): The number of classes of the vector embeddings of the latent pixels. Includes the class for the masked latent pixel. - num_train_timesteps (`int`, defaults to 100): + num_train_timesteps (`int`, defaults to `100`): The number of diffusion steps to train the model. - alpha_cum_start (`float`, defaults to 0.99999): + alpha_cum_start (`float`, defaults to `0.99999`): The starting cumulative alpha value. - alpha_cum_end (`float`, defaults to 0.00009): + alpha_cum_end (`float`, defaults to `0.000009`): The ending cumulative alpha value. - gamma_cum_start (`float`, defaults to 0.00009): + gamma_cum_start (`float`, defaults to `0.000009`): The starting cumulative gamma value. - gamma_cum_end (`float`, defaults to 0.99999): + gamma_cum_end (`float`, defaults to `0.99999`): The ending cumulative gamma value. """ @@ -136,7 +173,7 @@ def __init__( alpha_cum_end: float = 0.000009, gamma_cum_start: float = 0.000009, gamma_cum_end: float = 0.99999, - ): + ) -> None: self.num_embed = num_vec_classes # By convention, the index for the mask class is the last class index @@ -174,7 +211,7 @@ def __init__( self.num_inference_steps = None self.timesteps = torch.from_numpy(np.arange(0, num_train_timesteps)[::-1].copy()) - def set_timesteps(self, num_inference_steps: int, device: str | torch.device = None): + def set_timesteps(self, num_inference_steps: int, device: str | torch.device | None = None) -> None: """ Sets the discrete timesteps used for the diffusion chain (to be run before inference). @@ -199,31 +236,31 @@ def set_timesteps(self, num_inference_steps: int, device: str | torch.device = N def step( self, model_output: torch.Tensor, - timestep: torch.long, + timestep: int | torch.Tensor, sample: torch.LongTensor, generator: torch.Generator | None = None, return_dict: bool = True, - ) -> VQDiffusionSchedulerOutput | tuple: + ) -> VQDiffusionSchedulerOutput | tuple[torch.LongTensor]: """ Predict the sample from the previous timestep by the reverse transition distribution. See - [`~VQDiffusionScheduler.q_posterior`] for more details about how the distribution is computer. + [`~VQDiffusionScheduler.q_posterior`] for more details about how the distribution is computed. Args: - log_p_x_0: (`torch.Tensor` of shape `(batch size, num classes - 1, num latent pixels)`): + model_output (`torch.Tensor` of shape `(batch size, num classes - 1, num latent pixels)`): The log probabilities for the predicted classes of the initial latent pixels. Does not include a prediction for the masked class as the initial unnoised image cannot be masked. - t (`torch.long`): + timestep (`int` or `torch.Tensor`): The timestep that determines which transition matrices are used. - x_t (`torch.LongTensor` of shape `(batch size, num latent pixels)`): - The classes of each latent pixel at time `t`. - generator (`torch.Generator`, or `None`): + sample (`torch.LongTensor` of shape `(batch size, num latent pixels)`): + The classes of each latent pixel at the current timestep. + generator (`torch.Generator`, *optional*): A random number generator for the noise applied to `p(x_{t-1} | x_t)` before it is sampled from. - return_dict (`bool`, *optional*, defaults to `True`): + return_dict (`bool`, defaults to `True`): Whether or not to return a [`~schedulers.scheduling_vq_diffusion.VQDiffusionSchedulerOutput`] or `tuple`. Returns: - [`~schedulers.scheduling_vq_diffusion.VQDiffusionSchedulerOutput`] or `tuple`: + [`~schedulers.scheduling_vq_diffusion.VQDiffusionSchedulerOutput`] or `tuple[torch.LongTensor]`: If return_dict is `True`, [`~schedulers.scheduling_vq_diffusion.VQDiffusionSchedulerOutput`] is returned, otherwise a tuple is returned where the first element is the sample tensor. """ @@ -241,7 +278,7 @@ def step( return VQDiffusionSchedulerOutput(prev_sample=x_t_min_1) - def q_posterior(self, log_p_x_0, x_t, t): + def q_posterior(self, log_p_x_0: torch.Tensor, x_t: torch.LongTensor, t: int | torch.Tensor) -> torch.Tensor: """ Calculates the log probabilities for the predicted classes of the image at timestep `t-1`: @@ -255,7 +292,7 @@ def q_posterior(self, log_p_x_0, x_t, t): prediction for the masked class as the initial unnoised image cannot be masked. x_t (`torch.LongTensor` of shape `(batch size, num latent pixels)`): The classes of each latent pixel at time `t`. - t (`torch.Long`): + t (`int` or `torch.Tensor`): The timestep that determines which transition matrix is used. Returns: @@ -353,14 +390,14 @@ def q_posterior(self, log_p_x_0, x_t, t): return log_p_x_t_min_1 def log_Q_t_transitioning_to_known_class( - self, *, t: torch.int, x_t: torch.LongTensor, log_onehot_x_t: torch.Tensor, cumulative: bool - ): + self, *, t: int | torch.Tensor, x_t: torch.LongTensor, log_onehot_x_t: torch.Tensor, cumulative: bool + ) -> torch.Tensor: """ Calculates the log probabilities of the rows from the (cumulative or non-cumulative) transition matrix for each latent pixel in `x_t`. Args: - t (`torch.Long`): + t (`int` or `torch.Tensor`): The timestep that determines which transition matrix is used. x_t (`torch.LongTensor` of shape `(batch size, num latent pixels)`): The classes of each latent pixel at time `t`. @@ -371,12 +408,12 @@ def log_Q_t_transitioning_to_known_class( `True`, the cumulative transition matrix `0`->`t` is used. Returns: - `torch.Tensor` of shape `(batch size, num classes - 1, num latent pixels)`: + `torch.Tensor`: Each _column_ of the returned matrix is a _row_ of log probabilities of the complete probability - transition matrix. + transition matrix. The tensor has shape `(batch size, num classes - 1, num latent pixels)` when + `cumulative` is `True` and shape `(batch size, num classes, num latent pixels)` otherwise. - When non cumulative, returns `self.num_classes - 1` rows because the initial latent pixel cannot be - masked. + When cumulative, the tensor has one fewer row because the initial latent pixel cannot be masked. Where: - `q_n` is the probability distribution for the forward process of the `n`th latent pixel. @@ -451,7 +488,20 @@ def log_Q_t_transitioning_to_known_class( return log_Q_t - def apply_cumulative_transitions(self, q, t): + def apply_cumulative_transitions(self, q: torch.Tensor, t: int | torch.Tensor) -> torch.Tensor: + """ + Apply the cumulative transition matrix at a timestep to log probabilities over non-mask classes. + + Args: + q (`torch.Tensor` of shape `(batch size, num classes - 1, num latent pixels)`): + The log probabilities over the non-mask latent pixel classes. + t (`int` or `torch.Tensor`): + The timestep that determines which cumulative transition matrix is used. + + Returns: + `torch.Tensor` of shape `(batch size, num classes, num latent pixels)`: + The transitioned log probabilities with the mask class probabilities appended. + """ bsz = q.shape[0] a = self.log_cumprod_at[t] b = self.log_cumprod_bt[t] From b5bf054d8b01c722c0e0ae89a50d5b25e8111642 Mon Sep 17 00:00:00 2001 From: David El Malih Date: Thu, 30 Jul 2026 09:48:45 +0200 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20am=C3=A9liorer=20la=20documentation?= =?UTF-8?q?=20des=20arguments=20de=20SchedulerMixin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/diffusers/schedulers/scheduling_utils.py | 22 ++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/diffusers/schedulers/scheduling_utils.py b/src/diffusers/schedulers/scheduling_utils.py index d50c7e54dff3..8cdb21c2f011 100644 --- a/src/diffusers/schedulers/scheduling_utils.py +++ b/src/diffusers/schedulers/scheduling_utils.py @@ -120,8 +120,26 @@ def from_pretrained( The subfolder location of a model file within a larger model repository on the Hub or locally. return_unused_kwargs (`bool`, *optional*, defaults to `False`): Whether kwargs that are not consumed by the Python class should be returned or not. - kwargs (`dict[str, Any]`, *optional*): - Additional keyword arguments passed to [`~ConfigMixin.load_config`] and [`~ConfigMixin.from_config`]. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory where a downloaded pretrained model configuration is cached if the standard cache + is not used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force the (re-)download of the model weights and configuration files, overriding the + cached versions if they exist. + proxies (`dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, for example, `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. + output_loading_info (`bool`, *optional*, defaults to `False`): + Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages. + local_files_only (`bool`, *optional*, defaults to `False`): + Whether to only load local model weights and configuration files or not. If set to `True`, the model + won't be downloaded from the Hub. + token (`str` or `bool`, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, the token generated from + `diffusers-cli login` (stored in `~/.huggingface`) is used. + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier + allowed by Git. Returns: [`~schedulers.scheduling_utils.SchedulerMixin`] or `tuple[SchedulerMixin, dict[str, Any]]`: