Spaces:
				
			
			
	
			
			
		Running
		
			on 
			
			Zero
	
	
	
			
			
	
	
	
	
		
		
		Running
		
			on 
			
			Zero
	Create live_preview_helpers.py
Browse files- live_preview_helpers.py +165 -0
    	
        live_preview_helpers.py
    ADDED
    
    | @@ -0,0 +1,165 @@ | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            import torch
         | 
| 2 | 
            +
            import numpy as np
         | 
| 3 | 
            +
            from diffusers import FluxPipeline, AutoencoderTiny, FlowMatchEulerDiscreteScheduler
         | 
| 4 | 
            +
            from typing import Any, Dict, List, Optional, Union
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # Helper functions
         | 
| 7 | 
            +
            def calculate_shift(
         | 
| 8 | 
            +
                image_seq_len,
         | 
| 9 | 
            +
                base_seq_len: int = 256,
         | 
| 10 | 
            +
                max_seq_len: int = 4096,
         | 
| 11 | 
            +
                base_shift: float = 0.5,
         | 
| 12 | 
            +
                max_shift: float = 1.16,
         | 
| 13 | 
            +
            ):
         | 
| 14 | 
            +
                m = (max_shift - base_shift) / (max_seq_len - base_seq_len)
         | 
| 15 | 
            +
                b = base_shift - m * base_seq_len
         | 
| 16 | 
            +
                mu = image_seq_len * m + b
         | 
| 17 | 
            +
                return mu
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            def retrieve_timesteps(
         | 
| 20 | 
            +
                scheduler,
         | 
| 21 | 
            +
                num_inference_steps: Optional[int] = None,
         | 
| 22 | 
            +
                device: Optional[Union[str, torch.device]] = None,
         | 
| 23 | 
            +
                timesteps: Optional[List[int]] = None,
         | 
| 24 | 
            +
                sigmas: Optional[List[float]] = None,
         | 
| 25 | 
            +
                **kwargs,
         | 
| 26 | 
            +
            ):
         | 
| 27 | 
            +
                if timesteps is not None and sigmas is not None:
         | 
| 28 | 
            +
                    raise ValueError("Only one of `timesteps` or `sigmas` can be passed. Please choose one to set custom values")
         | 
| 29 | 
            +
                if timesteps is not None:
         | 
| 30 | 
            +
                    scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs)
         | 
| 31 | 
            +
                    timesteps = scheduler.timesteps
         | 
| 32 | 
            +
                    num_inference_steps = len(timesteps)
         | 
| 33 | 
            +
                elif sigmas is not None:
         | 
| 34 | 
            +
                    scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs)
         | 
| 35 | 
            +
                    timesteps = scheduler.timesteps
         | 
| 36 | 
            +
                    num_inference_steps = len(timesteps)
         | 
| 37 | 
            +
                else:
         | 
| 38 | 
            +
                    scheduler.set_timesteps(num_inference_steps, device=device, **kwargs)
         | 
| 39 | 
            +
                    timesteps = scheduler.timesteps
         | 
| 40 | 
            +
                return timesteps, num_inference_steps
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            # FLUX pipeline function
         | 
| 43 | 
            +
            @torch.inference_mode()
         | 
| 44 | 
            +
            def flux_pipe_call_that_returns_an_iterable_of_images(
         | 
| 45 | 
            +
                self,
         | 
| 46 | 
            +
                prompt: Union[str, List[str]] = None,
         | 
| 47 | 
            +
                prompt_2: Optional[Union[str, List[str]]] = None,
         | 
| 48 | 
            +
                height: Optional[int] = None,
         | 
| 49 | 
            +
                width: Optional[int] = None,
         | 
| 50 | 
            +
                num_inference_steps: int = 28,
         | 
| 51 | 
            +
                timesteps: List[int] = None,
         | 
| 52 | 
            +
                guidance_scale: float = 3.5,
         | 
| 53 | 
            +
                num_images_per_prompt: Optional[int] = 1,
         | 
| 54 | 
            +
                generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
         | 
| 55 | 
            +
                latents: Optional[torch.FloatTensor] = None,
         | 
| 56 | 
            +
                prompt_embeds: Optional[torch.FloatTensor] = None,
         | 
| 57 | 
            +
                pooled_prompt_embeds: Optional[torch.FloatTensor] = None,
         | 
| 58 | 
            +
                output_type: Optional[str] = "pil",
         | 
| 59 | 
            +
                return_dict: bool = True,
         | 
| 60 | 
            +
                joint_attention_kwargs: Optional[Dict[str, Any]] = None,
         | 
| 61 | 
            +
                max_sequence_length: int = 512,
         | 
| 62 | 
            +
            ):
         | 
| 63 | 
            +
                height = height or self.default_sample_size * self.vae_scale_factor
         | 
| 64 | 
            +
                width = width or self.default_sample_size * self.vae_scale_factor
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                # 1. Check inputs
         | 
| 67 | 
            +
                self.check_inputs(
         | 
| 68 | 
            +
                    prompt,
         | 
| 69 | 
            +
                    prompt_2,
         | 
| 70 | 
            +
                    height,
         | 
| 71 | 
            +
                    width,
         | 
| 72 | 
            +
                    prompt_embeds=prompt_embeds,
         | 
| 73 | 
            +
                    pooled_prompt_embeds=pooled_prompt_embeds,
         | 
| 74 | 
            +
                    max_sequence_length=max_sequence_length,
         | 
| 75 | 
            +
                )
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                self._guidance_scale = guidance_scale
         | 
| 78 | 
            +
                self._joint_attention_kwargs = joint_attention_kwargs
         | 
| 79 | 
            +
                self._interrupt = False
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                # 2. Define call parameters
         | 
| 82 | 
            +
                batch_size = 1 if isinstance(prompt, str) else len(prompt)
         | 
| 83 | 
            +
                device = self._execution_device
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                # 3. Encode prompt
         | 
| 86 | 
            +
                lora_scale = joint_attention_kwargs.get("scale", None) if joint_attention_kwargs is not None else None
         | 
| 87 | 
            +
                prompt_embeds, pooled_prompt_embeds, text_ids = self.encode_prompt(
         | 
| 88 | 
            +
                    prompt=prompt,
         | 
| 89 | 
            +
                    prompt_2=prompt_2,
         | 
| 90 | 
            +
                    prompt_embeds=prompt_embeds,
         | 
| 91 | 
            +
                    pooled_prompt_embeds=pooled_prompt_embeds,
         | 
| 92 | 
            +
                    device=device,
         | 
| 93 | 
            +
                    num_images_per_prompt=num_images_per_prompt,
         | 
| 94 | 
            +
                    max_sequence_length=max_sequence_length,
         | 
| 95 | 
            +
                    lora_scale=lora_scale,
         | 
| 96 | 
            +
                )
         | 
| 97 | 
            +
                # 4. Prepare latent variables
         | 
| 98 | 
            +
                num_channels_latents = self.transformer.config.in_channels // 4
         | 
| 99 | 
            +
                latents, latent_image_ids = self.prepare_latents(
         | 
| 100 | 
            +
                    batch_size * num_images_per_prompt,
         | 
| 101 | 
            +
                    num_channels_latents,
         | 
| 102 | 
            +
                    height,
         | 
| 103 | 
            +
                    width,
         | 
| 104 | 
            +
                    prompt_embeds.dtype,
         | 
| 105 | 
            +
                    device,
         | 
| 106 | 
            +
                    generator,
         | 
| 107 | 
            +
                    latents,
         | 
| 108 | 
            +
                )
         | 
| 109 | 
            +
                # 5. Prepare timesteps
         | 
| 110 | 
            +
                sigmas = np.linspace(1.0, 1 / num_inference_steps, num_inference_steps)
         | 
| 111 | 
            +
                image_seq_len = latents.shape[1]
         | 
| 112 | 
            +
                mu = calculate_shift(
         | 
| 113 | 
            +
                    image_seq_len,
         | 
| 114 | 
            +
                    self.scheduler.config.base_image_seq_len,
         | 
| 115 | 
            +
                    self.scheduler.config.max_image_seq_len,
         | 
| 116 | 
            +
                    self.scheduler.config.base_shift,
         | 
| 117 | 
            +
                    self.scheduler.config.max_shift,
         | 
| 118 | 
            +
                )
         | 
| 119 | 
            +
                timesteps, num_inference_steps = retrieve_timesteps(
         | 
| 120 | 
            +
                    self.scheduler,
         | 
| 121 | 
            +
                    num_inference_steps,
         | 
| 122 | 
            +
                    device,
         | 
| 123 | 
            +
                    timesteps,
         | 
| 124 | 
            +
                    sigmas,
         | 
| 125 | 
            +
                    mu=mu,
         | 
| 126 | 
            +
                )
         | 
| 127 | 
            +
                self._num_timesteps = len(timesteps)
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                # Handle guidance
         | 
| 130 | 
            +
                guidance = torch.full([1], guidance_scale, device=device, dtype=torch.float32).expand(latents.shape[0]) if self.transformer.config.guidance_embeds else None
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                # 6. Denoising loop
         | 
| 133 | 
            +
                for i, t in enumerate(timesteps):
         | 
| 134 | 
            +
                    if self.interrupt:
         | 
| 135 | 
            +
                        continue
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                    timestep = t.expand(latents.shape[0]).to(latents.dtype)
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                    noise_pred = self.transformer(
         | 
| 140 | 
            +
                        hidden_states=latents,
         | 
| 141 | 
            +
                        timestep=timestep / 1000,
         | 
| 142 | 
            +
                        guidance=guidance,
         | 
| 143 | 
            +
                        pooled_projections=pooled_prompt_embeds,
         | 
| 144 | 
            +
                        encoder_hidden_states=prompt_embeds,
         | 
| 145 | 
            +
                        txt_ids=text_ids,
         | 
| 146 | 
            +
                        img_ids=latent_image_ids,
         | 
| 147 | 
            +
                        joint_attention_kwargs=self.joint_attention_kwargs,
         | 
| 148 | 
            +
                        return_dict=False,
         | 
| 149 | 
            +
                    )[0]
         | 
| 150 | 
            +
                    latents = self.scheduler.step(noise_pred, t, latents, return_dict=False)[0]
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                    # Yield intermediate result
         | 
| 153 | 
            +
                    latents_for_image = self._unpack_latents(latents, height, width, self.vae_scale_factor)
         | 
| 154 | 
            +
                    latents_for_image = (latents_for_image / self.vae.config.scaling_factor) + self.vae.config.shift_factor
         | 
| 155 | 
            +
                    image = self.vae.decode(latents_for_image, return_dict=False)[0]
         | 
| 156 | 
            +
                    yield self.image_processor.postprocess(image, output_type=output_type)[0]
         | 
| 157 | 
            +
                    torch.cuda.empty_cache()
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                # Final image
         | 
| 160 | 
            +
                latents = self._unpack_latents(latents, height, width, self.vae_scale_factor)
         | 
| 161 | 
            +
                latents = (latents / self.vae.config.scaling_factor) + self.vae.config.shift_factor
         | 
| 162 | 
            +
                image = self.vae.decode(latents, return_dict=False)[0]
         | 
| 163 | 
            +
                self.maybe_free_model_hooks()
         | 
| 164 | 
            +
                torch.cuda.empty_cache()
         | 
| 165 | 
            +
                return self.image_processor.postprocess(image, output_type=output_type)[0], 0    
         | 
 
			
