mirror of
				https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
				synced 2025-11-04 12:03:36 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			71 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from __future__ import annotations
 | 
						|
import torch
 | 
						|
 | 
						|
 | 
						|
class Emphasis:
 | 
						|
    """Emphasis class decides how to death with (emphasized:1.1) text in prompts"""
 | 
						|
 | 
						|
    name: str = "Base"
 | 
						|
    description: str = ""
 | 
						|
 | 
						|
    tokens: list[list[int]]
 | 
						|
    """tokens from the chunk of the prompt"""
 | 
						|
 | 
						|
    multipliers: torch.Tensor
 | 
						|
    """tensor with multipliers, once for each token"""
 | 
						|
 | 
						|
    z: torch.Tensor
 | 
						|
    """output of cond transformers network (CLIP)"""
 | 
						|
 | 
						|
    def after_transformers(self):
 | 
						|
        """Called after cond transformers network has processed the chunk of the prompt; this function should modify self.z to apply the emphasis"""
 | 
						|
 | 
						|
        pass
 | 
						|
 | 
						|
 | 
						|
class EmphasisNone(Emphasis):
 | 
						|
    name = "None"
 | 
						|
    description = "disable the mechanism entirely and treat (:.1.1) as literal characters"
 | 
						|
 | 
						|
 | 
						|
class EmphasisIgnore(Emphasis):
 | 
						|
    name = "Ignore"
 | 
						|
    description = "treat all empasised words as if they have no emphasis"
 | 
						|
 | 
						|
 | 
						|
class EmphasisOriginal(Emphasis):
 | 
						|
    name = "Original"
 | 
						|
    description = "the original emphasis implementation"
 | 
						|
 | 
						|
    def after_transformers(self):
 | 
						|
        original_mean = self.z.mean()
 | 
						|
        self.z = self.z * self.multipliers.reshape(self.multipliers.shape + (1,)).expand(self.z.shape)
 | 
						|
 | 
						|
        # restoring original mean is likely not correct, but it seems to work well to prevent artifacts that happen otherwise
 | 
						|
        new_mean = self.z.mean()
 | 
						|
        self.z = self.z * (original_mean / new_mean)
 | 
						|
 | 
						|
 | 
						|
class EmphasisOriginalNoNorm(EmphasisOriginal):
 | 
						|
    name = "No norm"
 | 
						|
    description = "same as original, but without normalization (seems to work better for SDXL)"
 | 
						|
 | 
						|
    def after_transformers(self):
 | 
						|
        self.z = self.z * self.multipliers.reshape(self.multipliers.shape + (1,)).expand(self.z.shape)
 | 
						|
 | 
						|
 | 
						|
def get_current_option(emphasis_option_name):
 | 
						|
    return next(iter([x for x in options if x.name == emphasis_option_name]), EmphasisOriginal)
 | 
						|
 | 
						|
 | 
						|
def get_options_descriptions():
 | 
						|
    return ", ".join(f"{x.name}: {x.description}" for x in options)
 | 
						|
 | 
						|
 | 
						|
options = [
 | 
						|
    EmphasisNone,
 | 
						|
    EmphasisIgnore,
 | 
						|
    EmphasisOriginal,
 | 
						|
    EmphasisOriginalNoNorm,
 | 
						|
]
 |