Deep Neural Nets: 33 years ago and 33 years from now
Андрей Карпаты воспроизводит легендарную статью Янна ЛеКуна и соавторов 1989 года о применении обратного распространения ошибки к распознаванию рукописных почтовых индексов. Оригинальная сеть на 9760 параметров обучалась 3 дня на рабочей станции SUN-4/260, а реализация на PyTorch на MacBook Air (M1) укладывается примерно в 90 секунд — наивное ускорение около 3000×. Применяя современные приёмы (cross-entropy вместо MSE, AdamW, аугментация данных, Dropout, ReLU), Карпаты сокращает ошибку на тесте примерно на 60% — с ~80 до ~30 ошибок и ~1,5% error rate. Дополнительный прирост даёт расширение датасета за счёт MNIST до 50 000 примеров. Главный вывод: за 33 года на макроуровне мало что изменилось, но датасеты и модели выросли примерно в 10 000 000 раз, а к 2055 году обучение сетей с нуля под конкретную задачу, по мнению автора, будет почти полностью вытеснено дообучением и промптингом гигантских foundation-моделей вроде GPT.
The Yann LeCun et al. (1989) paper Backpropagation Applied to Handwritten Zip Code Recognition is I believe of some historical significance because it is, to my knowledge, the earliest real-world application of a neural net trained end-to-end with backpropagation. Except for the tiny dataset (7291 16x16 grayscale images of digits) and the tiny neural network used (only 1,000 neurons), this paper reads remarkably modern today, 33 years later - it lays out a dataset, describes the neural net architecture, loss function, optimization, and reports the experimental classification error rates over training and test sets. It’s all very recognizable and type checks as a modern deep learning paper, except it is from 33 years ago. So I set out to reproduce the paper 1) for fun, but 2) to use the exercise as a case study on the nature of progress in deep learning.
Статья Янна ЛеКуна и соавторов 1989 года Backpropagation Applied to Handwritten Zip Code Recognition, на мой взгляд, имеет определённое историческое значение, потому что это, насколько мне известно, самое раннее реальное применение нейросети, обученной end-to-end с помощью обратного распространения ошибки. Если не считать крошечного датасета (7291 чёрно-белое изображение цифр 16×16) и крошечной сети (всего 1000 нейронов), статья читается удивительно современно даже сегодня, спустя 33 года: в ней описан датасет, архитектура сети, функция потерь, оптимизация и приводятся экспериментальные показатели ошибки классификации на обучении и тесте. Всё это абсолютно узнаваемо и проходит «type check» как современная статья по deep learning, только написана она 33 года назад. Поэтому я решил воспроизвести её, во-первых, ради удовольствия, а во-вторых, чтобы использовать это упражнение как кейс о природе прогресса в deep learning.
Implementation. I tried to follow the paper as close as possible and re-implemented everything in PyTorch in this karpathy/lecun1989-repro github repo. The original network was implemented in Lisp using the Bottou and LeCun 1988 backpropagation simulator SN (later named Lush). The paper is in french so I can’t super read it, but from the syntax it looks like you can specify neural nets using higher-level API similar to what you’d do in something like PyTorch today. As a quick note on software design, modern libraries have adopted a design that splits into 3 components: 1) a fast (C/CUDA) general Tensor library that implements basic mathematical operations over multi-dimensional tensors, and 2) an autograd engine that tracks the forward compute graph and can generate operations for the backward pass, and 3) a scriptable (Python) deep-learning-aware, high-level API of common deep learning operations, layers, architectures, optimizers, loss functions, etc.
Реализация. Я старался следовать статье как можно точнее и переписал всё на PyTorch — код лежит в репозитории karpathy/lecun1989-repro на GitHub. Оригинальная сеть была реализована на Lisp с помощью симулятора обратного распространения SN (позже переименованного в Lush) Боттью и ЛеКуна 1988 года. Статья на французском, так что прочитать её я толком не могу, но по синтаксису видно, что нейросети там задаются через высокоуровневое API, похожее на то, как это сегодня делается в PyTorch. Если коротко про дизайн софта: современные библиотеки сошлись на архитектуре из трёх компонентов: 1) быстрая (C/CUDA) универсальная библиотека тензоров, реализующая базовые математические операции над многомерными тензорами; 2) autograd-движок, который отслеживает граф прямого вычисления и умеет генерировать операции для обратного прохода; 3) скриптуемое (Python) высокоуровневое API, понимающее специфику deep learning — типовые операции, слои, архитектуры, оптимизаторы, функции потерь и т. д.
Training. During the course of training we have to make 23 passes over the training set of 7291 examples, for a total of 167,693 presentations of (example, label) to the neural network. The original network trained for 3 days on a SUN-4/260 workstation. I ran my implementation on my MacBook Air (M1) CPU, which crunched through it in about 90 seconds (~3000X naive speedup). My conda is setup to use the native arm64 builds, rather than Rosetta emulation. The speedup may have been more dramatic if PyTorch had support for the full capability of the M1 (including the GPU and the NPU), but this seems to still be in development. I also tried naively running the code on an A100 GPU, but the training was actually slower, most likely because the network is so tiny (4 layer convnet with up to 12 channels, total of 9760 params, 64K MACs, 1K activations), and the SGD uses only a single example at a time. That said, if one really wanted to crush this problem with modern hardware (A100) and software infrastructure (CUDA, PyTorch), we’d need to trade per-example SGD for full-batch training to maximize GPU utilization and most likely achieve another ~100X speedup of training latency.
Обучение. В процессе обучения нужно сделать 23 прохода по тренировочному набору из 7291 примера, то есть всего 167 693 предъявлений пар (пример, метка) сети. Оригинальная сеть обучалась 3 дня на рабочей станции SUN-4/260. Я запустил свою реализацию на CPU MacBook Air (M1) — она прожевала всё примерно за 90 секунд (~3000× наивного ускорения). Моя conda настроена использовать нативные arm64-сборки, а не эмуляцию через Rosetta. Ускорение могло бы быть ещё более впечатляющим, если бы PyTorch поддерживал все возможности M1 (включая GPU и NPU), но это, похоже, всё ещё в разработке. Я также попробовал наивно запустить код на A100, но обучение, наоборот, шло медленнее, скорее всего, потому что сеть совсем маленькая (свёрточная сеть из 4 слоёв с до 12 каналами, всего 9760 параметров, 64K MAC, 1K активаций), а SGD использует по одному примеру за раз. При этом, если бы кто-то всерьёз захотел разделать эту задачу с современным железом (A100) и софтом (CUDA, PyTorch), пришлось бы променять пер-сэмпловый SGD на full-batch-обучение, чтобы максимально загрузить GPU, и тогда вполне реально получить ещё ~100× ускорения по времени обучения.
Reproducing 1989 performance. The original paper reports the following results:
Воспроизведение результатов 1989 года. Оригинальная статья приводит такие результаты:
eval: split train. loss 2.5e-3. error 0.14%. misses: 10 eval: split test . loss 1.8e-2. error 5.00%. misses: 102
eval: split train. loss 2.5e-3. error 0.14%. misses: 10 eval: split test . loss 1.8e-2. error 5.00%. misses: 102
While my training script repro.py in its current form prints at the end of the 23rd pass:
Мой обучающий скрипт repro.py в текущем виде в конце 23-го прохода выводит:
eval: split train. loss 4.073383e-03. error 0.62%. misses: 45 eval: split test . loss 2.838382e-02. error 4.09%. misses: 82
eval: split train. loss 4.073383e-03. error 0.62%. misses: 45 eval: split test . loss 2.838382e-02. error 4.09%. misses: 82
So I am reproducing the numbers roughly, but not exactly. Sadly, an exact reproduction is most likely not possible because the original dataset has, I believe, been lost to time. Instead, I had to simulate it using the larger MNIST dataset (hah never thought I’d say that) by taking its 28x28 digits, scaling them down to 16x16 pixels with bilinear interpolation, and randomly without replacement drawing the correct number of training and test set examples from it. But I am sure there are other culprits at play. For example, the paper is a bit too abstract in its description of the weight initialization scheme, and I suspect that there are some formatting errors in the pdf file that, for example, erase dots “.”, making “2.5” look like like “2 5”, and potentially (I think?) erasing square roots. E.g. we’re told that the weight init is drawn from uniform “2 4 / F” where F is the fan-in, but I am guessing this surely (?) means “2.4 / sqrt(F)”, where the sqrt helps preserve the standard deviation of outputs. The specific sparse connectivity structure between the H1 and H2 layers of the net are also brushed over, the paper just says it is “chosen according to a scheme that will not be discussed here”, so I had to make some some sensible guesses here with an overlapping block sparse structure. The paper also claims to use tanh non-linearity, but I am worried this may have actually been the “normalized tanh” that maps ntanh(1) = 1, and potentially with an added scaled-down skip connection, which was trendy at the time to ensure there is at least a bit of gradient in the flat tails of the tanh. Lastly, the paper uses a “special version of Newton’s algorithm that uses a positive, diagonal approximation of Hessian”, but I only used SGD because it is significantly simpler and, according to the paper, “this algorithm is not believed to bring a tremendous increase in learning speed”.
То есть я воспроизвожу цифры примерно, но не точно. К сожалению, точная репродукция, скорее всего, невозможна, потому что оригинальный датасет, насколько я понимаю, утрачен. Вместо этого мне пришлось симулировать его с помощью большего датасета MNIST (ха, никогда не думал, что произнесу такое): я взял цифры 28×28, уменьшил их билинейной интерполяцией до 16×16 пикселей и случайно без возвращения выбрал нужное количество тренировочных и тестовых примеров. Но я уверен, что играют роль и другие факторы. Например, статья слишком абстрактно описывает схему инициализации весов, и я подозреваю, что в pdf-файле есть ошибки форматирования: например, теряются точки «.», из-за чего «2.5» выглядит как «2 5», и, возможно, исчезают знаки корня. Скажем, нам сообщают, что веса инициализируются из равномерного распределения «2 4 / F», где F — fan-in, но я предполагаю, что это, конечно (?), означает «2.4 / sqrt(F)», где sqrt помогает сохранить стандартное отклонение выходов. Конкретная структура разреженной связности между слоями H1 и H2 тоже описана вскользь — в статье сказано, что она «выбрана по схеме, которая здесь обсуждаться не будет», так что мне пришлось разумно угадать, и я выбрал перекрывающуюся блочно-разреженную структуру. В статье также утверждается, что используется нелинейность tanh, но я опасаюсь, что на самом деле имелся в виду «нормализованный tanh», для которого ntanh(1) = 1, возможно, с добавленным масштабированным skip-соединением — в то время это было модно, чтобы хоть немного градиента просачивалось через плоские хвосты tanh. Наконец, в статье используется «специальная версия метода Ньютона с положительным диагональным приближением гессиана», а я использовал только SGD, потому что он значительно проще, и, как пишет сама статья, «считается, что этот алгоритм не даёт колоссального ускорения обучения».
Cheating with time travel. Around this point came my favorite part. We are living here 33 years in the future and deep learning is a highly active area of research. How much can we improve on the original result using our modern understanding and 33 years of R&D? My original result was:
Жульничество с путешествием во времени. Примерно здесь начинается моя любимая часть. Мы живём на 33 года в будущем, и deep learning — крайне активная область исследований. Насколько можно улучшить оригинальный результат с помощью нашего современного понимания и 33 лет R&D? Мой исходный результат был:
eval: split train. loss 4.073383e-03. error 0.62%. misses: 45 eval: split test . loss 2.838382e-02. error 4.09%. misses: 82
eval: split train. loss 4.073383e-03. error 0.62%. misses: 45 eval: split test . loss 2.838382e-02. error 4.09%. misses: 82
The first thing I was a bit sketched out about is that we are doing simple classification into 10 categories, but at the time this was modeled as a mean squared error (MSE) regression into targets -1 (for negative class) or +1 (for positive class), with output neurons that also had the tanh non-linearity. So I deleted the tanh on output layers to get class logits and swapped in the standard (multiclass) cross entropy loss function. This change dramatically improved the training error, completely overfitting the training set:
Первое, что меня немного смущало: мы решаем простую классификацию на 10 категорий, но в то время это моделировалось как mean squared error (MSE) — регрессия в таргеты −1 (для отрицательного класса) или +1 (для положительного), причём выходные нейроны тоже имели нелинейность tanh. Поэтому я убрал tanh с выходного слоя, чтобы получить логиты классов, и заменил функцию потерь на стандартную (мультикласс) cross entropy loss. Это изменение драматически улучшило ошибку на обучении — модель полностью переобучилась на тренировочном сете:
eval: split train. loss 9.536698e-06. error 0.00%. misses: 0 eval: split test . loss 9.536698e-06. error 4.38%. misses: 87
eval: split train. loss 9.536698e-06. error 0.00%. misses: 0 eval: split test . loss 9.536698e-06. error 4.38%. misses: 87
I suspect one has to be much more careful with weight initialization details if your output layer has the (saturating) tanh non-linearity and an MSE error on top of it. Next, in my experience a very finely-tuned SGD can work very well, but the modern Adam optimizer (learning rate of 3e-4, of course :)) is almost always a strong baseline and needs little to no tuning. So to improve my confidence that optimization was not holding back performance, I switched to AdamW with LR 3e-4, and decay it down to 1e-4 over the course of training, giving:
Подозреваю, что с инициализацией весов нужно быть гораздо аккуратнее, если на выходном слое стоит насыщающийся tanh и MSE сверху. Дальше — по моему опыту, очень тщательно подкрученный SGD может работать прекрасно, но современный оптимизатор Adam (с learning rate 3e-4, разумеется :)) почти всегда является сильным базовым решением и требует минимум тюнинга. Чтобы убедиться, что оптимизация не сдерживает производительность, я переключился на AdamW с LR 3e-4, плавно понижая его до 1e-4 за время обучения, что дало:
eval: split train. loss 0.000000e+00. error 0.00%. misses: 0 eval: split test . loss 0.000000e+00. error 3.59%. misses: 72
eval: split train. loss 0.000000e+00. error 0.00%. misses: 0 eval: split test . loss 0.000000e+00. error 3.59%. misses: 72
This gave a slightly improved result on top of SGD, except we also have to remember that a little bit of weight decay came in for the ride as well via the default parameters, which helps fight the overfitting situation. As we are still heavily overfitting, next I introduced a simple data augmentation strategy where I shift the input images by up to 1 pixel horizontally or vertically. However, because this simulates an increase in the size of the dataset, I also had to increase the number of passes from 23 to 60 (I verified that just naively increasing passes in original setting did not substantially improve results):
Это немного улучшило результат поверх SGD, но не стоит забывать, что заодно подъехал weight decay через дефолтные параметры, и он помогает бороться с переобучением. Поскольку мы всё ещё сильно переобучаемся, дальше я внедрил простую стратегию аугментации данных: сдвигаю входные изображения на ±1 пиксель по горизонтали или вертикали. Но поскольку это эквивалентно увеличению размера датасета, мне пришлось увеличить количество проходов с 23 до 60 (я проверил, что простое увеличение числа проходов в исходной постановке существенно результаты не улучшает):
eval: split train. loss 8.780676e-04. error 1.70%. misses: 123 eval: split test . loss 8.780676e-04. error 2.19%. misses: 43
eval: split train. loss 8.780676e-04. error 1.70%. misses: 123 eval: split test . loss 8.780676e-04. error 2.19%. misses: 43
As can be seen in the test error, that helped quite a bit! Data augmentation is a fairly simple and very standard concept used to fight overfitting, but I didn’t see it mentioned in the 1989 paper, perhaps it was a more recent innovation (?). Since we are still overfitting a bit, I reached for another modern tool in the toolbox, Dropout. I added a weak dropout of 0.25 just before the layer with the largest number of parameters (H3). Because dropout sets activations to zero, it doesn’t make as much sense to use it with tanh that has an active range of [-1,1], so I swapped all non-linearities to the much simpler ReLU activation function as well. Because dropout introduces even more noise during training, we also have to train longer, bumping up to 80 passes, but giving:
Как видно по тестовой ошибке, это очень даже помогло! Аугментация данных — довольно простая и очень стандартная техника борьбы с переобучением, но в статье 1989 года я её не заметил — возможно, это более позднее изобретение (?). Поскольку мы всё ещё немного переобучаемся, я потянулся за ещё одним современным инструментом из арсенала — Dropout. Я добавил слабый dropout с вероятностью 0.25 прямо перед слоем с наибольшим числом параметров (H3). Поскольку dropout зануляет активации, его не очень осмысленно применять с tanh, у которого активный диапазон [−1, 1], так что я заодно поменял все нелинейности на куда более простой ReLU. Так как dropout вносит больше шума во время обучения, обучать приходится дольше — пришлось увеличить число проходов до 80, что дало:
eval: split train. loss 2.601336e-03. error 1.47%. misses: 106 eval: split test . loss 2.601336e-03. error 1.59%. misses: 32
eval: split train. loss 2.601336e-03. error 1.47%. misses: 106 eval: split test . loss 2.601336e-03. error 1.59%. misses: 32
Which brings us down to only 32 / 2007 mistakes on the test set! I verified that just swapping tanh -> relu in the original network did not give substantial gains, so most of the improvement here is coming from the addition of dropout. In summary, if I time traveled to 1989 I’d be able to cut the rate of errors by about 60%, taking us from ~80 to ~30 mistakes, and an overall error rate of ~1.5% on the test set. This gain did not come completely free because we also almost 4X’d the training time, which would have increased the 1989 training time from 3 days to almost 12. But the inference latency would not have been impacted. The remaining errors are here:
Это сократило ошибки на тесте всего до 32 из 2007! Я проверил, что простая замена tanh → relu в оригинальной сети существенного выигрыша не даёт, так что почти весь прирост здесь — заслуга dropout. В сумме, если бы я отправился в 1989 год, я смог бы сократить долю ошибок примерно на 60% — с ~80 до ~30 промахов и общим уровнем ошибки ~1,5% на тесте. Это улучшение пришло не совсем бесплатно: время обучения тоже выросло почти в 4 раза, что увеличило бы тренировку с 3 дней до почти 12. Зато инференс-латентность бы не пострадала. Оставшиеся ошибки приведены ниже:
Going further. However, after swapping MSE -> Softmax, SGD -> AdamW, adding data augmentation, dropout, and swapping tanh -> relu I’ve started to taper out on the low hanging fruit of ideas. I tried a few more things (e.g. weight normalization), but did not get substantially better results. I also tried to miniaturize a Visual Transformer (ViT)) into a “micro-ViT” that roughly matches the number of parameters and flops, but couldn’t match the performance of a convnet. Of course, many other innovations have been made in the last 33 years, but many of them (e.g. residual connections, layer/batch normalizations) only become relevant in much larger models, and mostly help stabilize large-scale optimization. Further gains at this point would likely have to come from scaling up the size of the network, but this would bloat the test-time inference latency.
Дальше. После замены MSE → Softmax, SGD → AdamW, добавления аугментации, dropout и замены tanh → relu идеи «низковисящих плодов» у меня начали иссякать. Я попробовал ещё несколько вещей (например, weight normalization), но существенного улучшения не получил. Также я попытался уменьшить Visual Transformer (ViT) до «micro-ViT», примерно совпадающего по числу параметров и FLOP, но достичь качества свёрточной сети не удалось. Конечно, за последние 33 года появилось много других инноваций, но большинство из них (например, residual-связи, layer/batch normalization) становятся актуальными только в гораздо более крупных моделях и в основном помогают стабилизировать крупномасштабную оптимизацию. Дальнейшие приросты на этом этапе, скорее всего, требовали бы увеличения размера сети, но это раздуло бы инференс-латентность.
Cheating with data. Another approach to improving the performance would have been to scale up the dataset, though this would come at a dollar cost of labeling. Our original reproduction baseline, again for reference, was:
Жульничество с данными. Ещё один способ улучшить производительность — масштабировать датасет, хотя это и обходится в деньги за разметку. Наш исходный базовый репродукционный результат, напомню, был:
eval: split train. loss 4.073383e-03. error 0.62%. misses: 45 eval: split test . loss 2.838382e-02. error 4.09%. misses: 82
eval: split train. loss 4.073383e-03. error 0.62%. misses: 45 eval: split test . loss 2.838382e-02. error 4.09%. misses: 82
Using the fact that we have all of MNIST available to us, we can simply try scaling up the training set by ~7X (7,291 to 50,000 examples). Leaving the baseline training running for 100 passes already shows some improvement from the added data alone:
Учитывая, что весь MNIST у нас под рукой, можно просто увеличить тренировочный набор примерно в 7 раз (с 7 291 до 50 000 примеров). Запустив базовое обучение на 100 проходов, мы уже видим заметное улучшение только за счёт добавленных данных:
eval: split train. loss 1.305315e-02. error 2.03%. misses: 60 eval: split test . loss 1.943992e-02. error 2.74%. misses: 54
eval: split train. loss 1.305315e-02. error 2.03%. misses: 60 eval: split test . loss 1.943992e-02. error 2.74%. misses: 54
But further combining this with the innovations of modern knowledge (described in the previous section) gives the best performance yet:
А объединив это с инновациями современных знаний (описанными в предыдущем разделе), мы получаем лучший результат на сегодняшний день:
eval: split train. loss 3.238392e-04. error 1.07%. misses: 31 eval: split test . loss 3.238392e-04. error 1.25%. misses: 24
eval: split train. loss 3.238392e-04. error 1.07%. misses: 31 eval: split test . loss 3.238392e-04. error 1.25%. misses: 24
In summary, simply scaling up the dataset in 1989 would have been an effective way to drive up the performance of the system, at no cost to inference latency.
В сумме, простое масштабирование датасета в 1989 году было бы эффективным способом повысить производительность системы, без каких-либо потерь по инференс-латентности.
Reflections. Let’s summarize what we’ve learned as a 2022 time traveler examining state of the art 1989 deep learning tech:
Рефлексия. Подытожим, что мы узнали как путешественник во времени из 2022 года, изучающий передовые технологии deep learning 1989 года:
Прежде всего, на макроуровне за 33 года изменилось не так уж много. Мы по-прежнему собираем дифференцируемые архитектуры нейросетей из слоёв нейронов и оптимизируем их end-to-end с помощью обратного распространения и стохастического градиентного спуска. Всё читается удивительно знакомо, только меньше масштабом. Датасет по сегодняшним меркам — младенец: тренировочный сет — всего 7291 чёрно-белое изображение 16×16. Современные датасеты в computer vision обычно содержат сотни миллионов цветных изображений высокого разрешения из веба (например, у Google есть JFT-300M, OpenAI CLIP обучался на 400M), а доходят и до нескольких миллиардов. Это примерно ~1000× больше пиксельной информации на изображение (384·384·3/(16·16)), помноженное на 100 000× больше изображений (1e9/1e4), что даёт грубо 100 000 000× больше пиксельных данных на входе. Сеть тоже младенец: сеть 1989 года имеет ~9760 параметров, 64K MAC и 1K активаций. Современные (vision-) нейросети работают в масштабе нескольких миллиардов параметров (1 000 000×) и O(~1e12) MAC (~10 000 000×). Языковые модели достигают триллионов параметров. Лучший классификатор того времени, на обучение которого уходило 3 дня на рабочей станции, теперь обучается за 90 секунд на моём пассивно охлаждаемом ноутбуке (3000× наивного ускорения), и ещё ~100× выигрыша вполне вероятен при переходе к full-batch-оптимизации и использованию GPU. Я смог подкрутить модель, аугментацию, функцию потерь и оптимизацию на основе современных R&D-инноваций так, чтобы сократить ошибку на 60%, оставив датасет и инференс-латентность модели прежними. Скромные приросты доступны просто за счёт увеличения датасета. Дальнейшие существенные улучшения, скорее всего, потребовали бы более крупной модели, что означает больше вычислений и дополнительный R&D, чтобы стабилизировать обучение на этом масштабе. В частности, если бы меня перенесли в 1989 год, я бы в итоге упёрся в потолок по дальнейшему улучшению системы без более мощного компьютера.
Suppose that the lessons of this exercise remain invariant in time. What does that imply about deep learning of 2022? What would a time traveler from 2055 think about the performance of current networks?
Предположим, что выводы этого упражнения инвариантны во времени. Что это означает для deep learning 2022 года? Что подумал бы путешественник во времени из 2055 года о производительности нынешних сетей?
Нейросети 2055 года на макроуровне в основе своей такие же, как нейросети 2022 года, только больше. Наши датасеты и модели сегодня выглядят как шутка. И те, и другие примерно в 10 000 000× меньше. Современные state-of-the-art модели 2022 года можно обучить за ~1 минуту, наивно запустив их на личном вычислительном устройстве в качестве проекта на выходные. Сегодняшние модели сформулированы неоптимально, и, просто поменяв детали модели, функции потерь, аугментации или оптимизатора, можно примерно вдвое сократить ошибку. Наши датасеты слишком малы, скромные приросты дало бы одно только их масштабирование. Дальнейшие приросты на самом деле невозможны без расширения вычислительной инфраструктуры и без вложений в R&D по эффективному обучению моделей такого масштаба.
But the most important trend I want to comment on is that the whole setting of training a neural network from scratch on some target task (like digit recognition) is quickly becoming outdated due to finetuning, especially with the emergence of foundation models like GPT. These foundation models are trained by only a few institutions with substantial computing resources, and most applications are achieved via lightweight finetuning of part of the network, prompt engineering, or an optional step of data or model distillation into smaller, special-purpose inference networks. I think we should expect this trend to be very much alive, and indeed, intensify. In its most extreme extrapolation, you will not want to train any neural networks at all. In 2055, you will ask a 10,000,000X-sized neural net megabrain to perform some task by speaking (or thinking) to it in English. And if you ask nicely enough, it will oblige. Yes you could train a neural net too… but why would you?
Но самый важный тренд, который я хочу отметить, — это то, что сама постановка «обучить нейросеть с нуля под конкретную целевую задачу» (вроде распознавания цифр) быстро устаревает из-за дообучения, особенно с появлением foundation models вроде GPT. Эти foundation-модели тренируют лишь несколько институций с серьёзными вычислительными ресурсами, а большинство приложений достигается лёгким дообучением части сети, prompt engineering или опциональной дистилляцией данных или модели в более компактные специализированные инференс-сети. Думаю, этот тренд будет очень даже жив и, более того, будет только усиливаться. В крайней экстраполяции вы вообще не захотите обучать никакие нейросети. В 2055 году вы будете просить нейросеть-мегамозг размером 10 000 000× выполнить какую-то задачу, обращаясь к ней (или думая к ней) на английском. И если вы попросите достаточно вежливо, она выполнит. Да, вы могли бы и обучить нейросеть… но зачем?