ember.cpp 0.1.0
C++ inference engine for Llama-family and paperkiln models (CPU, CUDA, WebAssembly)
Loading...
Searching...
No Matches
gpu_initialization.cpp
Go to the documentation of this file.
2#include "logger.h"
3#include "utils.h"
4#include "quantization.h"
5#include "model_constants.h"
6#include "model_macros.h"
7#include "weight_management.h"
8#include "determinism.h"
9#ifdef HAS_CUDA
10#include "cuda_kernels.h"
11#endif
12#include <algorithm>
13#include <cstdlib>
14#include <cmath>
15#include <cstring>
16
18 Logger::info("[INIT_GPU_ROPE_DEBUG_L1113] Absolute Start of initialize_gpu_and_rope: config_.num_cpu_offload_layers = " + std::to_string(config_.num_cpu_offload_layers) +
19 ", config_.num_hidden_layers = " + std::to_string(config_.num_hidden_layers));
20 Logger::info("[GPU_ROPE_INIT_ENTRY] Entered initialize_gpu_and_rope. Requested CPU Offload Layers: " + std::to_string(config_.num_cpu_offload_layers) + ", Total Hidden Layers: " + std::to_string(config_.num_hidden_layers));
24 int vs = config_.vocab_size;
27
31 Logger::warning("Requested CPU offload layers (" + std::to_string(config_.num_cpu_offload_layers) +
32 ") exceeds total hidden layers (" + std::to_string(nhl) +
33 "). Clamping to " + std::to_string(nhl) + " layers on CPU.");
35 }
38
39 Logger::info("Effective CPU layers for this init: " + std::to_string(active_num_cpu_layers) + ", Effective GPU layers for this init: " + std::to_string(active_num_gpu_layers));
40
41 if (hs <= 0) throw std::runtime_error("Invalid model config: hidden_size must be positive.");
42 if (vs <= 0) throw std::runtime_error("Invalid model config: vocab_size must be positive.");
43 if (n_heads <= 0) throw std::runtime_error("Invalid model config: num_attention_heads must be positive.");
44 if (n_kv_heads <= 0) throw std::runtime_error("Invalid model config: num_key_value_heads must be positive.");
45 if (hs % n_heads != 0) throw std::runtime_error("Invalid model config: hidden_size not divisible by num_attention_heads.");
46
47 int kv_dim = (hs / n_heads) * n_kv_heads;
48 int head_dim = hs / n_heads;
49
50 Logger::info("Precomputing RoPE frequencies on CPU (always done).");
53 float theta = config_.rope_theta;
54 for (int pos = 0; pos < max_seq_len; ++pos) {
55 for (int i_rope = 0; i_rope < head_dim; i_rope += 2) {
56 float freq = std::pow(theta, -((float)i_rope) / head_dim);
57 float angle = pos * freq;
58 precomputed_freqs_cis_[(pos * head_dim / 2) + (i_rope / 2)] = {std::cos(angle), std::sin(angle)};
59 }
60 }
61 Logger::info("Finished precomputing RoPE cos/sin frequencies on CPU.");
62
63#ifdef HAS_CUDA
64#define SAFE_CUDA_FREE(ptr) if(ptr) { cudaFree(ptr); ptr = nullptr; }
65
66 if (active_num_gpu_layers == 0) {
67 Logger::info("No layers assigned to GPU (active_num_gpu_layers = 0). Cleaning up existing CUDA resources and skipping GPU initialization.");
68
70 for (int i = 0; i < nhl; ++i) {
73 }
87
89 return;
90 }
91
92 Logger::info("Initializing CUDA resources for " + std::to_string(active_num_gpu_layers) + " GPU layers.");
93 if (!cublas_handle_) {
94 ember::deterministic_cublas_env(); // EMBER_DETERMINISTIC=1 only (determinism.h)
97 throw std::runtime_error("Failed to initialize cuBLAS: " + std::to_string(cublas_status));
98 }
101 Logger::info("EMBER_DETERMINISTIC: deterministic CUDA mode on (fixed-order decode reductions; cuBLAS "
102 "workspace " + std::string(std::getenv("CUBLAS_WORKSPACE_CONFIG") ? std::getenv("CUBLAS_WORKSPACE_CONFIG") : "default") +
103 ", atomics not allowed).");
104 }
105 Logger::info("cuBLAS handle created successfully.");
106
107 // Check for BF16 Tensor Core support
108 this->use_bf16_tensor_cores_ = false; // Default to false
110 int current_device;
111 gpuErrchk(cudaGetDevice(&current_device));
113
114 bool has_bf16_tensor_core_hw = ((props.major == 7 && props.minor == 5) || props.major >= 8);
116
117 // EMBER_DISABLE_BF16=1 keeps every GEMM in FP32: the reference the
118 // tools/ttft_parity.py check holds the BF16 path and kernel variants to.
119 if (std::getenv("EMBER_DISABLE_BF16") != nullptr) {
120 Logger::info("EMBER_DISABLE_BF16 set: BF16 Tensor Core path disabled, all GEMMs FP32.");
121 } else if (has_bf16_tensor_core_hw) {
123 Logger::info("GPU " + std::string(props.name) + " (CC " + std::to_string(props.major) + "." + std::to_string(props.minor) + ") supports BF16 Tensor Cores AND model dimensions (hs: " + std::to_string(config_.hidden_size) + ", vs: " + std::to_string(config_.vocab_size) + ") are compatible. Enabling Tensor Core path for matvec_bf16_f32.");
124 this->use_bf16_tensor_cores_ = true;
125 } else {
126 Logger::info("GPU " + std::string(props.name) + " (CC " + std::to_string(props.major) + "." + std::to_string(props.minor) + ") supports BF16 Tensor Cores, BUT model dimensions (hs: " + std::to_string(config_.hidden_size) + " (must be div by 8), vs: " + std::to_string(config_.vocab_size) + " (must be div by 4)) are NOT compatible. Disabling Tensor Core path for matvec_bf16_f32.");
127 }
128 } else {
129 Logger::info("GPU " + std::string(props.name) + " (CC " + std::to_string(props.major) + "." + std::to_string(props.minor) + ") does not meet criteria for BF16 Tensor Core use (requires CC >= 7.5). Disabling Tensor Core path for matvec_bf16_f32.");
130 }
131 }
132
133 if (final_norm_f32.empty() && !final_norm.empty()) {
134 Logger::info("Converting final_norm (BF16) to FP32 for GPU.");
136 }
137 if (!final_norm_f32.empty()) {
139 gpuErrchk(cudaMalloc(&final_norm_dev, final_norm_f32.size() * sizeof(float)));
141 Logger::info("Copied final_norm weights (FP32) to GPU.");
142 } else {
143 Logger::warning("Final norm weights (FP32) are empty, skipping GPU copy. This might be an issue if GPU layers are expected to use it.");
144 }
145
146 for (int i = 0; i < active_num_cpu_layers; ++i) {
147 if (static_cast<size_t>(i) < layers.size()) {
150 }
151 }
152 Logger::info("Copying layer norm weights (FP32) to GPU for layers " + std::to_string(active_num_cpu_layers) + " to " + std::to_string(nhl - 1));
153 Logger::info("[INIT_DEBUG_PRE_LOOP] Active CPU layers: " + std::to_string(active_num_cpu_layers));
154 if (nhl > 0 && layers.size() > 0) {
155 Logger::info("[INIT_DEBUG_PRE_LOOP] layers[0].input_layernorm_f32.empty(): " + std::string(layers[0].input_layernorm_f32.empty() ? "YES" : "NO") +
156 ", Size: " + std::to_string(layers[0].input_layernorm_f32.size()));
157 }
158 for (int i = active_num_cpu_layers; i < nhl; ++i) {
159 if (static_cast<size_t>(i) >= layers.size()) {
160 Logger::error("Layer index " + std::to_string(i) + " out of bounds for layers vector (size: " + std::to_string(layers.size()) + ")");
161 continue;
162 }
165
166 if (layers[i].input_layernorm_f32.empty() && !layers[i].input_layernorm.empty()) {
167 layers[i].input_layernorm_f32 = bf16vec_to_float_vec(layers[i].input_layernorm);
168 }
169 if (layers[i].post_attention_layernorm_f32.empty() && !layers[i].post_attention_layernorm.empty()) {
170 layers[i].post_attention_layernorm_f32 = bf16vec_to_float_vec(layers[i].post_attention_layernorm);
171 }
172
173 if (!layers[i].input_layernorm_f32.empty()) {
174 gpuErrchk(cudaMalloc(&layers[i].input_layernorm_dev, layers[i].input_layernorm_f32.size() * sizeof(float)));
175 gpuErrchk(cudaMemcpy(layers[i].input_layernorm_dev, layers[i].input_layernorm_f32.data(), layers[i].input_layernorm_f32.size() * sizeof(float), cudaMemcpyHostToDevice));
176 if (i == active_num_cpu_layers) {
177 Logger::info("[INIT_DEBUG] layers[" + std::to_string(i) + "].input_layernorm_dev allocated. Pointer: " + Logger::ptrToString(layers[i].input_layernorm_dev) +
178 ", Size used for malloc: " + std::to_string(layers[i].input_layernorm_f32.size() * sizeof(float)) + " bytes (" +
179 std::to_string(layers[i].input_layernorm_f32.size()) + " elements). Host vector empty: " + (layers[i].input_layernorm_f32.empty() ? "YES" : "NO"));
180 }
181 } else {
182 throw std::runtime_error("GPU Layer " + std::to_string(i) + ": input_layernorm_f32 weights are empty. Cannot offload to GPU without them.");
183 }
184
185 if (!layers[i].post_attention_layernorm_f32.empty()) {
186 gpuErrchk(cudaMalloc(&layers[i].post_attention_layernorm_dev, layers[i].post_attention_layernorm_f32.size() * sizeof(float)));
187 gpuErrchk(cudaMemcpy(layers[i].post_attention_layernorm_dev, layers[i].post_attention_layernorm_f32.data(), layers[i].post_attention_layernorm_f32.size() * sizeof(float), cudaMemcpyHostToDevice));
188 } else {
189 throw std::runtime_error("GPU Layer " + std::to_string(i) + ": post_attention_layernorm_f32 weights are empty. Cannot offload to GPU without them.");
190 }
191 }
192 Logger::info("Finished processing layer norm weights for GPU layers.");
193
194
199
200 if (active_num_gpu_layers > 0) {
201 if (!embed_tokens.empty()) {
204 Logger::info("Copied token_embedding_table (bf16 direct from model.embed_tokens) to GPU.");
206 }
207 else if (!embed_tokens_f32.empty()) {
208 std::vector<uint16_t> bf16_data(embed_tokens_f32.size());
209 #pragma omp parallel for
210 for (int i = 0; i < (int)embed_tokens_f32.size(); ++i) {
212 }
215 Logger::info("Converted token_embedding_table (fp32 source -> bf16) to GPU.");
217 }
218 else if (!embed_tokens_q8_0.empty()) {
219 std::vector<float> temp_f32_data(embed_tokens_q8_0.size() * GGML_QK8_0);
220 #pragma omp parallel for
221 for (int i = 0; i < (int)embed_tokens_q8_0.size(); ++i) {
223 }
224 std::vector<uint16_t> bf16_data(temp_f32_data.size());
225 #pragma omp parallel for
226 for (int i = 0; i < (int)temp_f32_data.size(); ++i) {
228 }
231 Logger::info("Dequantized token_embedding_table (Q8_0 -> fp32 -> bf16) to GPU.");
233 }
234 else if (!embed_tokens_q4k.empty()) {
235 std::vector<float> temp_f32_data(embed_tokens_q4k.size() * GGML_QK_K);
236 #pragma omp parallel for
237 for (int i = 0; i < (int)embed_tokens_q4k.size(); ++i) {
239 }
240 std::vector<uint16_t> bf16_data(temp_f32_data.size());
241 #pragma omp parallel for
242 for (int i = 0; i < (int)temp_f32_data.size(); ++i) {
244 }
247 Logger::info("Dequantized token_embedding_table (Q4_K -> fp32 -> bf16) to GPU.");
249 }
250 else if (!embed_tokens_q6k.empty()) {
251 std::vector<float> temp_f32_data(embed_tokens_q6k.size() * GGML_QK_K);
252 #pragma omp parallel for
253 for (int i = 0; i < (int)embed_tokens_q6k.size(); ++i) {
255 }
256 std::vector<uint16_t> bf16_data(temp_f32_data.size());
257 #pragma omp parallel for
258 for (int i = 0; i < (int)temp_f32_data.size(); ++i) {
260 }
263 Logger::info("Dequantized token_embedding_table (Q6_K -> fp32 -> bf16) to GPU.");
265 }
266
268 Logger::info("[INIT_DEBUG] token_embedding_table_dev_ (BF16 on GPU) processed. Pointer: " + Logger::ptrToString(token_embedding_table_dev_) +
269 ". Flag token_embeddings_processed_to_gpu_bf16: YES");
270 }
272 Logger::warning("Token embeddings were not processed to GPU as BF16, despite GPU layers being active. This might indicate missing source embedding data in the model structure or an unhandled GGUF type for embeddings.");
273 }
274 } else {
275 Logger::info("No GPU layers active, skipping token embedding table processing for GPU.");
276 }
277
282
283 if (active_num_gpu_layers > 0) {
284 if (!lm_head.empty()) {
285 gpuErrchk(cudaMalloc(&lm_head_dev_, lm_head.size() * sizeof(uint16_t)));
287 Logger::info("Copied lm_head (bf16 direct from model.lm_head) to GPU.");
289 }
290 else if (!lm_head_f32.empty()) {
291 std::vector<uint16_t> bf16_data(lm_head_f32.size());
292 #pragma omp parallel for
293 for (int i = 0; i < (int)lm_head_f32.size(); ++i) {
295 }
298 Logger::info("Converted lm_head (fp32 source -> bf16) to GPU.");
300 }
301 else if (!lm_head_q8_0.empty()) {
302 std::vector<float> temp_f32_data(lm_head_q8_0.size() * GGML_QK8_0);
303 #pragma omp parallel for
304 for (int i = 0; i < (int)lm_head_q8_0.size(); ++i) {
306 }
307 std::vector<uint16_t> bf16_data(temp_f32_data.size());
308 #pragma omp parallel for
309 for (int i = 0; i < (int)temp_f32_data.size(); ++i) {
311 }
314 Logger::info("Dequantized lm_head (Q8_0 -> fp32 -> bf16) to GPU.");
316 }
317 else if (!lm_head_q4k.empty()) {
318 std::vector<float> temp_f32_data(lm_head_q4k.size() * GGML_QK_K);
319 #pragma omp parallel for
320 for (int i = 0; i < (int)lm_head_q4k.size(); ++i) {
322 }
323 std::vector<uint16_t> bf16_data(temp_f32_data.size());
324 #pragma omp parallel for
325 for (int i = 0; i < (int)temp_f32_data.size(); ++i) {
327 }
330 Logger::info("Dequantized lm_head (Q4_K -> fp32 -> bf16) to GPU.");
332 }
333 else if (!lm_head_q6k.empty()) {
334 std::vector<float> temp_f32_data(lm_head_q6k.size() * GGML_QK_K);
335 #pragma omp parallel for
336 for (int i = 0; i < (int)lm_head_q6k.size(); ++i) {
338 }
339 std::vector<uint16_t> bf16_data(temp_f32_data.size());
340 #pragma omp parallel for
341 for (int i = 0; i < (int)temp_f32_data.size(); ++i) {
343 }
346 Logger::info("Dequantized lm_head (Q6_K -> fp32 -> bf16) to GPU.");
348 }
349
351 Logger::warning("LM head was not processed to GPU as BF16, despite GPU layers being active. This might indicate missing source LM head data in the model structure or an unhandled GGUF type for LM head.");
352 }
353 } else {
354 Logger::info("No GPU layers active, skipping LM head processing for GPU.");
355 }
356
358
359 if (active_num_gpu_layers > 0) {
360 if (!lm_head_f32.empty()) {
361 gpuErrchk(cudaMalloc(&lm_head_f32_dev_, lm_head_f32.size() * sizeof(float)));
363 Logger::info("[INIT_GPU_ROPE] Copied lm_head_f32 (host FP32) to GPU for lm_head_f32_dev_. Pointer: " + Logger::ptrToString(lm_head_f32_dev_));
364 } else {
365 Logger::error("[INIT_GPU_ROPE] Host lm_head_f32 is EMPTY. Cannot populate lm_head_f32_dev_. This WILL CAUSE a cublasSgemm error in the final matvec. Check model loading and initialize_weights logic for lm_head_f32 population.");
366 lm_head_f32_dev_ = nullptr;
367 }
368 } else {
369 lm_head_f32_dev_ = nullptr;
370 }
371
372
373 Logger::info("Finished processing embedding and LM head tables for GPU.");
374
376 if (active_num_gpu_layers > 0) {
377 if (!precomputed_freqs_cis_.empty()) {
380 std::vector<float> flat_host_freqs; flat_host_freqs.reserve(total_freq_elements);
381 for (const auto& p : precomputed_freqs_cis_) { flat_host_freqs.push_back(p.first); flat_host_freqs.push_back(p.second); }
383 Logger::info("Copied all precomputed RoPE frequencies to persistent GPU buffer.");
384 } else {
385 Logger::warning("Host precomputed_freqs_cis_ is empty. Skipping GPU RoPE buffer allocation. This WILL cause issues if GPU layers use RoPE.");
386 }
387 Logger::info("Finished processing RoPE frequencies for GPU.");
388 } else {
389 Logger::info("No GPU layers active, skipping RoPE GPU buffer allocation.");
390 }
391
392 if (active_num_gpu_layers > 0) {
393 Logger::info("Allocating/Reallocating persistent GPU workspace buffers for " + std::to_string(active_num_gpu_layers) + " GPU layers.");
394 size_t hs_bytes = (size_t)hs * sizeof(float);
395 size_t is_bytes = (size_t)is * sizeof(float);
396 size_t vs_bytes = (size_t)vs * sizeof(float);
397 size_t k_dev_size_bytes = (size_t)n_kv_heads * head_dim * sizeof(float);
398 size_t v_dev_size_bytes = (size_t)n_kv_heads * head_dim * sizeof(float);
399
400#define REALLOC_GPU_WORKSPACE(ptr, sz) SAFE_CUDA_FREE(ptr); gpuErrchk(cudaMalloc(&ptr, sz));
415 Logger::info("Finished allocating/reallocating GPU workspace buffers.");
416 } else {
417 Logger::info("No GPU layers active, skipping GPU workspace buffer allocation.");
421 }
422
423 if (active_num_gpu_layers > 0) {
426
432 Logger::info("Allocated SELECTIVE KVCache dequantization buffers (K and V) on GPU. Size per buffer: " +
433 std::to_string(selective_buffer_bytes / (1024.0 * 1024.0)) + " MB (vs " +
434 std::to_string((static_cast<size_t>(config_.max_position_embeddings) * n_kv_heads * head_dim * sizeof(float)) / (1024.0 * 1024.0)) + " MB for full buffers)");
435 } else {
436 Logger::warning("Selective KVCache dequantization buffer size is 0. Skipping allocation.");
439 }
440
443 } else {
448 }
449
454
455 std::vector<uint16_t> h_q, h_k, h_v, h_o, h_gate, h_up, h_down;
460
461 Logger::info("Concatenating BF16 weights for GPU layers on host (zero-padding if missing for a layer)...");
462 for (int i = 0; i < active_num_gpu_layers; ++i) {
464 const auto& lw = layers[model_layer_idx];
465
466 if (!lw.q_proj.empty()) {
467 h_q.insert(h_q.end(), lw.q_proj.begin(), lw.q_proj.end());
468 } else {
469 h_q.insert(h_q.end(), layer_q_size, bfloat16::ZERO);
470 }
471
472 if (!lw.k_proj.empty()) {
473 h_k.insert(h_k.end(), lw.k_proj.begin(), lw.k_proj.end());
474 } else {
475 h_k.insert(h_k.end(), layer_k_size, bfloat16::ZERO);
476 }
477
478 if (!lw.v_proj.empty()) {
479 h_v.insert(h_v.end(), lw.v_proj.begin(), lw.v_proj.end());
480 } else {
481 h_v.insert(h_v.end(), layer_v_size, bfloat16::ZERO);
482 }
483
484 if (!lw.o_proj.empty()) {
485 h_o.insert(h_o.end(), lw.o_proj.begin(), lw.o_proj.end());
486 } else {
487 h_o.insert(h_o.end(), layer_o_size, bfloat16::ZERO);
488 }
489
490 if (!lw.gate_proj.empty()) {
491 h_gate.insert(h_gate.end(), lw.gate_proj.begin(), lw.gate_proj.end());
492 } else {
494 }
495
496 if (!lw.up_proj.empty()) {
497 h_up.insert(h_up.end(), lw.up_proj.begin(), lw.up_proj.end());
498 } else {
499 h_up.insert(h_up.end(), layer_up_size, bfloat16::ZERO);
500 }
501
502 if (!lw.down_proj.empty()) {
503 h_down.insert(h_down.end(), lw.down_proj.begin(), lw.down_proj.end());
504 } else {
506 }
507 }
508
509#define ALLOC_COPY_CONCAT_BF16(dev_ptr, host_vec, weight_name_str) \
510 SAFE_CUDA_FREE(dev_ptr); \
511 if (!host_vec.empty()) { \
512 gpuErrchk(cudaMalloc(&dev_ptr, host_vec.size() * sizeof(uint16_t))); \
513 gpuErrchk(cudaMemcpy(dev_ptr, host_vec.data(), host_vec.size() * sizeof(uint16_t), cudaMemcpyHostToDevice)); \
514 Logger::info("Copied concatenated " weight_name_str " (BF16) to GPU for GPU layers."); \
515 } else if (active_num_gpu_layers > 0) { \
516 Logger::info("Host vector for concatenated " weight_name_str " (BF16) is empty. Skipping GPU copy."); \
517 }
518
522#undef ALLOC_COPY_CONCAT_BF16
523
524 } else {
525 Logger::info("Skipping BF16 concatenated layer weight processing (first GPU layer appears not to use BF16 q_proj, or no GPU layers).");
528 }
529
530 Logger::info("DEFERRING concatenated F32 weight processing for GPU layers to save memory during initialization");
531 Logger::info("Concatenated F32 weights will be processed on-demand during first inference");
532
535
536 // Free BF16 concatenated weights
539
540 Logger::info("Finished deferring concatenated F32 weight processing for GPU layers.");
541
542 // Allocate persistent batch processing buffers for GPU memory optimization
543 if (active_num_gpu_layers > 0) {
545 }
546
547#undef SAFE_CUDA_FREE
548#else
549 if (active_num_gpu_layers > 0 && nhl > 0) {
550 Logger::warning("CUDA not available, but " + std::to_string(active_num_gpu_layers) + " layer(s) were configured for GPU. Model will run entirely on CPU.");
551 } else {
552 Logger::info("CUDA not available or no GPU layers configured. Model will run entirely on CPU.");
553 }
554#endif
555}
static void warning(const std::string &message)
Definition logger.cpp:139
static std::string ptrToString(const void *ptr)
Definition logger.cpp:225
static void info(const std::string &message)
Definition logger.cpp:135
static void error(const std::string &message)
Definition logger.cpp:143
bool use_bf16_tensor_cores_
Definition model.h:574
std::vector< block_q6_K > embed_tokens_q6k
Definition model.h:584
std::vector< float > final_norm_f32
Definition model.h:581
std::vector< uint16_t > final_norm
Definition model.h:580
std::vector< block_q4_K > lm_head_q4k
Definition model.h:582
std::vector< block_q6_K > lm_head_q6k
Definition model.h:584
std::vector< std::pair< float, float > > precomputed_freqs_cis_
Definition model.h:694
void ensure_embed_tokens_dequantized()
std::vector< LayerWeights > layers
Definition model.h:587
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_q8_0 > lm_head_q8_0
Definition model.h:585
std::vector< uint16_t > lm_head
Definition model.h:579
std::vector< uint16_t > embed_tokens
Definition model.h:578
std::vector< float > embed_tokens_f32
Definition model.h:581
void ensure_lm_head_dequantized()
std::vector< float > lm_head_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
const float * p[kIrDepthSourcesMax]
size_t j
Logging utilities for the TinyLlama implementation.
Constants used throughout the TinyLlama model implementation.
constexpr uint16_t ZERO
bool deterministic()
Definition determinism.h:22
void deterministic_cublas_env()
Definition determinism.h:32
void dequantize_q4_k_m(const block_q4_K *qblock, float *output, int num_weights_in_block, bool log_this_block)
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
int intermediate_size
Definition model.h:84
int num_cpu_offload_layers
Definition model.h:106
float rope_theta
Definition model.h:91
int num_hidden_layers
Definition model.h:87
int num_key_value_heads
Definition model.h:86
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
uint16_t float32_to_bfloat16(float val)
Definition utils.cpp:137