Перейти к содержимому
ПереводыMIT, Berkeley, CMU

CMU 11-868 LLM Systems: путеводитель по курсу и заданиям

Что такое курс Carnegie Mellon «Large Language Model Systems» и чему учат его открытые задания: свои CUDA-ядра в учебном фреймворке miniTorch, трансформер-декодер с нуля, слитые ядра softmax и LayerNorm, параллелизм данных и конвейерный параллелизм, DeepSpeed ZeRO с LoRA и сервинг на SGLang, RLHF в стиле verl. Как делать их на 4 × RTX 4080.

11-868 Large Language Model Systems — магистерский курс Института языковых технологий (LTI) Университета Карнеги — Меллона о том, как устроены системы, на которых обучаются и работают LLM: программирование GPU и CUDA, ускорение обучения, распределённое обучение, сервинг и сжатие моделей. Курс читается с весны 2024 года и входит (в немного изменённом виде) в онлайн-сертификат CMU по генеративному ИИ и LLM.

Курс отвечает на вопросы, которые встают, как только модель перестаёт помещаться в один ноутбук: почему умножение матриц на GPU в сотни раз быстрее, чем на CPU; как написать своё ядро CUDA; откуда берутся ускорения FlashAttention и слитых ядер; как разложить обучение на несколько GPU (данные, конвейер, тензоры, ZeRO); как обслуживать модель с высокой пропускной способностью (батчинг, KV-кэш, SGLang/vLLM); как сжимать модели (квантование) и как устроен RLHF на системном уровне.

Для кого: уровень 🔴. Нужны уверенный Python и PyTorch, понимание трансформера (ступень 4) и основ C/C++. В нашей программе курс идёт параллельно ступени 5 (модули 5.4 и 5.7) и ступени 7. Ваши 4 видеокарты — почти идеальная площадка: на них можно сделать все задания, кроме тех, что требуют одной карты с очень большим объёмом памяти.

Задания строятся друг на друге: в первых трёх вы дописываете miniTorch — учебный фреймворк глубокого обучения (автор исходной версии — Саша Раш, Cornell), подключая к нему свои ядра CUDA, и в итоге обучаете на нём трансформер. Дальше — настоящие инструменты: PyTorch distributed, DeepSpeed, SGLang, RLHF-фреймворк.

ЗаданиеО чёмНаш урокВажность
1. CUDA и автоград (2024)ядра CUDA для map, zip, reduce и умножения матриц в combine.cu; автоматическое дифференцирование в miniTorch; классификатор тональности5.7.1 Архитектура GPU, 3.2.2 Свой backward★★★
2. Трансформер на miniTorch (2024)tanh и степень на CUDA, GELU, logsumexp, one-hot, softmax-потеря; модули Embedding, Dropout, Linear, LayerNorm; многоголовое внимание, FFN, слой трансформера и декодер; машинный перевод (BLEU)4.5.1 Блок трансформера, 4.6.2 nanoGPT★★★
3. Слитые ядра (2024)свои ядра CUDA для softmax и LayerNorm (прямой и обратный проход) с тестами; ускорение обучения перевода5.7.3 Ядра на Triton, 5.7.2 FlashAttention★★
4. Распределённое обучение (2024)параллелизм данных (разбиение набора, all-reduce градиентов) и конвейерный параллелизм (разбиение модели на этапы, микробатчи, расписание) с замерами5.4.3 Распределённое обучение, 5.7.4 Практика на нескольких GPU★★★
5. DeepSpeed и SGLang (2025)дообучение Llama-2-7B с LoRA через DeepSpeed ZeRO (стадия 3, bf16, чекпоинтинг градиентов); ускорение инференса на SGLang для набора AlpacaEval6.2.2 Дообучение на практике, 7.1.2 Сервинг★★
6. —условие в открытом доступе не найдено——
7. Введение в RLHF (2025)свой мини-фреймворк в духе verl: модель награды, PPO-тренер, данные Anthropic/hh-rlhf, оценка до и после RLHF6.3.2 RLHF и PPO★★

Кроме заданий, в репозитории llmsys_code_examples лежат примеры с занятий: тензоры и бродкастинг, мини-реализация TensorFlow, простое ядро CUDA и плиточное (tiled) умножение матриц, сравнение обычного внимания с FlashAttention, токенизация, декодирование и спекулятивное декодирование, квантование, DDP и DeepSpeed. Это хороший материал для самостоятельного разбора даже без курса.

miniTorch реализует тензор как плоский массив данных (storage) плюс форму и шаги (strides). Все операции сводятся к четырём примитивам: map (поэлементно над одним тензором), zip (поэлементно над двумя, с бродкастингом), reduce (свёртка по измерению) и матричное умножение. Задание — написать эти четыре примитива ядрами CUDA. Главное, чему учит задание: как отображать индекс потока GPU на позицию в тензоре и почему матричное умножение быстрее, если блок потоков сначала загружает плитки матриц в разделяемую (shared) память.

Используя свои ядра, вы добавляете недостающие операции (tanh, степень), функции GELU, logsumexp, one-hot и softmax-потерю (с подсказкой: индексирования тензорами в miniTorch нет, поэтому one-hot делают через numpy.eye), затем модули Embedding, Dropout, Linear (инициализация равномерная на [−1/nin,1/nin][-\sqrt{1/n_\text{in}}, \sqrt{1/n_\text{in}}], как в PyTorch) и LayerNorm, и собираете декодер-трансформер. Итог — машинный перевод: по условию BLEU около 7 после первой эпохи и около 20 после десяти; эпоха занимает около часа. Чек-пойнт для отладки: линейная модель тональности с оптимизатором Adam должна превысить 60% на валидации за 5 эпох.

Softmax и LayerNorm в наивной реализации — несколько проходов по памяти. Слитое ядро считает максимум, сумму экспонент и нормализацию (или среднее, дисперсию и нормализацию) за один-два прохода, держа данные строки в регистрах и shared-памяти. Отдельно пишется обратный проход. Это та же логика, что у FlashAttention, только проще.

Две части. Параллелизм данных: каждый процесс получает свою долю данных, после обратного прохода градиенты усредняются через all-reduce, и все копии модели остаются одинаковыми. Конвейерный параллелизм: модель режется на этапы по слоям, каждый этап — на своей GPU, батч делится на микробатчи, и этапы работают одновременно над разными микробатчами по расписанию (идея GPipe). Замеряется ускорение и время эпохи.

Скрипт задания запускает дообучение Llama-2-7B с LoRA через DeepSpeed (ZeRO стадии 3 по умолчанию, bf16, чекпоинтинг градиентов, накопление градиентов на 4 шага) на основе DeepSpeed-Chat. Вторая часть — инициализировать движок SGLang и ускорить генерацию ответов на вопросы AlpacaEval, подбирая параметры (например, параллелизм данных dp_size и долю памяти под KV-кэш mem_fraction_static).

Нужно реализовать упрощённый аналог verl (HybridFlow): разделить фазы генерации и обучения, обучить модель награды на парах предпочтений из Anthropic/hh-rlhf и дообучить небольшую языковую модель алгоритмом PPO, а затем сравнить ответы до и после. Наш близкий материал — переводы о verl и урок 6.3.2.

  1. Окружение. Нужны CUDA Toolkit (компилятор nvcc) и Python-окружение с PyTorch. Задания 1–3 компилируют combine.cu скриптом compile_cuda.sh в разделяемую библиотеку, которую miniTorch подгружает через ctypes.

  2. Задания 1–3 идут на одной RTX 4080. Тесты запускаются через pytest с метками частей (например, python -m pytest -l -v -m a2_2).

  3. Задание 4 — на 2–4 картах через torchrun --nproc_per_node=4. Без NVLink all-reduce идёт через PCIe: ускорение будет меньше линейного — это полезно измерить и объяснить.

  4. Задание 5. Llama-2-7B с LoRA и ZeRO-3 на четырёх картах по 16 ГБ поместится; доступ к весам Llama 2 требует принять лицензию Meta на Hugging Face — можно заменить на открытую модель того же размера (например, Qwen2.5-7B). SGLang ставится отдельно и требует свежего драйвера.

  5. Задание 7 — на одной-двух картах с небольшой моделью (до 1–2 млрд параметров).

  • Наш перевод CS336, задание 2 (systems) — близкая по духу практика Stanford: FlashAttention на Triton, DDP и шардирование оптимизатора.
  • Гостевая лекция MIT 6.S191 о массово-параллельном обучении — конспект.
ENRU
kernel, thread, block, shared memoryядро, поток, блок, разделяемая память
map / zip / reduceпоэлементное отображение / попарное объединение / свёртка (редукция)
strides, broadcastingшаги, бродкастинг (растяжение)
tiled matrix multiplicationплиточное умножение матриц
fused kernelслитое ядро
data parallelism, all-reduceпараллелизм данных, all-reduce
pipeline parallelism, micro-batchконвейерный параллелизм, микробатч
ZeRO, gradient checkpointingZeRO, чекпоинтинг градиентов (активаций)
serving, throughput, KV cacheсервинг, пропускная способность, KV-кэш
reward model, PPO, RLHFмодель награды, PPO, обучение с подкреплением по отзывам людей