Математика глубокого обучения
LoRA
Малый ранг как способ дообучения — и что именно он экономит, а что нет
Задача
Полное дообучение модели на 7 миллиардов параметров требует держать в памяти не только веса. Adam хранит два момента, плюс сами градиенты — то есть четыре массива размера модели вместо одного. В fp32 это порядка 100 гигабайт под то, что содержательно является небольшой поправкой.
Отсюда вопрос: нельзя ли ограничить поправку так, чтобы она была маленькой по числу параметров, оставаясь при этом полноразмерной по действию?
Арифметика ранга
Экономия равна , и у неё есть точка безубыточности: ранг, при котором две тонкие матрицы содержат столько же чисел, сколько одна большая.
Для матрицы это . Практические ранги — от до , то есть в тридцать–пятьсот раз меньше точки безубыточности. Пространства тут столько, что выбор между и не про память вовсе.
- всего в W
- 2147.48M
- обучаемых
- 8.39M
- доля
- 0.39%
- безубыточный ранг
- 2048
- Adam: LoRA / полное
- 96 / 24576 МБ
Обратите внимание на последний readout — вот где настоящая экономия. Обучаемый параметр стоит не одно место, а три: сам параметр, первый момент, второй момент. Для проекций внимания при это МБ против ГБ. Замораживание убирает три массива, а не один.
Почему малый ранг вообще работает
Здесь нужна честность: теоремы нет. Есть эмпирическое наблюдение, что поправка, нужная для адаптации к задаче, имеет быстро убывающий спектр, и есть теорема Эккарта–Янга из блока 1 (урок 090), которая говорит, что если спектр убывает быстро, то усечение по рангу — наилучшее из возможных приближений.
Посмотрите на спектр: если сингулярные значения падают быстро, ранг забирает почти всю норму; если равномерны — не забирает ничего.
поправка ΔW
ранга r · k = 2
спектр сингулярных значений
- ошибка по Фробениусу
- 0.378
- хранимых чисел
- 66 / 256
Первые два-три сингулярных значения забирают почти всю норму. На такой поправке r = 8 не приближение, а практически точное представление — и ставка LoRA выигрывает.
Формулировка, которую стоит держать в голове: LoRA — это ставка на то, что поправка низкоранговая, а не факт про нейросети. Ставка обычно выигрывает, и известно, где она проигрывает: на задачах, требующих новых знаний, а не новой формы ответа, малого ранга не хватает, и это видно по тому, что качество упирается в потолок при росте вместо роста.
Три детали, без которых не работает
Инициализация . Матрица заполняется случайно, а — нулями, поэтому в начале и модель в точности равна предобученной. Если бы обе были случайными, обучение начиналось бы с испорченной модели, и первые шаги уходили бы на восстановление.
Здесь стоит быть точным, потому что «одна из двух — нулями» звучит произвольно. Выпишем градиенты: при и
Отсюда видно, что нулём обязана быть ровно одна из матриц. Обе нулями — мёртвая точка: оба градиента обращаются в нуль и остаются нулями навсегда. Любая одна нулевая — работает: при на первом шаге двигается , а со второго и . Зеркальный вариант (, случайно) тоже даёт и тоже трогается с места, так что выбор между ними — не математика, а эмпирика: с случайным и на практике проходят большие learning rate.
Масштаб . Без него величина поправки росла бы вместе с рангом, и learning rate пришлось бы подбирать заново под каждый . С ним и разделены: ранг отвечает за выразительность, — за силу.
Слияние. После обучения считается один раз, и на инференсе никакой поправки нет вовсе — ни лишних слоёв, ни лишней задержки. Это главное отличие от адаптеров, которые добавляют в сеть новые блоки и потому платят на каждом прогоне.
Что LoRA не экономит
Тут распространено завышенное ожидание. Обратный проход обязан пройти через всю сеть: чтобы получить градиент по в первом слое, нужно протащить производную через все последующие слои, замороженные они или нет.
| что | полное дообучение | LoRA |
|---|---|---|
| параметры | все | |
| градиенты | все | только по , |
| состояние Adam | все | по , |
| активации для backward | все | все |
| проход назад через сеть | целиком | целиком |
Экономия — в трёх верхних строках, и она огромна. В двух нижних — нулевая. Поэтому LoRA снимает ограничение по памяти под оптимизатор, но не делает шаг существенно быстрее: время по-прежнему уходит в прямой и обратный проходы.
Отсюда и QLoRA: если веса всё равно заморожены, их можно держать в 4 битах — они не обновляются, поэтому точность их представления нужна только для прямого прохода. Обучаемая часть при этом остаётся в fp16. Комбинация из двух независимых наблюдений, каждое из которых само по себе простое.
Итог
- Замена одна: ранга , и всё остальное — арифметика.
- Безубыточный ранг огромен по сравнению с используемыми, поэтому вопрос выбора — про качество, а не про память.
- Экономятся градиенты и состояние оптимизатора; активации и время проходов — нет.
- на старте, масштаб , слияние после обучения — три детали, каждая из которых решает конкретную проблему.
Источники
- Hu и др. — LoRA, Low-Rank Adaptation of Large Language Models — Исходная работа
- Dettmers и др. — QLoRA, Efficient Finetuning of Quantized LLMs — LoRA поверх квантованных весов
Проверки
0 из 2Что экономит малый ранг
Отметьте все верные утверждения о LoRA.
Бюджет низкоранговой поправки
Реализуйте
lora_budget(in_dim, out_dim, count, rank, bytes_per_param)— верните[trainable, percent, break_even_rank, adam_megabytes]:trainable= — параметры и для всехcountматриц такой формы;percent— их доля от , в процентах;break_even_rank= — ранг, при котором поправка перестаёт что-либо экономить (не округляйте);adam_megabytes— сколько мегабайт занимают обучаемые параметры вместе с двумя моментами Adam, то есть , делённое на .
Проверить себя можно так: при
rank, равномbreak_even_rank,percentобязан равняться ровно ста.Загрузка редактора…
Ctrl/⌘ + Enter