ember.cpp 0.1.0
C++ inference engine for Llama-family and paperkiln models (CPU, CUDA, WebAssembly)
Loading...
Searching...
No Matches
model_utils.cpp
Go to the documentation of this file.
1#include "model_utils.h"
2#include "logger.h"
3#include "utils.h"
4#include "quantization.h"
5#include "model_constants.h"
6#include "model_macros.h"
7#include <algorithm>
8#include <cstring>
9#include <cmath>
10
11std::vector<float> TinyLlamaModel::lookup_embedding(int token_id) {
13 int vs = config_.vocab_size;
14
16 Logger::error("Token ID out of bounds in lookup_embedding: " +
17 std::to_string(token_id));
18 return std::vector<float>(hs, 0.0f);
19 }
20
21 std::vector<float> embedding_vec(hs, 0.0f);
22
23 if (!embed_tokens_q4k.empty()) {
24 if (hs % GGML_QK_K != 0) {
25 Logger::error("Hidden size (" + std::to_string(hs) +
26 ") is not divisible by GGML_QK_K (" +
27 std::to_string(GGML_QK_K) + ") for Q4_K embedding lookup.");
28 return embedding_vec;
29 }
30
31 size_t blocks_per_row = hs / GGML_QK_K;
32 size_t start_block_idx = (size_t)token_id * blocks_per_row;
34
35 if (end_block_idx > embed_tokens_q4k.size()) {
37 "Calculated block index out of bounds for Q4_K embedding table. "
38 "Token: " +
39 std::to_string(token_id) +
40 ", StartBlock: " + std::to_string(start_block_idx) +
41 ", EndBlock: " + std::to_string(end_block_idx) +
42 ", TableSize: " + std::to_string(embed_tokens_q4k.size()));
43 return embedding_vec;
44 }
45
47 for (size_t block_n = 0; block_n < blocks_per_row; ++block_n) {
50
51 size_t dest_offset = block_n * GGML_QK_K;
52
53 size_t elements_to_copy = SAFE_MIN((size_t)GGML_QK_K, (size_t)(hs - dest_offset));
55 elements_to_copy * sizeof(float));
56 }
57 return embedding_vec;
58 }
59
60 else if (!embed_tokens_q8_0.empty()) {
61 if (hs % GGML_QK8_0 != 0) {
62 Logger::error("Hidden size (" + std::to_string(hs) +
63 ") is not divisible by GGML_QK8_0 (" +
64 std::to_string(GGML_QK8_0) +
65 ") for Q8_0 embedding lookup.");
66 return embedding_vec;
67 }
68 size_t blocks_per_row = hs / GGML_QK8_0;
69 size_t start_block_idx = (size_t)token_id * blocks_per_row;
71
72 if (end_block_idx > embed_tokens_q8_0.size()) {
74 "Calculated block index out of bounds for Q8_0 embedding table. "
75 "Token: " +
76 std::to_string(token_id) +
77 ", StartBlock: " + std::to_string(start_block_idx) +
78 ", EndBlock: " + std::to_string(end_block_idx) +
79 ", TableSize: " + std::to_string(embed_tokens_q8_0.size()));
80 return embedding_vec;
81 }
82
84
85 for (size_t block_n = 0; block_n < blocks_per_row; ++block_n) {
89 size_t elements_to_copy = SAFE_MIN(static_cast<size_t>(GGML_QK8_0), static_cast<size_t>(hs - dest_offset));
91 elements_to_copy * sizeof(float));
92
93 }
94
95 if (token_id < 2) {
96 float sum = 0.0f, min_val = embedding_vec[0], max_val = embedding_vec[0];
97 for (int i = 0; i < hs; ++i) {
99 min_val = std::min(min_val, embedding_vec[i]);
100 max_val = std::max(max_val, embedding_vec[i]);
101 }
102 Logger::info("[Q8_0_EMBED_FINAL] Token " + std::to_string(token_id) +
103 " embedding stats: sum=" + std::to_string(sum) +
104 ", mean=" + std::to_string(sum / hs) +
105 ", min=" + std::to_string(min_val) +
106 ", max=" + std::to_string(max_val) +
107 ", first_4=[" + std::to_string(embedding_vec[0]) +
108 ", " + std::to_string(embedding_vec[1]) +
109 ", " + std::to_string(embedding_vec[2]) +
110 ", " + std::to_string(embedding_vec[3]) + "]");
111 }
112 return embedding_vec;
113 }
114
115 else if (!embed_tokens_q6k.empty()) {
116 if (hs % GGML_QK_K != 0) {
117 Logger::error("Hidden size (" + std::to_string(hs) +
118 ") is not divisible by GGML_QK_K (" +
119 std::to_string(GGML_QK_K) + ") for Q6_K embedding lookup.");
120 return embedding_vec;
121 }
122 size_t blocks_per_row = hs / GGML_QK_K;
123 size_t start_block_idx = (size_t)token_id * blocks_per_row;
125
126 if (end_block_idx > embed_tokens_q6k.size()) {
128 "Calculated block index out of bounds for Q6_K embedding table. "
129 "Token: " +
130 std::to_string(token_id) +
131 ", StartBlock: " + std::to_string(start_block_idx) +
132 ", EndBlock: " + std::to_string(end_block_idx) +
133 ", TableSize: " + std::to_string(embed_tokens_q6k.size()));
134 return embedding_vec;
135 }
136
138 for (size_t block_n = 0; block_n < blocks_per_row; ++block_n) {
141 size_t dest_offset = block_n * GGML_QK_K;
142 size_t elements_to_copy = SAFE_MIN(static_cast<size_t>(GGML_QK_K), static_cast<size_t>(hs - dest_offset));
144 elements_to_copy * sizeof(float));
145 }
146 return embedding_vec;
147 }
148
149 else if (!embed_tokens_q5k.empty()) {
150 const size_t blocks_per_row = hs / GGML_QK_K, first = (size_t)token_id * blocks_per_row;
151 if (hs % GGML_QK_K != 0 || first + blocks_per_row > embed_tokens_q5k.size()) {
152 Logger::error("Q5_K embedding table: hidden size " + std::to_string(hs) + " or token " +
153 std::to_string(token_id) + " does not fit its " + std::to_string(embed_tokens_q5k.size()) +
154 " blocks");
155 return embedding_vec;
156 }
158 return embedding_vec;
159 }
160
161 else if (!embed_tokens_f32.empty()) {
162 size_t offset = (size_t)token_id * hs;
163 if (offset + hs > embed_tokens_f32.size()) {
164 Logger::error("Embedding offset out of bounds in F32 lookup for token: " +
165 std::to_string(token_id));
166 return embedding_vec;
167 }
168
169 std::copy(embed_tokens_f32.begin() + offset,
170 embed_tokens_f32.begin() + offset + hs, embedding_vec.begin());
171 return embedding_vec;
172
173 } else if (!embed_tokens.empty()) {
174 size_t offset = (size_t)token_id * hs;
175 if (offset + hs > embed_tokens.size()) {
177 "Embedding offset out of bounds in BF16 lookup for token: " +
178 std::to_string(token_id));
179 return embedding_vec;
180 }
181 std::vector<uint16_t> token_embedding_bf16(
182 embed_tokens.begin() + offset, embed_tokens.begin() + offset + hs);
183
185 return embedding_vec;
186
187 } else {
189 "No valid embedding table found (Q4_K, Q8_0, Q6_K, F32, BF16) for token: " +
190 std::to_string(token_id));
191
192 return embedding_vec;
193 }
194}
195
197 Logger::info("[ROPE_FREQ_ENTRY] Entered initialize_rope_freqs.");
198
199 Logger::info("[ROPE_FREQ_CHECK] num_attention_heads: " + std::to_string(config_.num_attention_heads));
200 if (config_.num_attention_heads == 0) {
201 Logger::error("Cannot initialize RoPE frequencies: num_attention_heads is zero.");
202 return;
203 }
205 Logger::info("[ROPE_FREQ_CHECK] calculated head_dim: " + std::to_string(head_dim));
206 if (head_dim == 0) {
207 Logger::error("Cannot initialize RoPE frequencies: calculated head_dim is zero.");
208 return;
209 }
210 Logger::info("[ROPE_FREQ_CHECK] head_dim % 2 check. head_dim: " + std::to_string(head_dim));
211 if (head_dim % 2 != 0) {
212 Logger::error("Cannot initialize RoPE frequencies: head_dim must be even.");
213 return;
214 }
215
216 Logger::info("[ROPE_INIT] Initializing RoPE with head_dim=" + std::to_string(head_dim) +
217 ", configured max_pos_emb=" + std::to_string(config_.max_position_embeddings) +
218 ", using internal rope::MAX_SEQUENCE_LENGTH=" + std::to_string(rope::MAX_SEQUENCE_LENGTH) +
219 ", configured rope_theta=" + std::to_string(config_.rope_theta));
220
221
222 if (precomputed_freqs_cis_.empty()) {
224 size_t required_size = (static_cast<size_t>(max_seq_len) * head_dim) / 2;
225 if (required_size == 0) {
226 Logger::warning("RoPE precomputation resulted in zero size. Max seq len: " +
227 std::to_string(max_seq_len) + ", head_dim: " + std::to_string(head_dim));
228 return;
229 }
231
232 float rope_theta = config_.rope_theta > 0 ? config_.rope_theta : rope::ROPE_THETA;
233
234 for (int pos = 0; pos < max_seq_len; ++pos) {
235 for (int i = 0; i < head_dim; i += 2) {
236 float freq = 1.0f / std::pow(rope_theta, float(i) / head_dim);
237 float val = static_cast<float>(pos) * freq;
238 float cos_val = std::cos(val);
239 float sin_val = std::sin(val);
240 size_t flat_idx = (static_cast<size_t>(pos) * head_dim / 2) + (i / 2);
241 if (flat_idx < precomputed_freqs_cis_.size()){
243 } else {
244 Logger::error("RoPE precomputation index out of bounds: " + std::to_string(flat_idx) +
245 " vs size " + std::to_string(precomputed_freqs_cis_.size()));
246 return;
247 }
248 }
249 }
250 Logger::info("Precomputed RoPE frequencies on CPU. Size: " + std::to_string(precomputed_freqs_cis_.size()));
251 } else {
252 Logger::info("RoPE frequencies already precomputed.");
253 }
254}
255
257 return config_.vocab_size;
258}
static void warning(const std::string &message)
Definition logger.cpp:139
static void info(const std::string &message)
Definition logger.cpp:135
static void error(const std::string &message)
Definition logger.cpp:143
std::vector< block_q6_K > embed_tokens_q6k
Definition model.h:584
std::vector< float > lookup_embedding(int token_id)
Lookup the embedding vector for a given token ID.
void initialize_rope_freqs()
int get_vocab_size() const
Get the vocabulary size for the model.
std::vector< std::pair< float, float > > precomputed_freqs_cis_
Definition model.h:694
std::vector< block_q8_0 > embed_tokens_q8_0
Definition model.h:585
ModelConfig config_
Definition model.h:573
std::vector< block_q4_K > embed_tokens_q4k
Definition model.h:582
std::vector< block_q5_K > embed_tokens_q5k
Definition model.h:583
std::vector< uint16_t > embed_tokens
Definition model.h:578
std::vector< float > embed_tokens_f32
Definition model.h:581
constexpr size_t GGML_QK8_0
Definition gguf_parser.h:43
constexpr size_t GGML_QK_K
Block size constants for different quantization formats.
Definition gguf_parser.h:42
size_t j
Logging utilities for the TinyLlama implementation.
Constants used throughout the TinyLlama model implementation.
#define SAFE_MIN(a, b)
constexpr float ROPE_THETA
constexpr int MAX_SEQUENCE_LENGTH
void dequantize_q4_k_m(const block_q4_K *qblock, float *output, int num_weights_in_block, bool log_this_block)
void dequantize_q5_k(const block_q5_K *qblock, float *output)
void dequantize_q8_0_block(const block_q8_0 *qblock, float *output)
Dequantizes a Q8_0 block to float32.
void dequantize_q6_k(const block_q6_K *qblock, float *output, int num_weights_in_block, bool log_this_block)
Weight quantization structures and functions for model compression.
int hidden_size
Definition model.h:83
int vocab_size
Definition model.h:88
int num_attention_heads
Definition model.h:85
float rope_theta
Definition model.h:91
int max_position_embeddings
Definition model.h:89
std::vector< float > bf16vec_to_float_vec(const std::vector< uint16_t > &v_bf16)
Definition utils.cpp:199