// portfolio

Aus dem Labor

Hier probiere ich Dinge aus, auch solche, die ich noch nicht beherrsche, und schreibe auf, was herauskam. Auch wenn es nicht funktioniert hat.

NeoDiffusion: Diffusions-Sprachmodelle auf Apple Silicon

pausiert Juli 2026, 11 Tage 116 Commits, Swift, Metal und Python

Welche Optimierungen machen ein Diffusions-Sprachmodell auf einem Mac messbar schneller, ohne dass die Antworten schlechter werden?

Was ich versucht habe

Eine Inferenz-Engine in Swift auf MLX-Swift für LLaDA2.1-mini, ein Mixture-of-Experts-Modell mit 256 Experten, mit einem OpenAI-kompatiblen Server. Darauf habe ich rund ein Dutzend Verfahren aus aktuellen Papers getestet, jedes als eigenes Arbeitspaket mit Logbuch. Qualität wurde blind verglichen, Benchmarks zählten nur auf sauberen Messläufen (kein Swapping, keine thermische Drosselung). Zum Schluss ein eigener, fusionierter Metal-Kernel für die Experten-Schicht.

Was herauskam

Mehr Nein als Ja. Elastic-Cache verworfen, Self-Speculation (S2D2) nicht als Standard, EOS Early Exit ohne Wirkung. Der dynamische Schwellwert sparte auf dem Entwicklungsrechner 14,8 % der Schritte im Chat; auf dem Mac Studio kehrte sich das Vorzeichen um. Übrig blieb ein Plus von 13,8 % Tokens pro Sekunde beim Reasoning. Der eigene Kernel war im Microbenchmark 17 bis 21 % schneller, aber gegen die falsche Baseline (float statt half). Im echten Forward-Pass: 27,41 gegen 27,43 ms, ein Unentschieden. Verworfen, der Code bleibt als dokumentiertes Negativ-Ergebnis im Repo.

Was ich gelernt habe

  • Zahlen vom Entwicklungsrechner sind kein Urteil für die Zielhardware. Ein Hebel kann dort das Vorzeichen wechseln, deshalb entscheidet die Messung auf dem Zielgerät.
  • Ein Microbenchmark braucht dieselben Datentypen wie die Produktion. Sonst misst man einen Gewinn, den es nie gab.
  • Metal und das Decoding von Diffusionsmodellen waren neu für mich. Konzeptionell hatte ich beides verstanden, begriffen habe ich es erst beim Bauen. Bewusst habe ich mit Diffusion angefangen statt mit dem üblichen autoregressiven Weg. Das Wissen dazu kam aus Papers, gesammelt und verknüpft im LLM-Wiki zu Diffusions-Sprachmodellen.
  • Implementiert und gemessen haben Claude Code und Subagents. Ich habe die Hausregeln gesetzt (jede Aussage als belegt, abgeleitet oder spekulativ markiert, Negativ-Ergebnisse festhalten) und über jedes Annehmen oder Verwerfen entschieden.

Kartei: eine strukturelle IDE für Svelte, in Rust

laufend seit April 2026 144 Commits, rund 57’000 Zeilen Rust

Versteht man Svelte-Code schneller, wenn man ihn nicht als Text liest, sondern als Baum von Karten, und zwischen Struktur und Referenzgraph umschalten kann?

Was ich versucht habe

Jede Datei wird mit tree-sitter in Karten zerlegt: eine pro Funktion, Markup-Block oder CSS-Regel. Die Karten stehen in Miller-Spalten, eine Spalte pro Ebene. Mit einer Taste zeigt die nächste Spalte statt der Kinder im Syntaxbaum die Nachbarn im Referenzgraph, also Aufrufe und Lesezugriffe. Gebaut auf GPUI, hexagonal geschnitten, mit strukturellem Undo, LSP und Git- und Jujutsu-Status.

Was herauskam

Ein Prototyp, der echte Projekte liest, bearbeitet und speichert. Der Weg dahin war lehrreich: an einem einzigen Tag fand ich sieben stille Datenverlust-Fehler. Cmd+S schrieb im Projektmodus nie auf die Festplatte, der TypeScript-Parser verwarf alles ausserhalb von sieben Knotentypen, und ein {#if}-Block konnte als CSS erkannt und zu {} formatiert werden. Die Tests stiegen an diesem Tag von 173 auf 563. Seither gilt eine Regel für alle Parser: der Text einer Karte ist ein wörtlicher Ausschnitt der Quelle, neu serialisieren ist der Fehler. Der ehrlichste Befund: das Kartenmodell ist stark zum Navigieren und schwach zum Editieren, und im Alltag greife ich noch immer zu meiner gewohnten IDE. Das Projekt läuft weiter, aber nicht mit erster Priorität.

Was ich gelernt habe

  • Reihenfolge zählt. Wer den Schreibpfad repariert, macht jede bisher unsichtbare Korruption im Speicher zu echtem Datenverlust. Zuerst müssen die Parser verlustfrei sein, dann darf gespeichert werden.
  • Agents schreiben viel Code sehr schnell (59 Commits mit Claude als Co-Autor). Die meisten der sieben Fehler fanden sich nicht durch gezielte Suche, sondern beim Reparieren von etwas Benachbartem. Viel Code ist nicht dasselbe wie geprüfter Code.
  • clippy --fix ist nicht harmlos: von 454 auf 41 Warnungen, aber 16 entfernte Re-Exports musste ich zurückholen.

Nächster Schritt

Herausfinden, was mich zur gewohnten IDE zurückzieht. Kandidaten sind Go-to-Definition, Projektsuche und das Editieren ganzer Dateien.

Schwarm-Logik für Übungsempfehlungen

verworfen Januar und April 2025, zwei kurze Anläufe rund 2’400 Zeilen Go

Kann ein Schwarm einfacher Agents, die Regeln auf gewichtete Fakten anwenden, die nächste passende Übung in einem Lernpfad finden?

Was ich versucht habe

Angestossen hat mich ein Video über Schwarm-Algorithmen, die sich selbst weiterentwickeln. Die Behauptungen darin waren übertrieben, die Grundidee fand ich gut. Erster Anlauf: ein Graph aus Mathematik-Konzepten mit Voraussetzungen und Schwierigkeit, A* für Lernpfade, PageRank und Redis als Cache. Zweiter Anlauf: eine Inferenz-Engine, in der Agents als Goroutinen Regeln wie parent(X,Y) ∧ parent(Y,Z) → grandparent(X,Z) auf Fakten mit Aktivierung anwenden. Eine zentrale Instanz summiert ihre Signale, Aktivierungen zerfallen, der Schwellwert passt sich an.

Was herauskam

Die Engine leitet aus einem kleinen Beispiel-Datensatz neue Fakten ab, 20 Iterationen in rund 70 ms. Mit den Empfehlungen verbunden habe ich sie nie: die Faktentypen für Übungen und Vorwissen sind definiert, aber unbenutzt. Die Datei für die Evaluation ist leer geblieben, im ersten Anlauf schlagen zwei von elf Tests fehl, der zweite hat keine. Ergebnis: keine Aussage darüber, ob ein Schwarm besser empfiehlt als ein Graph-Algorithmus.

Was ich gelernt habe

  • Zuerst der Anwendungsfall und die Messgrösse, dann der Algorithmus. Ohne definierte Evaluation konnte der Schwarm gegen A* weder gewinnen noch verlieren, und vermutlich passte die Idee gar nicht zu diesem Problem. Die Lernplattform empfiehlt heute mit BKT, übernommen wurde aus diesen Anläufen nichts.
  • KI half hier vor allem bei der Recherche (Perplexity). Die Papers dazu besorgte ich über Bekannte mit Zugang.
  • Nebenläufigkeit in Go (Goroutinen, sync.Pool) und Unifikation mit Variablenbindung habe ich hier geübt. Auch was schiefgeht: ein Mutex, der nur lokal in der Funktion lebt, schützt nichts.