Пост-мортем студенческого стартапа.Глава первая. Собственное разочарованиеЗима 2023-го. В это время и я, и мой будущий кофаундер Артур учились в 11-м классе, усПост-мортем студенческого стартапа.Глава первая. Собственное разочарованиеЗима 2023-го. В это время и я, и мой будущий кофаундер Артур учились в 11-м классе, ус

Как мы делали ИИ-репетитора для ЕГЭ по математике

Пост-мортем студенческого стартапа.

Глава первая. Собственное разочарование

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

однако полуспящий мозг усердно отказывался понимать, где конкретно в этой монструозной конструкции нужно применить теорему о трёх перпендикулярах, и почему именно точке Q суждено стать проекцией точки P на отрезок AC. Самые умные одноклассники уже давно всё решили и спят, возможность спросить учителей появится только через пару дней, параллельно выслушав жалобы на отсутствие и них времени и упрёки в невнимательности на уроках, а небрежные разборы из интернета только больше запутывают – ситуация патовая, недорогой помощи ждать не от кого.

Однако экспозиция открывалась с определения времени действия не просто так: именно зимой 23-го мы попробовали нашумевшую в локальных телеграм-каналах про ИИ штуку под кринжовым названием ChatGPT. Заплатив 35 рублей за СМСку с американского номера, мы восторженно принялись сливать все решения в сервис. Однако не прошло и недели, как мы осознали что этот чатик так же, как и мы прекрасно справляется с решением и разбором простых задач, и так же фатально ошибается в решении сложных.

Прошёл год, мы с Артуром стали студентами Иннополиса и уже неплохо понимали, как работают эти чудо языковые модели. В то же время развивались и сами модели. И вот тут возникал парадокс: несмотря на кратный прирост в размере и стоимости обучения, даже самая последняя GPT-4o (да что там 4o, и o1 порой грешила ошибками) не способна была тупо полностью правильно решить абсолютное большинство задач из второй части ЕГЭ по профильной математике. Казалось бы, LLMки уже покоряют всякие ARC челленджи, топят бенчмарки по типу MATH, а тут такое… Те, кто прошёл ЕГЭ, AGI не чувствуют.

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

Помимо этого было и жгучее желание попробовать «собрать» ИИ, в объяснениях которого было бы как можно больше смысла и как можно меньше… «непонятного переливания из пустого в порожнее» – надо бы в русском придумать подходящее звонкое слово для такого текста, в английском подобные вещи уже называют «AI slop».

Глава вторая. АПИ дешевле

Первое откровение создание стартапа на LLMках – это стоимость видеокарт. Одна выделенная масюся А100 в каком-нибудь «Селектеле» стоит под 400К в месяц – а одной картой многопользовательскому сервису никак не обойтись… Как такую проблему решают другие ребята? Используют «серверлес» решения – выделенные серверы, которые оплачиваются ровно столько, сколько используются.

Однако серверлес вообще не развит в России – буквально нет ни одного стартапа/компании, которая такие услуги предоставляла бы за карту «МИР». Выбор пал на использование готовых, closed-source LLMок, в нашем случает, от Майкрософт Азура (как мы получили доступ – как пели Фиксики – большой большой секрет).

Глава третья. Брутфорс

Пока основная команда разбиралась с import openai, остальные взялись за изучение способов решения геометрических задач нейросетями: традиционно, LLM трудно справляются с пространственным мышлением и такие задачки им даются тяжело, однако за несколько месяцев наших изысканий Google Deepmind выпустили «революционную» AlphaGeometry. Как оказалось, модель полагалась больше на брутфорс перебор различных простейших построений, чем на какое-то «разумное» решение, в следствие чего ЕГЭшные задачи средней сложности эта штука решала где-то аж за целую сотню шагов, конструируя наводящие страх и ужас множества окружностей и линий.

Глава четвёртая. deeplitlm I

Логотип первой версии – разбавляем лонгрид картиночкой
Логотип первой версии – разбавляем лонгрид картиночкой

Основная команда, разобравшись с import openai, занялась созданием первой, хоть на что-нибудь способной версии диалоговой модели. Основной задачей мы поставили увеличить вероятность правильного решения задач из профильного ЕГЭ по математике. Поскольку задачи из ЕГЭ достаточно типизированы и в каждом номере – похожи друг на друга, мы решили использовать эту приятную особенность, чтобы помогать модели идти по правильному пути решения. Для решения этой задачи нам в голову пришло интересное и в то же время простое решение – использовать in-context RAG, только не для ретривала какой-нибудь фактологической информации, а для предоставления примеров решений задач, подобных заданию, поданному на вход.

Для этого мы составили датасет из более чем четырёх тысяч пар задача-решение, группированных по номерам на экзамене и подтемам. Создали векторную базу данных, и проверяли на схожесть условие из входа модели с условием в таблице – таким образом выбирали top-k решений и прикрепляли в виде few-shot примеров в промпт модели. Таким образом мы повысили качество решений относительно базовой модели (а базовой в то ещё время была, кхм, GPT-3.5-Turbo) без RAG. Насколько повысили – не скажем, потому что мы тогда ещё не умели в метрики. Просто увидели что количество любых к тому моменту неберущихся задач стало поменьше.

Из интересного про сбор данных: в нашем случае просто спарсить текст со странички открытого источника не получалось, так как многие составители заданий вместо того, чтобы использовать «Латех» и красивенько рендерить у себя на сайте (как это делали мы в своём сервисе), прям посреди текста вставляют SVG/PNG картинки, в которых этот «Латех» был уже отрендерен. Что за повальная привычка у всех в России так делать и кто вообще до этого «элегантного» решения додумался – мы не знаем, но придумали как с этим работать. Поначалу, мы делали скрины всех заданий с сайтов и переводили их через «МатПикс», однако затем пришли к использованию своего бесплатного решения – прикрутили к парсеру текста парсер этих маленьких изображений и прямо во время процесса сбора данных прогоняли эти картинки через Христом посланное опен-сорс решение с «ГитХаба» – «Math OCR». Пара фиксов конфликтов с Pillow – и вот, эта чудо-смесь ViT и LSTM хавает на вход картинки и практически сразу выдаёт приличного качества Латех-строку. Работает быстро даже на Макбуке Про с «М»-процессором.

Так получилась первая итерация нашей языковой модели, которую мы стильно прозвали «deeplitlm I.»

Глава пятая. deeplitlm II

Логотип второй версии – дизайнер был в отрыве
Логотип второй версии – дизайнер был в отрыве

Дальнейшей задачей стало реализовать в чате поддержку так называемых «образовательных сценариев» (слово подслушали в подкасте «Яндекса» про образование и языковые модели) – мы заранее представили как чаще всего пользователи будут взаимодействовать с ИИ-репетитором и сообразили шесть основных «сюжетов»: решение задачи, проверка решения задачи, помощь с полуготовым решением, вопрос по теории математики, вопрос по теории самого экзамена, и наша «вишенка на торте» – режим «совместного решения», в котором модель маленькими шажочками продвигает пользователя по решению задачи, максимально дотошно объясняя каждый малипусенький момент и заставляя думать прежде чем смотреть, что делать дальше.

Деление диалога на образовательные сценарии помогает нам «выровнять» модель так, чтобы мы могли контролировать каждый процесс отдельно и предоставлять лучшие по качеству ответы. Добились мы этого созданием агентной системы под капотом чата – за каждый образовательных сценарий отвечает отдельная функция. Агент в нашем понимании вещь незамысловатая: тулза, вызывающая модель с отдельным промптом. Кстати, примерно такое же понимание агента и в OpenAI – похожая система была реализована у них во фреймворке для ресёрча агентов "Swarm".

Взаимодействие между нашими агентами происходит через вызов функций. Каждый раз главная модель-оркестратор думает, подходит ли запрос пользователя по какую-либо функцию, и если подходит, то пересылает нужные части промпта в новый объект модели, уже со своим кастомным промптом и другими ухищрениями. Из ухищрений, например, агент тоже может вызвать функцию уже для себя, например, калькулятор, или «поговорить» с другим агентом.

Была одна неочевидная сложность с реализацией. Сначала мы, как любые уважающие себя стартаперы, решили юзать «Лэнгчейн» – насмотрелись красивых обещаний в документации по типу «ReAct Agent» и «Track your agent in a loop» и решили мигрировать на этот фреймворк. Оказалось, что уважающие себя стартаперы на самом деле себя не уважают, поскольку ЛэнгЧейн оказался огромным монстром Франкенштейна с кучей разных версий, документаций, ненужных и непонятных параметров, и несовместимых друг с другом форматов данных. То есть, чтобы вы понимали, я несколько дней только пытался запустить эту штуку на минимальном примере, но то объект промпта не соответствовал аргументу функции из другого сценария, то какие-то дополнительные аргументы нельзя было ниоткуда получить, пока не выполнишь три танца с бубном в соседнем файле, и т. д.

Короче говоря, мы решили писать весь код вызова функций и общения агентов на «голом» API OpenAI. Да, код громоздкий, но зато действительно всё прозрачно и понятно: что, куда, откуда, и зачем. Блаженство. Кстати, если вам кажется, что код должен получиться негромоздким, потому что на страничке Гитxаба у OpenAI показаны красивые и минималистичные примеры использования – то это, конечно, правда, до тех пор, пока вы не попытаетесь реализовать вызов функций через стриминг по чанкам данных. В то время у компании не было нормальной документации, описывающей, как это делать, и нам приходилось вслепую разбираться, что к чему приконкатенировать. Но, ёмаё, даже это было приятнее, чем работать с Лэнгчейном.

Итак, объяснять система умеет, теперь нужно поднимать метрики по качеству решений. И oh boy – мы перечитали и перепробовали много методов из статей: Tree-of-Thoughts, Self-Consistency, Self-Verification, StateFlow, Abstract-of-Thoughts, Hint before solving, и около 140 остальных, менее значимых работ, чтобы понять, как вообще выглядят технологии «выбивания SOTA из API», что уже делали, как делали, что работало, а на что внимания можно не обращать. Привет, 2024-й. На самом деле все эти методы собирались вместе в одну большую идею: LLM – это генератор текста «за один присест», модели зачастую генерят что попало и думают весьма поверхностно. Ещё бы, попробуйте решить математическую задачу за 10 секунд просто думая по максимально прямому пути от точки А до точки Б – не получится. Вот и у LLMок не получалось.

Решение: заставить модели генерить текст дольше, сомневаться и критиковать, возвращаться обратно к своим мыслям – помещение языковых моделей в жёсткую алгоритмическую логику более верхнеуровневой системы, которая и управляет самим процессом «мышления». Так, например, авторы работы про Tree-of-Thoughts создают дерево решений, используя модель, потом DSFом проходят по этому дереву и верифицируют эти решения на каждом новом уровне, тоже с помощью модели. То есть общим поведением системы управляет незамысловатый программный код. Интуиция решения стала нам ясна: «больше токенов – лучше решение.» Вот такое масштабирование мы и планировали применить в нашей модели.

В том же сентябре 24-го, параллельно нам, OpenAI выпустили o1, и оказалось, что мы очень удачно попали в тренд масштабирования токенов. Только o1, конечно же, была именно обучена, через RL, рассуждать как ей захочется, без всяких внешних штук. Правда, смешно говорить, но с ЕГЭ она всё ещё полностью не справлялась.

В октябре мы доработали наше решение – шаг за шагом генерили решение задачи, поэтапно проверяя решение на адекватность, правдоподобность, логичность и математическую строгость. Так мы смогли выбить 86 вторичных баллов в демо-варианте ЕГЭ 2025. Процесс достаточно медленный, однако мы в команде придумали его визуализировать примерно так, как это делают в поиске «Перплексити», чтобы юзеры не скучали.

Этот демо-вариант, кстати, и стал нашей основной метрикой. Такого небольшого количества задач в принципе хватало, чтобы проследить процесс решения и понять трудности, с которыми чаще всего сталкивалась модель.

Однако и здесь мы столкнулись с несколькими непредвиденными трудностями. Во-первых, это очень дорого. И дело не в том, что у нас много промптов и т. д., а в том, как происходит работа с API. Каждый раз, когда мы подаём запрос в модель – на вход она получает не только новое сообщение, но и весь остальной контекст диалога. И тут рушится красивая идея того, что можно разделить одно большое решение в один проход на небольшие шаги – ведь они всё равно вместе будут такого же размера, как и решение в один проход! Нет. Вместо этого каждый новый шаг на вход модели будет передавать и все предыдущие шаги, чтобы она не забыла решение, и эта штука будет расти в цене в геометрической прогрессии по мере увеличения количества шагов решения задачи, что выходит уже даже не в копеечку, в целый рубль а то и два!

Кроме того, после множества взаимодействий, анализа генераций и промпт-тюнинга мы заметили, что, как минимум, небольшие, дистиллированные модели, по типу GPT-4o mini, с которой мы работали, плохо справляются с проверкой своих же генераций. Self-verifier games подкачали: модель, которую мы могли позволить себе по стоимости, была слишком глупа изначально, чтобы согласованно проверять свои же шаги. Примерно так же дела обстояли и с попытками «заалгоритмизировать» наш режим совместного решения – 4o-mini попросту «терялась» во множестве переплетений из запросов пользователя, системных промптов, и своих собственных ответов – что в итоге приводило к очень странным и непоследовательным формулировкам во время общения. Поэтому запоминаем правило «один большой толковый промпт лучше мелких двух» – модели хотя бы натренированы работать именно в таком режиме и запоминать инструкции в чате надолго.

Глава шестая. deeplitlm III

Логотип третьей версии, брендинг наше всё
Логотип третьей версии, брендинг наше всё

Несмотря на то, что решения второй версии получались в большинстве случаев правильными математически – это казалось только если смотреть переходы напрямую между шагами в частности, а не на весь путь решения в целом. На деле модель постоянно забывала результаты каких-нибудь вычислений и выводов, сделанных значительно ранее, и часто начинала идти по какому-то неверному пути, тратя нам время и деньги. Растущая стоимость уже не позволяля накрутить ещё пару циклов и ещё больше промптов (и слава Богу). Несколько бессонных ночей изучение пропозициональной логики, составления подробнейших инструкций на разных уровнях абстракции, и всё чтобы сделать неутешительный вывод: пора повзрослеть и написать LLM с нуля и натренить на Макбуке заняться дообучением. Так, модель уже будет «помнить» паттерны, куда идти и что делать для решения. Мы ограничились только SFT обучением, без всякого RL, потому что на тот момент не вышла даже DeepSeek R1 Zero чтобы показать, как это делается.

Датасет для дообучения – все ранее полученные нами задачи из векторной БД. Однако мы провели некоторый препроцессинг решений всех задач – прошлись по каждому и с помощью LLM перефразировали решения так, чтобы в них было сгенерено как можно больше текста, подробностей этого решения и объяснений математических переходов. Так мы помогаем модели лучше улавливать зависимости между токенами и представлениями слов в последовательности. Короче говоря, разжёвываем всё. Системный промпт, условия задач и перефразированные решения собираем в один большой JSONL файл и отправляем на дообучение в «Азур» со стандартными гиперпараметрами. И конечно же, в этот раз не забываем про метрики: здесь всё просто – отбираем несколько десятков позиций из нашего тренировочного датасета в валидационный и проверяем качество результата на нём. Здесь ещё важно не забыть, что валидационный, да и вообще любые датасеты лучше создавать с равномерным распределением задач каждого типа – только тогда есть вера в надёжность наших измерений.

На этом этапе сложность была только одна – это тупой Майкрософт Азур: мало того, что им абсолютно непонятно, как пользоваться, мало того, что для дообучения нам пришлось два раза менять регион, так он ещё и неправильно читал файл и отказывался заливать тренировочный датасет😬 ссылаясь на какую-то призрачную ошибку. В итоге к результату привели две недели (!!!) тыканья кнопочек.

По итогу обучения чуть подняли метрики и, в принципе, решали задачи из ЕГЭ на уровне большой и громоздкой второй версии, только в несколько раз быстрее и дешевле🥳

Глава седьмая. Эпилог

Эти разработки вкупе с бизнес-моделью принесли огромное количество признания на так называемой пре-сид стадии: мы выигрывали гранты ФСИ, КИвО, попадали в топы самых известных в России акселераторов, а сколько грантов на Yandex Cloud нам раздали...

Однако deeplitlm III. стала нашей последней итерацией языковой модели. Помимо уже рассказанного, она научилась шутить по теме и считывать изображения. С тех пор прошло уже больше года и мы, как большинство студенческих стартапов, медленно загнулись под натиском схожих решений от Яндекса и улучшений самого ChatGPT. Что еще раз может вам напомнить о том, что на технологии ИИ нужно смотреть с учетом их будущего развития и запускаться как можно быстрее, не пытаясь дорабатывать продукт до его идеала или до своего изнеможения.

В работе принимали участие:

  • Влад Калиниченко @vladotpad

  • Артур Бабкин @theother_archeee

и другие талантливые студенты, занимавшиеся разработкой и продвижением:

  • Влад Кузнецов @kvllad

  • Ильсаф Абдулхаков @haruyume

  • Лера Оглобина @kolonochkaa

  • Женя Чернов @Ch3vg

Источник

Отказ от ответственности: Статьи, размещенные на этом веб-сайте, взяты из общедоступных источников и предоставляются исключительно в информационных целях. Они не обязательно отражают точку зрения MEXC. Все права принадлежат первоисточникам. Если вы считаете, что какой-либо контент нарушает права третьих лиц, пожалуйста, обратитесь по адресу service@support.mexc.com для его удаления. MEXC не дает никаких гарантий в отношении точности, полноты или своевременности контента и не несет ответственности за любые действия, предпринятые на основе предоставленной информации. Контент не является финансовой, юридической или иной профессиональной консультацией и не должен рассматриваться как рекомендация или одобрение со стороны MEXC.

Вам также может быть интересно