| 68 | } |
| 69 | |
| 70 | void test_attn() { |
| 71 | constexpr int TEST_SEQ_LEN = 4; |
| 72 | constexpr int TEST_DIM = 6; |
| 73 | constexpr int TEST_HEAD_DIM = 3; |
| 74 | constexpr int TEST_N_HEADS = 2; |
| 75 | std::shared_ptr<Config> config = std::make_shared<Config>(); |
| 76 | config->dim = TEST_DIM; |
| 77 | config->hidden_dim = TEST_DIM; |
| 78 | config->head_dim = TEST_HEAD_DIM; |
| 79 | config->n_heads = TEST_N_HEADS; |
| 80 | config->vocab_size = 1; |
| 81 | config->max_seq_len = TEST_SEQ_LEN; |
| 82 | InferenceState s(config); |
| 83 | // (n_heads, head_dim) - query vectors |
| 84 | std::vector<float> q{ |
| 85 | 0., 1e4, 0., // h=0 |
| 86 | 0., 0., 1e4 // h=1 |
| 87 | }; |
| 88 | for (size_t i = 0; i < q.size(); i++) { |
| 89 | s.q()[i] = q[i]; |
| 90 | } |
| 91 | std::vector<f16_t> kb = float_array_to_half({ |
| 92 | 1., 0., 0., // t=0 |
| 93 | 0., 1., 0., // t=1 |
| 94 | 0., 0., 1., // t=2 |
| 95 | -1., 0., 0. // t=3 |
| 96 | }); // (kv_len, n_heads, head_dim) - buffer containing key vectors of the sequence for all KV heads |
| 97 | std::vector<f16_t> vb = float_array_to_half({ |
| 98 | 1., 0., 0., // t=0 |
| 99 | 0., 1., 0., // t=1 |
| 100 | 0., 0., 1., // t=2 |
| 101 | -1., 0., 0. // t=3 |
| 102 | }); // (kv_len, n_heads, head_dim) - buffer containing value vectors of the sequence for all KV heads |
| 103 | |
| 104 | // Multihead attention. Iterate over all heads. |
| 105 | int h; |
| 106 | #pragma omp parallel for private(h) |
| 107 | for (h = 0; h < TEST_N_HEADS; h++) { |
| 108 | int kv_head_offset = h * TEST_HEAD_DIM; |
| 109 | f16_t* kh = kb.data() + kv_head_offset; |
| 110 | f16_t* vh = vb.data() + kv_head_offset; |
| 111 | attn(s.xb(h), s.att(h), s.q(h), kh, vh, TEST_HEAD_DIM, TEST_HEAD_DIM, TEST_N_HEADS, TEST_SEQ_LEN); |
| 112 | } |
| 113 | // attention scores |
| 114 | // h=0 |
| 115 | assertArrayEquals(s.att(0), { |
| 116 | 0., 1., 0., 0. |
| 117 | }, "att(h=0)"); |
| 118 | // h=1 |
| 119 | assertArrayEquals(s.att(1), { |
| 120 | 0., 0., 1., 0. |
| 121 | }, "att(h=1)"); |
| 122 | assertArrayEquals(s.xb(), { |
| 123 | 0., 1., 0., // h=0 |
| 124 | 0., 0., 1. // h=1 |
| 125 | }, "xout"); |
| 126 | } |
| 127 |
no test coverage detected