diff --git a/apps/website/i18n/course.ru.json b/apps/website/i18n/course.ru.json
index 5efa2968ad..2839ef5fef 100644
--- a/apps/website/i18n/course.ru.json
+++ b/apps/website/i18n/course.ru.json
@@ -4,10 +4,10 @@
"$note": "Russian words for specs/course/course.t27. Keys are MODULE_IDS, LESSON_IDS and, under ui, the SAY_ names. Numbers and {placeholders} must match the English field; course-from-spec.mjs checks both.",
"ui": {
"TITLE": "С нуля до чипа: программирование FPGA на t27",
- "DESCRIPTION": "27 уроков, в каждом рабочий виджет: что такое FPGA, как числа становятся битами, ваша спека на t27, как её компилирует t27c и как она превращается в битстрим на настоящей плате. Затем лаборатория из 3 уроков о наших собственных исследованиях.",
+ "DESCRIPTION": "27 уроков, в каждом рабочий виджет: что такое FPGA, как числа становятся битами, ваша спека на t27, как её компилирует t27c и как она превращается в битстрим на настоящей плате. Затем лаборатория из 3 уроков о наших собственных исследованиях и 3 урока о форматах чисел MX, которыми пользуются ИИ-чипы.",
"KICKER": "Курс",
"LEAD": "Опыт с железом не нужен. Каждый урок открывает настоящий инструмент, собранный из реальных запусков на нашем стенде: прочитайте немного и попробуйте сами.",
- "SHAPE": "9 модулей по 3 урока, 27 клеток, затем лаборатория из 3. Закрашенная клетка — урок, который вы отметили пройденным.",
+ "SHAPE": "9 модулей по 3 урока, 27 клеток, затем лаборатория из 3 и модуль ИИ-чисел из 3. Закрашенная клетка — урок, который вы отметили пройденным.",
"START": "Начать урок 1",
"CONTINUE": "Продолжить",
"MODULE": "Модуль {0}",
@@ -45,7 +45,8 @@
"timing": { "TITLE": "Размещение, трассировка, тайминг", "LINE": "Где ячейки оказываются на кристалле и успевает ли тактовая частота." },
"bitstream": { "TITLE": "Битстрим", "LINE": "Как оттрассированный дизайн становится битами, которые загружает чип, без Vivado." },
"board": { "TITLE": "На плате", "LINE": "Спросите чип, кто он, загрузите биты и проверьте их." },
- "lab": { "TITLE": "Лаборатория: наши исследования", "LINE": "Свой формат чисел, честная таблица результатов и таблицы модели, перемноженные на плате." }
+ "lab": { "TITLE": "Лаборатория: наши исследования", "LINE": "Свой формат чисел, честная таблица результатов и таблицы модели, перемноженные на плате." },
+ "mx": { "TITLE": "ИИ-числа: блок MX", "LINE": "Как ИИ-чипы хранят веса в нескольких битах: один общий масштаб на блок, сам байт масштаба и что один выброс делает с соседями." }
},
"lessons": {
"fpga-is-a-grid": {
@@ -227,6 +228,24 @@
"GOAL": "Как компьютер кормит плату работой через последовательный мост, почему важен размер окна и что плата посчитала.",
"TEXT": "Арифметику делает плата; компьютер отправляет ей работу через последовательный USB-мост. Ответы платы ждут в маленьком приёмном буфере микросхемы моста, и если держать в полёте больше запросов, чем помещается их ответов, ответы теряются. Окно поменьше убрало потери и не замедлило прогон. По этой линии плата перемножила все троичные матрицы весов небольшой языковой модели, и каждая строка совпала с эталоном бит в бит. Сам текст генерирует Mac, который делает всё, кроме троичных скалярных произведений: плата — это калькулятор, а не вся модель.",
"TASK": "Тяните окно, пока ведро не переполнится, и запомните самое большое окно, которое помещается; затем сравните два настоящих прогона."
+ },
+ "one-scale-per-block": {
+ "TITLE": "Один масштаб на блок весов",
+ "GOAL": "Почему ИИ-форматы делят один масштаб на блок весов и как читается байт масштаба OCP MX.",
+ "TEXT": "У языковой модели миллионы весов, и хранить и пересылать полное число с плавающей точкой для каждого дорого. Форматы Microscaling (MX) консорциума Open Compute Project хранят каждый вес в 4, 6 или 8 битах и дают каждому блоку из 32 весов один общий масштаб. Этот масштаб — один байт, E8M0: без знака и без мантиссы, только порядок, так что код e означает 2 в степени e минус 127, а код 255 означает NaN. Плеер компилирует e8m0.t27, спеку этого байта, прямо в вашем браузере и запускает её тесты. Проверку, которую браузер выполнить не может, он пропускает и объясняет почему.",
+ "TASK": "Запустите тесты и посчитайте пропуски; затем откройте Verilog и найдите функцию, которая проверяет код 255."
+ },
+ "scale-byte-native": {
+ "TITLE": "Байт масштаба на настоящей машине",
+ "GOAL": "Что нативный компилятор проверяет в той же спеке, включая то, что браузер пропустил.",
+ "TEXT": "Плеер в прошлом уроке не смог выполнить все проверки в e8m0.t27 и прямо об этом сказал. Эта запись запускает нативный t27c и Zig на настоящей машине на той же спеке: её константы, отчёт о тестах, тесты Zig и Verilog для проверки на NaN. Часть проверок — инварианты, которые компилятор доказывает во время компиляции, так что компиляция и есть проверка. Каждый байт в записи напечатала команда; инсценирован только набор текста.",
+ "TASK": "Найдите, сколько инвариантов отчёт доказал во время компиляции, и сравните число пройденных тестов с числом у плеера."
+ },
+ "one-outlier": {
+ "TITLE": "Один выброс, много нулей",
+ "GOAL": "Чего стоит общий масштаб: как один крупный вес обнуляет мелкие веса своего блока, формат за форматом.",
+ "TEXT": "Общий масштаб задаёт самое большое значение в блоке, поэтому один выброс задаёт его для всех 32 весов. Веса, намного меньшие выброса, падают ниже самого мелкого шага, который может показать элемент, и записываются нулём. Эта запись нативно запускает ocp_mx.t27, нашу спеку OCP MX v1.0, на блоке из 31 мелкого веса и одного выброса и считает, сколько весов обнуляет каждый формат элемента. Затем она подкладывает ошибку, одно изменённое смещение порядка, и падает ровно один тест: спека, которая несёт свои тесты, ловит собственные ошибки.",
+ "TASK": "Найдите, какой формат элемента обнуляет больше всего мелких весов, а какие два — ни одного; затем найдите тест, который ломает подложенная ошибка."
}
}
}
diff --git a/apps/website/public/learn/a-build-receipt/card.png b/apps/website/public/learn/a-build-receipt/card.png
index 7a8d43e94b..7ddccc41cd 100644
Binary files a/apps/website/public/learn/a-build-receipt/card.png and b/apps/website/public/learn/a-build-receipt/card.png differ
diff --git a/apps/website/public/learn/a-build-receipt/index.html b/apps/website/public/learn/a-build-receipt/index.html
index 7530c1a17f..990d69434b 100644
--- a/apps/website/public/learn/a-build-receipt/index.html
+++ b/apps/website/public/learn/a-build-receipt/index.html
@@ -4,7 +4,7 @@
-
What a shared scale costs: how one large weight pushes the small weights of its block to zero, format by format.
+
A shared scale is set by the largest value in its block, so one outlier sets it for all 32 weights. Weights much smaller than the outlier then fall below the smallest step the element can show and are stored as zero. This recording runs ocp_mx.t27, our spec of OCP MX v1.0, natively on a block of 31 small weights and one outlier, and counts how many each element format flushes to zero. Then it plants a bug, one changed exponent bias, and exactly one test fails: a spec that carries its tests catches its own mistakes.
+
Try it
Read which element format flushes the most small weights to zero and which two flush none; then find the test the planted bug breaks.
t27c 0.4.0 and zig 0.16.0 on the t27c lab (Railway), spec at t27 1a3786657: 49 tests pass natively; one changed bias makes exactly one test fail; git restores the spec.
+
+
+
All lessons
Module 1 · The chip
What an FPGA is, which chip we use, and how its pins meet the board.