| 349 | } |
| 350 | |
| 351 | void KVCache::update_from_npu(size_t layer_idx, const __fp16* k_data, const __fp16* v_data, |
| 352 | size_t num_tokens, size_t kv_heads, size_t dim) { |
| 353 | if (layer_idx >= num_layers || !k_data || !v_data || num_tokens == 0) { |
| 354 | return; |
| 355 | } |
| 356 | |
| 357 | auto& cache = layer_caches[layer_idx]; |
| 358 | size_t old_seq_len = current_seq_len; |
| 359 | size_t new_total_len = old_seq_len + num_tokens; |
| 360 | size_t elements_per_token = kv_heads * dim; |
| 361 | size_t bytes_per_token = elements_per_token * element_size; |
| 362 | size_t num_groups = (dim + KV_QUANT_GROUP_SIZE - 1) / KV_QUANT_GROUP_SIZE; |
| 363 | size_t scales_per_token = kv_heads * num_groups; |
| 364 | |
| 365 | if (layer_idx == 0) { |
| 366 | total_seq_len += num_tokens; |
| 367 | } |
| 368 | |
| 369 | bool use_sliding_window = (window_size > 0 && new_total_len > window_size); |
| 370 | size_t effective_seq_len = use_sliding_window ? window_size : new_total_len; |
| 371 | |
| 372 | if (!use_sliding_window) { |
| 373 | size_t total_bytes = new_total_len * bytes_per_token; |
| 374 | cache.keys.resize(total_bytes); |
| 375 | cache.values.resize(total_bytes); |
| 376 | |
| 377 | size_t num_scales = new_total_len * scales_per_token; |
| 378 | cache.key_scales.resize(num_scales); |
| 379 | cache.value_scales.resize(num_scales); |
| 380 | |
| 381 | size_t dst_offset = old_seq_len * elements_per_token; |
| 382 | size_t scale_offset = old_seq_len * scales_per_token; |
| 383 | |
| 384 | cactus_quantize_kv_fp16_to_int8( |
| 385 | k_data, |
| 386 | reinterpret_cast<int8_t*>(cache.keys.data()) + dst_offset, |
| 387 | cache.key_scales.data() + scale_offset, |
| 388 | num_tokens, kv_heads, dim); |
| 389 | |
| 390 | cactus_quantize_kv_fp16_to_int8( |
| 391 | v_data, |
| 392 | reinterpret_cast<int8_t*>(cache.values.data()) + dst_offset, |
| 393 | cache.value_scales.data() + scale_offset, |
| 394 | num_tokens, kv_heads, dim); |
| 395 | } else { |
| 396 | size_t cache_bytes = window_size * bytes_per_token; |
| 397 | |
| 398 | if (cache.keys.size() != cache_bytes) { |
| 399 | cache.keys.resize(cache_bytes); |
| 400 | cache.values.resize(cache_bytes); |
| 401 | |
| 402 | size_t num_scales = window_size * scales_per_token; |
| 403 | cache.key_scales.resize(num_scales); |
| 404 | cache.value_scales.resize(num_scales); |
| 405 | } |
| 406 | |
| 407 | size_t remaining_window = window_size - sink_size; |
| 408 |
no test coverage detected