diff --git a/apps/website/src/components/Navigation.tsx b/apps/website/src/components/Navigation.tsx index d0fd208119..627f3493c2 100644 --- a/apps/website/src/components/Navigation.tsx +++ b/apps/website/src/components/Navigation.tsx @@ -25,6 +25,7 @@ const PAGES: PageLink[] = [ // кодов идентично takum-оракулу, поэтому сравнение шло не с tekum. { href: '#/gft', en: 'GF-T format', ru: 'Формат GF-T', note: 'A φ-derived static-split float family', noteRu: 'φ-производное семейство float со статическим разбиением' }, { href: '#/start', en: 'Start here', ru: 'С чего начать', note: 'Four checks you can run yourself, in order', noteRu: 'Четыре проверки, которые запускаете сами, по порядку' }, + { href: '#/select', en: 'Choose a format', ru: 'Выбор формата', note: 'A task-by-format comparison matrix', noteRu: 'Матрица сравнения формата и задачи' }, { href: '#/verification', en: 'Verification', ru: 'Верификация', note: 'Send RTL, get it measured on a live FPGA board', noteRu: 'Присылаете RTL — измеряю на живой FPGA-плате' }, { href: '#/ip', en: 'Licensing', ru: 'Лицензирование', note: 'Arithmetic cores with RTL, reference model and vectors', noteRu: 'Ядра: RTL, эталонная модель и векторы' }, { href: '#/proof', en: 'Proof', ru: 'Доказательства', note: 'Every measured number, and its limits', noteRu: 'Все измеренные цифры и их границы' }, diff --git a/apps/website/src/main.tsx b/apps/website/src/main.tsx index 57f52c4e11..6fe8920571 100644 --- a/apps/website/src/main.tsx +++ b/apps/website/src/main.tsx @@ -1,6 +1,7 @@ import { StrictMode, lazy, Suspense } from 'react' import { createRoot } from 'react-dom/client' import { HashRouter, Routes, Route, Navigate } from 'react-router-dom' +import FormatSelection from './pages/FormatSelection' import './index.css' import App from './App.tsx' import { I18nProvider } from './i18n/context.tsx' @@ -46,6 +47,7 @@ createRoot(document.getElementById('root')!).render( } /> } /> } /> + } /> } /> } /> } /> diff --git a/apps/website/src/pages/FormatSelection.tsx b/apps/website/src/pages/FormatSelection.tsx new file mode 100644 index 0000000000..8c91ddbc13 --- /dev/null +++ b/apps/website/src/pages/FormatSelection.tsx @@ -0,0 +1,227 @@ +import { useState } from 'react' +import { usePageMeta } from '../hooks/usePageMeta' +import { useI18n } from '../i18n/context' +import Navigation from '../components/Navigation' +import Footer from '../components/Footer' +import QuantumBackground from '../components/QuantumBackground' + +type TaskId = 'weights' | 'accumulation' | 'fpga' | 'audit' + +type Cell = { status: 'start' | 'compare' | 'check' | 'not'; text: { ru: string; en: string } } + +type Candidate = { + name: string + family: { ru: string; en: string } + note: { ru: string; en: string } + cells: Record +} + +const TASKS: { id: TaskId; ru: string; en: string }[] = [ + { id: 'weights', ru: 'Веса модели', en: 'Model weights' }, + { id: 'accumulation', ru: 'Накопление', en: 'Accumulation' }, + { id: 'fpga', ru: 'Арифметика на FPGA', en: 'FPGA arithmetic' }, + { id: 'audit', ru: 'Аудит и воспроизводимость', en: 'Audit and reproduction' }, +] + +const CANDIDATES: Candidate[] = [ + { + name: 'int8', + family: { ru: 'целочисленный', en: 'integer' }, + note: { ru: 'практическая точка сравнения для низкой разрядности', en: 'a practical low-bit comparison point' }, + cells: { + weights: { status: 'start', text: { ru: 'начать с замера на своих данных', en: 'start with a measurement on your data' } }, + accumulation: { status: 'check', text: { ru: 'проверить ширину аккумулятора отдельно', en: 'check accumulator width separately' } }, + fpga: { status: 'compare', text: { ru: 'сопоставить с ресурсами и задержкой', en: 'compare resources and latency' } }, + audit: { status: 'start', text: { ru: 'удобная базовая линия для векторов', en: 'a useful baseline for vectors' } }, + }, + }, + { + name: 'FP8 e4m3', + family: { ru: 'плавающая точка', en: 'floating point' }, + note: { ru: 'кандидат для компактного представления с явными границами', en: 'a compact candidate with explicit bounds' }, + cells: { + weights: { status: 'compare', text: { ru: 'сравнить с ошибкой и переполнением', en: 'compare error and overflow' } }, + accumulation: { status: 'check', text: { ru: 'накапливать в более широком формате', en: 'accumulate in a wider format' } }, + fpga: { status: 'check', text: { ru: 'проверить декодер и тайминг', en: 'check decoder and timing' } }, + audit: { status: 'compare', text: { ru: 'закрепить независимый оракул', en: 'pin an independent oracle' } }, + }, + }, + { + name: 'GF16', + family: { ru: 'фиксированные поля', en: 'fixed fields' }, + note: { ru: 'кандидат GoldenFloat; выбор зависит от задачи и распределения', en: 'a GoldenFloat candidate; the choice depends on task and distribution' }, + cells: { + weights: { status: 'compare', text: { ru: 'сверить с вашей моделью, не с SQNR одного слоя', en: 'compare on your model, not one layer’s SQNR' } }, + accumulation: { status: 'start', text: { ru: 'проверить широкий аккумулятор', en: 'check a wide accumulator' } }, + fpga: { status: 'compare', text: { ru: 'прогнать RTL и векторы на AX7203', en: 'run RTL and vectors on AX7203' } }, + audit: { status: 'start', text: { ru: 'зафиксировать формат и версию векторов', en: 'record format and vector version' } }, + }, + }, + { + name: 'binary16', + family: { ru: 'плавающая точка', en: 'floating point' }, + note: { ru: 'широкая точка отсчёта для точности и диапазона', en: 'a wider reference point for accuracy and range' }, + cells: { + weights: { status: 'compare', text: { ru: 'использовать как контрольный вариант', en: 'use as a control variant' } }, + accumulation: { status: 'start', text: { ru: 'сравнить ошибки накопления', en: 'compare accumulation error' } }, + fpga: { status: 'check', text: { ru: 'оценить цену ресурсов на плате', en: 'estimate board resource cost' } }, + audit: { status: 'start', text: { ru: 'проверить согласованность оракулов', en: 'check oracle agreement' } }, + }, + }, + { + name: 'takum16', + family: { ru: 'tapered', en: 'tapered' }, + note: { ru: 'сравнительный формат; не заменяет замер на вашей нагрузке', en: 'a comparison format; it does not replace a workload measurement' }, + cells: { + weights: { status: 'compare', text: { ru: 'сопоставить на том же наборе данных', en: 'compare on the same data' } }, + accumulation: { status: 'check', text: { ru: 'проверить поведение хвоста и округления', en: 'check tail and rounding behaviour' } }, + fpga: { status: 'check', text: { ru: 'проверить отдельный RTL-путь', en: 'check a separate RTL path' } }, + audit: { status: 'compare', text: { ru: 'использовать одинаковые векторы входов', en: 'use identical input vectors' } }, + }, + }, +] + +const STATUS_LABELS = { + start: { ru: 'начать здесь', en: 'start here' }, + compare: { ru: 'сравнить', en: 'compare' }, + check: { ru: 'проверить', en: 'check' }, + not: { ru: 'не применять', en: 'do not use' }, +} + +export default function FormatSelection() { + const { lang } = useI18n() + const ru = lang === 'ru' + const [task, setTask] = useState('weights') + const selectedTask = TASKS.find((item) => item.id === task) ?? TASKS[0] + + usePageMeta( + ru ? 'Выбор формата' : 'Format selection', + ru + ? 'Матрица выбора формата по задаче: 83 кандидата каталога, явные критерии сравнения и границы измерения.' + : 'A task-by-format selection matrix for the 83-format catalogue, with explicit comparison criteria and measurement boundaries.', + ) + + const text = (value: { ru: string; en: string }) => ru ? value.ru : value.en + + return ( +
+ + +
+
+ +
+

+ {ru ? 'Процедура выбора' : 'Selection procedure'} +

+

+ {ru ? 'Как сузить каталог форматов под задачу' : 'How to narrow the format catalogue to a task'} +

+

+ {ru + ? 'Это не автоматический вердикт и не рейтинг. Матрица помогает выбрать набор кандидатов для одного и того же замера: сначала фиксируются задача, данные и устройство, затем сравниваются точность, диапазон, ресурсы и воспроизводимость.' + : 'This is not an automatic verdict or a ranking. The matrix narrows the candidates for one measurement: fix the task, data and device first, then compare accuracy, range, resources and reproducibility.'} +

+
+ +
+

+ {ru ? 'Четыре вопроса перед выбором' : 'Four questions before choosing'} +

+
    + {(ru + ? ['Что именно кодируется: веса, активации, скоры или аккумуляторы?', 'Какова форма распределения и допустимая ошибка на вашей задаче?', 'Какое устройство ограничивает проект: CPU, GPU или бинарная FPGA AX7203?', 'Какие векторы и независимый оракул позволят повторить результат?'] + : ['What is being encoded: weights, activations, scores or accumulators?', 'What is the distribution and acceptable error for your task?', 'Which device constrains the project: CPU, GPU or the binary AX7203 FPGA?', 'Which vectors and independent oracle will make the result reproducible?'] + ).map((item) =>
  1. {item}
  2. )} +
+
+ +
+

+ {ru ? 'Матрица формат × задача' : 'Format × task matrix'} +

+

+ {ru + ? <>В каталоге 83 формата. Ниже — пять отправных кандидатов, а не сокращение каталога: в каждой ячейке указано, какое действие нужно выполнить до вывода. + : <>The catalogue contains 83 formats. Below are five starting candidates, not a reduction of the catalogue: each cell states what to do before drawing a conclusion.} +

+
+ +
+ {TASKS.map((item) => ( + + ))} +
+ +
+ + + + + + {TASKS.map((item) => ( + + ))} + + + + {CANDIDATES.map((candidate) => ( + + + {TASKS.map((item) => { + const cell = candidate.cells[item.id] + return ( + + ) + })} + + ))} + +
+ {ru ? <>Фокус сейчас: {selectedTask.ru}. Выбор действия не означает измеренный результат. : <>Current focus: {selectedTask.en}. An action label is not a measured result.} +
{ru ? 'Формат' : 'Format'}{ru ? item.ru : item.en}
+ {candidate.name} + {text(candidate.family)} + + + {text(STATUS_LABELS[cell.status])} + + {text(cell.text)} +
+
+ +
+

+ {ru ? 'Как читать результат' : 'How to read the result'} +

+

+ {ru + ? 'Метка «начать здесь» означает удобную первую проверку, а не присвоение формату статуса. «Сравнить» требует одинаковых данных, бюджета и метрики. «Проверить» указывает на риск, который нельзя закрыть одной таблицей.' + : '“Start here” marks a practical first check, not a status assigned to a format. “Compare” requires the same data, budget and metric. “Check” points to a risk that one table cannot close.'} +

+

+ {ru + ? 'Итоговый кандидат появляется только после прогона на вашей нагрузке. Публичные аппаратные проверки в этом проекте относятся к бинарной FPGA ALINX AX7203 на Xilinx Artix-7 XC7A200T; они не заменяют замер на другом устройстве.' + : 'A final candidate appears only after a run on your workload. Public hardware checks in this project target the binary ALINX AX7203 FPGA with a Xilinx Artix-7 XC7A200T; they do not replace a measurement on another device.'} +

+
+ + +
+
+ ) +}