1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15- from enum import Enum
1615from typing import Any , Dict , List , Optional , Tuple , Union
1716
1817import torch
@@ -109,13 +108,50 @@ def forward(
109108 )
110109
111110
112- class GlmImageAttenProcessorState (Enum ):
113- ImageGen = "ImageGen"
114- ImageEditWriteKV = "ImageEditWriteKV"
115- ImageEditReadKV = "ImageEditReadKV"
116- ImageEditDontReadKV = "ImageEditNoReadKV"
111+ class GlmImageLayerKVCache :
112+ """KV cache for GlmImage model."""
113+ def __init__ (self ):
114+ self .k_cache = None
115+ self .v_cache = None
116+ self .mode : Optional [str ] = None # "write", "read", "skip"
117+
118+ def store (self , k : torch .Tensor , v : torch .Tensor ):
119+ if self .k_cache is None :
120+ self .k_cache = k
121+ self .v_cache = v
122+ else :
123+ self .k_cache = torch .cat ([self .k_cache , k ], dim = 2 )
124+ self .v_cache = torch .cat ([self .v_cache , v ], dim = 2 )
125+
126+ def get (self ):
127+ return self .k_cache , self .v_cache
128+
129+ def clear (self ):
130+ self .k_cache = None
131+ self .v_cache = None
132+ self .mode = None
117133
118134
135+ class GlmImageKVCache :
136+ """Container for all layers' KV caches."""
137+
138+ def __init__ (self , num_layers : int ):
139+ self .num_layers = num_layers
140+ self .caches = [GlmImageLayerKVCache () for _ in range (num_layers )]
141+
142+ def __getitem__ (self , layer_idx : int ) -> GlmImageLayerKVCache :
143+ return self .caches [layer_idx ]
144+
145+ def set_mode (self , mode : Optional [str ]):
146+ if mode is not None and mode not in ["write" , "read" , "skip" ]:
147+ raise ValueError (f"Invalid mode: { mode } , must be one of 'write', 'read', 'skip'" )
148+ for cache in self .caches :
149+ cache .mode = mode
150+
151+ def clear (self ):
152+ for cache in self .caches :
153+ cache .clear ()
154+
119155class GlmImageAttnProcessor :
120156 """
121157 Processor for implementing scaled dot-product attention for the GlmImage model. It applies a rotary embedding on
@@ -128,9 +164,6 @@ class GlmImageAttnProcessor:
128164 def __init__ (self ):
129165 if not hasattr (F , "scaled_dot_product_attention" ):
130166 raise ImportError ("GlmImageAttnProcessor requires PyTorch 2.0. To use it, please upgrade PyTorch to 2.0." )
131- self .processor_state = GlmImageAttenProcessorState .ImageGen
132- self .k_cache = None
133- self .v_cache = None
134167
135168 def __call__ (
136169 self ,
@@ -139,6 +172,7 @@ def __call__(
139172 encoder_hidden_states : torch .Tensor ,
140173 attention_mask : Optional [torch .Tensor ] = None ,
141174 image_rotary_emb : Optional [Tuple [torch .Tensor , torch .Tensor ]] = None ,
175+ kv_cache : Optional [GlmImageLayerKVCache ] = None ,
142176 ) -> Tuple [torch .Tensor , torch .Tensor ]:
143177 dtype = encoder_hidden_states .dtype
144178
@@ -172,12 +206,15 @@ def __call__(
172206 key [:, :, text_seq_length :, :], image_rotary_emb , use_real_unbind_dim = - 2
173207 )
174208
175- if self .processor_state == GlmImageAttenProcessorState .ImageEditWriteKV :
176- self .k_cache = key if self .k_cache is None else torch .cat ([self .k_cache , key ], dim = 2 )
177- self .v_cache = value if self .v_cache is None else torch .cat ([self .v_cache , value ], dim = 2 )
178- elif self .processor_state == GlmImageAttenProcessorState .ImageEditReadKV :
179- key = torch .cat ([self .k_cache , key ], dim = 2 ) if self .k_cache is not None else key
180- value = torch .cat ([self .v_cache , value ], dim = 2 ) if self .v_cache is not None else value
209+ if kv_cache is not None :
210+ if kv_cache .mode == "write" :
211+ kv_cache .store (key , value )
212+ elif kv_cache .mode == "read" :
213+ k_cache , v_cache = kv_cache .get ()
214+ key = torch .cat ([k_cache , key ], dim = 2 ) if k_cache is not None else key
215+ value = torch .cat ([v_cache , value ], dim = 2 ) if v_cache is not None else value
216+ elif kv_cache .mode == "skip" :
217+ pass
181218
182219 # 4. Attention
183220 if attention_mask is not None :
@@ -246,6 +283,7 @@ def forward(
246283 ] = None ,
247284 attention_mask : Optional [Dict [str , torch .Tensor ]] = None ,
248285 attention_kwargs : Optional [Dict [str , Any ]] = None ,
286+ kv_cache : Optional [GlmImageLayerKVCache ] = None ,
249287 ) -> Tuple [torch .Tensor , torch .Tensor ]:
250288 # 1. Timestep conditioning
251289 (
@@ -270,6 +308,7 @@ def forward(
270308 encoder_hidden_states = norm_encoder_hidden_states ,
271309 image_rotary_emb = image_rotary_emb ,
272310 attention_mask = attention_mask ,
311+ kv_cache = kv_cache ,
273312 ** attention_kwargs ,
274313 )
275314 hidden_states = hidden_states + attn_hidden_states * gate_msa .unsqueeze (1 )
@@ -464,6 +503,7 @@ def forward(
464503 attention_kwargs : Optional [Dict [str , Any ]] = None ,
465504 return_dict : bool = True ,
466505 attention_mask : Optional [torch .Tensor ] = None ,
506+ kv_caches : Optional [GlmImageKVCache ] = None ,
467507 image_rotary_emb : Optional [
468508 Union [Tuple [torch .Tensor , torch .Tensor ], List [Tuple [torch .Tensor , torch .Tensor ]]]
469509 ] = None ,
@@ -491,7 +531,7 @@ def forward(
491531 temb = F .silu (temb )
492532
493533 # 3. Transformer blocks
494- for block in self .transformer_blocks :
534+ for idx , block in enumerate ( self .transformer_blocks ) :
495535 if torch .is_grad_enabled () and self .gradient_checkpointing :
496536 hidden_states , encoder_hidden_states = self ._gradient_checkpointing_func (
497537 block ,
@@ -501,6 +541,7 @@ def forward(
501541 image_rotary_emb ,
502542 attention_mask ,
503543 attention_kwargs ,
544+ kv_caches [idx ] if kv_caches is not None else None ,
504545 )
505546 else :
506547 hidden_states , encoder_hidden_states = block (
@@ -510,6 +551,7 @@ def forward(
510551 image_rotary_emb ,
511552 attention_mask ,
512553 attention_kwargs ,
554+ kv_cache = kv_caches [idx ] if kv_caches is not None else None ,
513555 )
514556
515557 # 4. Output norm & projection
@@ -523,12 +565,3 @@ def forward(
523565 if not return_dict :
524566 return (output ,)
525567 return Transformer2DModelOutput (sample = output )
526-
527- def set_attention_processors_state (self , state : GlmImageAttenProcessorState ):
528- for block in self .transformer_blocks :
529- block .attn1 .processor .processor_state = state
530-
531- def clear_attention_processors_cache (self ):
532- for block in self .transformer_blocks :
533- block .attn1 .processor .k_cache = None
534- block .attn1 .processor .v_cache = None
0 commit comments