О двойных BOS токенах в vllm (по мотивам тикета)



Рассмотрим на примере meta-llama/Meta-Llama-3-8B-Instruct.



В шаблоне есть такой кусочек:



{% if loop.index0 == 0 %}{% set content = bos_token + content %}{% endif %}



Написано буквально: к первому сообщению прибавь BOS токен.

Теперь если вызвать tokenizer.apply_chat_template, он и прибавится. Но в transformers дальше идёт вот что:



out = self(

...

add_special_tokens=False,

...

)





А в vllm вот что:



input_ids = self.tokenizer(prompt, **tokenizer_kwargs).input_ids



Причём tokenizer_kwargs точно не содержит add_special_tokens.

По умолчанию add_special_tokens=True, что означает, что в vllm будет 2 BOS токена.



На что в vllm говорят, что авторы модели это могут поправить, либо удалив bos_token в шаблоне, либо поставив add_bos_token=False в настройках токенизатора. Но у Llama-3 PreTrainedTokenizerFast, он не поддерживает add_bos_token=False!

А второй путь с исправлением шаблона может сломать всё в других местах. Да и в официальном-то шаблоне bos_token есть...



Вы скажете: "ну 2 и что?". А это довольно ощутимо влияет на качество, в моих тестах это было что-то типа 55% винрейта у модели с одним токеном против двух.



Так и живём.