Tokenize text into a fixed-length token ID vector [ctx_len]. Format: [SOT, bpe_tokens..., EOT, 0, 0, ..., 0]
| 1405 | // Tokenize text into a fixed-length token ID vector [ctx_len]. |
| 1406 | // Format: [SOT, bpe_tokens..., EOT, 0, 0, ..., 0] |
| 1407 | static std::vector<int32_t> sam3_tokenize(sam3_bpe_tokenizer& tok, |
| 1408 | const std::string& text, |
| 1409 | int ctx_len) { |
| 1410 | std::string lower; |
| 1411 | lower.reserve(text.size()); |
| 1412 | for (char c : text) { |
| 1413 | lower += (c >= 'A' && c <= 'Z') ? (char)(c + 32) : c; |
| 1414 | } |
| 1415 | |
| 1416 | std::string clean; |
| 1417 | clean.reserve(lower.size()); |
| 1418 | bool last_ws = true; |
| 1419 | for (char c : lower) { |
| 1420 | if (c == ' ' || c == '\t' || c == '\n' || c == '\r') { |
| 1421 | if (!last_ws) { |
| 1422 | clean += ' '; |
| 1423 | last_ws = true; |
| 1424 | } |
| 1425 | } else { |
| 1426 | clean += c; |
| 1427 | last_ws = false; |
| 1428 | } |
| 1429 | } |
| 1430 | if (!clean.empty() && clean.back() == ' ') clean.pop_back(); |
| 1431 | |
| 1432 | auto words = sam3_pretokenize(clean); |
| 1433 | |
| 1434 | std::vector<int32_t> ids; |
| 1435 | ids.push_back(tok.sot_token); |
| 1436 | |
| 1437 | for (const auto& word : words) { |
| 1438 | std::string encoded; |
| 1439 | for (uint8_t b : word) { |
| 1440 | auto it = tok.byte_encoder.find(b); |
| 1441 | if (it != tok.byte_encoder.end()) { |
| 1442 | encoded += it->second; |
| 1443 | } |
| 1444 | } |
| 1445 | |
| 1446 | std::string bpe_result = sam3_bpe_encode(tok, encoded); |
| 1447 | |
| 1448 | size_t start = 0; |
| 1449 | while (start < bpe_result.size()) { |
| 1450 | size_t end = bpe_result.find(' ', start); |
| 1451 | if (end == std::string::npos) end = bpe_result.size(); |
| 1452 | std::string bpe_tok = bpe_result.substr(start, end - start); |
| 1453 | |
| 1454 | auto eit = tok.encoder.find(bpe_tok); |
| 1455 | if (eit != tok.encoder.end()) { |
| 1456 | ids.push_back(eit->second); |
| 1457 | } |
| 1458 | // Unknown tokens are silently dropped (matches CLIP behavior |
| 1459 | // where all byte sequences are in the vocab) |
| 1460 | |
| 1461 | start = end + 1; |
| 1462 | } |
| 1463 | } |
| 1464 |
no test coverage detected