Davidmg0815's picture
Upload README.md with huggingface_hub
4c836a0 verified
|
Raw
History Blame
7.25 kB
metadata
license: apache-2.0
license_link: https://huggingface.co/Qwen/Qwen3.8-27B/blob/main/LICENSE
base_model:
  - Qwen/Qwen3.8-27B
base_model_relation: quantized
pipeline_tag: image-text-to-text
library_name: llama.cpp
language:
  - de
  - en
tags:
  - gguf
  - llama.cpp
  - mtp
  - speculative-decoding
  - qwen3
  - multimodal

Qwen3.8-27B GGUF — mit separatem MTP-Draft

GGUF-Konvertierung von Qwen/Qwen3.8-27B, gebaut am 14.08.2026 aus den BF16-Originalgewichten.

Der Grund für dieses Repo ist die Datei qwen3.8-27b-MTP-Q8_0.gguf: der Multi-Token-Prediction-Kopf als eigenständiges Draft-Modell, direkt nutzbar mit --spec-type draft-mtp. Die MTP-Gewichte stecken im Upstream-Checkpoint (mtp_num_hidden_layers in der config.json), werden von den üblichen GGUF-Repos aber nicht als getrennte Datei ausgeliefert — und ohne getrennte Datei kann llama-server sie nicht als Draft laden.

Es bringt Faktor 1,6 bis 2,7. Gemessen, nicht geschätzt — siehe unten.

Dateien

Datei Größe BPW Zweck
qwen3.8-27b-Q8_0.gguf 27,3 GB 8,50 Zielmodell — empfohlen
qwen3.8-27b-Q6_K.gguf 21,0 GB 6,57 kleinere Alternative
qwen3.8-27b-MTP-Q8_0.gguf 3,0 GB MTP-Draft für spekulatives Dekodieren
qwen3.8-27b-mmproj-F16.gguf 0,9 GB Vision/Video-Projektor

Die MTP-Tensoren sind aus den Zielmodellen entfernt (--no-mtp) und liegen ausschließlich in der Draft-Datei. Ziel- und Draft-Datei gehören zusammen.

Warum Q8_0 empfohlen ist, obwohl es größer ist: In der Messung war es durchgehend schneller als Q6_K — 39,5 gegen 32,8 t/s bei Fließtext, gleiche Einstellungen. Die k-Quant-Blockstruktur von Q6_K braucht pro Gewicht mehr Rechenschritte zum Entpacken als das schlichtere Q8_0. Mehr Bytes, weniger Arbeit. Q8_0 ist also gleichzeitig schneller und genauer.

Verwendung

llama-server \
  -m qwen3.8-27b-Q8_0.gguf \
  --mmproj qwen3.8-27b-mmproj-F16.gguf \
  -md qwen3.8-27b-MTP-Q8_0.gguf \
  --spec-type draft-mtp --spec-draft-n-max 3 --spec-draft-ngl 99 \
  --ctx-size 97000 --parallel 1 \
  --n-gpu-layers 99 --tensor-split 1,1,1 \
  --cache-type-k q8_0 --cache-type-v q8_0 \
  --flash-attn on --jinja

Ohne Spekulation einfach -md und die drei --spec-*-Schalter weglassen. Ohne Bildeingabe zusätzlich --mmproj weglassen.

Was MTP tatsächlich bringt

Beide Läufe mit identischer Konfiguration (Q8_0, 97K Kontext, eine Session), einziger Unterschied ist das Draft-Modell. Deutsche Prompts, je 2–3 Durchgänge, ausgewertet wird der Median. Die Zahlen kommen aus timings.predicted_per_second bzw. timings.draft_n / draft_n_accepted, die llama-server pro Anfrage selbst meldet.

Textsorte ohne Draft mit Draft Faktor Draft-Trefferquote
Wiederholung 22,9 t/s 62,0 t/s 2,71× 85,0 %
Aufzählung 23,0 t/s 61,6 t/s 2,68× 93,1 %
Übersetzung 22,9 t/s 51,8 t/s 2,26× 70,9 %
Struktur / JSON 23,0 t/s 47,6 t/s 2,07× 59,7 %
Fachtext 23,0 t/s 41,7 t/s 1,81× 48,0 %
Code 23,0 t/s 41,1 t/s 1,79× 48,9 %
Fließtext 22,9 t/s 39,5 t/s 1,72× 44,5 %
Kreativtext 23,0 t/s 35,9 t/s 1,56× 37,4 %

Gesamt über alle Textsorten: 57,3 % Trefferquote (4.491 von 7.842 Draft-Token).

Der wichtigste Befund

Ohne Draft ist die Rate völlig flach — 22,9 bis 23,0 t/s, egal was man generiert. Mit Draft spreizt sie sich um Faktor 1,7 auseinander, weil die Trefferquote massiv an der Textsorte hängt: vorhersagbarer Text wird zu über 90 Prozent korrekt geraten, freier Kreativtext nur zu gut einem Drittel.

Wer MTP an einem Aufzählungs-Benchmark misst, kommt auf 2,7× und überschätzt den Nutzen für normale Chatlast deutlich. Der realistische Wert für Fließtext-Dialog liegt bei rund 1,7×.

Was der Draft kostet

  • 3,0 GB auf der Platte
  • rund 2,7 GB VRAM ([spec] estimated memory usage of draft model is 2678.78 MiB bei 97K Kontext; 1.953 MiB bei 4K)
  • Ladezeit steigt kaum — 7 bis 27 Sekunden je nach Kontextgröße

Deutlich mehr als etwa der Gemma-4-12B-Draft mit 0,5 GB. Wer knapp an VRAM ist, muss das einplanen.

Testaufbau

  • 3× NVIDIA RTX 3080 20 GB — Ampere, SM 8.6
  • AMD EPYC 7F32, 8 Kerne / 16 Threads
  • llama.cpp Build 10423 (a94d563ed), Container ghcr.io/ggml-org/llama.cpp:full-cuda
  • --tensor-split 1,1,1, KV-Cache q8_0, --flash-attn on
  • Eine Session (--parallel 1), 97.024 Token Kontext
  • Belegt: 31,2 GB von 60 GB — Modell 27,3 + Draft 2,7 + KV/Puffer

Der Kontext ist praktisch gratis: dieselbe Konfiguration mit nur 4K statt 97K lieferte im Rahmen der Messstreuung dieselben Werte (58,8 gegen 60,5 t/s bei Aufzählungen). Man kann den großen Kontext also mitnehmen, ohne Durchsatz zu bezahlen.

Wie diese Dateien gebaut wurden

# Zielmodell ohne MTP-Tensoren
convert_hf_to_gguf.py Qwen3.8-27B/ --outfile tmp-BF16.gguf --outtype bf16 --no-mtp

# nur der MTP-Kopf, als Draft
convert_hf_to_gguf.py Qwen3.8-27B/ --outfile qwen3.8-27b-MTP-Q8_0.gguf --outtype q8_0 --mtp

# Vision/Video-Projektor
convert_hf_to_gguf.py Qwen3.8-27B/ --outfile qwen3.8-27b-mmproj-F16.gguf --outtype f16 --mmproj

# quantisieren
llama-quantize tmp-BF16.gguf qwen3.8-27b-Q8_0.gguf Q8_0 16
llama-quantize tmp-BF16.gguf qwen3.8-27b-Q6_K.gguf Q6_K 16

Die Flags --mtp und --no-mtp sind neu; ältere llama.cpp-Builds kennen sie nicht. Die Architektur Qwen3_5ForConditionalGeneration (Qwen3.8 nutzt sie unverändert weiter) erbt supports_mtp_export = True über Qwen3_5TextModel → _LinearAttentionVReorderBase → Qwen3NextModel → _QwenMtpMixin.

Quelle: Qwen/Qwen3.8-27B in BF16 (51,3 GB, 16,00 BPW), nicht das FP8-Release — also keine doppelte Quantisierung.

Zwei Hinweise für Ampere-Besitzer

FP8 läuft auf Ampere nicht nativ. SM 8.6 hat keine FP8-Tensorcores, die gibt es erst ab SM 8.9. Qwens FP8-Release lässt sich dort nur dequantisiert fahren — Speicher gespart, Tempo nicht. Für GGUF ist das gegenstandslos, weil Q8_0 und Q6_K reine Integer-Formate mit nativen Ampere-Kernen sind.

vLLM scheitert hier an drei GPUs. Das Modell hat 24 Attention-Heads, aber nur 4 KV-Heads. vLLM verlangt, dass tensor_parallel_size die KV-Head-Zahl teilt — 4 durch 3 geht nicht auf. Bleiben TP=2 und damit eine ungenutzte Karte. llama.cpp kennt das Problem nicht, weil --tensor-split Layer verteilt statt Attention-Köpfe. Für ungerade GPU-Zahlen ist llama.cpp hier der einzige Weg, alle Karten zu nutzen.

Reproduzieren

Das Messkript ist beigelegt (bench_mtp.py, deutsche Prompts über acht Textsorten, Median aus N Durchgängen):

python3 bench_mtp.py --port 8290 --runs 3 --max-tokens 300 --out ergebnis.md

Einzelmessungen schwanken um etwa ±6 Prozent, deshalb Median statt Einzelwert.

Lizenz

Apache 2.0, wie das Basismodell. Alle Rechte am Modell liegen beim Qwen-Team / Alibaba Cloud. Dieses Repo enthält ausschließlich formatkonvertierte Gewichte, kein zusätzliches Training und keine Änderung am Verhalten.