📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Teach AI to Code in Every Language with NVIDIA NeMo | NVIDIA GTC

NVIDIA Developer45:47

Transcription

Утро, добрый день, добрый вечер. Добро пожаловать на GTC. Меня зовут Мигель Мартинес. Я научный сотрудник NVIDIA, а со мной Мерием Бендрис, которая является менеджером по архитектуре решений, и также Олег Судаков, старший архитектор решений. Сегодня мы хотели бы поговорить о том, как научить ИИ писать код на каждом языке, и это означает не только сосредоточиться на английском, но и охватить другие человеческие языки, такие как испанский, например, сосредоточиться не только на Python, но и на других языках программирования, в данном случае на Rust. Мы начнем с объяснения самых основ LLM, как они работают и как мы можем использовать их для генерации кода. Затем мы объясним результаты нашего эксперимента. Мы обучили модель кода с нуля и хотели бы поделиться с вами нашим опытом. Затем мы сосредоточимся на различных этапах этого эксперимента. Мы объясним, как проводить предварительную обработку данных, как проводить предварительное обучение, как проводить постобучение и какие инструменты мы для этого используем. Наконец, мы объясним некоторые приложения, которые мы можем создавать с помощью LLM, и рассмотрим некоторые конкретные аспекты, такие как спекулятивное декодирование и несколько других вещей. Итак, давайте приступим. Давайте начнем с объяснения того, как работает LLM. Большинство LLM, которые мы используем сегодня, используют то, что мы называем авторегрессивным циклом. Что это такое? У нас есть ввод пользователя, который мы называем промптом. Например, ввод пользователя может быть вопросом, или это может быть просто предложение, такое как "кот сидел на", которое здесь представлено зеленым цветом. Что он попытается сделать, это сгенерировать следующий токен. Хорошо, наиболее вероятный токен после этого предложения. Токен — это не совсем слово. Хорошо, но мы объясним это позже. Пока давайте предположим, что токен — это слово, даже если мы осознаем, что это не так. Хорошо, так для предложения "кот сидел на", LLM может выдать, возможно, слово "коврике". "Кот сидел на коврике". А затем мы снова подадим это слово на вход и попытаемся сгенерировать следующее наиболее вероятное слово или токен. В этом случае это может быть "кот сидел на коврике" и, возможно, "со своими друзьями", что угодно. И мы продолжаем генерировать одно слово, один токен за другим, пока LLM не посчитает, что больше нечего добавлять, или пока мы не достигнем максимальной длины контекста, которая, по сути, является максимальным количеством токенов, которые LLM должна сгенерировать. Продолжим с нашим предыдущим примером. В предыдущем примере мы пытались сгенерировать следующее слово предложения. Если вы помните, это было "кот сидел на коврике". Хорошо, в этом случае наш ввод, наш промпт будет немного отличаться. Это будет "напишите эффективную функцию Python для проверки, является ли число простым и делится на пять". Итак, это наш промпт, наш ввод. Это то, что мы хотим, чтобы LLM сделала, и LLM может просто начать писать эту функцию. Хорошо, мы видим здесь, что следующий токен, который она выдает, это "def is_prime", и она выдает код, и это хорошо. И мы называем это "отключенным рассуждением", потому что LLM не было поручено ничего, кроме генерации следующего токена, а следующий токен — это ответ на ваш запрос. Но есть другой подход, который мы называем "рассуждением", где мы учим LLM или заставляем LLM генерировать цепочки рассуждений. Цепочки рассуждений могут быть своего рода планом, который мы, люди, составляем перед выполнением действия. В этом случае эти цепочки рассуждений находятся между тегами "думать" и "/думать". А посередине у нас процесс рассуждения, шаги, которые LLM хочет выполнить для генерации этого кода. И почему мы это делаем? В основном потому, что все эти токены, которые мы здесь генерируем, снова подаются в LLM, и это дополнительная информация, это дополнительный контекст, и этот дополнительный контекст поможет и доказал свою эффективность в улучшении точности результатов. Он будет давать лучшие результаты. Вот почему после этого процесса рассуждения LLM, по сути, способна генерировать более компактную, более эффективную функцию. Давайте на мгновение поговорим о том, что такое агент и как LLM может быть агентом. Итак, агент — это просто LLM, которую научили пользоваться инструментами. Представьте, что намерение пользователя — "сколько будет 2 + 3". Тогда LLM понимает, что пользователь хочет сделать, это сложить два значения, два и три, и ее научили пользоваться различными инструментами, например, калькулятором. Таким образом, она вызовет процедуру Python или внешний калькулятор. Она передаст значения два и три. Она получит результат, в данном случае пять, и выдаст ответ человеку на человеческом языке: "сумма двух и трех равна пяти". Хорошо. Она также может делать другие вещи. Она может не только использовать локальные инструменты, но и вызывать удаленный API. Например, она может вызвать API для получения погоды в определенном месте или даже может быть стратифицирована для общения с другими агентами. Итак, — и мы увидим это позже на слайде. Таким образом, реальная задача таких агентов, LLM, состоит в том, чтобы понять намерение пользователя, разбить процесс на различные шаги, вызвать любые инструменты, API, других агентов, получить эти результаты обратно и вычислить ответ. Этот слайд пытается подчеркнуть то, что мы обсуждали ранее: что оркестрационный агент LLM может взаимодействовать с другими специализированными агентами для вашей задачи. Например, представьте, что вы — программная компания, и у вас есть база данных ошибок. Тогда у нас может быть агент отслеживания ошибок, который осведомлен об этих ошибках и предоставляет полезную информацию при поступлении новых ошибок. Затем у нас также может быть, например, если у нас есть очень внутренний фреймворк, у нас может быть агент технической документации, который осведомлен о наших API, нашей документации, нашем стиле и будет передавать эту информацию обратно, когда мы хотим решить проблему. Возможно, эта проблема решается конкретным кодовым агентом, поэтому мы возьмем информацию от агента технической документации, агента отслеживания ошибок, и оркестрационный агент передаст проблему пользователя вместе с этой дополнительной информацией кодовому агенту, чтобы попытаться получить ответ. И, возможно, оркестрационный агент мог бы сделать что-то еще. Он мог бы дважды проверить с агентом технической документации, правильно ли кодовый агент использовал все API. На следующих нескольких слайдах мы увидим, что даже если LLM способны писать код на любом языке программирования, они обычно испытывают трудности с пониманием и написанием кода, когда к ним обращаются на языках, отличных от английского. В этом примере мы попросим LLM написать эффективную функцию Python для проверки, является ли число простым и делится на пять. Но мы делаем это на испанском языке. Наш входной промпт на испанском. И мы видим здесь, что даже LLM понимает намерение пользователя, она путается, потому что выдает ответ не на Python, а на Swift, и не эффективно. И, к сожалению, это не единичный случай. Это происходит чаще, чем я ожидал. Например, у нас есть еще один пример здесь, который гласит: "напишите JavaScript", который принимает два числа в качестве входных данных и определяет, какое из них больше, и делает это правильно. Он снова выдает код Swift, и здесь есть ошибка. Поэтому, даже если LLM способна генерировать код на JavaScript, код на Python, она путается, потому что мы ввели наш входной промпт на неанглийском языке. Надеемся, это легко исправить, и это цель этой сессии. Мы научим вас предварительно обучать модель с нуля. Как настроить модель, чтобы она понимала не только английский язык, но и другие человеческие языки, такие как испанский. И мы также сделаем ее компетентной не только в Python, но и в других языках, таких как Rust. Мы объясним вам различные шаги, необходимые для этого. Мы начнем с объяснения того, что такое подготовка данных и почему она важна. Затем мы объясним вам, как проводить предварительное обучение базовой модели и как постобучать ее с помощью таких методов, как контролируемое дообучение. Во время постобучения мы можем использовать другие методы, например, мы можем использовать прямое оптимизацию предпочтений или обучение с подкреплением. Чтобы, наконец, когда у нас будет эффективная модель, мы сможем эффективно развернуть ее для нашего использования. Давайте будем немного конкретнее для этого мероприятия. Мы обучили модель кода с нуля и также создали лабораторию для обучения, которой вы можете пользоваться бесплатно во время GTC. И поскольку мы хотели сделать это очень просто, мы сосредоточились только на трех шагах: подготовка данных, предварительное обучение базовой модели и постобучение SFT. Во время подготовки данных мы использовали некоторые наборы данных, которые NVIDIA предоставила бесплатно на Hugging Face. Это наборы данных для предварительного обучения Nemotron. Мы взяли все из них или некоторые из них вместе с Википедией на английском и испанском языках и предварительно обучили языковую модель. После этого мы взяли дополнительный набор наборов данных для постобучения, также выпущенных NVIDIA под названием Nemotron post-training datasets на Hugging Face, и постобучили эту модель. И, как мы говорили ранее, эта модель будет поддерживать английский и испанский языки, Python и Rust. И целью было сделать что-то, что вы или большинство людей могут делать в своих компаниях. Мы взяли относительно небольшую архитектуру. Мы основывали нашу модель на Qwen 3 с 1,7 миллиарда параметров. Это детали архитектуры. И мы обучили ее с нуля, но не используя слишком много ресурсов в течение длительного времени. Наш этап предварительного обучения состоит всего из 0,5 триллиона токенов, распределенных в 33 000 итераций. А наш этап постобучения, наш этап контролируемого дообучения состоит из 0,26 триллиона токенов или 15 000 итераций. Мы обучали ее с точностью BF16 на 32 серверах DGX A100 в течение одного дня и 10 часов. Это может показаться много, но мы использовали всего 0,88 триллиона токенов по сравнению с оригинальной моделью Qwen 3 с 1,7 миллиарда токенов, которая была обучена на 35 триллионах токенов. Это, я не знаю, примерно в 43, 44 раза меньше ресурсов. Это значительная экономия. Давайте углубимся в этап предварительного обучения. Как мы говорили ранее, мы использовали наборы данных для предварительного обучения Nemotron, доступные на Hugging Face. Здесь вы можете увидеть различные файлы, которые мы использовали вместе с Википедией на английском и испанском языках. И смесь очень проста. Мы просто выбрали из этого набора данных. Мы сказали, что 71% контента будет кодом, около 9% — математикой. Часть контента будет на английском и испанском языках. А затем мы также добавили некоторые наборы данных для контролируемого дообучения. Почему? Потому что эмпирически доказано, что есть некоторые преимущества, если мы используем контент SFT на этапе предварительного обучения, которые нельзя восстановить, если мы не сделаем это на этапе постобучения. Поэтому, если мы не сделаем это на этапе постобучения, мы не достигнем такого же прогресса, как если бы мы это сделали. Вот почему мы добавили — мы сохраняли контрольную точку каждые 500 итераций и оценивали контрольные точки каждые 1000 итераций на различных бенчмарках: HumanEval, HumanEval+, MBPP и MBPP+. HumanEval+ рассчитывается как среднее значение этих бенчмарков. И в конце предварительного обучения мы получили точность около 19,5% при проходе за один. Это нельзя считать слишком большим, но учитывая количество времени, которое мы выделили, количество итераций, я думаю, этого достаточно. Во время постобучения мы следовали аналогичному подходу. Мы взяли некоторые наборы данных из Nemotron post-training datasets на Hugging Face, и мы использовали 25% данных для предварительного обучения и 75% для контролируемого дообучения. Мы продолжали предварительно обучать нашу предыдущую базовую модель в течение 11 часов, и мы сохраняли контрольные точки каждые 500 итераций и оценивали каждые 1000 итераций. И вот результаты, которые мы получили. В конце постобучения мы получили около 38% при проходе за один на HumanEval+. Но вы можете увидеть здесь другую цифру. Вы можете увидеть, что после слияния контрольных точек мы получаем точность около 38,87%. Что такое слияние контрольных точек? Для меня это все еще похоже на колдовство, потому что, по сути, мы берем две разные контрольные точки. Одна контрольная точка, которая очень хорошо работает на бенчмарках HumanEval, и другая контрольная точка, которая очень хорошо работает на бенчмарках MBPP, и мы, по сути, усредняем веса, и это дает лучшую контрольную точку. Это — это колдовство, но реальность такова, что это используется чаще, чем ожидалось, потому что во время этапов постобучения мы не только используем SFT, но и выполняем некоторые этапы обучения с подкреплением, и во время процесса обучения с подкреплением в некоторых случаях улучшаются некоторые бенчмарки, требующие размышлений, но бенчмарки, которые выигрывают от SFT, ухудшаются. Поэтому мы продолжаем делать SFT, обучение с подкреплением, SFT, обучение с подкреплением, и в любой момент мы просто объединяем две контрольные точки и получаем лучшую контрольную точку. Когда вы предварительно обучаете или постобучаете модель, есть много ценной информации, которую вы можете получить из графиков обучения. Здесь у нас есть пара из них, и они рассказывают историю. Вы можете увидеть здесь, что мы начали предварительное обучение, и в любой момент во время предварительного обучения, когда оно заканчивается, я сбрасываю скорость обучения. Затем я продолжил постобучение и снова сбросил ее до другого значения и продолжил постобучение, и эти изменения можно увидеть здесь. Они влияют на потерю языковой модели, перплексию валидации. Вы можете увидеть здесь, что она развивается очень хорошо, а затем скачкообразно увеличивается точность, а затем продолжает снижаться. Затем она снова скачкообразно увеличивается, чтобы продолжать снижаться, пока мы не закончим. Почему? В основном потому, что мы хотели показать в этом эксперименте, как предварительно обучать модель с нуля, и, честно говоря, как можно более честно, потому что я не повторял эксперимент. Я допустил пару ошибок. Я предположил, что полное предварительное обучение займет всего или оценил 34 000 итераций. Но я передумал, потому что заметил, что во время предварительного обучения оно продолжало улучшаться, улучшаться, улучшаться. Поэтому я решил использовать все эти итерации только для предварительного обучения, а затем сбросил скорость обучения, чтобы начать постобучение. Я мог бы продолжить с этой конкретной скоростью обучения, но она была слишком низкой. Поэтому я просто сбросил скорость обучения и начал этап постобучения, этап SFT. А затем, когда мы достигли этого количества итераций, я заметил, что еще есть место для улучшения, и я сделал что-то похожее. Я как бы изменил скорость обучения на более высокое значение, а затем она просто восстановилась и продолжила улучшаться. И это те скачки. И я хотел показать вам, рассказать вам, что даже если в более серьезном эксперименте мы обычно очень хорошо планируем, сколько итераций — у нас была только одна попытка для этого эксперимента, и мы хотели показать, что мы сделали, чтобы учиться на наших ошибках или изменениях во время выполнения. Прежде чем закончить эту секцию, передаю микрофон Мерием, которая подробно расскажет о необходимых для этого шагах. Давайте посмотрим на результаты оценки. Мы видим, что модель развивается во время этапа предварительного обучения, который доходит до сюда, а затем во время этапа постобучения происходит значительный скачок. Это ожидаемо и обычно. Мы достигаем определенного числа, которое составляет 38% точности, и мы считаем, что это очень хорошо, потому что по сравнению с другими моделями, которые обучаются на 35 триллионах токенов, мы использовали всего 0,88 триллиона токенов и получили хорошую модель, разумно хорошую модель, которая понимает английский и испанский языки, Python и Rust. И теперь это ваша очередь, Мерием. Спасибо. Спасибо, Мигель. Давайте теперь углубимся в методы, используемые для обучения LLM, лежащих в основе кодовых ассистентов. И начнем с обработки данных. Подготовка данных — критически важный этап, поскольку качество данных напрямую влияет на качество самой модели. Итак, здесь на этом рисунке из статьи Nemotron CC мы можем увидеть влияние курации данных на точность модели. Он показывает оценку MMLU для модели с 8 миллиардами параметров, обученной на одном триллионе токенов. И, как вы можете видеть здесь, она фактически достигает более высокой оценки MMLU, используя подмножество токенов более высокого качества с Nemotron CC HQ, высоким качеством. И мы также можем видеть, что модель может достичь аналогичных результатов с наборами данных в четыре раза больше с конвейером Nemotron CC, позволяя сохранить больше высококачественного контента из DCLM, при этом очищая данные. Таким образом, это подчеркивает, насколько качество данных, а также состав данных критически важны для производительности модели, особенно при обучении моделей в течение очень длительных периодов обучения. В целом, подготовка данных включает четыре основных этапа: очистка и фильтрация данных. Затем дедупликация для уменьшения повторяющегося контента. Затем определение стратегий смешивания данных, то есть как мы можем комбинировать различные наборы данных для создания сбалансированной смеси различных возможностей, таких как понимание языков программирования, вызов функций, следование инструкциям и так далее. И, наконец, токенизация для подготовки данных к потреблению LLM. Таким образом, эти четыре этапа могут гарантировать, что обучающие данные чистые, разнообразные, сбалансированные и готовы к потреблению в эффективной среде обучения. Итак, давайте разберем их по одному. Очистка и фильтрация данных заключается в удалении низкокачественного контента, шума и небезопасного контента, чтобы гарантировать, что мы начинаем с надежного набора данных. Для этого мы обычно начинаем с очень базового форматирования текста, базовой очистки, исправления некоторых проблем, таких как плохие символы Unicode, сломанные переносы строк или повторяющийся текст, например, который может очень часто встречаться в веб-наборах данных. Второе, что мы можем сделать, это фильтрация на уровне документов. Здесь мы удаляем низкокачественный контент, используя несколько подходов, таких как фильтрация качества на основе классификатора, где мы оцениваем такие вещи, как точность, ясность, связность, грамматика или общая полезность документа или абзаца. Мы также можем применять некоторые эвристические фильтры для выявления очевидных проблем. И, наконец, мы можем выполнить некоторую классификацию данных для удаления, скажем, личной информации или классификаторов для определения домена, уровня токсичности или сложности некоторых документов. Может быть применено несколько методов дедупликации, от лексической дедупликации, включая точную дедупликацию или нечеткую дедупликацию, которая заключается в идентификации документов, которые не являются точно одинаковыми, но очень похожими. Для этого могут использоваться такие методы, как MinHash. Мы также можем выполнять семантическую дедупликацию, где мы используем своего рода представление в виде эмбеддингов для идентификации семантически похожих документов, даже если слова и предложения отличаются. И, наконец, мы можем применить деконтаминацию задач. Это очень важно для обеспечения того, чтобы обучающие данные не содержали никакого контента из эталонных оценок. И поскольку LLM часто обладают сильными многоязычными возможностями, мы также можем применять деконтаминацию задач между языками, чтобы обеспечить справедливую оценку обученной модели. Все эти этапы очистки, фильтрации и дедупликации данных могут быть выполнены в масштабе эффективным способом с использованием NVIDIA NeMo Curator. Давайте теперь поговорим о смешивании данных, которое заключается в объединении нескольких источников обучающих данных для создания набора данных, который является достаточно разнообразным и сбалансированным с высоким качеством. Поэтому нам действительно нужно тщательно выбирать эту смесь, потому что она сильно влияет на навыки и поведение, которые модель будет изучать во время обучения. Например, веб-данные предоставят общие знания, а наборы данных кода улучшат навыки программирования. Итак, здесь на этом слайде вы можете увидеть пример смеси данных для предварительного обучения из статьи Nemotron Nano V3, где различные наборы данных комбинируются в определенных пропорциях. Обратите внимание, что также очень распространено включать небольшой набор контролируемых наборов данных на этапе предварительного обучения, таких как рассуждение и следование инструкциям, чтобы помочь модели изучить полезные взаимодействия на ранних стадиях. Мы настоятельно рекомендуем вдохновляться уже опубликованными смесями данных. Как правило, они являются результатом нескольких абляционных исследований для поиска правильных смесей данных для целевых случаев использования. И в экспериментах Мигеля мы хотели сделать модель хорошо понимающей человеческие языки, такие как английский и испанский, а также языки программирования Python и Rust. И именно поэтому более 70% данных составлял код на Python и Rust, а остальная часть смеси представляла собой смесь математических, английских и испанских наборов данных. И, наконец, токенизатор. Токенизация преобразует необработанные текстовые данные в токены или субслова, единицы, которые обрабатывает языковая модель. Итак, справа вы можете увидеть примеры использования токенизатора Qwen для двух языков, английского и испанского, а также языков программирования Python и Rust. Таким образом, эффективная токенизация важна, потому что она уменьшает количество токенов, необходимых для представления текста, что напрямую влияет на скорость вывода, а также на использование длины контекста. Оба очень важны для кодовых ассистентов. Поэтому, хотя токенизация может показаться небольшим шагом, она фактически играет ключевую роль в обеспечении масштабируемости LLM в приложениях. Поэтому, если вы обучаете модель с нуля, полезно рассмотреть возможность обучения токенизатора, адаптированного к вашему конкретному случаю использования. И именно это Мигель показал в разделе экспериментов по обучению LLM. Как только у нас есть токенизатор и до обучения модели, мы обычно преобразуем весь обучающий набор данных в токены для эффективного обучения. Итак, на этом слайде вы можете увидеть ссылку на учебное пособие Megatron-LM по предварительной обработке набора данных DCLM, включая перемешивание, токенизацию и преобразование в двоичный формат. Хорошо, давайте теперь сосредоточимся на этапе предварительного обучения. Этап предварительного обучения — это этап, на котором модель развивает сильные способности к пониманию языка. На этапе предварительного обучения мы используем огромное количество неразмеченных данных, в основном необработанных текстовых данных, для обучения нейронной сети предсказывать следующий токен. Это довольно простая функция потерь, но она довольно важна, поскольку она формирует основные способности модели к пониманию языка, а также к приобретению знаний. Предварительное обучение обычно является наиболее интенсивным с точки зрения данных и вычислительных ресурсов, и в результате получается базовая модель, которую мы обычно называем базовой моделью. Также часто используются существующие базовые модели вместо обучения с нуля. Мы можем добавить новые возможности, взяв базовую модель и продолжив предварительное обучение этой модели в новой области, используя ту же функцию потерь, которая заключается в предсказании следующего токена. И в этом случае этот процесс называется непрерывным предварительным обучением или CPT. Обычно за предварительным обучением следует этап расширения контекста. Особенно для кодовых ассистентов этот этап очень важен для оснащения модели сильными способностями к пониманию сложных кодовых баз и рассуждению над расширенным контентом. При предварительном обучении с длинным контекстом модель обучается на очень длинных последовательностях текста, чтобы снова предсказывать следующий токен. Это позволяет модели улавливать зависимости между большими фрагментами и документами. Это особенно важно для кодовых ассистентов, поскольку позволяет модели понимать вызовы функций между файлами, отслеживать определения типов, константы, конфигурации и предлагать более точные предложения по рефакторингу. Хорошо, автодополнение кода — это особый случай использования для кодовых ассистентов. Чтобы включить эту возможность в LLM, мы можем использовать подход "заполнение середины" или также называемый FIM, где модель учится генерировать недостающие части кода из середины последовательности, а не только предсказывать следующий токен. И для этого мы можем фактически преобразовать те же большие неразмеченные наборы данных, используемые для предварительного обучения, переместив фрагмент кода из середины документа в конец и используя специальные токены для обозначения префикса, суффикса и середины фрагментов. Если вас интересует подход FIM, вы можете ознакомиться с приведенной здесь статьей, исследующей соотношение FIM по сравнению с обычными пропорциями наборов данных слева направо во время предварительного обучения, чтобы модель могла получить возможности заполнения без потери своих основных возможностей генерации. Хорошо. Итак, когда у нас есть базовая модель, давайте углубимся в методы, которые мы используем для выравнивания этой модели. В основном мы называем это этапом постобучения. Хорошо, начиная с контролируемого дообучения или SFT. Это этап, на котором предварительно обученная LLM снова обучается, на этот раз на размеченных наборах данных, чтобы следовать явным инструкциям или выполнять конкретные задачи. Например, для LLM кода это обычно включает фрагменты кода, сопоставленные с желаемыми результатами, такими как задачи по кодированию и их решения, строки документации и так далее. И SFT помогает модели выровнять свое поведение с намерением разработчика. Например, повышая точность, релевантность и пригодность для использования в реальных сценариях. Другой метод постобучения — выравнивание предпочтений, которое представляет собой процесс дообучения LLM для соответствия конкретным предпочтениям. Например, для кодовых ассистентов это гарантирует, что предложение соответствует лучшим практикам, поддерживает согласованность и отдает приоритет решениям, которые разработчики, скорее всего, примут, и так далее. Примеры подходов, которые могут быть использованы, включают DPO для прямого оптимизации предпочтений или обучение с подкреплением, такое как PPO для проксимального оптимизации политики или GRPO, группового относительного оптимизации политики. Хорошо, если вы не знакомы с обучением с подкреплением для LLM, то этот слайд показывает принцип RL в мире LLM. Это включает состояние, которое является пользовательским промптом. Здесь, например, мы просим модель решить уравнение, математическую задачу, например. Агент или политика здесь, которая состоит из LLM. Обычно действие, которое заключается в генерации ответа LLM, и модель вознаграждения, которая оценивает, насколько хорош или плох каждый ответ. И идея здесь в том, что мы будем обучать политику или LLM, по сути, модель, максимизировать вознаграждение. И когда правильность выходных данных модели может быть математически или логически проверена, мы можем фактически заменить функцию вознаграждения на вознаграждение, основанное на правилах, и это то, что мы называем проверяемым вознаграждением или RLVR. Это фактически широко используется в качестве метода постобучения для моделей языков программирования, где мы можем использовать модульные тесты и компиляторы в качестве функции вознаграждения. Фактически, в двух словах, RLVR учит модель не только генерировать код, который выглядит как код, но и код, который фактически работает. Хорошо. Итак, подводя итог, вот список подходов к обучению, начиная с предварительного обучения и CPT, до контролируемого дообучения, до выравнивания предпочтений. Итак, предварительное обучение и CPT, цель — добавить в модель понимание языка, фактические знания. Требуются необработанные текстовые данные, и обычно их довольно легко собирать и собирать высококачественные данные для этого. И некоторые из соображений — это проведение экспериментов для поиска лучшего смешивания данных для этого этапа. С другой стороны, контролируемое дообучение, по сути, имеет целью внедрить в модель следование инструкциям, чат, возможности рассуждения. Таким образом, тип данных, необходимый для SFT, — это обычно промпт и метки или ответы, и некоторые из преимуществ — это то, что его обычно довольно просто и стабильно обучать. Однако одним из соображений является то, что очень трудно собрать высококачественные аннотированные данные для SFT. И если мы углубимся в выравнивание предпочтений. Итак, идея здесь снова заключается в улучшении некоторых возможностей и их выравнивании с человеческими предпочтениями. Тип наборов данных, которые нам нужно собрать, — это промпт, ответы и вознаграждение или ранжирование этих ответов. Итак, есть несколько преимуществ, и одно из них — это то, что оно обычно применяется после SFT для исправления любого поведения, которое не было охвачено SFT, и наборы данных обычно легче собрать по сравнению с частью SFT. Теперь, углубляясь в методы, DPO, например, это не совсем метод обучения с подкреплением, поскольку нет модели вознаграждения. Он напрямую нацелен на человеческие предпочтения и является довольно быстрым методом выравнивания. PPO требует больше дополнительных моделей. Он чувствителен к обучению и может быть вычислительно дорогим, в то время как GRPO, по сути, предлагает гораздо более эффективный вычислительно алгоритм по сравнению с PPO. И некоторые из методов постобучения, такие как контролируемое дообучение и все выравнивание предпочтений, могут фактически применяться при дообучении всей модели или при дообучении ее в режиме параметрически эффективного дообучения, который заключается в добавлении дополнительных параметров, которые будут дообучаться только в этих настройках. Хорошо, давайте теперь посмотрим на некоторые инструменты NVIDIA, позволяющие обучать такие большие языковые модели. Давайте посмотрим на фреймворк NVIDIA NeMo. Он охватывает создание моделей речи, базовых моделей зрения, VLM и LLM. Например, NeMo Curator предоставляет ускоренную библиотеку для подготовки наборов данных, а Megatron-LM обеспечивает эффективное распределенное обучение в большом масштабе. Megatron-LM основан на бэкэнде Megatron-Core, оптимизированной библиотеке, ориентированной на предварительное обучение, CPT и SFT. Фреймворк NeMo основан на реализации PyTorch, предлагает поддержку моделей Hugging Face с первого дня. А для постобучения NeMo RL поддерживает алгоритмы обучения с подкреплением, в то время как NeMo Gym предлагает стандартные среды, оркестрирующие сбор политики, определение задач и логику проверки, например. И для развертывания NeMo поддерживает оптимизированные конвейеры вывода, оценку, а также механизмы защиты. И все эти компоненты предлагают полную экосистему для разработки передовых приложений ИИ. И в эксперименте, показанном Мигелем, мы использовали NeMo Curator для обработки данных и Megatron-LM для предварительного обучения и SFT. Итак, давайте посмотрим на следующих слайдах, как это работает на самом деле. Идея рецептов обучения Megatron-LM заключается в предоставлении готовых к использованию и оптимизированных рабочих процессов обучения. Рецепты — это предварительно настроенные наборы гиперпараметров, настроек оптимизатора, стратегий параллелизма, конфигурации точности, разработанные для оптимизации крупномасштабного обучения моделей. Например, вы можете начать с создания экземпляра рецепта, например, SFT Qwen, и напрямую переопределить определенные параметры, чтобы соответствовать желаемой настройке. Этот пример показывает, как загрузить рецепт предварительного обучения Qwen 3 1.7 с помощью Megatron-LM и просто запустить предварительное обучение на предоставленных данных. Итак, мы просто импортируем рецепт предварительного обучения для целевой модели, а также шаги прямого и обратного распространения, а также конвейер обучения здесь, предварительное обучение. А затем мы можем переопределить некоторые из предварительно настроенных гиперпараметров, например, путь к данным. Здесь мы можем предоставить не только список наборов данных, но и соответствующее смешивание. Мы можем указать количество итераций, например, здесь 150 тысяч шагов, и мы можем указать глобальный размер пакета, например, здесь. И, наконец, мы можем просто вызвать конвейер предварительного обучения, используя конфигурацию. Если вам нужны более подробные сведения, ознакомьтесь с документацией по ссылке ниже. Для расширения контекста мы просто должны провести тот же эксперимент, что и предварительное обучение, при этом нам нужно предоставить ссылку для возобновления с контрольной точки, а также установить новую длину последовательности. Здесь показано с длиной последовательности 32k. Наконец, для SFT нам нужно загрузить рецепт Qwen 3 1.7 SFT, а также конвейер дообучения. Нам также нужно указать, хотим ли мы выполнять полное дообучение всех параметров или использовать параметрически эффективное дообучение, такое как LoRA, например. Здесь нам также нужно указать, что мы хотим возобновить с контрольной точки, например, базовой модели. И, наконец, мы можем просто вызвать конвейер дообучения здесь. Хорошо. Мы видели во вводной части, что LLM используются в приложениях для кодовых ассистентов. В этом разделе мы рассмотрим некоторые методы эффективного использования LLM для создания кодовых ассистентов, выходящие за рамки классической оптимизации задержки и пропускной способности LLM, такие как квантование, KV-кэширование и агентные рабочие процессы. Сначала давайте посмотрим на LLM во время вывода. Пример методов, которые мы можем использовать, называется структурированным декодированием или управляемым декодированием, которое ограничивает LLM генерировать токены, соответствующие грамматике, так что во время вывода разрешены только синтаксически допустимые токены. Эта диаграмма здесь показывает статью SynCode. Она показывает цикл на основе грамматики, чтобы гарантировать, что сгенерированный код строго соответствует грамматике языка программирования, уменьшая синтаксические ошибки в выходных данных, как показано здесь в качестве примера для генерации кода на Python. Несколько библиотек для вывода, таких как vLLM или TensorRT-LLM, предлагают возможности управляемого декодирования, поддерживая регулярные выражения, JSON или грамматические структуры. Другой метод оптимизации вывода, связанный не только с кодовыми ассистентами, — это спекулятивное декодирование, которое заключается в использовании меньшей модели, называемой черновой моделью, для генерации нескольких будущих токенов, а затем большая или целевая LLM проверяет их за один проход. Черновая модель генерирует несколько будущих токенов, обычно от 3 до 12 токенов, а затем целевая LLM параллельно оценивает черновики токенов, чтобы увидеть, совпадают ли они. И любые токены, которые не совпадают, фактически отклоняются, и с момента несоответствия система возобновляет стандартную генерацию токен за токеном, что гарантирует, что мы всегда получаем идентичную генерацию по сравнению с классическим декодированием. И фреймворки, такие как TensorRT-LLM, поддерживают спекулятивное декодирование и могут значительно увеличить пропускную способность. Иногда мы видим улучшение более чем в 3 раза без ущерба для качества сгенерированного вывода. Поэтому, если вас интересует спекулятивное декодирование, я рекомендую ознакомиться с блогом, приведенным здесь. Наконец, мы хотели закончить разговор об автономных системах. Основная возможность автономных систем — это способность оценивать и улучшать генерацию без какого-либо вмешательства человека. Например, подход самоотладки, который использует LLM для итеративного выявления и исправления ошибок в собственном сгенерированном коде. Вместо того, чтобы выдавать один ответ, агент может генерировать код, выполнять его, анализировать сбои, рассуждать об ошибках и итеративно улучшать решение. И эта графика здесь показывает пример из NeMo Agent Toolkit с кодовым агентом, который генерирует код, запускает модульные тесты в песочнице, анализирует сбои с помощью модели рассуждения и итеративно исправляет код, пока он не пройдет все тесты. И вот как это работает. Давайте, например, у нас есть постановка задачи, например, проблема на GitHub. Кодовая LLM, аналогичная той, что была представлена в разделе Мигеля, могла бы сгенерировать git-патч, который пытается исправить проблему, но также, возможно, модульные тесты, например. Затем на шаге 2 код патча выполняется против модульных тестов в среде песочницы, например. Если тесты не проходят, мы используем модель рассуждения для размышления, анализа вывода и предложения потенциальных исправлений, и мы можем итерировать, пока не пройдем все модульные тесты. Итак, мы видим появление этих типов методов, которые перемещают нас от разработки кодовых ассистентов к более автономным кодовым агентам. И на этом я передам микрофон Мигелю, чтобы он завершил нашу беседу. Спасибо, Мерием. Я думаю, пора подвести итоги. В течение последних 45 минут мы пытались раскрыть процесс предварительного обучения модели с нуля, как ее настроить, и мы прошли от самых основ — от того, как работает авторегрессивный цикл, до того, как использовать самые сложные инструменты обучения с подкреплением для достижения этого. Хорошая новость в том, что это путешествие не заканчивается здесь. Мы также создали лабораторию, практическую лабораторию, где вы можете попрактиковаться с различными ноутбуками с кодом, который мы создали для демонстрации этого. Я очень рекомендую вам взглянуть на нее, потому что там много рецептов и примеров, которые вы можете использовать для своих собственных случаев использования. И я думаю, мы закончили. Я хотел бы поблагодарить всех за участие в этой сессии. Мы останемся еще на 40 минут в чате. Поэтому, пожалуйста, задавайте свои последние вопросы. Олег не выступал во время этой сессии, потому что он отвечал на вопросы в чате. Так что спасибо Олегу за эту отличную работу. Увидимся на GTC. Пока.