| 460 | } |
| 461 | |
| 462 | size_t server_tokens::get_common_prefix(const server_tokens & b) const { |
| 463 | const size_t max_idx = std::min(tokens.size(), b.tokens.size()); |
| 464 | |
| 465 | if (!has_mtmd) { |
| 466 | for (size_t i = 0; i < max_idx; ++i) { |
| 467 | if (tokens[i] == b.tokens[i]) { |
| 468 | continue; |
| 469 | } |
| 470 | |
| 471 | return i; |
| 472 | } |
| 473 | |
| 474 | return max_idx; |
| 475 | } |
| 476 | |
| 477 | for (size_t i = 0; i < max_idx; ++i) { |
| 478 | const llama_token ai = tokens[i]; |
| 479 | const llama_token bi = b.tokens[i]; |
| 480 | |
| 481 | if (ai == LLAMA_TOKEN_NULL && bi == LLAMA_TOKEN_NULL) { |
| 482 | const auto & a_chunk = find_chunk(i); |
| 483 | const auto & b_chunk = b.find_chunk(i); |
| 484 | |
| 485 | GGML_ASSERT(a_chunk && b_chunk); |
| 486 | |
| 487 | const std::string id_ai = mtmd_input_chunk_get_id(a_chunk.get()); |
| 488 | const std::string id_bi = mtmd_input_chunk_get_id(b_chunk.get()); |
| 489 | |
| 490 | const size_t n_tok_a = mtmd_input_chunk_get_n_tokens(a_chunk.get()); |
| 491 | const size_t n_tok_b = mtmd_input_chunk_get_n_tokens(b_chunk.get()); |
| 492 | |
| 493 | if (id_ai == id_bi && n_tok_a == n_tok_b) { |
| 494 | GGML_ASSERT(n_tok_a > 0 && "Invalid media chunk"); // should never happen |
| 495 | i += n_tok_a - 1; // will be +1 by the for loop |
| 496 | continue; |
| 497 | } |
| 498 | |
| 499 | return i; |
| 500 | } |
| 501 | |
| 502 | if (ai == bi) { |
| 503 | continue; |
| 504 | } |
| 505 | |
| 506 | return i; |
| 507 | } |
| 508 | |
| 509 | return max_idx; // all tokens are equal |
| 510 | } |
| 511 | |
| 512 | bool server_tokens::validate(const struct llama_context * ctx) const { |
| 513 | const llama_model * model = llama_get_model(ctx); |
no test coverage detected