Привет!
Привет! Последнюю неделю я продолжаю занимался реализацией обучениея модели YOLOv11. Основная проблема - обучение упорно не сходилось, после нескольких эпох лосс начинал катастрофически разваливаться. Потратил немало времени на поиски причины, пока не вскрылись две большие проблемы: критический баг в ядре фреймворка и классическая боль с датасетом. 🚨 Главный фикс: баг с накоплением градиентов Это и было основной причиной расхождения. Оказалось, что backward passes для conv2d, conv_transpose2d и batchnorm2d писали напрямую в input.grad(). В результате градиенты просто перезаписывались, вместо того чтобы суммироваться с разных путей(ребер вычислительного графа) для одного входного тензора. Решение: Заменил прямую запись на add_grad. Теперь вклад от всех операций корректно суммируется. Обучение наконец-то поехало! 📊 Борьба с несбалансированным MS COCO и YOLOv11 туллинг Вторая головная боль — сам датасет MS COCO. В нём сильный перекос в сторону класса 0 (person). Чтобы нивелировать этот дисбаланс и упростить жизнь при обучении, я добавил в туллинг YOLOv11: • Class-weighted loss: взвешивание по классам для классификационного BCE. • Balanced subset builder: утилита для создания сбалансированных сабсетов COCO. • CSV logging: логирование лосса по батчам с поддержкой resume/append. • Loss-curve viewer: интерактивный вьювер для отрисовки этих CSV-логов - это позволило лучше наблюдать за динамикой обучения. 🛠 Другие важные фиксы в ядре Adept: Vulkan push-constant packing. Буфер shader-constants паковался без std430 alignment padding. Из-за этого 64-битные скаляры могли попадать на невалидные оффсеты. Выровнял по спецификации. Misc: В Python-биндингах тензоров теперь корректно экспортируются bool значения в protocols buffer интерфейсе. 🔮 Что дальше: оптимизация памяти Следующая большая задача — потребление памяти. Сейчас Adept расходует почти в 4 раза больше памяти GPU по сравнению с зеркальной реализацией на PyTorch. Причина кроется в неоптимальной политике memory pool. При обучении YOLO генерируется огромное количество тензоров переменной длины — из-за разного количества anchors на каждом изображении. Простой пул аллокаторов приходится сильно раздувать, чтобы сократить число аллокаций, и это убивает эффективность по памяти. Нужно переработывать стратегию пула — это в планах на ближайшее время. 💡 Вывод Решение реальной комплексной задачи вроде обучения YOLOv11 вскрыло массу проблем, которые просто невозможно было обнаружить на отдельных юнит-тестах и простых моделях. Баг с перезаписью градиентов, проблемы с non-contiguous тензорами, перерасход памяти — всё это всплыло только когда пайплайн был собран целиком и поставлен под нагрузку. Хорошее напоминание о том, что integration testing и реальные нагрузки - незаменимы. #Adept #YOLOv11 #DeepLearning #ComputerVision #MachineLearning #Vulkan #C++ #Python #MLOps #ModelTraining