| 286 | } |
| 287 | |
| 288 | std::vector<int32_t> VoxCPM2TextTokenizer::encode(const std::string & text) const { |
| 289 | std::vector<int32_t> ids; |
| 290 | for (size_t i = 0; i < text.size();) { |
| 291 | const auto special_it = std::find_if( |
| 292 | impl_->special_tokens.begin(), |
| 293 | impl_->special_tokens.end(), |
| 294 | [&](const auto & item) { return starts_with_at(text, i, item.first); }); |
| 295 | if (special_it != impl_->special_tokens.end()) { |
| 296 | impl_->append_expanded_id(ids, special_it->second); |
| 297 | i += special_it->first.size(); |
| 298 | continue; |
| 299 | } |
| 300 | |
| 301 | size_t next_special = text.size(); |
| 302 | for (const auto & [special, _] : impl_->special_tokens) { |
| 303 | const size_t pos = text.find(special, i); |
| 304 | if (pos != std::string::npos) { |
| 305 | next_special = std::min(next_special, pos); |
| 306 | } |
| 307 | } |
| 308 | const std::string normalized = normalize_text(std::string_view( |
| 309 | text.data() + static_cast<std::ptrdiff_t>(i), |
| 310 | next_special - i)); |
| 311 | for (const auto & bpe_token : impl_->bpe(normalized)) { |
| 312 | const auto vocab_it = impl_->vocab.find(bpe_token); |
| 313 | if (vocab_it == impl_->vocab.end()) { |
| 314 | throw std::runtime_error("VoxCPM2 tokenizer produced token not present in vocab: " + bpe_token); |
| 315 | } |
| 316 | impl_->append_expanded_id(ids, vocab_it->second); |
| 317 | } |
| 318 | i = next_special; |
| 319 | } |
| 320 | return ids; |
| 321 | } |
| 322 | |
| 323 | VoxCPM2TextPrompt VoxCPM2TextTokenizer::build_prompt(const std::string & text) const { |
| 324 | if (text.empty()) { |
nothing calls this directly
no test coverage detected