Вторая статья про проект GoldenFloat. Первая была про φ-лестницу форматов и троичную «Сетунь» Брусенцова. Здесь — про инструмент, который из той работы вырос: один машинно-проверяемый каталог числовых форматов, где у каждого формата прописана разрядка битов, битовый отпечаток и метка зрелости — вплоть до той ступени, где формула ещё есть, а железа под ней уже нет.
Если вы хоть раз ловили расхождение точности между двумя реализациями одной сети, то знаете это чувство. Один и тот же matmul на двух устройствах даёт разные числа. И ты сидишь и гадаешь: это баг, или bf16 так округлил, или вообще на одном устройстве формат не тот, что ты думал. Беда в том, что две команды на разных концах конвейера меряют один результат разными линейками — и абсолютно корректное значение у одного читается как брак у другого.
Я решил сделать одну линейку с точными насечками. Для каждого формата — сколько бит уходит на знак, экспоненту и мантиссу, чему равно смещение, как кодируются inf, NaN и субнормали, где лежит общая реперная точка. Не текстом в README, а машинным источником истины: один файл, из которого автоматом генерируются Markdown, JSON, Python, Rust, C и RTL для кремния. Разойдётся спека с декодером — это ловит CI, а не человек на ревью в три часа ночи.
Препринт каталога: arXiv:2606.09686.
Оглавление
Зачем вообще каталог форматов
Лет десять назад в ML хватало float32 и float16. Дальше зоопарк начал разрастаться: bfloat16, TF32, два несовместимых FP8 (E4M3 и E5M2), FP6, FP4, микромасштабируемые MX-форматы с общей экспонентой, NF4 из мира QLoRA, posit’ы, takum’ы, логарифмические LNS. У каждого свой компромисс между диапазоном и точностью, свои правила округления, свои углы.
Проблема даже не в количестве, а в том, что спеки этих форматов растащены по статьям, стандартам и кодовым базам — и противоречат друг другу порой внутри одной библиотеки. Любимый пример: что делает FP8 E4M3 при переполнении на кодировании? У tt-metal и AMD — насыщается до 448.0, у JAX и TPU — уходит в NaN. Стандарт OCP MX разрешает оба. Пока вы не зафиксировали, какой вариант у вас, вопрос «совпадает ли результат» становится не проверяемым, а вкусовым.
Каталог отвечает на это одним файлом-спецификацией, из которого всё остальное выводится механически.
Что внутри: 83 формата в 13 кластерах
На сегодня живой источник истины (specs/numeric/formats_catalog.t27) держит 83 формата в 13 кластерах. Число я каждый раз перепроверяю на свежем клоне репозитория — почему именно так, скажу в разделе про ограничения. Разбивка:
|
Кластер |
Кол-во |
Что внутри |
|---|---|---|
|
GoldenFloat |
22 |
φ-семейство GF2…GF1024 + гибриды (GF+LNS, MXGF) (arXiv:2606.05017) |
|
HistoricalVendor |
10 |
IBM HFP, VAX (F/D/G/H), Cray, Microsoft MBF |
|
PositUnumIII |
8 |
Posit8…64, takum8…64 (Hunhold 2024) |
|
IntegerFixed |
8 |
INT4…INT128, Q-формат, BCD |
|
MlLowPrecision |
7 |
bfloat16, TF32, FP8 (E4M3/E5M2), FP6, FP4 |
|
Ieee754Binary |
5 |
binary16/32/64/128/256 |
|
Theoretical |
4 |
minifloat, Unum I/II, tapered FP |
|
Lns |
4 |
логарифмические LNS-8…64 |
|
CompressionTrick |
4 |
block FP, shared-exponent, per-channel scale, stochastic rounding |
|
Microscaling |
3 |
MXFP8/6/4 (общая экспонента E8M0) (Rouhani 2023) |
|
Ieee754Decimal |
3 |
decimal32/64/128 |
|
ExtendedFloat |
3 |
x87 FP80, double-double, quad-double |
|
QuantTuned |
2 |
NF4 (Dettmers 2023), AFP |
Разрядность тянется от 2 бит (балансная троичность GFTernary, привет Брусенцову) до 1024 бит (GF1024, крайняя ступень φ-лестницы). У каждой строки кроме s/e/m/bias есть поле phi_distance — насколько разбиение формата близко к тому, что даёт золотое сечение через тождество φ² + φ⁻² = 3.
Раз уж речь зашла про слово «golden» — это обычный отраслевой термин, эталонное значение, с которым сравнивают результат, как эталонный метр в палате мер и весов. Им оперируют и в NVIDIA, и в Intel, и любой инженер на HDL. Каталог просто говорит на том же языке, а не выдумывает свой.
Метки зрелости
Дисциплина, на которой держится весь проект, — метка зрелости у каждого формата. Она говорит ровно одно: насколько эта строка проверена на самом деле.
|
Статус |
Кол-во |
Что означает |
|---|---|---|
|
Verified |
51 |
сверен с эталоном (стандарт или ml_dtypes) |
|
Historical |
12 |
исторический формат (IBM, VAX, Cray…), для полноты |
|
Experimental |
11 |
спека плюс частичная реализация, без полного покрытия |
|
Open |
9 |
только спецификация из правила, без RTL |
Здесь же проходит граница, которая мне важнее красивых цифр: где правило e = round((N−1)/φ²) ещё работающее железо, а где оно уже гипотеза. GF16 доведён до кремния (FPGA 35/35 тестов, 323 МГц на Artix-7, кремниевый якорь). Под ступенями GF48…GF256 есть RTL, но кремния нет. GF512 и GF1024 — экстраполяция правила, у них в SSOT прямо стоит (extrapolation, no RTL), и я не делаю вид, что они проверены. Эту лестницу разбираю ниже.
Побочный эффект такой дисциплины: значение 0.1 в bfloat16 показано в каталоге с ненулевой ошибкой — потому что 0.1 в bf16 точно не представимо. Спрятать эту ошибку значило бы сломать саму линейку, ради которой всё затевалось.
Где правило перестаёт быть железом
φ-семейство держится на одном правиле: для ширины N бит экспонента e = round((N−1)/φ²), мантисса m = N − 1 − e, смещение bias = 2^(e−1) − 1. Правило короткое и применимо к любой ширине. Но «формат описан правилом» и «формат крутится в железе» — это разные вещи, и смешивать их я себе не позволяю.
Вот как лестница φ-ступеней выглядит в репозиториях прямо сейчас:
|
Уровень зрелости |
Ступени |
Что реально есть |
|---|---|---|
|
Доведено до кремния |
GF16 |
RTL + FPGA 35/35 @ 323 МГц + кремниевый якорь |
|
RTL + бенчмарк (Verified) |
GF8, GF12, GF32, GF64 |
файлы |
|
RTL написан, кремния нет (Open / Exp) |
GF6, GF10, GF14, GF20, GF24, GF48, GF96, GF128, GF256 |
|
|
Экстраполяция, RTL нет (Open) |
GF512, GF1024 |
только спека; файлов |
Тут вылезает неудобная вещь про GF1024. По метрике близости к φ это лучшая ступень лестницы (phi_distance ≈ 0.0006), и при этом она проверена меньше всех — ни одной строки Verilog. Красивая метрика не повышает уровень зрелости, и каталог это показывает, а не заметает.
RTL, который уже есть, — не для вида. Умножитель GF256 в начале июня пришлось переписать после реального бага: произведение мантисс выходило на 2 бита у́же положенного, и 1.0 × 1.0 давало 0.5. Поймали это только потому, что под форматом лежит железо, которое можно прогнать на тестах. Под GF512 и GF1024 такого железа пока нет — отсюда и честная пометка.
Якорь 0x47C0
У каталога есть одна общая реперная точка, и она растёт из того же тождества: φ² + φ⁻² = 3 = L₂, второе число Люка. Если посчитать dot4(1, 2, 3, 4) в GF16, бит-в-бит получается значение с отпечатком 0x47C0. Этот якорь проходит без изменений через все реализации — от JSON-векторов до RTL-декодеров на кремнии (проект Corona). Разъехалась эта одна точка — значит линейка где-то сбита, ищи где.
Это проверка на одинаковость, а не доказательство превосходства. Оговорка, которую держу жёстко: φ-семейство заслуживает место в каталоге широтой охвата и связностью тулчейна, а не тем, что каждая ступень кого-то побеждает. takum (Hunhold, 2024) — сильный контрпример, и он не спрятан, лежит в каталоге рядом со всеми.
Связь с IEEE P3109
Рабочая группа IEEE P3109 стандартизирует семейство 8-битных форматов для ML. В каталоге лежит cross-walk — одностраничная карта, сопоставляющая семейство P3109 binary8 (p1…p7) с индексами каталога. Это не заявление о соответствии стандарту, а справочник для разработчиков, который сама рабочая группа может проверить и поправить. Где есть расхождение — каталог уступает Lean-формализации FLoPS (arXiv:2602.15965).
Позиция тут сознательная: заходить не с «примите нас», а с проверяемой таблицей, которую можно сверить и опровергнуть.
Что это даёт на практике
Самое прямое применение — арбитр при расхождении точности. Когда один расчёт даёт разные числа на двух устройствах (классика: PCC проседает с 0.99 до 0.93 при другой блокировке редукции), бит-точный эталон формата механически отвечает, чей результат корректен, без споров на глаз.
Второе — кодоген под новое железо. Из одной спеки выводятся декодеры на нужном языке, включая RTL. Цепочка SSOT → кодоген → RTL → кремний целиком механическая, а CI-гейт rom_readback ловит любое расхождение между спекой и тем, что реально лежит в ПЗУ декодера на чипе.
Третье — общий словарь. Когда вы и собеседник из другой команды называете формат одинаково, с одной разрядкой и одним поведением на границах, исчезает целый класс споров в духе «а у нас не так».
Ограничения
Чтобы статья не съехала в рекламу, перечислю прямо:
-
Кремнием проверен пока только GF16. Для GF48…GF256 RTL написан, но не в кремнии; GF512 и GF1024 — экстраполяция правила без RTL. Самая близкая к φ ступень (GF1024) проверена меньше всех.
-
Кремний Corona — это законченный дизайн (RTL + GDS + формальная верификация + cocotb), а не отлитый чип. Проверено в симуляции и формально; кремний впереди.
-
φ-семейство не заявлено как «лучше всех». Место в каталоге — за широту и связность, не за победу на каждой ступени. takum лежит там же как сильный контрпример.
Каталог — это инструмент и дисциплина, а не финальное слово. Линейка стоит ровно столько, сколько стоят её насечки, — поэтому я и показываю, где они сейчас сбиты.
Источники и материалы:
-
Препринт каталога: arXiv:2606.09686
-
GoldenFloat (φ-семейство): arXiv:2606.05017
-
SSOT каталога: gHashTag/t27 · formats_catalog.t27
-
takum (контрпример): Hunhold 2024 · arXiv:2412.20273
-
OCP Microscaling: Rouhani 2023 · arXiv:2310.10537
-
NF4 / QLoRA: Dettmers 2023 · arXiv:2305.14314
-
FLoPS (P3109 формализация): arXiv:2602.15965
Аффилиация: Trinity S³AI (независимый исследовательский коллектив). ORCID: 0009-0008-4294-6159. Контакт: admin@t27.ai (асинхронно).
ссылка на оригинал статьи https://habr.com/ru/articles/1051520/