11use super :: { Context , Distribution , Linear , NNError , NuralNetwork , TPTensor , Tensor , macros:: * } ;
22use crate :: {
33 Arg , TPAction ,
4- weight_types:: { AttnQKV , RowTPWeight } ,
4+ weight_types:: { AttnQKV , ColumnTPWeight , RowTPWeight } ,
55} ;
66use tensor:: digit_layout:: types;
77
88#[ derive( Clone ) ]
9- pub struct Attention < T > {
9+ pub struct Attention < T : Clone > {
1010 pub nh : usize ,
1111 pub nkvh : usize ,
12- pub qkv : Linear < T > ,
12+ pub qkv : QKVFormat < T > ,
1313 pub rope : Option < RoPE < T > > ,
1414 pub output : Linear < T > ,
1515}
1616
17+ #[ derive( Clone ) ]
18+ pub enum QKVFormat < T : Clone > {
19+ Combined ( Linear < T > ) ,
20+ Separated {
21+ q : Linear < T > ,
22+ k : Linear < T > ,
23+ v : Linear < T > ,
24+ } ,
25+ }
26+
1727#[ derive( Clone ) ]
1828pub struct RoPE < T > {
1929 pub multimodal : bool ,
@@ -22,7 +32,7 @@ pub struct RoPE<T> {
2232 pub cos : T ,
2333}
2434
25- impl < T > Attention < T > {
35+ impl < T : Clone > Attention < T > {
2636 pub fn tensor_parallel ( self , dist : Distribution ) -> Attention < TPTensor < T > > {
2737 let Self {
2838 nh,
@@ -36,7 +46,16 @@ impl<T> Attention<T> {
3646 Attention {
3747 nh : nh / dist. total * dist. len ,
3848 nkvh : nkvh / dist. total * dist. len ,
39- qkv : qkv. parallel ( TPAction :: new ( AttnQKV ( nh / nkvh) , dist) ) ,
49+ qkv : match qkv {
50+ QKVFormat :: Combined ( qkv) => {
51+ QKVFormat :: Combined ( qkv. parallel ( TPAction :: new ( AttnQKV ( nh / nkvh) , dist) ) )
52+ }
53+ QKVFormat :: Separated { q, k, v } => QKVFormat :: Separated {
54+ q : q. parallel ( TPAction :: new ( ColumnTPWeight , dist) ) ,
55+ k : k. parallel ( TPAction :: new ( ColumnTPWeight , dist) ) ,
56+ v : v. parallel ( TPAction :: new ( ColumnTPWeight , dist) ) ,
57+ } ,
58+ } ,
4059 rope : rope. map (
4160 |RoPE {
4261 multimodal,
@@ -55,7 +74,7 @@ impl<T> Attention<T> {
5574 }
5675}
5776
58- impl < T > NuralNetwork < T > for Attention < T > {
77+ impl < T : Clone > NuralNetwork < T > for Attention < T > {
5978 fn launch (
6079 self ,
6180 inputs : impl IntoIterator < Item = Tensor < T > > ,
@@ -71,24 +90,35 @@ impl<T> NuralNetwork<T> for Attention<T> {
7190 output,
7291 } = self ;
7392
74- destruct ! ( [ x] = ctx. trap( "attn-qkv" , qkv, [ x] ) ?) ;
75- dims ! ( [ _, dqkv] = x) ;
76- let dh = dqkv. clone ( ) / ( nh + nkvh + nkvh) ;
93+ dims ! ( [ _, d] = x) ;
94+ let dh = d. clone ( ) / nh;
7795
78- destruct ! (
79- [ q, k, v] = ctx. call(
80- "split-qkv" ,
81- "split" ,
82- Some ( Arg :: dict( [
83- ( "axis" . into( ) , Arg :: int( 1 ) ) ,
84- (
85- "parts" . into( ) ,
86- Arg :: arr( [ Arg :: dim( nh) , Arg :: dim( nkvh) , Arg :: dim( nkvh) ] )
87- )
88- ] ) ) ,
89- [ x] ,
90- ) ?
91- ) ;
96+ let [ q, k, v] = match qkv {
97+ QKVFormat :: Combined ( qkv) => {
98+ destruct ! ( [ x] = ctx. trap( "attn-qkv" , qkv, [ x] ) ?) ;
99+ destruct ! (
100+ [ q, k, v] = ctx. call(
101+ "split-qkv" ,
102+ "split" ,
103+ Some ( Arg :: dict( [
104+ ( "axis" . into( ) , Arg :: int( 1 ) ) ,
105+ (
106+ "parts" . into( ) ,
107+ Arg :: arr( [ Arg :: dim( nh) , Arg :: dim( nkvh) , Arg :: dim( nkvh) ] )
108+ )
109+ ] ) ) ,
110+ [ x] ,
111+ ) ?
112+ ) ;
113+ [ q, k, v]
114+ }
115+ QKVFormat :: Separated { q, k, v } => {
116+ destruct ! ( [ q] = ctx. trap( "attn-q" , q, [ x. clone( ) ] ) ?) ;
117+ destruct ! ( [ k] = ctx. trap( "attn-k" , k, [ x. clone( ) ] ) ?) ;
118+ destruct ! ( [ v] = ctx. trap( "attn-v" , v, [ x] ) ?) ;
119+ [ q, k, v]
120+ }
121+ } ;
92122
93123 let [ q, k] = match rope {
94124 Some ( RoPE {
@@ -98,9 +128,8 @@ impl<T> NuralNetwork<T> for Attention<T> {
98128 cos,
99129 } ) => {
100130 let shape = [ nctx. into ( ) , dh. clone ( ) / 2 ] ;
101- let sin = ctx. load_external ( "rope.sin" , types:: F32 , shape. clone ( ) , sin) ;
102- let cos = ctx. load_external ( "rope.cos" , types:: F32 , shape, cos) ;
103-
131+ destruct ! ( [ sin] = ctx. load_external( "rope.sin" , types:: F32 , shape. clone( ) , sin) ?) ;
132+ destruct ! ( [ cos] = ctx. load_external( "rope.cos" , types:: F32 , shape, cos) ?) ;
104133 let op = if multimodal { "mrope" } else { "rope" } ;
105134 destruct ! (
106135 [ q_] = ctx. call(
0 commit comments