Adding support for Aquila (GPT2?) tokenizer.
This commit is contained in:
parent
1b5442923a
commit
19e950f051
6 changed files with 110 additions and 48 deletions
11
convert.py
11
convert.py
|
@ -237,12 +237,12 @@ class SentencePieceVocab:
|
||||||
def __init__(self, fname_tokenizer: Path, fname_added_tokens: Optional[Path], vocabtype: Optional[str]) -> None:
|
def __init__(self, fname_tokenizer: Path, fname_added_tokens: Optional[Path], vocabtype: Optional[str]) -> None:
|
||||||
self.vocabtype = vocabtype
|
self.vocabtype = vocabtype
|
||||||
if self.vocabtype == "bpe":
|
if self.vocabtype == "bpe":
|
||||||
self.sentencepiece_tokenizer = json.loads(open(str(fname_tokenizer)).read())
|
self.sentencepiece_tokenizer = json.loads(open(str(fname_tokenizer), encoding="utf-8").read())
|
||||||
else:
|
else:
|
||||||
self.sentencepiece_tokenizer = SentencePieceProcessor(str(fname_tokenizer))
|
self.sentencepiece_tokenizer = SentencePieceProcessor(str(fname_tokenizer))
|
||||||
added_tokens: Dict[str, int]
|
added_tokens: Dict[str, int]
|
||||||
if fname_added_tokens is not None:
|
if fname_added_tokens is not None:
|
||||||
added_tokens = json.load(open(fname_added_tokens))
|
added_tokens = json.load(open(fname_added_tokens, encoding="utf-8"))
|
||||||
else:
|
else:
|
||||||
added_tokens = {}
|
added_tokens = {}
|
||||||
if self.vocabtype == "bpe":
|
if self.vocabtype == "bpe":
|
||||||
|
@ -267,8 +267,9 @@ class SentencePieceVocab:
|
||||||
byte_encoder = tokenization_gpt2.bytes_to_unicode()
|
byte_encoder = tokenization_gpt2.bytes_to_unicode()
|
||||||
byte_decoder = {v: k for k, v in byte_encoder.items()}
|
byte_decoder = {v: k for k, v in byte_encoder.items()}
|
||||||
for i, item in enumerate(tokenizer):
|
for i, item in enumerate(tokenizer):
|
||||||
text: bytes
|
# text: bytes
|
||||||
text = b''.join([x.to_bytes(1, byteorder='big') for x in [byte_decoder[y] for y in item]])
|
# text = b''.join([x.to_bytes(1, byteorder='big') for x in [byte_decoder[y] for y in item]])
|
||||||
|
text: bytes = item.encode("utf-8")
|
||||||
score: float = -i
|
score: float = -i
|
||||||
yield text, score
|
yield text, score
|
||||||
else:
|
else:
|
||||||
|
|
93
llama.cpp
93
llama.cpp
|
@ -539,7 +539,7 @@ struct llama_file_loader {
|
||||||
float score = 0.0f;
|
float score = 0.0f;
|
||||||
file.read_raw(&score, sizeof(score));
|
file.read_raw(&score, sizeof(score));
|
||||||
|
|
||||||
assert(vocab.token_to_id.find(word) == vocab.token_to_id.end());
|
GGML_ASSERT(vocab.token_to_id.find(word) == vocab.token_to_id.end());
|
||||||
vocab.token_to_id[word] = i;
|
vocab.token_to_id[word] = i;
|
||||||
|
|
||||||
auto & tok_score = vocab.id_to_token[i];
|
auto & tok_score = vocab.id_to_token[i];
|
||||||
|
@ -1832,36 +1832,77 @@ static bool llama_eval_internal(
|
||||||
// tokenizer
|
// tokenizer
|
||||||
//
|
//
|
||||||
|
|
||||||
bool llama_is_normal_token(llama_token token) {
|
static std::string llama_vocab_type(const llama_vocab& vocab) {
|
||||||
return token >= 259;
|
return vocab.token_to_id.size() == 32000 ? "spm": "bpe";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llama_is_unknown_token(llama_token token) {
|
static bool llama_is_normal_token(const llama_vocab& vocab, llama_token token) {
|
||||||
return token == 0;
|
if(llama_vocab_type(vocab) == "spm")
|
||||||
|
return token >= 259;
|
||||||
|
else if(llama_vocab_type(vocab) == "bpe")
|
||||||
|
return token >= 95;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llama_is_control_token(llama_token token) {
|
static bool llama_is_unknown_token(const llama_vocab& vocab, llama_token token) {
|
||||||
return token == 1 || token == 2;
|
if(llama_vocab_type(vocab) == "spm")
|
||||||
|
return token == 0;
|
||||||
|
else
|
||||||
|
// TODO: improve?
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llama_is_bos_token(llama_token token) {
|
static bool llama_is_control_token(const llama_vocab& vocab, llama_token token) {
|
||||||
return token == 1;
|
if(llama_vocab_type(vocab) == "spm")
|
||||||
|
return token == 1 || token == 2;
|
||||||
|
else
|
||||||
|
// TODO: improve?
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llama_is_eos_token(llama_token token) {
|
static bool llama_is_bos_token(const llama_vocab& vocab, llama_token token) {
|
||||||
return token == 2;
|
if(llama_vocab_type(vocab) == "spm")
|
||||||
|
return token == 1;
|
||||||
|
else
|
||||||
|
// TODO: improve?
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llama_is_user_defined_token(llama_token token) {
|
static bool llama_is_eos_token(const llama_vocab& vocab, llama_token token) {
|
||||||
|
if(llama_vocab_type(vocab) == "spm")
|
||||||
|
return token == 2;
|
||||||
|
else
|
||||||
|
// TODO: improve?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool llama_is_user_defined_token(const llama_vocab& vocab, llama_token token) {
|
||||||
|
// TODO: improve?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llama_is_unused_token(llama_token token) {
|
static bool llama_is_unused_token(const llama_vocab& vocab, llama_token token) {
|
||||||
|
// TODO: improve?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llama_is_byte_token(llama_token token) {
|
static bool llama_is_byte_token(const llama_vocab& vocab, llama_token token) {
|
||||||
return 3 <= token && token < 259;
|
if(llama_vocab_type(vocab) == "spm")
|
||||||
|
return 3 <= token && token < 259;
|
||||||
|
else if(llama_vocab_type(vocab) == "bpe")
|
||||||
|
return 1 <= token && token < 95;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t llama_byte_to_char(const llama_vocab& vocab, uint8_t byte) {
|
||||||
|
if(llama_vocab_type(vocab) == "spm")
|
||||||
|
return byte + 3;
|
||||||
|
else if(llama_vocab_type(vocab) == "bpe")
|
||||||
|
return byte + 32;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string llama_escape_whitespace(const std::string& text) {
|
static std::string llama_escape_whitespace(const std::string& text) {
|
||||||
|
@ -1932,6 +1973,7 @@ struct llama_tokenizer {
|
||||||
while (offs < text.size()) {
|
while (offs < text.size()) {
|
||||||
llama_sp_symbol sym;
|
llama_sp_symbol sym;
|
||||||
size_t len = utf8_len(text[offs]);
|
size_t len = utf8_len(text[offs]);
|
||||||
|
GGML_ASSERT(offs + len <= text.size());
|
||||||
sym.text = text.c_str() + offs;
|
sym.text = text.c_str() + offs;
|
||||||
sym.n = len;
|
sym.n = len;
|
||||||
offs += len;
|
offs += len;
|
||||||
|
@ -1999,7 +2041,7 @@ private:
|
||||||
if (p == rev_merge.end()) {
|
if (p == rev_merge.end()) {
|
||||||
// output any symbols that did not form tokens as bytes.
|
// output any symbols that did not form tokens as bytes.
|
||||||
for (int j = 0; j < (int)symbol.n; ++j) {
|
for (int j = 0; j < (int)symbol.n; ++j) {
|
||||||
llama_vocab::id token_id = static_cast<uint8_t>(symbol.text[j]) + 3;
|
llama_vocab::id token_id = llama_byte_to_char(vocab_, symbol.text[j]);
|
||||||
output.push_back(token_id);
|
output.push_back(token_id);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -4054,7 +4096,7 @@ int llama_tokenize_with_model(
|
||||||
llama_token * tokens,
|
llama_token * tokens,
|
||||||
int n_max_tokens,
|
int n_max_tokens,
|
||||||
bool add_bos) {
|
bool add_bos) {
|
||||||
auto res = llama_tokenize(model->vocab, text, add_bos, true);
|
auto res = llama_tokenize(model->vocab, text, add_bos, llama_vocab_type(model->vocab) == "spm");
|
||||||
|
|
||||||
if (n_max_tokens < (int) res.size()) {
|
if (n_max_tokens < (int) res.size()) {
|
||||||
return -((int) res.size());
|
return -((int) res.size());
|
||||||
|
@ -4186,29 +4228,32 @@ float * llama_get_embeddings(struct llama_context * ctx) {
|
||||||
|
|
||||||
int llama_token_to_str_with_model(const struct llama_model * model, llama_token token, char * str, int length) {
|
int llama_token_to_str_with_model(const struct llama_model * model, llama_token token, char * str, int length) {
|
||||||
if (0 <= token && token < llama_n_vocab_from_model(model)) {
|
if (0 <= token && token < llama_n_vocab_from_model(model)) {
|
||||||
if (llama_is_normal_token(token)) {
|
if (llama_is_normal_token(model->vocab, token)) {
|
||||||
std::string result = llama_unescape_whitespace(model->vocab.id_to_token[token].tok);
|
std::string result = model->vocab.id_to_token[token].tok;
|
||||||
|
if(llama_vocab_type(model->vocab) == "spm") {
|
||||||
|
result = llama_unescape_whitespace(result);
|
||||||
|
}
|
||||||
if(result.length() > length) {
|
if(result.length() > length) {
|
||||||
return - result.length();
|
return - result.length();
|
||||||
}
|
}
|
||||||
strcpy(str, result.c_str());
|
strcpy(str, result.c_str());
|
||||||
return result.length();
|
return result.length();
|
||||||
} else if (llama_is_unknown_token(token)) {
|
} else if (llama_is_unknown_token(model->vocab, token)) {
|
||||||
if(3 > length) {
|
if(3 > length) {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
strcpy(str, "\xe2\x96\x85");
|
strcpy(str, "\xe2\x96\x85");
|
||||||
return 3;
|
return 3;
|
||||||
} else if (llama_is_control_token(token)) {
|
} else if (llama_is_control_token(model->vocab, token)) {
|
||||||
;
|
;
|
||||||
} else if (llama_is_byte_token(token)) {
|
} else if (llama_is_byte_token(model->vocab, token)) {
|
||||||
if(1 > length) {
|
if(1 > length) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
str[0] = token - 3;
|
str[0] = llama_byte_to_char(model->vocab, token);
|
||||||
str[1] = 0x00;
|
str[1] = 0x00;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
BIN
models/ggml-vocab-aquila.bin
Normal file
BIN
models/ggml-vocab-aquila.bin
Normal file
Binary file not shown.
|
@ -1,4 +1,19 @@
|
||||||
function(llama_add_test source)
|
function(llama_build_executable source)
|
||||||
|
get_filename_component(TEST_TARGET ${source} NAME_WE)
|
||||||
|
add_executable(${TEST_TARGET} ${source})
|
||||||
|
install(TARGETS ${TEST_TARGET} RUNTIME)
|
||||||
|
target_link_libraries(${TEST_TARGET} PRIVATE llama)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(llama_test_executable name source)
|
||||||
|
get_filename_component(TEST_TARGET ${source} NAME_WE)
|
||||||
|
# add_executable(${TEST_TARGET} ${source})
|
||||||
|
# install(TARGETS ${TEST_TARGET} RUNTIME)
|
||||||
|
# target_link_libraries(${TEST_TARGET} PRIVATE llama)
|
||||||
|
add_test(NAME ${name} COMMAND $<TARGET_FILE:${TEST_TARGET}> ${ARGN})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(llama_build_and_test_executable source)
|
||||||
get_filename_component(TEST_TARGET ${source} NAME_WE)
|
get_filename_component(TEST_TARGET ${source} NAME_WE)
|
||||||
add_executable(${TEST_TARGET} ${source})
|
add_executable(${TEST_TARGET} ${source})
|
||||||
install(TARGETS ${TEST_TARGET} RUNTIME)
|
install(TARGETS ${TEST_TARGET} RUNTIME)
|
||||||
|
@ -6,11 +21,14 @@ function(llama_add_test source)
|
||||||
add_test(NAME ${TEST_TARGET} COMMAND $<TARGET_FILE:${TEST_TARGET}> ${ARGN})
|
add_test(NAME ${TEST_TARGET} COMMAND $<TARGET_FILE:${TEST_TARGET}> ${ARGN})
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# llama_add_test(test-double-float.c) # SLOW
|
# llama_build_and_test_executable(test-double-float.c) # SLOW
|
||||||
llama_add_test(test-quantize-fns.cpp)
|
llama_build_and_test_executable(test-quantize-fns.cpp)
|
||||||
llama_add_test(test-quantize-perf.cpp)
|
llama_build_and_test_executable(test-quantize-perf.cpp)
|
||||||
llama_add_test(test-sampling.cpp)
|
llama_build_and_test_executable(test-sampling.cpp)
|
||||||
llama_add_test(test-tokenizer-0.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../models/ggml-vocab.bin)
|
llama_build_executable(test-tokenizer-0.cpp)
|
||||||
llama_add_test(test-tokenizer-1.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../models/ggml-vocab.bin)
|
llama_test_executable(test-tokenizer-0.llama test-tokenizer-0.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../models/ggml-vocab-llama.bin)
|
||||||
llama_add_test(test-grad0.c) # SLOW
|
llama_build_executable(test-tokenizer-1.cpp)
|
||||||
# llama_add_test(test-opt.c) # SLOW
|
llama_test_executable(test-tokenizer-1.llama test-tokenizer-1.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../models/ggml-vocab-llama.bin)
|
||||||
|
llama_test_executable(test-tokenizer-1.aquila test-tokenizer-1.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../models/ggml-vocab-aquila.bin)
|
||||||
|
llama_build_and_test_executable(test-grad0.c) # SLOW
|
||||||
|
# llama_build_and_test_executable(test-opt.c) # SLOW
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
static std::string vocab_type(llama_context* ctx) {
|
||||||
|
return llama_n_vocab(ctx) == 32000 ? "spm": "bpe";
|
||||||
|
}
|
||||||
|
|
||||||
static std::string escape_whitespace(const std::string& text) {
|
static std::string escape_whitespace(const std::string& text) {
|
||||||
std::string result;
|
std::string result;
|
||||||
bool escaping = false;
|
bool escaping = false;
|
||||||
|
@ -75,13 +79,6 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
const int n_vocab = llama_n_vocab(ctx);
|
const int n_vocab = llama_n_vocab(ctx);
|
||||||
|
|
||||||
if (n_vocab != 32000) {
|
|
||||||
fprintf(stderr, "%s : expected 32000 tokens, got %d\n", __func__, n_vocab);
|
|
||||||
llama_free_model(model);
|
|
||||||
llama_free(ctx);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < n_vocab; ++i) {
|
for (int i = 0; i < n_vocab; ++i) {
|
||||||
std::string forward = llama_token_to_str_bpe(ctx, i);
|
std::string forward = llama_token_to_str_bpe(ctx, i);
|
||||||
std::vector<llama_token> tokens = llama_tokenize_bpe(ctx, forward, false);
|
std::vector<llama_token> tokens = llama_tokenize_bpe(ctx, forward, false);
|
||||||
|
@ -90,16 +87,17 @@ int main(int argc, char **argv) {
|
||||||
std::string backward = llama_token_to_str(ctx, tokens[0]);
|
std::string backward = llama_token_to_str(ctx, tokens[0]);
|
||||||
fprintf(stderr, "%s : error: token %d is string %s but bpe returns token %d %s\n",
|
fprintf(stderr, "%s : error: token %d is string %s but bpe returns token %d %s\n",
|
||||||
__func__, i, llama_token_to_str(ctx, i).c_str(), tokens[0], backward.c_str());
|
__func__, i, llama_token_to_str(ctx, i).c_str(), tokens[0], backward.c_str());
|
||||||
return 3;
|
return 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (i <= 258) {
|
if ((vocab_type(ctx) == "spm" && i <= 258) ||
|
||||||
|
(vocab_type(ctx) == "bpe" && (i == 0 || i >= 100000))) {
|
||||||
fprintf(stderr, "%s : info: token %d is string %s and bpe returns tokens %s\n",
|
fprintf(stderr, "%s : info: token %d is string %s and bpe returns tokens %s\n",
|
||||||
__func__, i, llama_token_to_str(ctx, i).c_str(), unescape_whitespace(ctx, tokens).c_str());
|
__func__, i, llama_token_to_str(ctx, i).c_str(), unescape_whitespace(ctx, tokens).c_str());
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s : error: token %d is string %s but bpe returns tokens %s\n",
|
fprintf(stderr, "%s : error: token %d is string %s but bpe returns tokens %s\n",
|
||||||
__func__, i, llama_token_to_str(ctx, i).c_str(), unescape_whitespace(ctx, tokens).c_str());
|
__func__, i, llama_token_to_str(ctx, i).c_str(), unescape_whitespace(ctx, tokens).c_str());
|
||||||
return 3;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue