GPTQ
есть ли возможность выложить модели saiga 7b, 13b, 30b в GPTQ 4bit? Хотелось бы их на видеокарте поюзать.
Спасибо за ваши труды и удачи в проектах )
извините ошибся, на работе завал, GPTQ
Да, теперь понял. А в чём сейчас профит использовать GPTQ после выхода qlora? Казалось бы, пишешь load_in_4bit и ещё пару флагов (типа nf4) при загрузке модели, и оно вполне работает.
Плюс llama.cpp нынче умеет в инференс на GPU.
первое я виндовый сисадмин, с питоном не на ты, сам не осилил в квантизация. второе это не для работы, а поиграться дома, поэтому ресурсы ограниченны. третье я хочу 30B модели использовать, а это опять ограничение, по факту сейчас у меня получается использовать KoboldAI 4битный форк, он более менее работает. oobabooga нужно много RAM что бы загрузить 30B 4bit, потому как он грузит сначала в память потом в VRAM. да это можно победить сделав файл подкачки 65+ГБ, но решение так себе. Сейчас попробую llama.cpp за ней я не следил т.к. она на CPU, но опять таки если она сначала в RAM начнет модель загонять, то мне 32ГБ опять не хватит ). Так то есть https://huggingface.co/models?sort=modified&search=30b+4bit и wizard и неплохая MetaIX/GPT4-X-Alpasta-30b-4bit , но очень хочется русскую модель пощупать.
P.s. еслиб у меня вышло квантовать модель, я бы не писал ), я пытался, но моих ограниченных знаний не хватило )
P.S.S. в принципе если у Вас нету возможности не критично (но если будет возможность сделайте пожалуйста, надеюсь многим пригодится), llama.ccp не запустил, разбираться лень, запустил через koboldccp, пошел тестить и еще раз спасибо, Вы по-моему единственный кто занимается русскими моделями, сбер еще, но их модели .... не очень
Да я в общем могу GPTQ приготовить, это совсем не большая проблема. Просто я уже делал подход к этому снаряду, код там мягко говоря так себе. Постараюсь до конца недели выложить.
Llama.cpp не только на CPU, см https://github.com/ggerganov/llama.cpp/discussions/915. Это уже давно в основной ветке и успешно работает.
Модели Сбера не так плохи, вот только их 13B модель всё никак не пройдёт все круги бюрократического ада.
Здравствуйте, спасибо Вам за этот грандиозный проект, его opensource, развитие и выступление на ODS Data Fest - по пользе для opensource исследователей; "домашних" энтузиастов; а также людей, изучающих вопрос и обучающихся по специальности, кажется, что корпорациям Вас еще догонять и догонять от очень долго до никогда! Как и пользователь выше, я не профессионал и речь идет о домашних условиях. Использую llama.cpp (запускаю как server.exe -c 2000 -ngl 5 -m ggml-model-q4_1.bin - на 1060 вполне работает), но хотел уточнить:
- различаются ли модели по качеству (ggml-model-q5_1.bin, ggml-model-q8_0.bin, ggml-model-q3_K.bin) и скорости инференса или это просто разный формат/способ квантования (как я понял из доклада про квантование), т.е. если в моем домашнем ПК 64 Гб Ram и nvme диск (и swap) имеет ли смысл запускать ggml-model-q8_0.bin с частичным offload на 1060, или если это не лучше по качеству генерации, то может быть работает быстрее на CPU/GPU? Из того, что читал по теме, просто запутался, на форумах пишут и спорят, что сами по себе форматы q5_1 и q8_0 и медленнее и хуже по качеству, или иногда по качеству лучше на 5-10% но скорость на 80% и более падает или что q8_0 сильно лучше по скорости, но только для профессиональных GPU со встроенными int8 вычислительными cuda ядрами и большим объемом памяти... буду благодарен, если внесете хотя бы небольшую ясность, ведь Сайга, несмотря на q4_1, в нескольких вариантах по какой-то причине публикуется?
- в Вашем примере interact_llamacpp.py указан такой критерий остановки генерации:
if token == model.token_eos(): break
а как его указать в llama.cpp server или llama-cpp-python web server, где в API надо отправлять list из стоп-критериев по типу stop: ["\n### Human:"]? Я пробовал [" bot"], но тогда не работает на английском слове both, может быть надо ["bot\n","\nbot"] или что-то еще?
- как правильно для использования в llama.cpp server API у текущей версии модели выглядит prompt шаблон одной строчкой?
"prompt": f''' system\nТы — Сайга, русскоязычный автоматический ассистент. Ты разговариваешь с людьми и помогаешь им.\n user\nНапиши десять больших похвал своему создателю.\n bot''',
нужны ли пробелы перед названиями ролей, или их надо в \<s>оборачивать\</s>? Обязательно ли каждый раз подавать system сообщение, если не использовать модель в режиме чата/предыстории? Нужно ли как-то трактовать или использовать SYSTEM_TOKEN = 1788, USER_TOKEN = 1404, BOT_TOKEN = 9225, LINEBREAK_TOKEN = 13 из interact_llamacpp.py если речь идет об использовании модели не в собственном коде, а через llma.cpp API?
- не смог найти в репозитории rulm как можно было бы не финансово помочь проекту (разметкой (попытался исправить мелкие недочеты в переводах в [ru_alpaca_seed_tasks.jsonl](https://github.com/IlyaGusev/rulm/blob/master/self_instruct/data/ru_alpaca_seed_tasks.jsonl), но там быстро другие датасеты появились и качество моего видения по исправлению тоже вещь относительная), обычным несложным кодом (например, могу пример/инструкцию для windows написать как llama.cpp сервер на CPU/GPU запустить и из python requests.post к этому API запросы слать), тестами какими-то, ссылками на открытые датасеты с русским языком [Natasha Corpus](https://github.com/natasha/corus) )?
- Какова судьба llama_13b_ru_turbo_alpaca_lora_llamacpp ? По Вашему выступлению я понял, что она немного другого класса - инструктивная (а Сайга - диалоговая, инструктивная и ведутся работы в сторону ролевой) и нужна для каких-то отличных от Сайги задач, но запустить не получилось, видимо ggml-model-q4_0.bin сделан для старой llama.cpp (до обновления формата) и новой не поддерживается.
Извиняюсь, что получилось много вопросов, но буду рад и кратким и частичным ответам, может быть просто ссылками на литературу/код. Еще раз Спасибо за Ваши усилия и больших успехов!
различаются ли модели по качеству
Да, различаются. Чем больше битрейт, тем меньше потерь, тем лучше качество. См. таблички в README llama.cpp.
а как его указать критерий остановки в llama.cpp server
Никак, только патчить код. У llama.cpp другой токенизатор, у него нет явных строк для bos/eos токенов, поэтому промпт, содержащий эти токены, надо вручную собирать из индексов.
как правильно для использования в llama.cpp server API у текущей версии модели выглядит prompt шаблон одной строчкой?
Никак, по тем же причинам. В общем случае промпт выглядит так: saiga_ooba.txt
как можно было бы не финансово помочь проекту
Измерить модели на разных бенчмарках, выложить чиселки в сравнении с другими моделями.
какова судьба llama_13b_ru_turbo_alpaca_lora_llamacpp
Она устарела и не обновляется, о чём висят warning'и на основных моделях. Сайга во всём её превосходит, нет смысла поддерживать две модели.
Спасибо за ответы, тщетно и долго пытался разобраться с ними сам, но не получалось.
- В saiga_ooba.txt начальный открывающий <s> перед system не потерялся? Будет ли в конце генерации </s> т.е. будет ли хорошим критерием остановки для llama.cpp stop: ["</s>"]?
- По поводу измерения, на каком бенчмарке интересно его провести, опубликованные (пока без кода, но вроде бы выложат) измерения Сайги от NLP Core Team Вам не подходят с учётом таблицы DeCLaRe Lab по которой Сайгу косвенно можно сравнить со многими другими моделями и сделать выводы, что 13b модель не на много, но лучшая в мире (а еще компенсировала обычную потерю от LoRA дообучения)? Или уже интереснее на TAPE (сайт бенчмарка) про который было выступление на Data Fest? Не уверен, что у меня получится сделать это без GPU, но, возможно, попробую разобраться и очень интересно какой бенчмарк для Вас в этом вопросе/области авторитетен.
- Существуют ли (и много ли) в мире таких моделей как Сайга со специфичным bos/eos в том плане, что имеется ли смысл в issues llama.cpp попросить добавить поддержку указания номеров bos/eos токенов в стоп критериях и prompt server API как некоторого общественно значимого улучшения? Мне будет сложно объяснить в issues в чем дело, но если такие модели существуют и без этого никак, то это было бы полезным улучшением llama.cpp.
- Можно ли каким-то словом в promt бороться с тем, что Сайга на многие вопросы выводит ответы, начинающиеся на "Выходные данные:", "Выход:", "Ответ:", "Оценка:"? Это потребляет токены на генерацию, что чувствительно на CPU.
В saiga_ooba.txt начальный открывающий
<s>
перед system не потерялся?`
Большинство фреймворков (в том числе oobabooga из названия файла) автоматически его добавляют. В llama.cpp он всё равно не сработает.
Будет ли в конце генерации
</s>
т.е. будет ли хорошим критерием остановки для llama.cpp stop: ["</s>
"]?
Нет. Ещё раз, у llama.cpp другой токенизатор. </s>
он разбивает на несколько токенов, типа ["<", "/s", ">"].
По поводу измерения, на каком бенчмарке...
MMLU, а тем более переведённый, не самый лучший бенчмарк, но это тоже очень интересные цифры. TAPE проблемный, у меня был подход (см. eval_tape). Основная его проблема это от 3 до 7 тысяч примеров на задачу, что делает очень больно на инференсе, а ещё отсутствие публичного валидационного сета. Но на нём тоже хотелось бы замериться. Мне всё ещё хочется полноценный сабмит на RussianSuperGLUE, чтобы прямо отображался в таблице.
Существуют ли (и много ли) в мире таких моделей как Сайга со специфичным bos/eos
У Сайги не специфичный bos/eos, как раз самые стандартные. У Сайги специфичный промпт.
Вот одна из проблем: строчка в convert.py. Если её убрать, то bos и eos станут <s>
и </s>
, только это не поможет, потому что это не работает в обратную сторону: <s>
будет всё ещё разбиваться на 3 токена. Токенизатор llama.cpp фундаментально так работает. system
, user
и bot
тоже имеют другие индексы.
Решение же очень простое: забить и использовать сваренные из индексов промпты.
Можно ли каким-то словом в promt бороться с тем, что Сайга на многие вопросы выводит ответы, начинающиеся на "Выходные данные:", "Выход:", "Ответ:", "Оценка:"? Это потребляет токены на генерацию, что чувствительно на CPU.
Ну например в самом промпте написать "Ответ:".
Я прежде с такими вещами не сталкивался, но попробовал написать тест для задачи DaNetQA бенчмарка Russian SuperGLUE и на его основе понять общий принцип. Получается, что задача бенчмаркинга по Russian SuperGLUE состоит в написании отдельных программ-тестов для выполнения отдельных видов заданий из бенчмарка, при этом, под каждый вид задания нужно на test (и на обучающей если без обучения работаем) выборке подобрать "самый удачный" промпт и параметры генерации, а потом всё это собрать в сабмит.
- Если я правильно понимаю, когда NLP Core Team опубликуют код для MMLU, из него можно будет взять готовую основу (если не код, то хотя бы промпты) для пересекающихся/схожих заданий.
- Касательно DaNetQA. Этап обучения получается не нужен, а дальше нужно в Zero-shot? Нужно ли в Сайгу подавать Контекст из теста (или надо пробовать с ним и без)? Считается ли честным при прохождении отдельного теста бенчмарка варьировать:
- промпт,
- параметры генерации,
- подачу контекста (то подаем, то нет),
- Zero-shot/Few-shot режим,
исходя из конкретного sampl'a теста или все шаблоны/параметры модели должны быть фиксированы на весь проход по тесту? - Как, например, относится к таким случаям, когда модель всё знает и ответила правильно, но вопрос был так поставлен, что в нем надо поменять "да" на "нет" (т.е. подковырка в постановке формулировки вопроса, а не в фактах и знаниях для ответа на него - я бы мог попытаться обойти такие трюки поиском в вопросе слова " ли " (и наверное " бы ") и как-то менять промпт - но без опыта бенчмаркинга, честно/нормально ли так делать в бенчмарках не знаю, думаю "дизельгейт" никто не хотел бы получить, тем более неумышленно, ведь на мой взгляд ситуация спорная и "каков вопрос" - "таков ответ" к ней было бы применимо):
*Вопрос из теста: Действительно ли в ссср не было адвокатов?
*Контекст из теста: Семён Львович Ария — советский и российский юрист, один из крупнейших советских адвокатов, Заслуженный юрист РСФСР. Родился в еврейской семье , детство провёл на Украине в г. Харькове. После окончания средней школы в течение года учился на мостовом факультете Новосибирского института военных инженеров транспорта. В начале Великой Отечественной войны был призван в Красную Армию в Харькове, окончив курсы 19-го учебного танкового полка в Нижнем Тагиле, стал механиком-водителем танка, затем — разведчиком дивизиона гвардейских минометов . Участвовал в боевых действиях на Северном Кавказе, Кубани, Украине, в Болгарии, Венгрии, Австрии, старший сержант.
*Правильный ответ из теста: False
Ответ модели: Да, в СССР существовали адвокаты. Однако, они работали под строгими правилами и ограниче
!!! Модель ошиблась
- Вот получившийся код для DaNetQA теста в копилку тестов по Russian SuperGLUE, если пригодится. Основные выработанные при его написании идеи: 1) Писать "Ответь одним словом," - чтобы да/нет отвечала в начале предложения 2) ограничивать max_new_tokens маленьким числом, так как нужны только первые токены да/нет - чтобы проход теста был быстрее (в моем случае на CPU чувствительно, еще пару часов тест будет проходить, как законичиться цифры напишу ) 3) парсить/искать да/нет в bool
from llama_cpp import Llama
SYSTEM_PROMPT = "Ты — Сайга, русскоязычный автоматический ассистент. Ты разговариваешь с людьми и помогаешь им."
SYSTEM_TOKEN = 1788
USER_TOKEN = 1404
BOT_TOKEN = 9225
LINEBREAK_TOKEN = 13
ROLE_TOKENS = {
"user": USER_TOKEN,
"bot": BOT_TOKEN,
"system": SYSTEM_TOKEN
}
def get_message_tokens(model, role, content):
message_tokens = model.tokenize(content.encode("utf-8"))
message_tokens.insert(1, ROLE_TOKENS[role])
message_tokens.insert(2, LINEBREAK_TOKEN)
message_tokens.append(model.token_eos())
return message_tokens
def get_system_tokens(model):
system_message = {"role": "system", "content": SYSTEM_PROMPT}
return get_message_tokens(model, **system_message)
def user(message, history, system_prompt):
new_history = history + [[message, None]]
return "", new_history
def inference(user_message, max_new_tokens=None):
tokens = get_system_tokens(model)[:]
message_tokens = get_message_tokens(model=model, role="user", content=user_message)
role_tokens = [model.token_bos(), BOT_TOKEN, LINEBREAK_TOKEN]
tokens += message_tokens + role_tokens
generator = model.generate(
tokens,
top_k=top_k,
top_p=top_p,
temp=temperature,
repeat_penalty=repeat_penalty
)
result_tokens = []
for i, token in enumerate(generator):
if token == model.token_eos() or (max_new_tokens is not None and i >= max_new_tokens):
break
#token_str = model.detokenize([token]).decode("utf-8", errors="ignore")
#print(token_str, end="", flush=True)
result_tokens.append(token)
return model.detokenize(result_tokens).decode("utf-8", errors="ignore")
model_path = 'F:/RussianSuperGLUE/ggml-model-q4_1.bin'
n_ctx=2000
top_k=30
top_p=0.9
temperature=0.1
repeat_penalty=1.1
model = Llama(model_path=model_path, n_ctx=n_ctx, n_parts=1, n_gpu_layers=10, seed=1337, f16_kv=True, logits_all=False, vocab_only=False, use_mmap=False, use_mlock=True, embedding=False, n_threads=6, n_batch=512, last_n_tokens_size=64, lora_base=None, lora_path=None, verbose=False)
system_tokens = get_system_tokens(model)
#tokens = system_tokens
#model.eval(tokens)
import json
import codecs
import requests
from sklearn.metrics import accuracy_score
""" Yes/no Question Answering Dataset for the Russian """
""" https://russiansuperglue.com/ru/tasks/task_info/DaNetQA """
""" https://russiansuperglue.com/ru/tasks/download/DaNetQA """
y_true = []
y_pred = []
for line in codecs.open("F:/RussianSuperGLUE/DaNetQA/val.jsonl","r","utf-8"):
""" загрузка вопроса из бенчмарка """
test = json.loads(line)
#print(test.keys())
print(f'''*Вопрос из теста: {test["question"]}''')
print(f'''*Контекст из теста: {test["passage"]}''')
print(f'''*Правильный ответ из теста: {test["label"]}''')
y_true.append(bool(test["label"]))
""" получение ответа из модели """
user_message = f'''Ответь одним словом, на вопрос: {test["question"]}'''
model_responce = inference(user_message, 30)
print(f'''Ответ модели: {model_responce}''')
""" преобразование ответа модели в формат, сравнимый с бенчмарком """
result = None
if model_responce.startswith("Да"):
result = True
elif model_responce.startswith("Нет"):
result = False
else:
print("ERROR! Не удалось найти Да/Нет в ответе модели и преобразовать его в bool")
y_pred.append(result)
if (result != bool(test["label"])): print("!!! Модель ошиблась")
print("-"*20)
accuracy_score(y_true, y_pred)
Закончились измерения на текущей 7b ggml-model-q4_1.bin модели на валидационном "val.jsonl" наборе DaNetQA бенчмарка Russian SuperGLUE.
- Хотел уточнить, если у llama.cpp другой токенизатор, то получается, что запускать Сайгу экзешником llama.cpp server.exe API нельзя? Или можно, просто только </s> портиться будет, а не весь вход/выход будет по другому токенизироваться? Я думал, что q4_1 форматы моделей включают в себя токенизатор и веса в одном файле и больших проблем с llama.cpp не наблюдал, кроме иногда очень странного поведения и зацикливаний "bot bot bot bot... до заданного предела n_predict".
- В приведенный ранее код мне пришлось добавить замену None на False, чтобы посчитать acccuracy (пропустить тестовые примеры, для которых из модели не удалось получить ответ):
а как обычно принято делать, если на какой-то вопрос теста не удалось добиться от модели никакого ответа?for i in range(len(y_pred)): if y_pred[i] == None: print(i) y_pred[i]=False accuracy_score(y_true, y_pred)
- Результат без указания контекста (1 замена None на False): 0.5858708891595615
- Результат с указанием контекста затравкой
f'''Контекст: {test["passage"]}\n\nИспользуя контекст, ответь одним словом на вопрос: {test["question"]}'''
(8 замен None на False): 0.6918392204628502 - Заметил у Сайги общую склонность, что если в контексте перечисляются несколько значений одного и того же факта:
Председатель шахматного клуба Иван Иванович. С 2018 года председатель шахматного клуба Николай Николаевич. С 2020 года председатель шахматного клуба Мария Ивановна.
, то на вопросКто является председателем шахматного клуба?
она всегда выдает первое встретившиесяИван Иванович
- есть ли типовой промпт способ с этим бороться? - Схоже с предыдущим, обнаружил вид "хитрых" вопросов - когда в контексте присутствует сразу несколько противоречащих по датам фактов (в 2013 разрешили, но не вступило в силу; потом в 2014 перенесли вступление в силу до 2017; а потом в 2016 другим указом запретили, но разрешение от 2013г. в 2017 г. всё равно вступило в силу, просто с запретительной поправкой от 2016 г. - т.е. как я понял есть и действует указ в котором так и написано, что разрешено, но к нему еще есть поправка...), вот пример из теста:
*Вопрос из теста: Разрешено ли в россии гмо?
*Контекст из теста: С 1 июля 2014 г. вступает в силу Постановление Правительства Российской Федерации от 23 сентября 2013 г. № 839 «О государственной регистрации генно-инженерно-модифицированных организмов, предназначенных для выпуска в окружающую среду, а также продукции, полученной с применением таких организмов или содержащей такие организмы», которым разрешено сеять генно-модифицированные зерновые. В июне 2014 года Правительство РФ приняло постановление № 548, которое предусматривает перенос срока вступления в силу постановления № 839 на три года, то есть на 1 июля 2017 года. 24 июня 2016 года Государственная Дума РФ приняла в третьем чтении федеральный закон «О внесении изменений в отдельные законодательные акты РФ в части совершенствования государственного регулирования в области генно-инженерной деятельности». Закон запрещает ввоз на территорию РФ и использование семян растений, генетическая программа которых изменена с использованием методов генной инженерии и которые содержат генно-инженерный материал, внесение которого не может являться результатом природных процессов.
*Правильный ответ из теста: False
Ответ модели: Да, разрешено сеять генно-модифицированные зерновые в России. Постановление Пра
!!! Модель ошиблась
- В [leaderboard](https://russiansuperglue.com/ru/leaderboard/2) такие результаты примерно после 15 места, но ведь это лишь обывательский baseline (не каждый водитель за рулем Ferrari, поставит рекорд Нюрбургринга) самой маленькой модели без подбора промпта и параметров модели, да и 0,915 у HUMAN говорит о том, что не на все можно сходу ответить правильно. На Ваш взгляд, без файнтюнинга и подбора многоуровневых промтов конкретно под этот тест, можно ли вырваться в первую десятку? А ведь с разной температурой или даже просто при проведении повторного теста результаты могут различаться в силу "случайной составляющей генерации", тогда как правильнее итоговый сабмит делать? Можно ли, например, раз 5-7 (может быть и с разными параметрами) прогнать тест и сделать итоговые ответы методом большинства голосов, будет ли так принято/честно/нормально?
Спасибо за обратную связь, надеюсь принёс немного пользы.
На будущее - не надо столько писать в чужих issue, открыл форум здесь: https://github.com/IlyaGusev/rulm/discussions
Получается, что задача бенчмаркинга по Russian SuperGLUE состоит в написании отдельных программ-тестов для выполнения отдельных видов заданий из бенчмарка, при этом, под каждый вид задания нужно на test (и на обучающей если без обучения работаем) выборке подобрать "самый удачный" промпт и параметры генерации, а потом всё это собрать в сабмит.
Ну да, а ещё выложить код и промпты.
Нужно ли в Сайгу подавать Контекст из теста (или надо пробовать с ним и без)?
Нужно, в этом суть бенчмарка. Это же не open QA.
Считается ли честным при прохождении отдельного теста бенчмарка варьировать:
Всё да. Только нужно указывать, что именно было сделано. Код лучше сразу в репозиторий заливать через pull request. Заодно там же и ревью сделаю. Иначе я его скопирую и сам залью, а авторство хотелось бы сохранить.
получается, что запускать Сайгу экзешником llama.cpp server.exe API нельзя?
Получается так. Она не то чтобы не будет работать, но просто качество просядет.
а как обычно принято делать, если на какой-то вопрос теста не удалось добиться от модели никакого ответа?
Да вот ровно так же, ставить одну из меток.
0.6918392204628502
Вообще достойно, у меня на старых версиях хуже получалось.
есть ли типовой промпт способ с этим бороться?
Нет.
На Ваш взгляд, без файнтюнинга и подбора многоуровневых промтов конкретно под этот тест, можно ли вырваться в первую десятку?
Да это отличный результат для 7b zero-shot. Почти все модели там дообучались на обучающей выборке. В целом до 0.75 должно быть можно добить.
А ведь с разной температурой или даже просто при проведении повторного теста результаты могут различаться в силу "случайной составляющей генерации", тогда как правильнее итоговый сабмит делать? Можно ли, например, раз 5-7 (может быть и с разными параметрами) прогнать тест и сделать итоговые ответы методом большинства голосов, будет ли так принято/честно/нормально?
Да, но только с указанием того, что происходило.
надеюсь принёс немного пользы
Да, вполне.
Понятно, извините, что много написал - не было опыта в таких вещах.
Код на 3/4 из Вашего interact_llamacpp.py сделан, копируйте куда сочтёте необходимым без всякого авторства.
Метрика ~0.7 на "val.jsonl" получена (надеюсь она воспроизводима, а не везение), чтобы официальная цифра была надо на test.json померять и отослать в Russian SuperGLUE - там может и другая цифра выйти. На сайте бенчмарка надо регистрироваться и неясно можно ли отдельно слать один тест - в любом случае я этого никак не планировал делать, только передать Вам, что получилось. Надеюсь в вариантах 13b и 30b в q8_0 моделях цифра будет еще лучше, я на своем CPU наверное не смогу померять, по ощущениям 30b суток двое считался бы... лучше попробую другие типы задач освоить и написать, если, конечно, получатся какие-то результаты.
Еще раз Спасибо за Сайгу: адаптацию, доступность и популяризацию современных технологий, в том числе на ODS Data Fest ; поддержку, а также этот интересный, новый для меня опыт бенчмаркинга - надеюсь, когда соберется весь сабмит Сайга займет свое почетное место даже без файнтюнинга, хотя, как по мне, Ваш профессиональный опыт и авторитет, труд и многочисленные общественные достижения (Telegram Contest, статьи на Habr, github ...) итак уникальны, выше всяких похвал и просто вне конкуренции без каких-либо частных метрик и названий версий бенчмарков!
Досчитались новые данные (условия те же: "val.jsonl" из DaNetQA):
- 0.7978075517661388 accuracy набрала saiga_30b q4_1
- 0.8416565164433617 accuracy набрала предыдущая версия saiga_30b q4_1
30b модели не так стабильны при ответе как 7b и могут перед ответом вставлять пробел или \n, а также использовать заглавные/строчные буквы (Да, да), поэтому пришлось доработать преобразование ответа моделей в bool:
""" преобразование ответа модели в формат, сравнимый с бенчмарком """
""" Учтены: непечатные символы перед ответом модели; Фразы "Ответ:" и т.п. перед ответом; вопрос - ответы отличные, но обозначающие Да: Верно ли? - верно, Правда ли? - правда, Может ли? - может"""
result = None
if bool(re.match(r'''^[^\w]*(Выходные данные|Выход|Ответ|Оценка)?[^\w]*(да|верно|правда|может)''', model_responce, re.IGNORECASE | re.MULTILINE | re.DOTALL)):
result = True
elif bool(re.match(r'''^[^\w]*(Выходные данные|Выход|Ответ|Оценка)?[^\w]*нет''', model_responce, re.IGNORECASE | re.MULTILINE | re.DOTALL)):
result = False
else:
print("ERROR! Не удалось найти Да/Нет в ответе модели и преобразовать его в bool")
Пропробовал пройти тест Textual Entailment Recognition for Russian - TERRa, на его "val.jsonl" сходу получилось 0.52 - продолжу поиск промптов, на данный момент пробовал такие:
user_message = f'''Контекст: {test["premise"]}\nГипотеза: {test["hypothesis"]}\n\nОтветь одним словом на вопрос: может ли гипотеза следовать из контекста?'''
user_message = f'''Контекст: {test["premise"]}\n\nГипотеза: {test["hypothesis"]}\n\nИспользуя контекст, ответь одним словом на вопрос: из него следует гипотеза?'''
user_message = f'''Контекст: {test["premise"]}\n\nИспользуя контекст, ответь одним словом на вопрос: из него следует, что {test["hypothesis"]}?'''
Ответы модели для считывания entailment/not_entailment стабильны, но она склонна всегда отвечать Да, как будто часто "не видит" гипотезу. Считывание ответа реализовано так:
""" преобразование ответа модели в формат, сравнимый с бенчмарком """
result = None
if bool(re.match(r'''^[^\w]*(Выходные данные|Выход|Ответ|Оценка)?[^\w]*(да|верно|правда|может)''', model_responce, re.IGNORECASE | re.MULTILINE | re.DOTALL)):
result = "entailment"
elif bool(re.match(r'''^[^\w]*(Выходные данные|Выход|Ответ|Оценка)?[^\w]*нет''', model_responce, re.IGNORECASE | re.MULTILINE | re.DOTALL)):
result = "not_entailment"
else:
print("ERROR! Не удалось найти Да/Нет в ответе модели и преобразовать его в entailment/not_entailment ")