Skip to content

Repository files navigation

Задача

Я выбрал следующую задачу:

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

  1. Ответ легко верифицируем: достаточно убедиться в том что путь состоит из корректных символов, имеет такую же длину, как и в оптимальном ответе, а также выполнены формальные ограничения (начинается в точке входа, заканчивается в точке выхода, во время движения мы ходим строго по доступным клеткам).

  2. Сложность задачи регулируема: можно менять размер лабиранта - чем он больше, тем сложнее найти кратчайший путь.

  3. Для решения задачи не требуется многошагового взаимодействия со средой, действительно - на задачу можно посмотреть как на граф и поиск кратчайшего пути между двумя его вершинами. Это очень простая и известная задача, которая решается алгоритмом поиска в ширину - BFS. Это значит что LLM также может найти кратчайший путь за 1 шаг.

Обучение

Для обучения по условию необходимо было использовать небольшую модель Qwen2.5-1.5b-Instruct. Я использовал небольшие тренировочные датасеты - количество задач в легком, среднем и тяжёлом датасетах состовляло 50, 75, 100. Тут моя идея заключалась в том, что если задача простая, то модели не нужно иметь множество однотипных примеров. В случае когда уровень сложности тяжёлый лабиринты становятся больше и разнообразнее, а значит и размер тренировочного датасета должен быть больше. Это помогает достичь "равномерности" тренировки.

В моём распоряжении находилась NVIDIA 4090, однако тренировку пришлось делать из WSL - это урезает память видеокарты в 2 раза. По этой причине пришлось урезать размер batch и время обучения растянулось на 5 часов.

Результаты

В целом это самое интересное в данном проекте. В качестве метрики я выбрал accuracy (отношение числа правильных ответов к числу всех ответов). Изначальная необученная модель показывает следующие результаты:

  1. Easy ~40%
  2. Medium ~25%
  3. Hard ~20%

А вот результаты модели после обучения:

  1. Easy ~100%
  2. Medium ~92%
  3. Hard ~90%

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

Что получилось?

  1. Формат выучен: Модель стабильно генерирует ответы нужной длины и структуры.
  2. Задача решается: Высокая accuracy говорит о том, что лабиринты проходятся верно.
  3. Быстрый ответ: средняя длина ответа ~60 токенов.

Что не получилось?

  1. Задача слишком проста: Судя по тому, что награда упирается в потолок уже на 200-м шаге, текущий датасет больше не дает стимула для обучения.
  2. Эффективность: Частые нули в KL-дивергенции говорят о том, что на многих итерациях обучение фактически стоит на месте. Мы тратим время GPU, но веса модели меняются незначительно.

Как это изменить?

  1. Усложнить задачу: можно добавить более сложные примеры лабиринтов или усложнить правила.
  2. Уменьшить датасет: для обучения можно обойтись и меньшим количеством в наборе задач.

Запуск

Для воспроизведения результатов и запуска бенчмарков следуйте инструкции ниже.
Код протестирован на Python 3.12 с использованием GPU NVIDIA 4070.

Клонирование

git https://github.com/TITANOBOXER/MazeProjectRL.git
cd MazeProjectRL

Создание виртуального окружения

Создайте и активируйте чистое окружение (Python 3.12):

python3.12 -m venv venv 
source venv/bin/activate

Установка зависимостей

pip install -r requirements.txt

Запуск бенчмарков

Они находятся в файле с именем benchmarks.ipynb в корне проекта. Убедитесь, что ядро Jupyter установлено в ваше окружение:

python -m ipykernel install --user --name=venv --display-name "Python (Maze Solver)"

Запустите Jupyter Notebook:

jupyter notebook
  1. В открывшемся браузере выберите файл benchmarks.ipynb.
  2. В меню ноутбука проверьте, что выбрано ядро "Python (Maze Solver)" (или то, которое соответствует вашему venv).
  3. Запустите все ячейки: Run -> Run All Cells.

Запуск тестов может занять много времени для необученной модели (поскольку она начинает "галлюцинировать"). На моей видеокарте 4070 тесты необученной модели длились ~50 минут (в то время как обученной - 15 минут). Для уменьшения времени работы можно либо укоротить тесты (уменьшить размер набора задач в датасетах 'Easy', 'Medium', 'Hard'), либо увеличить соответствующие batch_sizes если мощности позволяют.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages