Я выбрал следующую задачу:
Дан лабиринт, у него есть строго фиксированный вход и выход. Необходимо найти кратчайший путь от входа к выходу и вывести его. Данная задача удовлетворяет условию:
-
Ответ легко верифицируем: достаточно убедиться в том что путь состоит из корректных символов, имеет такую же длину, как и в оптимальном ответе, а также выполнены формальные ограничения (начинается в точке входа, заканчивается в точке выхода, во время движения мы ходим строго по доступным клеткам).
-
Сложность задачи регулируема: можно менять размер лабиранта - чем он больше, тем сложнее найти кратчайший путь.
-
Для решения задачи не требуется многошагового взаимодействия со средой, действительно - на задачу можно посмотреть как на граф и поиск кратчайшего пути между двумя его вершинами. Это очень простая и известная задача, которая решается алгоритмом поиска в ширину - BFS. Это значит что LLM также может найти кратчайший путь за 1 шаг.
Для обучения по условию необходимо было использовать небольшую модель Qwen2.5-1.5b-Instruct. Я использовал небольшие тренировочные датасеты - количество задач в легком, среднем и тяжёлом датасетах состовляло 50, 75, 100. Тут моя идея заключалась в том, что если задача простая, то модели не нужно иметь множество однотипных примеров. В случае когда уровень сложности тяжёлый лабиринты становятся больше и разнообразнее, а значит и размер тренировочного датасета должен быть больше. Это помогает достичь "равномерности" тренировки.
В моём распоряжении находилась NVIDIA 4090, однако тренировку пришлось делать из WSL - это урезает память видеокарты в 2 раза. По этой причине пришлось урезать размер batch и время обучения растянулось на 5 часов.
В целом это самое интересное в данном проекте. В качестве метрики я выбрал accuracy (отношение числа правильных ответов к числу всех ответов). Изначальная необученная модель показывает следующие результаты:
- Easy ~40%
- Medium ~25%
- Hard ~20%
А вот результаты модели после обучения:
- Easy ~100%
- Medium ~92%
- Hard ~90%
Полученное можно объяснить как успешно обученную модель, которая научилась решать поставленную мною задачу. Модель демонстрирует высокую производительность, достигая максимально возможной награды на многих шагах.
Что получилось?
- Формат выучен: Модель стабильно генерирует ответы нужной длины и структуры.
- Задача решается: Высокая accuracy говорит о том, что лабиринты проходятся верно.
- Быстрый ответ: средняя длина ответа ~60 токенов.
Что не получилось?
- Задача слишком проста: Судя по тому, что награда упирается в потолок уже на 200-м шаге, текущий датасет больше не дает стимула для обучения.
- Эффективность: Частые нули в KL-дивергенции говорят о том, что на многих итерациях обучение фактически стоит на месте. Мы тратим время GPU, но веса модели меняются незначительно.
Как это изменить?
- Усложнить задачу: можно добавить более сложные примеры лабиринтов или усложнить правила.
- Уменьшить датасет: для обучения можно обойтись и меньшим количеством в наборе задач.
Для воспроизведения результатов и запуска бенчмарков следуйте инструкции ниже.
Код протестирован на 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/activatepip install -r requirements.txtОни находятся в файле с именем benchmarks.ipynb в корне проекта. Убедитесь, что ядро Jupyter установлено в ваше окружение:
python -m ipykernel install --user --name=venv --display-name "Python (Maze Solver)"Запустите Jupyter Notebook:
jupyter notebook- В открывшемся браузере выберите файл benchmarks.ipynb.
- В меню ноутбука проверьте, что выбрано ядро "Python (Maze Solver)" (или то, которое соответствует вашему venv).
- Запустите все ячейки: Run -> Run All Cells.
Запуск тестов может занять много времени для необученной модели (поскольку она начинает "галлюцинировать"). На моей видеокарте 4070 тесты необученной модели длились ~50 минут (в то время как обученной - 15 минут). Для уменьшения времени работы можно либо укоротить тесты (уменьшить размер набора задач в датасетах 'Easy', 'Medium', 'Hard'), либо увеличить соответствующие batch_sizes если мощности позволяют.