@@ -19,6 +19,7 @@ use crate::pipeline::text_models_inputs_processor::PagedAttentionInputMetadata;
1919use crate :: pipeline:: EitherCache ;
2020use crate :: pipeline:: KvCache ;
2121use crate :: pipeline:: NormalCache ;
22+ use crate :: pipeline:: NormalCacheType ;
2223use crate :: utils:: gguf_metadata:: ContentMetadata ;
2324use crate :: utils:: model_config as ModelConfig ;
2425use crate :: utils:: progress:: { new_multi_progress, NiceProgressBar } ;
@@ -351,6 +352,30 @@ fn gemma3_use_sliding_window(
351352 !( layer_idx + 1 ) . is_multiple_of ( sliding_window_pattern_interval)
352353}
353354
355+ fn gemma3_cache_types (
356+ block_count : usize ,
357+ max_seq_len : usize ,
358+ sliding_window : usize ,
359+ sliding_window_pattern : & [ bool ] ,
360+ sliding_window_pattern_interval : usize ,
361+ ) -> Vec < NormalCacheType > {
362+ ( 0 ..block_count)
363+ . map ( |layer_idx| {
364+ if gemma3_use_sliding_window (
365+ layer_idx,
366+ sliding_window_pattern,
367+ sliding_window_pattern_interval,
368+ ) {
369+ NormalCacheType :: SlidingWindow {
370+ window : sliding_window,
371+ }
372+ } else {
373+ NormalCacheType :: Normal { max_seq_len }
374+ }
375+ } )
376+ . collect ( )
377+ }
378+
354379fn ensure_gemma3_causal_mode ( causal : bool ) -> Result < ( ) > {
355380 if !causal {
356381 candle_core:: bail!(
@@ -634,6 +659,13 @@ impl ModelConfig::FromGGUF for ModelWeights {
634659 dtype,
635660 } )
636661 }
662+ let cache_types = gemma3_cache_types (
663+ block_count,
664+ max_seq_len,
665+ sliding_window,
666+ & sliding_window_pattern,
667+ sliding_window_pattern_interval,
668+ ) ;
637669 Ok ( Self {
638670 tok_embeddings : Embedding :: new ( tok_embeddings, embedding_length) ,
639671 layers,
@@ -643,7 +675,7 @@ impl ModelConfig::FromGGUF for ModelWeights {
643675 b : None ,
644676 } ) ?) ,
645677 device : device. clone ( ) ,
646- cache : EitherCache :: Normal ( NormalCache :: new ( block_count , max_seq_len ) ) ,
678+ cache : EitherCache :: Normal ( NormalCache :: from_types ( cache_types ) ) ,
647679 max_seq_len,
648680 mapper : Some ( mapper) ,
649681 dtype,
@@ -744,7 +776,10 @@ impl ModelWeights {
744776
745777#[ cfg( test) ]
746778mod tests {
747- use super :: { ensure_gemma3_causal_mode, gemma3_use_sliding_window} ;
779+ use super :: {
780+ ensure_gemma3_causal_mode, gemma3_cache_types, gemma3_use_sliding_window, KvCache ,
781+ NormalCache ,
782+ } ;
748783
749784 #[ test]
750785 fn sliding_window_pattern_bool_array_is_honored ( ) {
@@ -767,6 +802,15 @@ mod tests {
767802 assert_eq ! ( got, expected) ;
768803 }
769804
805+ #[ test]
806+ fn cache_uses_rotating_kv_only_for_sliding_layers ( ) {
807+ let cache = NormalCache :: from_types ( gemma3_cache_types ( 6 , 8192 , 1024 , & [ ] , 6 ) ) ;
808+ let cache = cache. lock ( ) . expect ( "cache lock poisoned" ) ;
809+ let got: Vec < bool > = cache. 0 . iter ( ) . map ( KvCache :: is_rotating) . collect ( ) ;
810+ let expected = vec ! [ true , true , true , true , true , false ] ;
811+ assert_eq ! ( got, expected) ;
812+ }
813+
770814 #[ test]
771815 fn non_causal_gemma3_is_rejected ( ) {
772816 let err = ensure_gemma3_causal_mode ( false ) . expect_err ( "non-causal must be rejected" ) ;
0 commit comments