commit
faecdd96dc
@ -0,0 +1 @@ |
||||
*.pdf |
||||
@ -0,0 +1,4 @@ |
||||
{ |
||||
"tinymist.serverPath": "/nix/store/svghwcmy5qbhf3flz0g09m9i1llfm0m5-tinymist-0.15.8/bin/tinymist", |
||||
|
||||
} |
||||
@ -0,0 +1,14 @@ |
||||
TYPST := typst
|
||||
|
||||
SRC := $(filter-out template.typ,$(wildcard *.typ))
|
||||
PDF := $(SRC:.typ=.pdf)
|
||||
|
||||
.PHONY: all clean |
||||
|
||||
all: $(PDF) |
||||
|
||||
%.pdf: %.typ template.typ references.bib |
||||
$(TYPST) compile $< $@
|
||||
|
||||
clean: |
||||
rm -f $(PDF)
|
||||
|
After Width: | Height: | Size: 389 B |
@ -0,0 +1,155 @@ |
||||
#let accent = rgb("#22617f") |
||||
#let ember = rgb("#a85430") |
||||
#let paper = rgb("#faf8f3") |
||||
|
||||
#let _row(label, frac, pct, color) = grid( |
||||
columns: (86pt, 1fr, 36pt), |
||||
column-gutter: 5pt, |
||||
align(right + horizon, text(size: 10pt)[#label]), |
||||
place(left + horizon, place(left + horizon, rect(width: 100%, height: 7pt, fill: luma(242), radius: 1.5pt)) + place(left + horizon, rect(width: frac * 100%, height: 7pt, fill: color, radius: 1.5pt))), |
||||
align(right + horizon, text(size: 9.5pt, fill: luma(110))[#pct]), |
||||
) |
||||
|
||||
#let next-token-chart() = block(width: 100%, { |
||||
box(width: 100%, stroke: 0.8pt + accent.lighten(30%), fill: accent.lighten(94%), radius: 3pt, inset: (x: 8pt, y: 4pt), align(left, text(size: 11.5pt)[„Der Himmel über der Stadt ist …“])) |
||||
v(5pt) |
||||
_row("blau", 0.58, "58 %", accent) |
||||
v(2.5pt) |
||||
_row("bedeckt", 0.17, "17 %", accent.lighten(35%)) |
||||
v(2.5pt) |
||||
_row("dunkel", 0.09, "9 %", accent.lighten(52%)) |
||||
v(2.5pt) |
||||
_row("grau", 0.07, "7 %", accent.lighten(62%)) |
||||
v(2.5pt) |
||||
_row("…", 0.09, "9 %", luma(224)) |
||||
}) |
||||
|
||||
#let _pipebox(title, ..lines, highlight: false, dashed: false) = block( |
||||
width: 100%, |
||||
stroke: ( |
||||
paint: if highlight { accent } else { luma(205) }, |
||||
thickness: if highlight { 1.1pt } else { 0.6pt }, |
||||
dash: if dashed { "dashed" }, |
||||
), |
||||
fill: if highlight { accent.lighten(94%) } else { paper }, |
||||
radius: 3pt, |
||||
inset: (x: 5pt, y: 6pt), |
||||
align(center)[ |
||||
#text(size: 10pt, weight: "bold")[#title] |
||||
#v(2pt) |
||||
#for l in lines.pos() [ #text(size: 8.5pt, fill: luma(110))[#l] #v(1pt) ] |
||||
], |
||||
) |
||||
|
||||
#let training-pipeline() = grid( |
||||
columns: (1fr, 11pt, 1fr, 11pt, 1fr, 11pt, 1fr, 11pt, 1fr), |
||||
align(horizon, _pipebox("Rohdaten", "")), |
||||
align(horizon, text(fill: accent)[→]), |
||||
_pipebox("Pretraining", "Nächstes Token", "Tausende GPUs", "Wochen–Monate", highlight: true), |
||||
align(horizon, text(fill: accent)[→]), |
||||
align(horizon, _pipebox("Basismodell", "reiner Text-", "vervollständiger", dashed: true)), |
||||
align(horizon, text(fill: accent)[→]), |
||||
align(horizon, _pipebox("Fine-Tuning", "SFT: Dialoge", "RLHF: Präferenzen")), |
||||
align(horizon, text(fill: accent)[→]), |
||||
align(horizon, _pipebox("Assistent", "Chat · API · Agents")), |
||||
) |
||||
|
||||
#let _edot(x, y, c) = place(top + left, dx: x - 2.4pt, dy: y - 2.4pt, circle(radius: 2.4pt, fill: c)) |
||||
|
||||
#let _head(x, y, ang, color) = { |
||||
let c = calc.cos(ang) |
||||
let s = calc.sin(ang) |
||||
let bx = x - 6.5pt * c |
||||
let by = y - 6.5pt * s |
||||
place(top + left, dx: 0pt, dy: 0pt, polygon( |
||||
(x, y), |
||||
(bx - 2.6pt * s, by + 2.6pt * c), |
||||
(bx + 2.6pt * s, by - 2.6pt * c), |
||||
fill: color, |
||||
)) |
||||
} |
||||
|
||||
#let _elabel-c(x, y, body) = place(top, dx: x - 35pt, dy: y, box(width: 70pt, align(center, text(size: 10.5pt, fill: luma(70))[#body]))) |
||||
|
||||
#let embedding-plot() = align(center, block(width: 330pt, height: 122pt, { |
||||
place(top + left, dx: 56pt, dy: 16pt, line(angle: 90deg, length: 76pt, stroke: 0.7pt + luma(175))) |
||||
place(top + left, dx: 56pt, dy: 92pt, line(angle: 0deg, length: 250pt, stroke: 0.7pt + luma(175))) |
||||
_head(56pt, 16pt, -90deg, luma(175)) |
||||
_head(306pt, 92pt, 0deg, luma(175)) |
||||
place(top + left, dx: -6pt, dy: 46pt, rotate(-90deg, text(size: 9pt, fill: luma(140))[einfach → königlich])) |
||||
place(top, dx: 56pt, dy: 101pt, box(width: 250pt, align(center, text(size: 9pt, fill: luma(140))[männlich → weiblich]))) |
||||
place(top, dx: 46pt, dy: -3pt, box(width: 270pt, align(center, text(size: 12pt, weight: "bold")[König − Mann + Frau ≈ Königin]))) |
||||
place(top + left, dx: 106pt, dy: 78pt, line(angle: 0deg, length: 94pt, stroke: (paint: luma(160), thickness: 0.8pt, dash: "dashed"))) |
||||
place(top + left, dx: 106pt, dy: 78pt, line(angle: -81.3deg, length: 47pt, stroke: 1.1pt + accent)) |
||||
place(top + left, dx: 206pt, dy: 78pt, line(angle: -81.3deg, length: 47pt, stroke: 1.1pt + accent)) |
||||
_head(200pt, 78pt, 0deg, luma(160)) |
||||
_head(113.2pt, 31.6pt, -81.3deg, accent) |
||||
_head(213.2pt, 31.6pt, -81.3deg, accent) |
||||
place(top, dx: 46pt, dy: 47pt, box(width: 58pt, align(right, text(size: 9pt, fill: accent)[König − Mann]))) |
||||
place(top, dx: 111pt, dy: 60pt, box(width: 90pt, align(center, text(size: 9pt, fill: luma(130))[Frau − Mann]))) |
||||
place(top, dx: 223pt, dy: 47pt, box(width: 82pt, align(left, text(size: 9pt, fill: accent)[≈ gleicher Vektor]))) |
||||
_edot(106pt, 78pt, luma(85)) |
||||
_edot(206pt, 78pt, luma(85)) |
||||
_edot(114pt, 26pt, accent) |
||||
_edot(214pt, 26pt, accent) |
||||
_elabel-c(106pt, 84pt, [Mann]) |
||||
_elabel-c(206pt, 84pt, [Frau]) |
||||
place(top, dx: 48pt, dy: 20pt, box(width: 60pt, align(right, text(size: 10.5pt, fill: luma(70))[König]))) |
||||
place(top, dx: 222pt, dy: 20pt, box(width: 66pt, align(left, text(size: 10.5pt, fill: luma(70))[Königin]))) |
||||
})) |
||||
|
||||
#let _tl-fx(y) = 22pt + (y - 2023.0) / 2.72 * 378pt |
||||
|
||||
#let _tl-ev(yr, above, lvl, label, w: 95pt) = ( |
||||
x: _tl-fx(yr), |
||||
dy: if above { 17pt - lvl * 17pt } else { 55pt + lvl * 17pt }, |
||||
label: label, |
||||
w: w, |
||||
) |
||||
|
||||
#let _tl-lane(events, color, title) = block(width: 100%, height: 98pt, { |
||||
for yr in (2023, 2024, 2025) { |
||||
place(top + left, dx: _tl-fx(yr), dy: 2pt, line(angle: 90deg, length: 94pt, stroke: 0.4pt + luma(235))) |
||||
} |
||||
place(horizon + left, line(length: 100%, stroke: 0.8pt + luma(205))) |
||||
place(top + left, dx: 2pt, dy: 0pt, text(size: 10pt, weight: "bold", fill: color)[#title]) |
||||
for e in events { |
||||
place(top + left, dx: e.x - e.w / 2, dy: e.dy, box(width: e.w, align(center, text(size: 9.5pt, fill: luma(70))[#e.label]))) |
||||
} |
||||
for e in events { |
||||
place(top + left, dx: e.x - 2.2pt, dy: 46.8pt, circle(radius: 2.2pt, fill: color)) |
||||
} |
||||
}) |
||||
|
||||
#let _tl-years() = block(width: 100%, height: 14pt, { |
||||
for (yr, name) in ((2023, [2023]), (2024, [2024]), (2025, [2025])) { |
||||
place(top, dx: _tl-fx(yr) - 25pt, box(width: 50pt, align(center, text(size: 8.5pt, fill: luma(140), font: "DejaVu Sans Mono")[#name]))) |
||||
} |
||||
}) |
||||
|
||||
#let two-llm-timeline() = block(width: 100%, { |
||||
_tl-lane(( |
||||
_tl-ev(2023.21, true, 0, []), |
||||
_tl-ev(2023.87, false, 0, []), |
||||
_tl-ev(2024.21, true, 1, []), |
||||
_tl-ev(2025.08, false, 1, []), |
||||
_tl-ev(2025.24, true, 0, []), |
||||
_tl-ev(2025.52, false, 0, [], w: 120pt), |
||||
), ember, []) |
||||
_tl-lane(( |
||||
_tl-ev(2023.28, true, 0, []), |
||||
_tl-ev(2023.71, false, 0, [], w: 120pt), |
||||
_tl-ev(2024.54, true, 0, []), |
||||
_tl-ev(2025.10, false, 0, []), |
||||
_tl-ev(2025.71, true, 1, [], w: 66pt), |
||||
), accent, []) |
||||
_tl-years() |
||||
}) |
||||
|
||||
#let hbar(label, value, max, fillc: accent, valstr: "") = grid( |
||||
columns: (92pt, 1fr, 42pt), |
||||
column-gutter: 5pt, |
||||
align(right + horizon, text(size: 10pt)[#label]), |
||||
place(left + horizon, place(left + horizon, rect(width: 100%, height: 7pt, fill: luma(242), radius: 1.5pt)) + place(left + horizon, rect(width: value / max * 100%, height: 7pt, fill: fillc, radius: 1.5pt))), |
||||
align(right + horizon, text(size: 9.5pt, fill: luma(110))[#valstr]), |
||||
) |
||||
@ -0,0 +1,34 @@ |
||||
#import "template.typ": * |
||||
#import "diagrams.typ": * |
||||
|
||||
#let src(body) = { |
||||
v(0.35em) |
||||
block( |
||||
width: 100%, |
||||
fill: paper.darken(3%), |
||||
inset: (x: 6pt, y: 3.5pt), |
||||
radius: 2pt, |
||||
text(size: 9.5pt, fill: luma(145))[#text(fill: accent)[Quellen:] #body], |
||||
) |
||||
} |
||||
|
||||
#show: presentation.with( |
||||
title: "KiCad", |
||||
subtitle: "", |
||||
author: "Your Name", |
||||
) |
||||
|
||||
#slide(title: "Ablauf")[ |
||||
- ..? |
||||
- Danach: Worauf besteht besonderes Interesse? |
||||
] |
||||
|
||||
// =================================================================== |
||||
#section("Technologie-Grundlagen", note: "30–45 min") |
||||
// =================================================================== |
||||
|
||||
#slide(title: "Was ist KiCad?") |
||||
#sample-chart() |
||||
#v(0.4em) |
||||
#src[@vaswani2017, @brown2020, @bbycroft] |
||||
] |
||||
@ -0,0 +1,8 @@ |
||||
{ pkgs ? import <nixpkgs> {} }: |
||||
|
||||
pkgs.mkShell { |
||||
packages = with pkgs; [ |
||||
typst |
||||
tinymist |
||||
]; |
||||
} |
||||
@ -0,0 +1,170 @@ |
||||
// ============================================================================ |
||||
// template.typ — technical, minimal presentation template |
||||
// |
||||
// Usage: |
||||
// #import "template.typ": * |
||||
// #show: presentation.with(title: "...", subtitle: "...", author: "...") |
||||
// |
||||
// #slide(title: "Title")[ ... ] // two-part slide: title part | content part |
||||
// #slide[ ... ] // single-part, full-width slide |
||||
// #img("assets/fig.svg") // centered image, optional caption |
||||
// ============================================================================ |
||||
|
||||
// Palette: warm paper, petrol accent, terracotta counterpoint. |
||||
// All text/background pairs keep >= 4.5:1 contrast; decorative |
||||
// elements (bars, markers, watermarks) never carry information. |
||||
#let paper = rgb("#faf8f3") |
||||
#let ink = rgb("#2d2a26") |
||||
#let accent = rgb("#22617f") |
||||
#let accent-soft = rgb("#4c8fad") |
||||
#let ember = rgb("#a85430") |
||||
#let wash = rgb("#edf2f5") |
||||
#let mono = "DejaVu Sans Mono" |
||||
|
||||
// Short vertical accent rule (petrol -> terracotta). |
||||
#let hairline-v = 3.5pt + gradient.linear(accent, ember, angle: 90deg) |
||||
// Horizontal hairline for title/section slides. |
||||
#let hairline-h = 1pt + gradient.linear(accent, ember, angle: 0deg) |
||||
|
||||
#let slide-counter = counter("slide") |
||||
#let deck-title = state("deck-title", none) |
||||
|
||||
// Footer: deck title bottom-left, slide counter bottom-right. |
||||
#let slide-footer() = context { |
||||
let n = slide-counter.get().first() |
||||
let total = slide-counter.final().first() |
||||
set text(font: mono, size: 0.55em, fill: luma(150)) |
||||
place(bottom + left, dy: -1em, deck-title.get()) |
||||
place(bottom + right, dy: -1em, { |
||||
text(fill: accent, weight: "bold", str(n)) |
||||
text(fill: luma(165), " / " + str(total)) |
||||
}) |
||||
} |
||||
|
||||
// Tinted content panel with a colored spine — used for paired columns |
||||
// (Grok = ember, Mistral = petrol). The spine is decorative reinforcement; |
||||
// the column headers carry the information. |
||||
#let panel(body, c: accent) = block( |
||||
width: 100%, |
||||
fill: c.lighten(95%), |
||||
stroke: (left: 2.5pt + c), |
||||
inset: (x: 0.55em, y: 0.45em), |
||||
radius: (top-right: 2pt, bottom-right: 2pt), |
||||
{ |
||||
set par(spacing: 0.85em) |
||||
body |
||||
}, |
||||
) |
||||
|
||||
// Thin gradient band across the top edge of every page. |
||||
#let top-band = place(top + left, rect(width: 100%, height: 2.5pt, fill: gradient.linear(accent, ember, angle: 0deg))) |
||||
|
||||
// Import an image, centered; optional caption (never numbered). |
||||
#let img(path, width: 82%, caption: none) = { |
||||
let im = image(path, width: width) |
||||
if caption == none { |
||||
align(center, im) |
||||
} else { |
||||
align(center, figure(im, caption: caption, numbering: none)) |
||||
} |
||||
} |
||||
|
||||
// Two-part slide: a narrow title part on the left, content on the right. |
||||
// Without `title`, the body takes the full width. |
||||
#let slide(body, title: none, ..args) = { |
||||
slide-counter.update(n => n + 1) |
||||
page( |
||||
footer: slide-footer(), |
||||
..args, |
||||
if title == none { |
||||
body |
||||
} else { |
||||
grid( |
||||
columns: (0.3fr, 1.1fr), |
||||
column-gutter: 2.2em, |
||||
align(top, block( |
||||
stroke: (left: hairline-v), |
||||
inset: (left: 0.9em, top: 0.4em, bottom: 0.1em), |
||||
text(font: mono, weight: "bold", size: 0.85em, tracking: 0.1em, fill: accent, upper(title)), |
||||
)), |
||||
align(top, body), |
||||
) |
||||
}, |
||||
) |
||||
} |
||||
|
||||
// Section divider slide, with a large decorative ghost numeral. |
||||
#let section-counter = counter("section") |
||||
#let section(name, note: none) = { |
||||
section-counter.step() |
||||
slide[ |
||||
#align(horizon)[ |
||||
#block(width: 72%, align(left)[ |
||||
#context { |
||||
let n = section-counter.get().first() |
||||
place(top + right, dy: -1.1em, dx: 0.2em, |
||||
text(font: mono, size: 4.2em, weight: "bold", fill: accent.lighten(86%))[ |
||||
0#str(n) |
||||
]) |
||||
} |
||||
#text(font: mono, size: 0.65em, weight: "bold", tracking: 0.2em, fill: accent)[SECTION] |
||||
#v(0.4em) |
||||
#text(size: 2em, weight: "bold")[#name] |
||||
#v(0.55em) |
||||
#box(width: 4.5em, align(left, line(length: 100%, stroke: hairline-h))) |
||||
#if note != none [#v(0.5em); #text(font: mono, size: 0.7em, fill: luma(110))[#note]] |
||||
]) |
||||
] |
||||
] |
||||
} |
||||
|
||||
// Title slide. |
||||
#let title-slide(title, subtitle: none, author: none, date: none) = { |
||||
align(center + horizon)[ |
||||
#block(width: 72%, align(left)[ |
||||
#text(size: 2.1em, weight: "bold")[#title] |
||||
#if subtitle != none [#v(0.4em); #text(size: 1.15em, fill: luma(90))[#subtitle]] |
||||
#v(0.9em) |
||||
#line(length: 100%, stroke: hairline-h) |
||||
#v(0.6em) |
||||
#let meta = if author == none { date } else if date == none { author } else { author + " · " + date } |
||||
#text(font: mono, size: 0.7em, fill: luma(110))[#meta] |
||||
]) |
||||
] |
||||
pagebreak() |
||||
} |
||||
|
||||
// Main presentation wrapper. All options are named; the document content is |
||||
// bound to `doc` by the show rule. |
||||
#let presentation( |
||||
title: "Presentation", |
||||
subtitle: none, |
||||
author: none, |
||||
date: auto, |
||||
doc, |
||||
) = { |
||||
set page(paper: "presentation-16-9", margin: (x: 3em, y: 2.6em), fill: paper, footer: none, background: top-band) |
||||
set text(size: 20pt, fill: ink) |
||||
set par(justify: false, leading: 0.68em) |
||||
show strong: set text(fill: accent) |
||||
show list: set list(marker: ( |
||||
text(fill: accent-soft)[•], |
||||
text(fill: accent-soft)[–], |
||||
)) |
||||
show raw: set text(font: mono, size: 0.85em) |
||||
show raw.where(block: true): it => block(width: 100%, fill: wash, inset: 0.9em, radius: 0pt, it) |
||||
|
||||
deck-title.update(title) |
||||
|
||||
let d = datetime.today() |
||||
let mm = if d.month() < 10 { "0" + str(d.month()) } else { str(d.month()) } |
||||
let dd = if d.day() < 10 { "0" + str(d.day()) } else { str(d.day()) } |
||||
let the-date = if date == auto { |
||||
str(d.year()) + "-" + mm + "-" + dd |
||||
} else { |
||||
date |
||||
} |
||||
|
||||
title-slide(title, subtitle: subtitle, author: author, date: the-date) |
||||
doc |
||||
} |
||||
Loading…
Reference in new issue