Quick keys
— Navigate with ← → or spacebar.
F
fullscreen ·
S
speaker view ·
O
overview ·
Alt+Click
zoom
Navigation
×
<style> :root { --conf-ink: #0f172a; --conf-muted: #475569; --conf-soft: #e2e8f0; --conf-panel: rgba(255, 255, 255, 0.82); --conf-blue: #2563eb; --conf-blue-soft: rgba(37, 99, 235, 0.1); --conf-teal: #0f766e; --conf-teal-soft: rgba(15, 118, 110, 0.1); --conf-amber: #b45309; --conf-amber-soft: rgba(180, 83, 9, 0.11); --conf-rose: #be123c; --conf-rose-soft: rgba(190, 18, 60, 0.09); --conf-green: #15803d; --conf-green-soft: rgba(21, 128, 61, 0.1); } .reveal .slides { text-align: left; } .reveal section.conf-slide { box-sizing: border-box; width: 100%; height: 100%; padding: 54px 70px 44px; color: var(--conf-ink); background: linear-gradient(135deg, rgba(37, 99, 235, 0.055), rgba(255, 255, 255, 0) 32%), linear-gradient(225deg, rgba(15, 118, 110, 0.055), rgba(255, 255, 255, 0) 36%), #f8fafc; overflow: hidden; } .reveal section.conf-title { padding: 64px 82px 54px; } .reveal .conf-slide h1, .reveal .conf-slide h2, .reveal .conf-slide h3 { color: var(--conf-ink); letter-spacing: 0; text-transform: none; } .reveal .conf-slide h1 { font-size: 76px; line-height: 1.03; margin: 0; } .reveal .conf-slide h2 { font-size: 46px; line-height: 1.08; margin: 0 0 26px; } .reveal .conf-slide h3 { font-size: 25px; line-height: 1.18; margin: 0 0 10px; } .reveal .conf-slide p, .reveal .conf-slide li { color: var(--conf-muted); font-size: 24px; line-height: 1.36; } .reveal .conf-slide strong { color: var(--conf-ink); font-weight: 720; } .reveal .conf-kicker { color: var(--conf-teal); font-size: 18px; font-weight: 760; letter-spacing: 0.08em; margin-bottom: 14px; text-transform: uppercase; } .reveal .conf-subtitle { max-width: 950px; color: var(--conf-muted); font-size: 31px; line-height: 1.32; margin-top: 26px; } .reveal .conf-title-grid { display: grid; grid-template-columns: minmax(0, 1100px) 286px; gap: 42px; align-content: center; align-items: center; height: 100%; max-width: none; } .reveal .conf-title-main { min-width: 0; } .reveal .conf-title-qr { box-sizing: border-box; justify-self: end; width: 286px; padding: 18px; text-align: center; } .reveal .conf-title-qr img { display: block; width: 238px; height: 238px; max-width: none; max-height: none; object-fit: contain; margin: 0 auto 13px; border-radius: 0; box-shadow: none; } .reveal .conf-title-qr strong { display: block; color: var(--conf-ink); font-size: 21px; line-height: 1.15; } .reveal .conf-acl-logo { display: block; width: 300px; max-width: none; height: auto; margin: 0 0 48px; object-fit: contain; border-radius: 0; box-shadow: none; } .reveal .conf-meta { color: var(--conf-muted); font-size: 21px; line-height: 1.45; margin-top: 24px; } .reveal .conf-event-line { color: var(--conf-teal); font-size: 23px; font-weight: 760; line-height: 1.25; margin-top: 18px; } .reveal .conf-logo-row { display: flex; align-items: center; gap: 24px; margin-top: 40px; flex-wrap: nowrap; } .reveal .conf-logo-badge { display: flex; align-items: center; justify-content: center; height: 84px; padding: 10px 18px; border-radius: 14px; background: rgba(255, 255, 255, 0.92); box-shadow: 0 18px 46px rgba(15, 23, 42, 0.12); } .reveal .conf-logo-badge.nsf { width: 104px; height: 92px; padding: 7px; } .reveal .conf-logo-badge.scorio { width: 250px; } .reveal .conf-logo-row img { display: block; width: auto; max-width: none; height: 100%; max-height: none; object-fit: contain; border-radius: 0; box-shadow: none; margin: 0; } .reveal .conf-panel { border: 1px solid rgba(15, 23, 42, 0.14); border-radius: 8px; background: var(--conf-panel); box-shadow: 0 18px 46px rgba(15, 23, 42, 0.08); } .reveal .conf-title-card { padding: 24px; } .reveal .conf-title-card img { width: 100%; height: 370px; object-fit: contain; display: block; } .reveal .conf-title-metric { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 20px; } .reveal .conf-title-metric p, .reveal .conf-metric p { margin: 0; } .reveal .conf-title-metric strong, .reveal .conf-metric strong { display: block; color: var(--conf-blue); font-size: 34px; line-height: 1; } .reveal .conf-title-metric span, .reveal .conf-metric span { display: block; color: var(--conf-muted); font-size: 16px; line-height: 1.22; margin-top: 7px; } .reveal .conf-chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; } .reveal .conf-chip { display: inline-flex; align-items: center; border: 1px solid rgba(15, 23, 42, 0.14); border-radius: 999px; color: var(--conf-muted); background: rgba(255, 255, 255, 0.74); font-size: 16px; font-weight: 720; line-height: 1; padding: 9px 13px; } .reveal .conf-chip.blue { color: var(--conf-blue); background: var(--conf-blue-soft); border-color: rgba(37, 99, 235, 0.24); } .reveal .conf-chip.teal { color: var(--conf-teal); background: var(--conf-teal-soft); border-color: rgba(15, 118, 110, 0.24); } .reveal .conf-chip.amber { color: var(--conf-amber); background: var(--conf-amber-soft); border-color: rgba(180, 83, 9, 0.24); } .reveal .conf-grid { display: grid; gap: 18px; } .reveal .conf-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); } .reveal .conf-grid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); } .reveal .conf-grid.four { grid-template-columns: repeat(4, minmax(0, 1fr)); } .reveal .conf-card { border: 1px solid rgba(15, 23, 42, 0.13); border-radius: 8px; background: rgba(255, 255, 255, 0.78); padding: 20px 22px; min-height: 138px; box-shadow: 0 12px 28px rgba(15, 23, 42, 0.055); } .reveal .conf-card p { margin: 0; font-size: 20px; } .reveal .conf-num { color: var(--conf-blue); font-size: 18px; font-weight: 780; margin-bottom: 12px; } .reveal .conf-callout { border-left: 5px solid var(--conf-blue); border-radius: 8px; background: var(--conf-blue-soft); padding: 18px 22px; color: var(--conf-ink); font-size: 25px; line-height: 1.34; } .reveal .conf-callout.teal { border-left-color: var(--conf-teal); background: var(--conf-teal-soft); } .reveal .conf-callout.amber { border-left-color: var(--conf-amber); background: var(--conf-amber-soft); } .reveal .conf-callout.rose { border-left-color: var(--conf-rose); background: var(--conf-rose-soft); } .reveal .conf-big-question { margin-top: 24px; padding: 26px 30px; color: var(--conf-ink); font-size: 35px; line-height: 1.2; } .reveal .conf-equation { display: flex; align-items: center; justify-content: center; box-sizing: border-box; min-width: 0; min-height: 112px; max-width: 100%; overflow-x: auto; border: 1px solid rgba(15, 23, 42, 0.12); border-radius: 8px; background: rgba(15, 23, 42, 0.04); color: var(--conf-ink); font-size: 31px; line-height: 1.25; padding: 18px 22px; } /* Keep display math inside its panel instead of bleeding over the next column. Wide formulas still read best one size down: add `conf-equation sm` or give the equation a full-width row (see slide-patterns.md). */ .reveal .conf-equation .katex { max-width: 100%; } .reveal .conf-equation.sm { font-size: 24px; } .reveal .conf-figure { border: 1px solid rgba(15, 23, 42, 0.12); border-radius: 8px; background: rgba(255, 255, 255, 0.84); padding: 16px; } .reveal .conf-figure img { display: block; width: 100%; height: 100%; object-fit: contain; } .reveal .conf-figure figcaption { color: var(--conf-muted); font-size: 16px; line-height: 1.25; margin-top: 10px; } .reveal .conf-fig-short { height: 430px; } .reveal .conf-fig-mid { height: 540px; } .reveal .conf-fig-wide { height: 465px; } .reveal .conf-fig-tall { height: 610px; } .reveal .conf-split { display: grid; grid-template-columns: minmax(0, 0.98fr) minmax(420px, 0.82fr); gap: 30px; align-items: stretch; } .reveal .conf-split.reverse { grid-template-columns: minmax(420px, 0.76fr) minmax(0, 1fr); } .reveal .conf-metric { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 18px; } .reveal .conf-metric .conf-card { min-height: 104px; } .reveal .conf-mini-table, .reveal .conf-table { width: 100%; border-collapse: collapse; } .reveal .conf-mini-table { font-size: 18px; } .reveal .conf-table { font-size: 20px; } .reveal .conf-mini-table th, .reveal .conf-mini-table td, .reveal .conf-table th, .reveal .conf-table td { border-bottom: 1px solid rgba(15, 23, 42, 0.12); padding: 11px 10px; text-align: right; color: var(--conf-muted); } .reveal .conf-mini-table th:first-child, .reveal .conf-mini-table td:first-child, .reveal .conf-table th:first-child, .reveal .conf-table td:first-child { text-align: left; } .reveal .conf-mini-table th, .reveal .conf-table th { color: var(--conf-ink); font-weight: 760; } .reveal .conf-win { color: var(--conf-green) !important; font-weight: 760; background: rgba(21, 128, 61, 0.08); } .reveal .conf-loss { color: var(--conf-rose) !important; } .reveal .conf-flow { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-top: 18px; } .reveal .conf-flow .conf-card { min-height: 148px; } .reveal .conf-flow h3 { font-size: 23px; } .reveal .conf-list { margin: 0; padding-left: 1.1em; } .reveal .conf-list li { margin: 0 0 12px; } .reveal .conf-footer-note { position: absolute; left: 70px; right: 70px; bottom: 28px; color: rgba(71, 85, 105, 0.78); font-size: 16px; } .reveal .conf-takeaway-header { display: flex; align-items: center; gap: 24px; margin: 0 0 34px; } .reveal .conf-takeaway-icon { display: block; width: 104px; height: 104px; max-width: none; max-height: none; object-fit: contain; border-radius: 0; box-shadow: none; margin: 0; } .reveal .conf-takeaway-title { color: var(--conf-ink); font-size: 62px; line-height: 0.98; margin: 0; } .reveal .conf-takeaway-subtitle { color: var(--conf-teal); font-size: 28px; font-weight: 760; line-height: 1.12; margin-top: 12px; } .reveal .conf-takeaway-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; } .reveal .conf-takeaway-card { position: relative; min-height: 250px; padding: 30px 30px 28px; overflow: hidden; border-top: 5px solid var(--conf-teal); background: linear-gradient(180deg, rgba(15, 118, 110, 0.08), rgba(255, 255, 255, 0.82) 42%), rgba(255, 255, 255, 0.84); box-shadow: 0 18px 42px rgba(15, 23, 42, 0.09); } .reveal .conf-takeaway-card:nth-child(2) { border-top-color: var(--conf-blue); background: linear-gradient(180deg, rgba(37, 99, 235, 0.08), rgba(255, 255, 255, 0.82) 42%), rgba(255, 255, 255, 0.84); } .reveal .conf-takeaway-card:nth-child(3) { border-top-color: var(--conf-amber); background: linear-gradient(180deg, rgba(180, 83, 9, 0.08), rgba(255, 255, 255, 0.82) 42%), rgba(255, 255, 255, 0.84); } .reveal .conf-takeaway-num { display: inline-grid; place-items: center; width: 42px; height: 42px; margin-bottom: 20px; border-radius: 50%; background: var(--conf-teal-soft); color: var(--conf-teal); font-size: 22px; font-weight: 820; } .reveal .conf-takeaway-card:nth-child(2) .conf-takeaway-num { background: var(--conf-blue-soft); color: var(--conf-blue); } .reveal .conf-takeaway-card:nth-child(3) .conf-takeaway-num { background: var(--conf-amber-soft); color: var(--conf-amber); } .reveal .conf-takeaway-card h3 { font-size: 30px; line-height: 1.08; min-height: 42px; margin-bottom: 16px; } .reveal .conf-takeaway-card p { font-size: 25px; line-height: 1.34; min-height: 128px; } .reveal .conf-closing-layout { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 26px; align-items: stretch; height: 100%; } .reveal .conf-closing-main { display: grid; justify-items: center; align-content: start; text-align: center; padding-top: 8px; } .reveal .conf-closing-title { font-size: 72px; line-height: 1.03; margin: 0 0 18px; } .reveal .conf-closing-main .conf-subtitle { max-width: none; margin-top: 0; } .reveal .conf-closing-authors { color: var(--conf-muted); font-size: 22px; line-height: 1.25; margin-top: 12px; } .reveal .conf-qr-grid { display: grid; grid-template-columns: repeat(4, 260px); justify-content: center; gap: 24px; width: min(1120px, 100%); margin: 32px auto 0; } .reveal .conf-qr-item { border: 1px solid rgba(15, 23, 42, 0.13); border-radius: 8px; background: rgba(255, 255, 255, 0.82); padding: 18px; text-align: center; box-shadow: 0 12px 28px rgba(15, 23, 42, 0.055); } .reveal .conf-qr-item img { display: block; width: 210px; height: 210px; max-width: none; max-height: none; object-fit: contain; margin: 0 auto 12px; border-radius: 0; box-shadow: none; } .reveal .conf-qr-item strong { display: block; color: var(--conf-ink); font-size: 20px; line-height: 1.1; } .reveal .conf-contact-line { max-width: 1220px; margin: 18px auto 0; color: var(--conf-muted); font-size: 20px; line-height: 1.25; } .reveal .conf-contact-email { color: var(--conf-blue); font-weight: 780; white-space: nowrap; } .reveal .conf-ack-stack { display: grid; grid-template-columns: 450px 760px; justify-content: center; align-items: center; gap: 34px; width: 100%; margin: 0 auto; padding: 0; } .reveal .conf-ack-item { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 22px; align-items: center; border: 0; border-radius: 0; background: transparent; padding: 0; box-shadow: none; } .reveal .conf-ack-cwru { grid-template-columns: 290px minmax(0, 1fr); } .reveal .conf-ack-item img { display: block; width: auto; max-width: none; max-height: none; object-fit: contain; border-radius: 0; box-shadow: none; margin: 0; } .reveal .conf-ack-nsf img { width: 84px; height: 84px; } .reveal .conf-ack-cwru img { width: 270px; height: auto; } .reveal .conf-ack-item h3 { font-size: 26px; line-height: 1.08; margin: 0 0 8px; white-space: nowrap; } .reveal .conf-ack-item p { font-size: 22px; line-height: 1.18; margin: 0; white-space: nowrap; } .reveal .slides section.conf-slide .conf-acl-logo { width: 300px; max-width: none; height: auto; margin: 0 0 48px; border-radius: 0; box-shadow: none; } .reveal .slides section.conf-slide .conf-logo-row img { width: auto; max-width: none; height: 64px; max-height: none; border-radius: 0; box-shadow: none; margin: 0; } .reveal .slides section.conf-slide .conf-logo-badge.nsf img { width: 76px; height: 76px; } .reveal .slides section.conf-slide .conf-logo-badge.scorio img { width: 214px; height: auto; } .reveal .slides section.conf-slide .conf-qr-item img { width: 210px; height: 210px; max-width: none; max-height: none; border-radius: 0; box-shadow: none; margin: 0 auto 12px; } .reveal .slides section.conf-slide .conf-title-qr img { width: 238px; height: 238px; max-width: none; max-height: none; border-radius: 0; box-shadow: none; margin: 0 auto 13px; } .reveal .slides section.conf-slide .conf-ack-item img { max-width: none; max-height: none; border-radius: 0; box-shadow: none; margin: 0; } .reveal .slides section.conf-slide .conf-ack-nsf img { width: 84px; height: 84px; } .reveal .slides section.conf-slide .conf-ack-cwru img { width: 270px; height: auto; } .reveal .conf-title-thesis { max-width: 1080px; color: var(--conf-muted); font-size: 29px; line-height: 1.28; margin-top: 28px; } .reveal .conf-slide .conf-lead { max-width: 1210px; color: var(--conf-muted); font-size: 30px; line-height: 1.28; margin: -8px 0 28px; } .reveal .conf-slide .conf-small { color: var(--conf-muted); font-size: 18px; line-height: 1.3; } .reveal .conf-stat-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-top: 20px; } .reveal .conf-stat { border: 1px solid rgba(15, 23, 42, 0.12); border-radius: 8px; background: rgba(255, 255, 255, 0.78); padding: 18px 18px 16px; min-height: 112px; box-shadow: 0 12px 28px rgba(15, 23, 42, 0.055); } .reveal .conf-stat strong { display: block; color: var(--conf-blue); font-size: 43px; line-height: 1; } .reveal .conf-stat span { display: block; color: var(--conf-muted); font-size: 17px; line-height: 1.22; margin-top: 9px; } .reveal .conf-slide .conf-table.compact { font-size: 17px; } .reveal .conf-slide .conf-table.compact th, .reveal .conf-slide .conf-table.compact td { padding: 8px 8px; } .reveal .conf-slide .conf-table.wide-text td, .reveal .conf-slide .conf-table.wide-text th { text-align: left; } .reveal .conf-slide .conf-table.wide-text td:last-child, .reveal .conf-slide .conf-table.wide-text th:last-child { text-align: right; } .reveal .conf-slide .conf-table .conf-method-cell { color: var(--conf-ink); font-weight: 720; } .reveal .conf-two-thirds { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(420px, 0.72fr); gap: 28px; align-items: stretch; } .reveal .conf-figure-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(390px, 0.52fr); gap: 24px; align-items: stretch; } .reveal .conf-figure-grid.reverse { grid-template-columns: minmax(390px, 0.52fr) minmax(0, 1fr); } .reveal .conf-figure-grid .conf-figure { height: 590px; } .reveal .conf-figure-grid .conf-figure.short { height: 500px; } .reveal .conf-stack { display: grid; gap: 16px; align-content: start; } .reveal .conf-target-card { min-height: 210px; } .reveal .conf-target-card .conf-equation { min-height: 82px; margin-bottom: 16px; font-size: 27px; } .reveal .conf-method-map { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; margin-top: 20px; } .reveal .conf-method-map .conf-card { min-height: 255px; } .reveal .conf-method-map .conf-equation { min-height: 76px; font-size: 23px; margin-bottom: 14px; } .reveal .conf-rule-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 13px; margin-top: 26px; } .reveal .conf-rule-grid .conf-card { min-height: 190px; padding: 18px 18px; } .reveal .conf-rule-grid h3 { font-size: 22px; } .reveal .conf-code { box-sizing: border-box; max-width: 100%; overflow-x: auto; border: 1px solid rgba(15, 23, 42, 0.14); border-radius: 8px; background: #111827; color: #e5e7eb; font-size: 20px; line-height: 1.42; margin: 0; padding: 24px 26px; white-space: pre; } .reveal .conf-code .kw { color: #67e8f9; } .reveal .conf-code .fn { color: #a7f3d0; } .reveal .conf-code .arg { color: #fbbf24; } .reveal .conf-qrs-small { display: grid; grid-template-columns: repeat(2, 180px); gap: 18px; justify-content: start; margin-top: 16px; } .reveal .conf-qrs-small .conf-qr-item { padding: 14px; } .reveal .conf-qrs-small .conf-qr-item img { width: 144px; height: 144px; } .reveal .conf-scorio-header { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 24px; align-items: center; margin-bottom: 18px; } .reveal .conf-scorio-logo-panel { display: flex; align-items: center; justify-content: flex-start; height: 104px; } .reveal .conf-scorio-logo-panel img { display: block; width: 202px; height: auto; max-width: none; max-height: none; border-radius: 0; box-shadow: none; margin: 0; } .reveal .conf-scorio-header h2 { font-size: 40px; line-height: 1.08; margin: 0; } .reveal .conf-scorio-app { border: 1px solid rgba(15, 118, 110, 0.22); border-radius: 999px; background: var(--conf-teal-soft); color: var(--conf-teal); font-size: 17px; font-weight: 780; line-height: 1; padding: 11px 15px; text-align: center; } .reveal .conf-scorio-layout { display: grid; grid-template-columns: minmax(0, 0.66fr) minmax(0, 1.34fr); gap: 18px; align-items: stretch; } .reveal .conf-scorio-panel, .reveal .conf-api-board { border: 1px solid rgba(15, 23, 42, 0.13); border-radius: 8px; background: rgba(255, 255, 255, 0.8); box-shadow: 0 12px 28px rgba(15, 23, 42, 0.055); } .reveal .conf-scorio-panel { padding: 18px; } .reveal .conf-scorio-panel h3, .reveal .conf-api-board h3 { font-size: 23px; line-height: 1.08; margin: 0 0 12px; } .reveal .conf-scorio-code { font-size: 15px; line-height: 1.34; padding: 16px 18px; } .reveal .conf-scorio-note { color: var(--conf-muted); font-size: 18px; line-height: 1.26; margin-top: 14px; } .reveal .conf-scorio-note strong { color: var(--conf-ink); } .reveal .conf-scorio-use { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 14px; } .reveal .conf-scorio-use .conf-scorio-app { display: grid; place-items: center; min-height: 52px; border: 1px solid rgba(15, 118, 110, 0.22); border-radius: 999px; background: var(--conf-teal-soft); color: var(--conf-teal); font-size: 15px; font-weight: 780; line-height: 1.08; padding: 10px 12px; text-align: center; } .reveal .conf-api-board { padding: 16px 18px 14px; } .reveal .conf-api-board h3 { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; } .reveal .conf-api-board h3 span { color: var(--conf-muted); font-size: 15px; font-weight: 680; } .reveal .conf-api-group { padding: 8px 0; border-top: 1px solid rgba(15, 23, 42, 0.11); } .reveal .conf-api-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 4px; } .reveal .conf-api-head code { color: var(--conf-ink); font-size: 16px; font-weight: 820; } .reveal .conf-api-head span { color: var(--conf-teal); font-size: 14px; font-weight: 760; } .reveal .conf-api-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 16px; row-gap: 2px; } .reveal .conf-slide .conf-api-line { color: var(--conf-muted); font-size: 13px; line-height: 1.22; margin: 0 0 5px; } .reveal .conf-slide .conf-api-line strong { display: inline; color: var(--conf-ink); font-size: 13px; font-weight: 800; } .reveal .conf-slide .conf-api-line code { display: inline-block; border-radius: 5px; background: rgba(15, 23, 42, 0.055); color: var(--conf-ink); font-size: 11.5px; line-height: 1.18; margin: 0 2px 3px 0; padding: 2px 5px; } .reveal .conf-slide .conf-fit-list li { font-size: 21px; line-height: 1.28; margin-bottom: 10px; } .reveal .conf-slide .conf-tight-list li { font-size: 19px; line-height: 1.24; margin-bottom: 8px; } .reveal .conf-banner { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 18px; align-items: center; border: 1px solid rgba(15, 23, 42, 0.13); border-radius: 8px; background: rgba(255, 255, 255, 0.78); padding: 18px 22px; margin-top: 20px; } .reveal .conf-banner-number { color: var(--conf-blue); font-size: 54px; font-weight: 780; line-height: 1; } .reveal .conf-banner p { margin: 0; font-size: 23px; line-height: 1.26; } .reveal .conf-label { display: inline-flex; align-items: center; border-radius: 999px; background: rgba(15, 23, 42, 0.08); color: var(--conf-ink); font-size: 15px; font-weight: 760; line-height: 1; padding: 8px 10px; text-transform: uppercase; } .reveal .conf-figure img.no-stretch { height: auto; max-height: 100%; } /* ---- deck-specific overrides (after the pasted theme) ---- */ .reveal .conf-qr-grid { grid-template-columns: repeat(3, 260px); } .reveal .slides section.conf-slide .conf-acl-logo { width: 180px; margin-bottom: 36px; } .reveal .conf-closing-layout { grid-template-rows: auto; height: 100%; align-content: center; } .reveal .conf-slide .conf-fit-list li strong { color: var(--conf-ink); } </style> <!-- .slide: class="conf-slide conf-title" data-background-color="#F8FAFC" --> <div class="conf-title-grid"> <div class="conf-title-main"> <img class="conf-acl-logo" src="/assets/slides/2025-12-02-dfloat11/neurips.svg" alt="NeurIPS 2025" /> <h1>70% Size, 100% Accuracy</h1> <div class="conf-subtitle">Lossless LLM compression for efficient GPU inference via Dynamic-Length Float (DF11).</div> <div class="conf-event-line">NeurIPS 2025 · San Diego Convention Center</div> <div class="conf-meta"> <strong>Tianyi Zhang</strong>, Mohsen Hariri, Shaochen Zhong, Vipin Chaudhary, Yang Sui, Xia Hu, Anshumali Shrivastava </div> <div class="conf-logo-row"> <span class="conf-logo-badge"><img src="/assets/slides/2025-12-02-dfloat11/rice.svg" alt="Rice University" /></span> <span class="conf-logo-badge"><img src="/assets/slides/2025-12-02-dfloat11/cwru.svg" alt="Case Western Reserve University" /></span> </div> </div> <aside class="conf-title-qr conf-panel" aria-label="Interactive slides QR code"> <img src="/assets/slides/2025-12-02-dfloat11/slide_qr.svg" alt="QR code for the interactive slides" /> <strong>Scan for interactive slides</strong> </aside> </div> Note: Every BFloat16 model wastes about five bits per weight in its exponent field. DF11 reclaims them with entropy coding, losslessly: 30% smaller, bit-for-bit identical outputs, and a GPU kernel that keeps inference fast. The headline demo is running Llama 3.1 405B on a single eight-GPU node instead of two. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">Lossy compression</div> <h2>Quantization shrinks models, but the loss is real and hard to see</h2> <div class="conf-flow"> <div class="conf-card"> <div class="conf-num">01</div> <h3>Accuracy drops</h3> <p>8-bit SmoothQuant on a distilled Qwen 1.5B loses 9.09% average accuracy on reasoning tasks.</p> </div> <div class="conf-card"> <div class="conf-num">02</div> <h3>Answers flip</h3> <p>W8A16 GPTQ Qwen2 1.5B moves only 0.3% on GSM8K, yet 6.37% of answers flip correctness.</p> </div> <div class="conf-card"> <div class="conf-num">03</div> <h3>Benchmarks hide it</h3> <p>Perplexity and MMLU are narrow; the gap an end-user feels rarely shows up there.</p> </div> <div class="conf-card"> <div class="conf-num">04</div> <h3>Compliance breaks</h3> <p>In finance or healthcare, an output that differs from the original is a non-starter.</p> </div> </div> <div class="conf-callout amber" style="margin-top: 28px;"> Lossy quantization adds an uncontrolled variable you have to re-validate for every model, task, and bit-width. </div> Note: Quantization is the default, and 8-bit looks safe on the usual leaderboards. But the loss reappears as flipped answers and behavioral drift that those benchmarks miss, and in regulated settings any deviation is disqualifying. So the question that motivates the paper: can we get the memory savings with zero loss? --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">BFloat16 entropy</div> <h2>BFloat16 spends 8 bits on an exponent worth about 2.6</h2> <div class="conf-split"> <figure class="conf-figure conf-fig-mid"> <img src="/assets/slides/2025-12-02-dfloat11/entropy.webp" alt="Shannon entropy of the sign, exponent, and mantissa bits of BFloat16 weights across five LLMs" /> <figcaption>Shannon entropy of each BFloat16 field across LLMs. Sign (≈1 bit) and mantissa (≈7 bits) are near their widths; the 8-bit exponent carries only ≈2.6 bits.</figcaption> </figure> <div> <div class="conf-card"> <h3>The exponent is the slack</h3> <p>Sign and mantissa are essentially uniform, so they barely compress. The exponent is wildly skewed: only ~40 of 256 possible values ever appear.</p> </div> <div class="conf-card" style="margin-top: 16px;"> <h3>Same story everywhere</h3> <p>Llama, Gemma, Qwen, Mistral — the ~2.6-bit exponent holds across families. This is a property of the format, not one model.</p> </div> <div class="conf-callout teal" style="margin-top: 16px;"> ≈5 bits per weight are pure redundancy — reclaimable losslessly. </div> </div> </div> Note: This figure is the whole idea. Measure the information content of each BFloat16 field, and sign and mantissa are basically random, so there is nothing to compress. The exponent is different: only about forty of the 256 values are ever used, so its real content is about 2.6 bits, not 8. That is roughly five free bits per weight, if we encode the exponent by frequency. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">Dynamic-Length Float</div> <h2>DF11: Huffman-code the exponent, leave the rest alone</h2> <div class="conf-equation" style="margin-bottom: 22px;"> \[ x = (-1)^{\text{sign}} \cdot 2^{\,\text{exponent} - 127} \cdot (1.\text{mantissa}) \] </div> <div class="conf-split"> <figure class="conf-figure conf-fig-short"> <img src="/assets/slides/2025-12-02-dfloat11/DFloat11.webp" alt="The DFloat11 format: variable-length Huffman-coded exponents plus fixed sign and mantissa bits, decoded through a Huffman tree" /> <figcaption>Exponents become variable-length Huffman codes (avg ~2.6 bits); sign (1 bit) and mantissa (7 bits) stay fixed and are decoded by a tree walk.</figcaption> </figure> <div> <div class="conf-callout teal"> Frequent exponents get short codes, rare ones long — near the information-theoretic limit, with no rounding. </div> <ul class="conf-list conf-fit-list" style="margin-top: 18px;"> <li><strong>16 → ~11 bits</strong> average weight width</li> <li><strong>~70%</strong> of the original model size</li> <li><strong>Bit-for-bit identical</strong> weights after decompression</li> </ul> </div> </div> Note: The format itself is simple. Build one Huffman tree over the exponent values of all the linear-layer weights, replace each 8-bit exponent with its variable-length code, and bit-pack. Sign and mantissa are untouched. The average weight drops from 16 to about 11 bits, so roughly 30% smaller, and because nothing is rounded, the decompressed weights are exactly the originals. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">Online decompression</div> <h2>Variable-length codes are murder on a GPU</h2> <div class="conf-grid three"> <div class="conf-card"> <h3>Can't multiply compressed</h3> <p>Entropy-coded weights aren't matrices. Each one must be decoded back to BFloat16 on the fly, used, then discarded.</p> </div> <div class="conf-card"> <h3>Huffman decode is serial</h3> <p>Classic decoding walks the tree bit by bit — inherently sequential, the opposite of what a GPU wants.</p> </div> <div class="conf-card"> <h3>One thread per weight stalls</h3> <p>Naive per-element threads leave the GPU mostly idle and latency high. The packed stream has no obvious split points.</p> </div> </div> <div class="conf-callout" style="margin-top: 28px;"> The fix is three hardware-aware ideas that turn a tightly-packed, variable-length bitstream into parallel work. </div> Note: Compression was the easy half. The hard half: entropy-coded weights can't be multiplied directly, so every matrix has to be decoded back to BFloat16 right before it's used. And classic Huffman decoding is a bit-by-bit tree walk, completely serial, so a GPU with one thread per weight sits idle. The next three slides are how we make that decode parallel and fast. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">GPU kernel — 1 of 3</div> <h2>Decode by table lookup, not tree walk</h2> <div class="conf-split"> <figure class="conf-figure conf-fig-mid"> <img src="/assets/slides/2025-12-02-dfloat11/hierarchical_luts.webp" alt="A Huffman tree decomposed into a hierarchy of compact lookup tables" /> <figcaption>The Huffman tree is split into height-8 subtrees, each a 256-entry lookup table. Unused exponent values become pointers to the next table.</figcaption> </figure> <div> <div class="conf-card"> <h3>Table, not traversal</h3> <p>Read the next bits, index a LUT, get the exponent and its code length. No branching, no thread divergence.</p> </div> <div class="conf-card" style="margin-top: 14px;"> <h3>Fits in SRAM</h3> <p>A 4.3-billion-entry table is impossible. Decompose it into 4–8 compact 256-entry LUTs — a few KB that live on-chip.</p> </div> <div class="conf-card" style="margin-top: 14px;"> <h3>Pointers come free</h3> <p>Only ~40 exponents are used, so the unused values (240–255) double as pointers between LUTs.</p> </div> </div> </div> Note: Instead of walking the tree one bit at a time, we precompute lookup tables: take the next bits, index a table, get the decoded exponent and how many bits it used. A full table would need over four billion entries, so we decompose the tree into height-8 subtrees, a handful of 256-byte LUTs that fit in SRAM. What makes the hierarchy free: only about forty exponent values occur, so we reuse the unused ones as pointers between tables. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">GPU kernel — 2 of 3</div> <h2>Two passes turn a serial stream into parallel work</h2> <div class="conf-split"> <figure class="conf-figure conf-fig-short"> <img src="/assets/slides/2025-12-02-dfloat11/gap_outputpos.webp" alt="The gap array and block-level output-position array that coordinate per-thread reads and writes" /> <figcaption>Each thread owns 8 bytes. <em>Gaps</em> stores its start-bit offset (5 bits each); <em>Block Output Positions</em> stores one 32-bit index per block.</figcaption> </figure> <div> <div class="conf-card"> <h3>Where do I start and write?</h3> <p>Variable-length codes mean a thread knows neither its first code's bit offset nor its output index.</p> </div> <div class="conf-card" style="margin-top: 14px;"> <h3>Tiny, block-level metadata</h3> <p>A 5-bit gap per thread fixes the start. Output positions are stored per block, not per thread — so the compression survives.</p> </div> <div class="conf-card" style="margin-top: 14px;"> <h3>Count, then write</h3> <p>Pass 1 counts elements and prefix-sums (Blelloch) the write offsets; pass 2 decodes and writes. Bytes are cached in SRAM.</p> </div> </div> </div> Note: To parallelize, each thread takes a fixed eight-byte chunk. Two unknowns follow from variable-length codes: a thread doesn't know which bit its first code starts on, and it doesn't know where to write. We fix the first with a five-bit gap per thread. For the second, we store the output position only once per block, then a first pass counts elements and a prefix sum hands each thread its offset; the second pass writes. Keeping metadata per block, not per thread, is what preserves the compression ratio. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">GPU kernel — 3 of 3</div> <h2>Decompress a whole transformer block at once</h2> <div class="conf-grid three"> <div class="conf-card"> <div class="conf-num">01</div> <h3>One matrix wastes the GPU</h3> <p>A single weight matrix is too small to fill the device; decompression throughput climbs with matrix size.</p> </div> <div class="conf-card"> <div class="conf-num">02</div> <h3>Batch per block</h3> <p>Decode every matrix in a transformer block together, right before its forward pass, so the work saturates the GPU.</p> </div> <div class="conf-card"> <div class="conf-num">03</div> <h3>Then discard</h3> <p>Free the BFloat16 immediately. Only one block is ever expanded, so the extra memory is negligible.</p> </div> </div> <div class="conf-callout teal" style="margin-top: 28px;"> Decompression overlaps with compute, so it costs a small fixed amount — and that cost shrinks per token as the batch grows. </div> Note: A single weight matrix is too small to saturate the GPU, so we batch: decode every matrix in a transformer block at once, right before that block runs, then throw the BFloat16 away. Only one block is decompressed at a time, so the memory overhead is tiny, and the decode overlaps with the block's own compute. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">Results · compression</div> <h2>About 70% size and ~11 bits, across every family</h2> <div class="conf-split"> <table class="conf-table compact conf-panel" aria-label="DF11 compression statistics across models"> <thead> <tr><th>Model</th><th>Original → DF11</th><th>Ratio</th><th>Bits</th></tr> </thead> <tbody> <tr><td>Llama 3.1 8B</td><td>16.06 → 10.90 GB</td><td>67.8%</td><td>10.85</td></tr> <tr><td>Llama 3.3 70B</td><td>141.1 → 95.4 GB</td><td>67.6%</td><td>10.82</td></tr> <tr><td>Llama 3.1 405B</td><td>811.7 → 551.2 GB</td><td>67.9%</td><td>10.87</td></tr> <tr><td>Qwen 3 14B</td><td>29.5 → 20.1 GB</td><td>68.2%</td><td>10.91</td></tr> <tr><td>Mistral Small 3</td><td>47.1 → 31.9 GB</td><td>67.6%</td><td>10.81</td></tr> <tr><td>Phi 4 Reasoning+</td><td>29.3 → 19.8 GB</td><td>67.6%</td><td>10.82</td></tr> <tr><td>FLUX.1 dev</td><td>23.8 → 16.3 GB</td><td>68.6%</td><td>10.98</td></tr> <tr><td>Stable Diffusion 3.5</td><td>16.3 → 11.3 GB</td><td>69.5%</td><td>11.12</td></tr> </tbody> </table> <div> <div class="conf-metric" style="grid-template-columns: minmax(0,1fr); grid-auto-rows: 1fr; margin-top: 0;"> <div class="conf-card"><p><strong>67.6–69.5%</strong><span>compressed size, every model tested</span></p></div> <div class="conf-card"><p><strong>~11 bits</strong><span>effective weight width</span></p></div> <div class="conf-card"><p><strong>LLMs + diffusion</strong><span>Llama, Qwen, Mistral, Phi, DeepSeek, FLUX, SD 3.5</span></p></div> </div> </div> </div> Note: Across Llama, Qwen, Mistral, Phi, and DeepSeek, plus the FLUX and Stable Diffusion transformers, DF11 lands near 68% of original size and about 11 bits per weight. The exponent redundancy is universal, not model-specific. The number that matters operationally is in the third row: Llama 3.1 405B drops from 812 to 551 gigabytes. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">Results · losslessness</div> <h2>Same bits out — and 405B fits on one node</h2> <div class="conf-split"> <table class="conf-table conf-panel" aria-label="Accuracy and perplexity, BF16 versus DF11, Llama 3.1 8B Instruct"> <thead> <tr><th>Llama 3.1 8B</th><th>BF16</th><th>DF11</th></tr> </thead> <tbody> <tr><td>MMLU (acc)</td><td>68.010</td><td class="conf-win">68.010</td></tr> <tr><td>TruthfulQA (acc)</td><td>36.965</td><td class="conf-win">36.965</td></tr> <tr><td>WikiText (ppl)</td><td>8.649</td><td class="conf-win">8.649</td></tr> <tr><td>C4 (ppl)</td><td>21.677</td><td class="conf-win">21.677</td></tr> </tbody> </table> <div> <div class="conf-banner"> <div class="conf-banner-number">405B</div> <p>Llama 3.1 405B runs losslessly on a single 8×80 GB node — half the hardware, none of the loss.</p> </div> <div class="conf-callout teal" style="margin-top: 18px;"> Not "within noise" — identical. Every decompressed weight matches the original bit-for-bit. </div> </div> </div> Note: Losslessness here is not "no measurable difference on a benchmark." It's identical. Accuracy and perplexity match to the digit, and every decompressed weight is bit-for-bit the original. The practical payoff: Llama 3.1 405B, which needs two eight-GPU nodes in BFloat16, now fits on one. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">Results · throughput</div> <h2>2.3–46× faster than spilling to the CPU</h2> <figure class="conf-figure conf-fig-short"> <img src="/assets/slides/2025-12-02-dfloat11/latency_throughput_cpu.webp" alt="Throughput and latency for token decoding: BF16 with CPU offloading versus DF11" /> <figcaption>Token-generation throughput (left three) and latency (right three). The BF16 model must offload to CPU to fit; DF11 stays entirely in GPU memory.</figcaption> </figure> <div class="conf-metric" style="margin-top: 32px;"> <div class="conf-card"><p><strong>2.31–46.24×</strong><span>higher throughput or lower latency vs. offloading</span></p></div> <div class="conf-card"><p><strong>No offload</strong><span>DF11 fits in GPU memory; no PCIe round-trip</span></p></div> <div class="conf-card"><p><strong>Identical output</strong><span>the speedup costs nothing in accuracy</span></p></div> </div> Note: The honest baseline isn't a smaller GPU, it's BFloat16 with part of the model offloaded to CPU, because that's what people actually do when a model doesn't fit. DF11 fits entirely in GPU memory, so it avoids the PCIe round-trip and runs 2.3 to 46 times faster, depending on how much the BFloat16 model had to offload. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">Results · memory</div> <h2>The freed memory becomes 5.7–14.9× longer generation</h2> <figure class="conf-figure conf-fig-short"> <img src="/assets/slides/2025-12-02-dfloat11/memory_usage.webp" alt="GPU memory consumption versus decoded tokens for BF16 and DF11 models" /> <figcaption>Same GPU budget, batch size 1. DF11's smaller footprint leaves room for the KV cache; BF16 hits out-of-memory far sooner.</figcaption> </figure> <div class="conf-metric" style="margin-top: 32px;"> <div class="conf-card"><p><strong>5.70–14.86×</strong><span>more tokens before out-of-memory</span></p></div> <div class="conf-card"><p><strong>KV cache</strong><span>the saved memory directly buys context length</span></p></div> <div class="conf-card"><p><strong>−28% / +5%</strong><span>diffusion memory saved at a few percent more latency</span></p></div> </div> Note: The memory you save doesn't just lower the GPU count. During decoding the KV cache is what runs you out of memory, and DF11's smaller weights leave five to fifteen times more room for it before you hit the limit. Same effect for diffusion models: about 28% less memory at a few percent more latency. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-kicker">Results · cost and baselines</div> <h2>The overhead amortizes, and it beats nvCOMP outright</h2> <div class="conf-split"> <figure class="conf-figure conf-fig-mid"> <img src="/assets/slides/2025-12-02-dfloat11/latency_breakdown.webp" alt="Latency breakdown for DF11 and BF16 Llama 3.1 8B across token batch sizes" /> <figcaption>Latency breakdown, Llama 3.1 8B on one A100. DF11's decompression is a fixed cost; larger batches amortize it.</figcaption> </figure> <div> <div class="conf-metric" style="grid-template-columns: minmax(0,1fr); grid-auto-rows: 1fr; margin-top: 0;"> <div class="conf-card"><p><strong>34.95×</strong><span>throughput vs. CPU-to-GPU transfer</span></p></div> <div class="conf-card"><p><strong>20.97×</strong><span>faster than NVIDIA nvCOMP (ANS)</span></p></div> <div class="conf-card"><p><strong>68% vs. 79%</strong><span>better compression ratio than nvCOMP</span></p></div> </div> <div class="conf-callout teal" style="margin-top: 16px;"> The only open, GPU-friendly lossless option — faster and more compressive. </div> </div> </div> Note: The cost of DF11 is a fixed per-block decompression that's independent of batch size, so the per-token overhead shrinks as you batch. Against the alternatives, streaming weights from CPU or NVIDIA's nvCOMP, our kernel is up to 35 and 21 times faster, and it compresses better than nvCOMP, 68 versus 79 percent, while nvCOMP isn't even open source. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-takeaway-header"> <img class="conf-takeaway-icon" src="/assets/slides/2025-12-02-dfloat11/takeaway.webp" alt="" aria-hidden="true" /> <div> <h2 class="conf-takeaway-title">Takeaways</h2> <div class="conf-takeaway-subtitle">Free memory, zero loss</div> </div> </div> <div class="conf-takeaway-grid"> <div class="conf-card conf-takeaway-card"> <div class="conf-takeaway-num">1</div> <h3>The exponent is the slack</h3> <p>BFloat16's 8-bit exponent carries ~2.6 bits. Huffman-coding it reclaims ~5 bits per weight, losslessly.</p> </div> <div class="conf-card conf-takeaway-card"> <div class="conf-takeaway-num">2</div> <h3>Lossless can be fast</h3> <p>SRAM lookup tables, a two-phase kernel, and block-level batching make variable-length decode practical on GPUs.</p> </div> <div class="conf-card conf-takeaway-card"> <div class="conf-takeaway-num">3</div> <h3>30% smaller, 100% identical</h3> <p>~70% size across LLMs and diffusion; 2.3–46× over CPU offload; 405B on a single node.</p> </div> </div> Note: Three things to remember. The redundancy lives in the exponent and it's universal. A careful GPU kernel makes lossless compression actually usable at inference time. And you get about 30% off with bit-for-bit identical outputs, so there's nothing to re-validate. --- <!-- .slide: class="conf-slide" data-background-color="#F8FAFC" --> <div class="conf-closing-layout"> <div class="conf-closing-main"> <h1 class="conf-closing-title">Thank you! Questions?</h1> <div class="conf-subtitle">70% Size, 100% Accuracy — Dynamic-Length Float (DF11)</div> <div class="conf-qr-grid" aria-label="Project links"> <div class="conf-qr-item"> <img src="/assets/slides/2025-12-02-dfloat11/qr_arxiv.svg" alt="QR code for the arXiv paper" /> <strong>arXiv</strong> </div> <div class="conf-qr-item"> <img src="/assets/slides/2025-12-02-dfloat11/qr_github.svg" alt="QR code for the GitHub repository" /> <strong>GitHub</strong> </div> <div class="conf-qr-item"> <img src="/assets/slides/2025-12-02-dfloat11/qr_pypi.svg" alt="QR code for the PyPI package" /> <strong>PyPI · vllm-df11</strong> </div> </div> </div> </div> Note: The code, the paper, and the pip-installable package are all linked here. Reach out any time — happy to collaborate.