| 7252 | llm_tokenizer_bpe(const llama_vocab & vocab): vocab(vocab) {} |
| 7253 | |
| 7254 | void tokenize(const std::string & text, std::vector<llama_vocab::id> & output) { |
| 7255 | int final_prev_index = -1; |
| 7256 | auto word_collection = bpe_gpt2_preprocess(text); |
| 7257 | |
| 7258 | symbols_final.clear(); |
| 7259 | |
| 7260 | for (auto & word : word_collection) { |
| 7261 | work_queue = llm_bigram_bpe::queue(); |
| 7262 | symbols.clear(); |
| 7263 | |
| 7264 | int index = 0; |
| 7265 | size_t offset = 0; |
| 7266 | |
| 7267 | while (offset < word.size()) { |
| 7268 | llm_symbol sym; |
| 7269 | size_t char_len = std::min(word.size() - offset, (size_t) ::utf8_len(word[offset])); |
| 7270 | sym.text = word.c_str() + offset; |
| 7271 | sym.n = char_len; |
| 7272 | offset += sym.n; |
| 7273 | sym.prev = index - 1; |
| 7274 | sym.next = offset == word.size() ? -1 : index + 1; |
| 7275 | index++; |
| 7276 | symbols.emplace_back(sym); |
| 7277 | } |
| 7278 | for (size_t i = 1; i < symbols.size(); ++i) { |
| 7279 | add_new_bigram(i - 1, i); |
| 7280 | } |
| 7281 | |
| 7282 | // build token(s) |
| 7283 | while (!work_queue.empty()) { |
| 7284 | auto bigram = work_queue.top(); |
| 7285 | work_queue.pop(); |
| 7286 | |
| 7287 | auto & left_symbol = symbols[bigram.left]; |
| 7288 | auto & right_symbol = symbols[bigram.right]; |
| 7289 | |
| 7290 | if (left_symbol.n == 0 || right_symbol.n == 0) { |
| 7291 | continue; |
| 7292 | } |
| 7293 | std::string left_token = std::string(left_symbol.text, left_symbol.n); |
| 7294 | std::string right_token = std::string(right_symbol.text, right_symbol.n); |
| 7295 | if (left_token + right_token != bigram.text) { |
| 7296 | continue; // Skip this bigram if it's outdated |
| 7297 | } |
| 7298 | |
| 7299 | // merge the right sym into the left one |
| 7300 | left_symbol.n += right_symbol.n; |
| 7301 | right_symbol.n = 0; |
| 7302 | |
| 7303 | // remove the right sym from the chain |
| 7304 | left_symbol.next = right_symbol.next; |
| 7305 | if (right_symbol.next >= 0) { |
| 7306 | symbols[right_symbol.next].prev = bigram.left; |
| 7307 | } |
| 7308 | |
| 7309 | add_new_bigram(left_symbol.prev, bigram.left); // left side of current symbol |
| 7310 | add_new_bigram(bigram.left, left_symbol.next); // right side of current symbol |
| 7311 | } |
nothing calls this directly
no test coverage detected