KI & Werkzeuge

Das Ollama-Update hat nichts beschleunigt — aber ein Modell zerstört

Ollama 0.32.5 war draußen, meine Workstation lief noch auf 0.31.2, und ich hatte gerade 26 Modelle darauf durchgemessen. Damit ergab sich eine seltene Gelegenheit: dieselbe Maschine, dieselben Modelle, dieselben Einstellungen — und die Versionsnummer als einzige Variable.

Das Ergebnis ist ein Nullergebnis, und genau deshalb scheint es mir aufschreibenswert. Elf von zwölf Modellen bewegen sich um weniger als drei Prozent. Das zwölfte ist kaputtgegangen.

Alles andere festhalten

Dieselbe RTX 3090 an nativem PCIe, Treiber 610.88, Windows 11, KV-Cache auf q8_0, Flash Attention aktiv. Zwölf Modelle über neun Architekturen von 4,9 bis 19,7 GB, Mixture-of-Experts und dicht, Denkmodelle und Instruct-Modelle, dazu ein Bildmodell.

Elf Aufgaben je Modell, jede dreimal mit verschiedenen Seeds. Der letzte Punkt wiegt schwerer, als er klingt: Bei Temperatur 0 ist die Generierung nahezu deterministisch, eine Wiederholung mit demselben Seed bringt also fast nichts. Verschiedene Seeds sagen dir, ob ein Modell eine Aufgabe zuverlässig löst oder einmal Glück hatte.

Eine Einstellung musste ausdrücklich gepinnt werden. Die beiden Maschinen, die ich am Ende vergleichen will, waren sich bei der Standard-Kontextlänge uneinig — 65.536 auf der einen, Modellvorgabe auf der anderen. Größerer Kontext heißt größerer KV-Cache und weniger Durchsatz; hätte ich das laufen lassen, wäre eine Konfigurationseinstellung als Plattformunterschied im Bericht gelandet. Alles, was die Messung beeinflusst, gehört in die Anfrage, nicht in die Umgebung.

Die Zahlen

Durchsatz ist der Median über Generierungen ab 50 Tokens. Punktzahlen sind gelöst von gestellt, über drei Seeds.

ModellReasoningDenkendCode0.31.20.32.5Δ
qwen3-coder-abliterated15/15abgewiesen9/9144,7149,4+3,2 %
qwen3-vl-abliterated15/1515/159/9138,0141,4+2,5 %
laguna-xs-2.18/1511/159/9145,0141,0defekt
glm-4.7-flash6/1512/159/9124,6124,9+0,2 %
ornith:35b15/1515/159/9117,9119,5+1,4 %
qwen3:8b12/1515/159/9119,1116,1−2,5 %
gemma4:26b15/1515/159/9103,2102,7−0,5 %
deepseek-r1:14b12/1515/153/969,268,2−1,4 %
devstral:24b15/15abgewiesen9/949,748,4−2,6 %
qwen3.6:27b15/1515/159/939,139,2+0,3 %
qwq:32b8/1515/150/919,735,2Kontext

Alles liegt zwischen −2,6 und +3,2 Prozent. Der eine große Wert, qwq:32b mit +78,7 Prozent, ist überhaupt nicht die Version — die Grundlinie lief mit 64k Kontext, der Vergleich mit 8k, und qwq ist das einzige Modell im Satz, das bei großem Kontext auf die CPU auslagert. Alle anderen zeigten null Auslagerung, und genau deshalb bewegte sich sonst nichts.

Was die Tabelle außerdem zeigt: Elf von zwölf Modellen reproduzierten ihre Punktzahlen exakt gegenüber einem Einzeldurchlauf der Vornacht — einschließlich Teilergebnissen wie 3/9 und 12/15. Das ist mein stärkster Beleg dafür, dass der Aufgabensatz eine Eigenschaft der Modelle misst und nicht der Stichprobe.

Das eine, das kaputtging

laguna-xs-2.1 lief bei jeder einzelnen Denkaufgabe ins Tokenlimit — 30 von 30, bei exakt 900 und exakt 3.000 Tokens. Auf 0.31.2 brauchte dasselbe Modell im Mittel 215 und 897 Tokens und wurde kein einziges Mal abgeschnitten.

Die JSON-Aufgabe zeigt, was passiert:

{"name": "Tobias", "city": "Berlin", "age": 42}</assistant>{"name": "Tobias", "city": "Berlin", "age": 42}</assistant>{"name": ...

Das Modell liefert die richtige Antwort, sendet seine Endmarke — und macht weiter. Es erzeugt dieselbe Antwort erneut, bis das Budget aufgebraucht ist. Das Stop-Token wird nicht beachtet.

Verdächtig ist Version 0.32.3, in deren Notizen steht, sie habe „chat, thinking, and tool calling support for Laguna 2.1 models“ ergänzt. Ausgerechnet die Version, die dieses Modell ordentlich anbinden sollte, scheint dabei die Stop-Tokens verdorben zu haben. Dass es kein Kontexteffekt ist, habe ich geprüft: dasselbe Modell bei 8k und 64k — identisch defekt.

Seine 8/15 und 11/15 in der Tabelle sind bedeutungslos. Sie entstehen dadurch, dass meine Regel „letzte Zahl der Antwort“ irgendwo im Wiederholungstext landet. Die ehrliche Bezeichnung lautet defekt, nicht schlechter.

„Denken abschalten“ ist eine Bitte, keine Garantie

Das war der nützlichste Fund der ganzen Übung, und er hat mit Versionen nichts zu tun. Bittet man ein Modell, seine Gedankenkette wegzulassen, passiert eines von drei Dingen:

  • Honoriert — die Tokenzahl fällt um den Faktor 27 bis 812. Ein Modell ging von 2.435 Tokens auf 2.
  • Stillschweigend ignoriert — Tokenzahlen in beiden Modi gleich. Der Schalter wird angenommen und tut nichts.
  • Abgewiesen — HTTP 400. Das Modell hat keinen Denkmodus und sagt das auch.

Der mittlere Fall ist der gefährliche, weil alles nach Erfolg aussieht. Ich hatte zunächst die Ollama-Version dafür verantwortlich gemacht. Sie ist es nicht — dasselbe Modell ignoriert den Schalter auf 0.31.2 und 0.32.5 gleichermaßen. Es ist eine Modelleigenschaft, in mindestens einer Familie verursacht durch ein Template, das ohne die Denksteuerung ausgeliefert wird.

Der Test kostet zwei Anfragen: dieselbe Frage mit und ohne Denken senden, Tokenzahlen vergleichen. Liegen sie wenige Prozent auseinander, hat der Schalter nichts bewirkt — und jeder Vergleich direkt gegen denkend misst bei diesem Modell eine Achse, die es nicht gibt.

Eine echte Verbesserung zwischen den Versionen gab es, und sie ist von dieser Art: qwen2.5vl:7b weist den Schalter jetzt mit 400 zurück, wo es ihn früher annahm und verwarf. Ein ausdrücklicher Fehler schlägt ein stilles Nichtstun jedes Mal.

Ein Tag-Name ist keine Identität

Beim Vorbereiten der zweiten Hälfte dieses Vergleichs zog ich ein Modell, das eine andere Maschine bereits hatte — in der Erwartung eines sauberen Eins-zu-eins-Tests. Die beiden Kopien desselben Tags erwiesen sich als verschiedene Dateien: 17,28 gegen 18,25 GB, und unterschiedliche Modellfamilien. Der Tag war zwischen den beiden Downloads auf ein anderes Basismodell umgestellt worden.

Es kam schlimmer. Auf der anderen Maschine zeigten drei Tags — einer namens „coder“, einer „coder-abliterated“, einer „vl-abliterated“ — auf einen einzigen Blob, und der war ein Vision-Language-Modell, überhaupt kein Coder. Ein Durchsatzvergleich zwischen den beiden Maschinen, den ich bereits gezogen hatte, verglich damit ein Bildmodell gegen ein Programmiermodell und nannte den Unterschied „Hardware“.

Vor jedem maschinenübergreifenden Vergleich: Manifest-Digest prüfen, dann den tatsächlichen Gewichts-Blob, dann die Modellfamilie. Der Tag beweist nichts.

Zwei eigene Fehler

Auf halber Strecke habe ich die Durchsatzmetrik verbessert — vom Mittelwert über alle Anfragen zum Median über Generierungen ab 50 Tokens, weil man bei einer Zwei-Token-Antwort den Anfrage-Overhead misst und nicht die Dekodiergeschwindigkeit. Gute Änderung. Dann habe ich die neuen Werte gegen die alten Zusammenfassungszahlen gestellt.

Kurze Antworten haben niedrigen Durchsatz, der alte Mittelwert war also gedrückt, also schien jedes Modell durch das Update 3 bis 11 Prozent zu gewinnen. Ich habe das für vier Modelle in Folge berichtet, bevor mich die Gleichförmigkeit stutzig machte — vier Modelle von vier Herstellern, die alle ähnlich zulegen, so verhält sich Software nicht. Aus den Rohdaten neu gerechnet, verschwanden die Gewinne vollständig.

Die Regel, an die ich mich hätte halten sollen: Niemals eine Zahl aus einer Metrik gegen eine aus einer anderen stellen. Ändert sich die Metrik, muss alles neu gerechnet werden, womit sie verglichen wird — was nur geht, wenn man die Rohdaten aufgehoben hat.

Der zweite Fehler war subtiler. Beim Neuberechnen ließ ich einen Filter weg und zog damit versehentlich die Dauerlast-Anfragen der Nacht in die Grundlinien-Mediane — 66 Messwerte statt 10 —, was bei mehreren Modellen das Vorzeichen kippte. Aufgefallen ist es, weil ein Wert stärker von einer früheren Rechnung abwich, als er durfte.

Also aktualisieren oder nicht?

Ja — aber nicht wegen der Geschwindigkeit. Die gibt es hier nicht. Aktualisiere wegen Fehlerbehebungen und wegen der Unterstützung für Modelle, die du wirklich fahren willst.

Und prüfe danach, ob unterwegs etwas kaputtgegangen ist, denn das ist es. Ein Modell, das stillschweigend nie aufhört zu generieren, kündigt sich in keinem Changelog an. Es zeigt sich als Job, der früher fertig wurde und jetzt ins Tokenlimit läuft — oder als Rechnung, die ohne sichtbaren Grund größer geworden ist.

Als Nächstes: dieselben zwölf Modelle auf einer zweiten RTX 3090 — gleiche Karte, aber per Thunderbolt an einem Linux-Host mit einem Viertel des Arbeitsspeichers und einer Mobil-CPU. Gleiche GPU, völlig anderer Aufbau. Und eine saubere Kontextreihe über 8k, 32k, 64k und 128k, denn der eine große Wert in diesem Beitrag ist bisher ein Kontexteffekt, den ich argumentiert und nicht gemessen habe.