| 607 | |
| 608 | template <typename CharT> |
| 609 | static std::vector<size_t> unicode_regex_split_stl(const std::basic_string<CharT> & text, const std::basic_string<CharT> & regex, const std::vector<size_t> & offsets) { |
| 610 | using BidirIt = typename std::basic_string<CharT>::const_iterator; |
| 611 | #ifdef _MSC_VER |
| 612 | // Bypass bug in MSVC: https://github.com/ggml-org/llama.cpp/issues/17830 |
| 613 | constexpr auto regex_flags = std::regex_constants::ECMAScript; |
| 614 | #else |
| 615 | constexpr auto regex_flags = std::regex_constants::optimize | std::regex_constants::nosubs; |
| 616 | #endif |
| 617 | std::basic_regex<CharT> expr(regex, regex_flags); |
| 618 | std::vector<size_t> bpe_offsets; // store the offset of each word |
| 619 | bpe_offsets.reserve(offsets.size()); // Reserve memory for the approximate size |
| 620 | size_t start = 0; |
| 621 | for (auto offset : offsets) { |
| 622 | std::regex_iterator<BidirIt> it(text.begin() + start, text.begin() + start + offset, expr); |
| 623 | std::regex_iterator<BidirIt> end; |
| 624 | |
| 625 | int64_t start_idx = 0; |
| 626 | while (it != end) { |
| 627 | std::match_results<BidirIt> match = *it; |
| 628 | if (match.position() > start_idx) { |
| 629 | bpe_offsets.emplace_back(match.position() - start_idx); |
| 630 | } |
| 631 | bpe_offsets.emplace_back(match.length()); |
| 632 | start_idx = match.position() + match.length(); |
| 633 | ++it; |
| 634 | } |
| 635 | |
| 636 | if (start_idx < (int64_t) offset) { |
| 637 | bpe_offsets.emplace_back(offset - start_idx); |
| 638 | } |
| 639 | start += offset; |
| 640 | } |
| 641 | |
| 642 | return bpe_offsets; |
| 643 | } |
| 644 | |
| 645 | // K2 system regex patterns (from tokenization_kimi.py): |
| 646 | // [\p{Han}]+|[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}&&[^\p{Han}]]*[\p{Ll}\p{Lm}\p{Lo}\p{M}&&[^\p{Han}]]+(?i:'s|'t|'re|'ve|'m|'ll|'d)?|[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}&&[^\p{Han}]]+[\p{Ll}\p{Lm}\p{Lo}\p{M}&&[^\p{Han}]]*(?i:'s|'t|'re|'ve|'m|'ll|'d)?|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+ |
no test coverage detected