Как стать автором
Обновить
75.44

Как мы научили LLM проверять себя и сэкономили ресурсы на RAG-пайплайне

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров2.7K

Привет, чемпионы! Сегодня я расскажу вам, как мы придумали решение, как используя небольшую надстройку над LLM сделать ее несколько самооценивающейся, что позволило нам при работе с локальными данными и внутренней документацией уменьшить число иницирований работы RAG пайплайна, когда в этом нет необходимости.

Суть проблемы

Мы разрабатывали Endpoint , который должен был иметь следующие функции:

  1. Ответы на вопросы по аналитике полученных данных сотрудниками

  2. Взаимодействие с внутренними документами для ответов на вопросы

  3. Ответы на вопросы сотрудников системы при всех остальных случаях, когда внутренние документации или данные не требуются

Как итог, мы получаем систему в виде модели, в которую идут запросы по разным темам.

В каждом из узлов нашей системы мы решали системы по оптимизации вычислений совместно с повышением качества ответов. И одним из таких узлов стало использование вычислений на RAG пайплайны.

Решение с тем, чтобы разделить 1 и 2, 3 направлением задач было весьма простое, хоть и потенциально странное для кого-то, но работало очень эффективно, мы добавлением простой кнопочки для разделения того, к какой инфраструктуре хранения обращаться, смогли снизить нагрузки на gpu на 11%, однако с тем, чтобы разделить 2 и 3 направление задач возникла сложность.

Добавление кнопочки "обратись к внутренним документам" возможно и было бы простым решением, однако ответьте себе честно, как часто вы бы сами нажимали эту переключалку?

Ведь даже добавление перехода режима работы с данными на диалоговый уже потребовал много усилий по тому, чтобы сотрудники не забывали переключиться. А как вы знаете, чем больше кнопок и разных настроек, тем менее дружелюбным становится интерфейс.

Наши гипотезы и их результаты

Тут мы разберем пул поставленных нами гипотез, опишем их оценку или попытку интеграции, а также то, к чему мы пришли сами.

Сначала появилась куриц...корпус из 100 диалогов, в которых мы оценивали ответы на вопросы по логам из обращений в RAG и производили оценку, разбивая их на сообщения с ответами модели и делая оценку насколько вообще внешние источники данных реально помогали модели, а где она справлялась сама. После составив тестовый корпус, что состоял из примерно 3500 взаимодействий юзер-модель мы пришли к выставлению набора решений

Дать модели оценить саму себя

Идея проста, отправить запрос модели, после чего с помощью промта сделать модель, что будет эмулировать проверяющего, который оценивает ответ своего брата-близнеца и выдает свои оценки от 1-5 по категориям: "Релевантность", "полнота", "степень уверенности в ответе"

Как прототип для старта в целом пойдет, однако результат снижения обращений к RAG, а как следствие понижение нагрузки на дашбордах был 2% и порядка 15 процентов recall. И действительно, чем это отличается от того, когда вы на самостоятельной меняетесь с другом листочками и проверяете друг друга?

Обращение к модели с более большим числом параметров

Данная идея вышла бы неплохо в случае api, заплатить сколько-то денег за токены, пооценивались и круто. Закончилось все правда на том, что инфраструктура локальна.

Не беда! Возьмем опенсорсную модель просто большего размера. Но тут мы сталкиваемся с тем, что это влияет напрямую на пиковую нагрузку на VRAM при работе с большой моделью.

Коллективная проверка

Мы задаем трижды запрос пользователя к модели, получая при этом разные ответы. Разные, но! Часто-ли вы отвечаете по-разному о том, как создать функцию на питоне? Или какова корреляция будет у ответов студентов о том, что такое интернет? В среднем должна быть высокая.

Данная гипотеза состоит из того, что мы получаем несколько ответов на вопросы

Скрытый текст
def self_check_consistency(question: str, n_variants: int = 3):
    answers = []
    for _ in range(n_variants):
        a = generate_answer(question)
        answers.append(a)

    emb_score = embedding_similarity(answers)

    return emb_score, answers[0], answers

После чего мы получаем фичи у ответов и выстроим их корреляцию

Скрытый текст
def embedding_similarity(answers: list[str]) -> float:
    embeddings = embed_model.encode(answers, convert_to_tensor=True)
    similarities = []

    for i in range(len(answers)):
        for j in range(i + 1, len(answers)):
            sim = util.cos_sim(embeddings[i], embeddings[j]).item()
            similarities.append(sim)

    return sum(similarities) / len(similarities) if similarities else 0.0

Какие плюсы? Данное решение делала отсев ответов, которые в явном виде на запросы из документаций внутри системы позволяло получить низкий скор, что требовало обращение к RAG и повторному ответу. Это дало 5 процентов понижения нагрузки c 43 recall.

Минусы? Нет явного отсева чистого рода "коллективного бреда", то есть когда вы хотите спросить про метод из документации, а модели посовещались и решили, что знают одноименный, поэтому ответим примерно также.

Соединяем коллективизацию с оценкой.

Мы также считали скор между ответами, а также выдавали оценку от критика. Итогом мы получаем оценку скора схожести и оценку критика. Но остается проблема, вернее теперь их две, первая и вторая соответствует тем решениям, что описаны выше. Тогда мы придумали костыли для нашей модельки в виде небольшого взвешивания всех результатов и итогового принятия решения нужен ли RAG или нет. Тут же возник момент с тем, что мы можем до обучать на ответах модели нужен-ли ей RAG, но диапазон признакового пространства в этом случае становится сильно выше. Тогда мы сделали решение обучить на ответах от созданных наших аналитиков меток и целевой меткой нужен-ли наш пайплайн, ведь информация эта уже была.

После обучения нашей выдачи весов мы получили наш итог маленького модуля

Такое решение дало наше финальное снижение на 11% с recall 93 процента.

Итоги

На текущий момент мы прорабатываем более оптимальное и более качественное решение. Если вы хотите что-то предложить, пишите об этом в комментариях. Самое интересное, что несмотря на всю казалось бы костыльность решений, это действительно помогло нам.

🔥 Ставьте лайк и пишите, какие темы разобрать дальше! Главное — пробуйте и экспериментируйте!


✔️ Присоединяйтесь к нашему Telegram-сообществу @datafeeling, где мы делимся новыми инструментами, кейсами, инсайтами и рассказываем, как всё это применимо к реальным задачам

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
+9
Комментарии0

Публикации

Информация

Сайт
t.me
Дата регистрации
Дата основания
Численность
2–10 человек
Местоположение
Россия