| 3082 | } |
| 3083 | |
| 3084 | int32_t llama_vocab::impl::token_to_piece(llama_token token, char * buf, int32_t length, int32_t lstrip, bool special) const { |
| 3085 | // ref: https://github.com/ggml-org/llama.cpp/pull/7587#discussion_r1620983843 |
| 3086 | static const int attr_special = LLAMA_TOKEN_ATTR_UNKNOWN | LLAMA_TOKEN_ATTR_CONTROL; |
| 3087 | const llama_token_attr attr = token_get_attr(token); |
| 3088 | if (!special && (attr & attr_special)) { |
| 3089 | return 0; |
| 3090 | } |
| 3091 | |
| 3092 | // copy piece chars to output text buffer |
| 3093 | // skip up to 'lstrip' leading spaces before copying |
| 3094 | auto _try_copy = [=] (const char * token, size_t size) -> int32_t { |
| 3095 | if (size >= static_cast<size_t>(std::numeric_limits<int32_t>::max())) { |
| 3096 | GGML_ABORT("invalid token size: %zu exceeds int32_t limit", size); |
| 3097 | } |
| 3098 | |
| 3099 | for (int32_t i = 0; i < lstrip && size && *token == ' '; ++i) { |
| 3100 | token++; |
| 3101 | size--; |
| 3102 | } |
| 3103 | if (length < (int32_t)size) { |
| 3104 | return -(int32_t) size; |
| 3105 | } |
| 3106 | memcpy(buf, token, size); |
| 3107 | return (int32_t) size; |
| 3108 | }; |
| 3109 | |
| 3110 | // if we have a cache - use it |
| 3111 | { |
| 3112 | const auto & cache = cache_token_to_piece; |
| 3113 | |
| 3114 | if (!cache.empty()) { |
| 3115 | const auto & result = cache.at(token); |
| 3116 | return _try_copy(result.data(), result.size()); |
| 3117 | } |
| 3118 | } |
| 3119 | |
| 3120 | if (0 <= token && token < (int32_t) id_to_token.size()) { |
| 3121 | const std::string & token_text = id_to_token[token].text; |
| 3122 | switch (get_type()) { |
| 3123 | case LLAMA_VOCAB_TYPE_WPM: |
| 3124 | case LLAMA_VOCAB_TYPE_SPM: |
| 3125 | case LLAMA_VOCAB_TYPE_UGM: { |
| 3126 | // NOTE: we accept all unsupported token types, |
| 3127 | // suppressing them like CONTROL tokens. |
| 3128 | if (attr & (attr_special | LLAMA_TOKEN_ATTR_USER_DEFINED)) { |
| 3129 | return _try_copy(token_text.data(), token_text.size()); |
| 3130 | } |
| 3131 | if (attr & LLAMA_TOKEN_ATTR_NORMAL) { |
| 3132 | std::string result = token_text; |
| 3133 | llama_unescape_whitespace(result); |
| 3134 | return _try_copy(result.data(), result.size()); |
| 3135 | } |
| 3136 | if (attr & LLAMA_TOKEN_ATTR_BYTE) { |
| 3137 | char byte = (char) token_to_byte(token); |
| 3138 | return _try_copy((char*) &byte, 1); |
| 3139 | } |
| 3140 | break; |
| 3141 | } |
no test coverage detected