| 109 | } |
| 110 | |
| 111 | core::TensorValue build_attention( |
| 112 | core::ModuleBuildContext & ctx, |
| 113 | const core::TensorValue & hidden_states, |
| 114 | const core::TensorValue & positions, |
| 115 | const AceStepDiTAttentionWeights & weights, |
| 116 | const AceStepDiffusionConfig & config, |
| 117 | const std::optional<core::TensorValue> & attention_mask, |
| 118 | core::BackendType backend_type, |
| 119 | const std::optional<PrecomputedCrossAttentionKV> & cross_attention_kv = std::nullopt, |
| 120 | const std::optional<core::TensorValue> & encoder_hidden_states = std::nullopt) { |
| 121 | const int64_t dim = ace_step_diffusion_attention_head_dim(config, "ACE-Step diffusion"); |
| 122 | const int64_t kv_repeats = config.num_attention_heads / config.num_key_value_heads; |
| 123 | const bool is_cross = cross_attention_kv.has_value() || encoder_hidden_states.has_value(); |
| 124 | auto q = modules::LinearModule({config.hidden_size, config.num_attention_heads * dim, false, GGML_PREC_F32}) |
| 125 | .build(ctx, hidden_states, {weights.q_weight, std::nullopt}); |
| 126 | core::TensorValue k; |
| 127 | core::TensorValue v; |
| 128 | if (cross_attention_kv.has_value()) { |
| 129 | k = cross_attention_kv->key; |
| 130 | v = cross_attention_kv->value; |
| 131 | } else { |
no test coverage detected