Skip to content

vulkan: add TQ2_0 (ternary) support#25850

Open
michaeltrabalka-tech wants to merge 2 commits into
ggml-org:masterfrom
michaeltrabalka-tech:vulkan-tq2_0
Open

vulkan: add TQ2_0 (ternary) support#25850
michaeltrabalka-tech wants to merge 2 commits into
ggml-org:masterfrom
michaeltrabalka-tech:vulkan-tq2_0

Conversation

@michaeltrabalka-tech

@michaeltrabalka-tech michaeltrabalka-tech commented Jul 18, 2026

Copy link
Copy Markdown

Overview

Adds Vulkan backend support for GGML_TYPE_TQ2_0 (the 2.06 bpw ternary type used
by BitNet/TriLM-style models), which is currently CPU-only. This complements the
recently added q2_0 work — ternary models are where 2-bit weight traffic pays
off most (~8x smaller FFN weights vs F16).

What's included:

  • types.glsl: block_tq2_0 (+ _packed16) and quant constants
  • dequant_tq2_0.comp: dequant pipeline
  • mul_mat_vec_tq2_0.comp: dedicated mmv shader. TQ2_0's qs group/level layout
    matches Q2_K's thread-access scheme, so this reuses the Q2_K thread layout with a
    d * (Σ b·q − Σ b) factorization (the −1 offset is hoisted out of the inner loop).
  • dequant_funcs.glsl / mul_mm_funcs.glsl: 2-wide dequant + tile loads for the
    float-dequant matmul path
  • dequant_funcs_cm2.glsl: coopmat2 decode callbacks
  • vulkan-shaders-gen.cpp: type registration + dedicated-mmv predicate
  • ggml-vulkan.cpp: pipeline creation/dispatch switches, supports_op, GET_ROWS

Deliberately not in this PR (follow-up material): MMQ/integer-dot path for
TQ2_0 and TQ1_0 support. The float-dequant path is correct and already useful;
int-dot is an optimization on top.

Block layout reference

TQ2_0 block = 256 elements: qs[64] as two 32-byte groups, element index
g*128 + l*32 + m stored at bit position 2*l of byte g*32 + m; codes map
{0,1,2,3} → {-1,0,1,2} via w = (q-1) * d with one f16 scale d per block.
The packer/layout was validated bit-exact against ggml's CPU reference.

Testing

  • AMD Radeon RX 9070 XT (RDNA4), Windows 11, MSVC 19, VulkanSDK 1.4.350.
  • Correctness: on a 125M ternary model fully offloaded, TQ2_0-vs-F16 top-12
    logprobs are identical to 4 decimal places on Vulkan. (Notably tighter than the
    CPU TQ2_0 path, whose Q8_K activation quantization introduces small logit noise —
    the Vulkan float-dequant path avoids that.)
  • test-backend-ops test -p tq2_0: 21/21 pass on Vulkan0 vs CPU reference
    (MUL_MAT ×11, MUL_MAT_ID ×3, GET_ROWS ×4, CPY ×3). This PR also enables TQ2_0 in
    the test type lists (was commented out as "TODO: implement for all backends" —
    backends without support skip via the normal not-supported path; TQ1_0 stays
    disabled).
  • Performance at 125M: pp 81.6k / tg 979 t/s vs F16 85.1k / 1025 (−4%) — decode at
    this size is launch-overhead-bound, not weight-bandwidth-bound; the type exists
    for larger BitNet-class models where the 8x weight-traffic cut dominates.

Happy to split the mmv shader into a follow-up or adjust to maintainer preferences
on pipeline wiring.

Additional information

Perf at 125M is parity with F16 (decode there is launch-overhead-bound); the type
targets larger BitNet-class models where the ~8x FFN weight-traffic reduction is
the decode lever. MMQ/integer-dot and TQ1_0 are deliberately left for follow-ups.

Requirements

AI usage disclosure: implementation and tests were co-developed with an AI assistant
(Claude); all correctness/performance results were produced and verified on real
hardware (AMD RX 9070 XT, Vulkan, test-backend-ops vs CPU reference).

Michael Trabalka and others added 2 commits July 17, 2026 19:55
…atmul via dequant_funcs

First Vulkan ternary type in ggml. Correctness: OM-125m TQ2_0 vs F16 top-12
logprobs identical to 4 decimals fully offloaded (float dequant path, no Q8_K
activation quant). Speed at 125m ~= F16 (overhead-bound at this scale); the
bandwidth win targets larger BitNet SKUs. MMQ/int-dot path intentionally not
wired yet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Vulkan now implements TQ2_0 (dequant, mul_mat_vec, mul_mm, get_rows); backends
without support skip via not-supported as usual. TQ1_0 stays disabled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@michaeltrabalka-tech
michaeltrabalka-tech requested review from a team and ggerganov as code owners July 18, 2026 02:45
@michaeltrabalka-tech michaeltrabalka-tech changed the title Vulkan tq2 0 vulkan: add TQ2_0 (ternary) support Jul 18, 2026
@ggml-gh-bot

ggml-gh-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

Hi @michaeltrabalka-tech, thanks for your contribution!

Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:

  • PR Template not respected: Please respect the template when creating a new pull request. Make sure to fill out all required sections.

  • AI-generated content: This project does not accept PRs, descriptions or commit messages that are fully or predominantly AI-generated. If you have used AI to assist you in writing code, please make sure to disclose that explicitly.


Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below.

@michaeltrabalka-tech

Copy link
Copy Markdown
Author

Thanks — two clarifications:

  1. Template: the description was accidentally submitted empty and has since been edited to fill all template sections (Overview / Additional information / Requirements / AI usage disclosure).

  2. AI disclosure, explicitly: the implementation was written with substantial AI assistance (Claude), under my direction — the design decisions (using the existing TQ2_0 format rather than a custom one, dedicated mmv first with MMQ/int-dot deferred, Q2_K-style thread layout) and all validation were mine: parity criteria and runs on real hardware (RX 9070 XT / RDNA4), test-backend-ops 21/21 vs the CPU reference, and the perf measurements in the description. The Co-Authored-By trailer on the test commit reflects this.

If this level of AI involvement falls outside what the project accepts, I understand and will defer to maintainer judgment — happy to rework, split, or close as preferred.

@github-actions github-actions Bot added testing Everything test related Vulkan Issues specific to the Vulkan backend ggml changes relating to the ggml tensor library for machine learning labels Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ggml changes relating to the ggml tensor library for machine learning testing Everything test related Vulkan Issues specific to the Vulkan backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant