epfl-dlab / epfl-dlab/transformers-CFG

Prefix Space with Llama Tokenizer

Open
#40 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
139
Forks
23
PR merge metrics
No merged PRs in 30d

Description

`

tokenizer = AutoTokenizer.from_pretrained("NousResearch/Llama-2-7b-hf",
token="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")

tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"

with open(f"examples/grammars/geo_query.ebnf", "r") as file:
grammar_str = file.read()

query = "answer(population_1(cityid('austin', _)))"
query_prefix_1 = ""
query_prefix_2 = "answer"
query_prefix_3 = "answer("

grammar = IncrementalGrammarConstraint(grammar_str, "root", tokenizer)
# Parse from the first token
grammar_processor = GrammarConstrainedLogitsProcessor(grammar, 0)

encoded_1 = tokenizer(query_prefix_1, add_special_tokens=False, return_tensors="pt", padding=True)
encoded_2 = tokenizer(query_prefix_2, add_special_tokens=False, return_tensors="pt", padding=True)
encoded_3 = tokenizer(query_prefix_3, add_special_tokens=False, return_tensors="pt", padding=True)

scores_1 = grammar_processor.process_logits(encoded_1["input_ids"], torch.zeros(1, len(tokenizer)))
print(torch.nonzero(scores_1[0] != -math.inf).squeeze(axis=1))
#tensor([ 273, 550, 12011, 29874])
scores_2 = grammar_processor.process_logits(encoded_2["input_ids"], torch.zeros(1, len(tokenizer)))
print(torch.nonzero(scores_2[0] != -math.inf).squeeze(axis=1))
#tensor([2])
grammar_processor.process_logits(encoded_3["input_ids"], torch.zeros(1, len(tokenizer)))
`

would give out the following error for the final `process_logits` call:

> ValueError: All stacks are empty, so the only token accepted is EOS(2) but got 29898

This is because the Llama tokenizer adds a **dummy white space** at the start of the sequence. Therefore, when encoding **answer**, the tokenizer would give token_id **1234**, instead of **12011**

`

print(tokenizer.convert_ids_to_tokens([1234]))
#['▁answer']
print(tokenizer.convert_ids_to_tokens([12011]))
#['answer']
`

When parsing the first empty prefix, the next allowed token won't contain [1234], but only token_ids correspond to tokens without the prefix space, which will make the parsing of the second prefix illegal, thus only accepting EOS token for the next token, so the third prefix would raise an error.

It would be very helpful if we could deal with this prefix whitespace problem.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.