| 128 | if (cross_attention_kv.has_value()) { |
| 129 | k = cross_attention_kv->key; |
| 130 | v = cross_attention_kv->value; |
| 131 | } else { |
| 132 | const auto & kv_source = is_cross ? *encoder_hidden_states : hidden_states; |
| 133 | k = modules::LinearModule({config.hidden_size, config.num_key_value_heads * dim, false, GGML_PREC_F32}) |
| 134 | .build(ctx, kv_source, {weights.k_weight, std::nullopt}); |
| 135 | v = modules::LinearModule({config.hidden_size, config.num_key_value_heads * dim, false, GGML_PREC_F32}) |
| 136 | .build(ctx, kv_source, {weights.v_weight, std::nullopt}); |
| 137 | } |
| 138 | q = modules::RMSNormModule({dim, config.rms_norm_eps, true, false}) |
| 139 | .build(ctx, reshape_heads(ctx, q, config.num_attention_heads, dim), {weights.q_norm, std::nullopt}); |
| 140 | if (!cross_attention_kv.has_value()) { |
| 141 | k = modules::RMSNormModule({dim, config.rms_norm_eps, true, false}) |
| 142 | .build(ctx, reshape_heads(ctx, k, config.num_key_value_heads, dim), {weights.k_norm, std::nullopt}); |
| 143 | v = reshape_heads(ctx, v, config.num_key_value_heads, dim); |
| 144 | } |
| 145 | if (!is_cross) { |
| 146 | q = modules::RoPEModule({dim, GGML_ROPE_TYPE_NEOX, config.rope_theta}).build(ctx, q, positions); |
| 147 | k = modules::RoPEModule({dim, GGML_ROPE_TYPE_NEOX, config.rope_theta}).build(ctx, k, positions); |
| 148 | } |
| 149 | auto q_heads = ensure_contiguous( |
| 150 | ctx, |
| 151 | modules::TransposeModule({{0, 2, 1, 3}, q.shape.rank}).build(ctx, q)); |
| 152 | auto k_heads = repeat_kv_heads( |
| 153 | ctx, |
| 154 | modules::TransposeModule({{0, 2, 1, 3}, k.shape.rank}).build(ctx, k), |
| 155 | kv_repeats); |
| 156 | auto v_heads = repeat_kv_heads( |
| 157 | ctx, |
| 158 | modules::TransposeModule({{0, 2, 1, 3}, v.shape.rank}).build(ctx, v), |
| 159 | kv_repeats); |
| 160 | k_heads = ensure_contiguous(ctx, k_heads); |
| 161 | v_heads = ensure_contiguous(ctx, v_heads); |
| 162 | auto context = attention_from_heads(ctx, q_heads, k_heads, v_heads, dim, attention_mask, backend_type); |
| 163 | context = ensure_contiguous(ctx, context); |
| 164 | context = core::reshape_tensor( |
| 165 | ctx, |
| 166 | context, |
| 167 | core::TensorShape::from_dims({hidden_states.shape.dims[0], hidden_states.shape.dims[1], config.hidden_size})); |
no test coverage detected