whispercpp 1.3.7 → 1.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -4
  3. data/ext/options.rb +1 -1
  4. data/ext/ruby_whisper.c +0 -1
  5. data/ext/ruby_whisper.h +7 -1
  6. data/ext/ruby_whisper_context.c +50 -1
  7. data/ext/ruby_whisper_log_settable.h +1 -2
  8. data/ext/ruby_whisper_params.c +9 -8
  9. data/ext/ruby_whisper_transcribe.cpp +0 -19
  10. data/ext/ruby_whisper_vad_context.c +30 -10
  11. data/ext/ruby_whisper_vad_context_detect.cpp +8 -9
  12. data/ext/ruby_whisper_vad_params.c +4 -4
  13. data/ext/ruby_whisper_vad_segment.c +2 -2
  14. data/ext/sources/CMakeLists.txt +2 -1
  15. data/ext/sources/cmake/parakeet.pc.in +2 -2
  16. data/ext/sources/cmake/whisper.pc.in +2 -2
  17. data/ext/sources/examples/cli/cli.cpp +9 -1
  18. data/ext/sources/examples/common-ggml.cpp +2 -0
  19. data/ext/sources/examples/vad-speech-segments/speech.cpp +3 -2
  20. data/ext/sources/ggml/CMakeLists.txt +3 -4
  21. data/ext/sources/ggml/include/ggml-cuda.h +0 -3
  22. data/ext/sources/ggml/include/ggml-sycl.h +8 -0
  23. data/ext/sources/ggml/include/ggml.h +3 -1
  24. data/ext/sources/ggml/src/CMakeLists.txt +8 -1
  25. data/ext/sources/ggml/src/ggml-backend-meta.cpp +7 -4
  26. data/ext/sources/ggml/src/ggml-common.h +13 -2
  27. data/ext/sources/ggml/src/ggml-cpu/CMakeLists.txt +1 -1
  28. data/ext/sources/ggml/src/ggml-cpu/amx/mmq.cpp +5 -6
  29. data/ext/sources/ggml/src/ggml-cpu/arch/arm/quants.c +78 -4
  30. data/ext/sources/ggml/src/ggml-cpu/arch/x86/quants.c +142 -4
  31. data/ext/sources/ggml/src/ggml-cpu/arch-fallback.h +7 -2
  32. data/ext/sources/ggml/src/ggml-cpu/ggml-cpu.c +14 -0
  33. data/ext/sources/ggml/src/ggml-cpu/llamafile/sgemm.cpp +26 -19
  34. data/ext/sources/ggml/src/ggml-cpu/ops.cpp +129 -46
  35. data/ext/sources/ggml/src/ggml-cpu/quants.c +51 -0
  36. data/ext/sources/ggml/src/ggml-cpu/quants.h +3 -0
  37. data/ext/sources/ggml/src/ggml-cpu/simd-gemm.h +1 -1
  38. data/ext/sources/ggml/src/ggml-cpu/simd-mappings.h +11 -0
  39. data/ext/sources/ggml/src/ggml-cpu/vec.cpp +2 -2
  40. data/ext/sources/ggml/src/ggml-cuda/binbcast.cu +90 -46
  41. data/ext/sources/ggml/src/ggml-cuda/col2im-1d.cu +81 -0
  42. data/ext/sources/ggml/src/ggml-cuda/col2im-1d.cuh +3 -0
  43. data/ext/sources/ggml/src/ggml-cuda/common.cuh +4 -0
  44. data/ext/sources/ggml/src/ggml-cuda/concat.cu +33 -21
  45. data/ext/sources/ggml/src/ggml-cuda/conv-transpose-1d.cu +14 -12
  46. data/ext/sources/ggml/src/ggml-cuda/convert.cu +86 -34
  47. data/ext/sources/ggml/src/ggml-cuda/cpy.cu +80 -29
  48. data/ext/sources/ggml/src/ggml-cuda/fattn-common.cuh +9 -5
  49. data/ext/sources/ggml/src/ggml-cuda/fattn-mma-f16.cuh +4 -0
  50. data/ext/sources/ggml/src/ggml-cuda/fattn-tile.cuh +9 -5
  51. data/ext/sources/ggml/src/ggml-cuda/fattn.cu +27 -21
  52. data/ext/sources/ggml/src/ggml-cuda/gated_delta_net.cu +40 -25
  53. data/ext/sources/ggml/src/ggml-cuda/gated_delta_net.cuh +10 -0
  54. data/ext/sources/ggml/src/ggml-cuda/getrows.cu +15 -12
  55. data/ext/sources/ggml/src/ggml-cuda/ggml-cuda.cu +718 -1248
  56. data/ext/sources/ggml/src/ggml-cuda/mmq.cu +7 -0
  57. data/ext/sources/ggml/src/ggml-cuda/mmvq.cu +77 -40
  58. data/ext/sources/ggml/src/ggml-cuda/out-prod.cu +55 -12
  59. data/ext/sources/ggml/src/ggml-cuda/set-rows.cu +64 -4
  60. data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_2.cu +1 -0
  61. data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_32-ncols2_2.cu +1 -0
  62. data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_2.cu +1 -0
  63. data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_2.cu +1 -0
  64. data/ext/sources/ggml/src/ggml-cuda/topk-moe.cu +7 -1
  65. data/ext/sources/ggml/src/ggml-cuda/vendors/hip.h +1 -0
  66. data/ext/sources/ggml/src/ggml-cuda/vendors/musa.h +1 -0
  67. data/ext/sources/ggml/src/ggml-hexagon/CMakeLists.txt +0 -5
  68. data/ext/sources/ggml/src/ggml-hexagon/ggml-hexagon.cpp +1634 -1293
  69. data/ext/sources/ggml/src/ggml-hexagon/htp/CMakeLists.txt +11 -40
  70. data/ext/sources/ggml/src/ggml-hexagon/htp/cmake-toolchain.cmake +13 -15
  71. data/ext/sources/ggml/src/ggml-hexagon/htp/concat-ops.c +1 -1
  72. data/ext/sources/ggml/src/ggml-hexagon/htp/flash-attn-ops.c +1749 -399
  73. data/ext/sources/ggml/src/ggml-hexagon/htp/flash-attn-ops.h +303 -0
  74. data/ext/sources/ggml/src/ggml-hexagon/htp/hex-common.h +80 -0
  75. data/ext/sources/ggml/src/ggml-hexagon/htp/hex-dma.h +26 -23
  76. data/ext/sources/ggml/src/ggml-hexagon/htp/hex-profile.h +64 -0
  77. data/ext/sources/ggml/src/ggml-hexagon/htp/hex-utils.h +1 -83
  78. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-fa-kernels.h +555 -0
  79. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-mm-kernels-tiled.h +1303 -0
  80. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-queue.c +9 -0
  81. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-queue.h +27 -4
  82. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-utils.h +59 -37
  83. data/ext/sources/ggml/src/ggml-hexagon/htp/htp-ctx.h +11 -3
  84. data/ext/sources/ggml/src/ggml-hexagon/htp/htp-ops.h +52 -12
  85. data/ext/sources/ggml/src/ggml-hexagon/htp/htp-vtcm.h +19 -0
  86. data/ext/sources/ggml/src/ggml-hexagon/htp/htp_iface.idl +2 -1
  87. data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-base.h +14 -30
  88. data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-exp.h +39 -0
  89. data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-fa-kernels.h +232 -0
  90. data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-mm-kernels-flat.h +1511 -0
  91. data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-mm-kernels-tiled.h +1200 -0
  92. data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-sigmoid.h +39 -0
  93. data/ext/sources/ggml/src/ggml-hexagon/htp/main.c +127 -32
  94. data/ext/sources/ggml/src/ggml-hexagon/htp/matmul-ops.c +3023 -4425
  95. data/ext/sources/ggml/src/ggml-hexagon/htp/matmul-ops.h +650 -0
  96. data/ext/sources/ggml/src/ggml-hexagon/htp/rope-ops.c +48 -13
  97. data/ext/sources/ggml/src/ggml-hexagon/htp/ssm-conv.c +10 -9
  98. data/ext/sources/ggml/src/ggml-hexagon/htp/worker-pool.c +15 -3
  99. data/ext/sources/ggml/src/ggml-hexagon/htp/worker-pool.h +8 -0
  100. data/ext/sources/ggml/src/ggml-hexagon/htp-opnode.h +168 -50
  101. data/ext/sources/ggml/src/ggml-hexagon/libggml-htp.inf +0 -4
  102. data/ext/sources/ggml/src/ggml-hip/CMakeLists.txt +5 -0
  103. data/ext/sources/ggml/src/ggml-metal/ggml-metal-device.cpp +69 -5
  104. data/ext/sources/ggml/src/ggml-metal/ggml-metal-device.h +4 -1
  105. data/ext/sources/ggml/src/ggml-metal/ggml-metal-device.m +27 -6
  106. data/ext/sources/ggml/src/ggml-metal/ggml-metal-impl.h +38 -0
  107. data/ext/sources/ggml/src/ggml-metal/ggml-metal-ops.cpp +132 -2
  108. data/ext/sources/ggml/src/ggml-metal/ggml-metal-ops.h +2 -0
  109. data/ext/sources/ggml/src/ggml-metal/ggml-metal.metal +345 -87
  110. data/ext/sources/ggml/src/ggml-opencl/CMakeLists.txt +13 -0
  111. data/ext/sources/ggml/src/ggml-opencl/fa_tune.h +92 -0
  112. data/ext/sources/ggml/src/ggml-opencl/ggml-opencl.cpp +4060 -357
  113. data/ext/sources/ggml/src/ggml-opencl/kernels/cvt.cl +198 -0
  114. data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f16.cl +81 -41
  115. data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f32.cl +88 -39
  116. data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f32_f16.cl +1995 -96
  117. data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f32_q4_0.cl +1615 -0
  118. data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f32_q8_0.cl +1486 -0
  119. data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_pre_f16.cl +156 -0
  120. data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_mxfp4_f32_ns.cl +74 -6
  121. data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q4_0_f32_ns.cl +74 -6
  122. data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q4_1_f32_ns.cl +74 -6
  123. data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q4_k_f32_ns.cl +71 -6
  124. data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q5_0_f32_ns.cl +74 -6
  125. data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q5_1_f32_ns.cl +74 -6
  126. data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q5_k_f32_ns.cl +74 -6
  127. data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q6_k_f32_ns.cl +74 -6
  128. data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q1_0_f32.cl +94 -0
  129. data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q1_0_f32.cl +121 -0
  130. data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q8_0_f32.cl +1 -1
  131. data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mm_q1_0_f32_l4_lm.cl +156 -0
  132. data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_l4.cl +1149 -0
  133. data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q1_0_f32.cl +141 -0
  134. data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q1_0_f32_flat.cl +190 -0
  135. data/ext/sources/ggml/src/ggml-opencl/kernels/norm.cl +5 -2
  136. data/ext/sources/ggml/src/ggml-opencl/kernels/set_rows.cl +500 -0
  137. data/ext/sources/ggml/src/ggml-opencl/libdl.h +79 -0
  138. data/ext/sources/ggml/src/ggml-openvino/.clang-format +0 -5
  139. data/ext/sources/ggml/src/ggml-openvino/CMakeLists.txt +2 -4
  140. data/ext/sources/ggml/src/ggml-openvino/ggml-decoder.cpp +733 -130
  141. data/ext/sources/ggml/src/ggml-openvino/ggml-decoder.h +76 -23
  142. data/ext/sources/ggml/src/ggml-openvino/ggml-openvino-extra.cpp +57 -3
  143. data/ext/sources/ggml/src/ggml-openvino/ggml-openvino-extra.h +29 -8
  144. data/ext/sources/ggml/src/ggml-openvino/ggml-openvino.cpp +307 -59
  145. data/ext/sources/ggml/src/ggml-openvino/ggml-quants.cpp +66 -0
  146. data/ext/sources/ggml/src/ggml-openvino/ggml-quants.h +10 -4
  147. data/ext/sources/ggml/src/ggml-openvino/openvino/decoder.h +56 -16
  148. data/ext/sources/ggml/src/ggml-openvino/openvino/frontend.h +1 -1
  149. data/ext/sources/ggml/src/ggml-openvino/openvino/input_model.h +4 -4
  150. data/ext/sources/ggml/src/ggml-openvino/openvino/node_context.h +94 -37
  151. data/ext/sources/ggml/src/ggml-openvino/openvino/op/add_id.cpp +76 -0
  152. data/ext/sources/ggml/src/ggml-openvino/openvino/op/argsort.cpp +47 -0
  153. data/ext/sources/ggml/src/ggml-openvino/openvino/op/clamp.cpp +33 -0
  154. data/ext/sources/ggml/src/ggml-openvino/openvino/op/concat.cpp +48 -0
  155. data/ext/sources/ggml/src/ggml-openvino/openvino/op/cont.cpp +8 -16
  156. data/ext/sources/ggml/src/ggml-openvino/openvino/op/cpy.cpp +14 -1
  157. data/ext/sources/ggml/src/ggml-openvino/openvino/op/div.cpp +146 -0
  158. data/ext/sources/ggml/src/ggml-openvino/openvino/op/flash_attn_ext.cpp +108 -21
  159. data/ext/sources/ggml/src/ggml-openvino/openvino/op/gated_delta_net.cpp +282 -0
  160. data/ext/sources/ggml/src/ggml-openvino/openvino/op/gated_delta_net.hpp +65 -0
  161. data/ext/sources/ggml/src/ggml-openvino/openvino/op/get_rows.cpp +2 -9
  162. data/ext/sources/ggml/src/ggml-openvino/openvino/op/glu_geglu.cpp +21 -7
  163. data/ext/sources/ggml/src/ggml-openvino/openvino/op/glu_swiglu.cpp +41 -8
  164. data/ext/sources/ggml/src/ggml-openvino/openvino/op/im2col.cpp +120 -0
  165. data/ext/sources/ggml/src/ggml-openvino/openvino/op/l2_norm.cpp +44 -0
  166. data/ext/sources/ggml/src/ggml-openvino/openvino/op/mul_mat_id.cpp +226 -0
  167. data/ext/sources/ggml/src/ggml-openvino/openvino/op/mulmat.cpp +19 -9
  168. data/ext/sources/ggml/src/ggml-openvino/openvino/op/norm.cpp +58 -0
  169. data/ext/sources/ggml/src/ggml-openvino/openvino/op/pad.cpp +95 -0
  170. data/ext/sources/ggml/src/ggml-openvino/openvino/op/permute.cpp +58 -13
  171. data/ext/sources/ggml/src/ggml-openvino/openvino/op/repeat.cpp +74 -0
  172. data/ext/sources/ggml/src/ggml-openvino/openvino/op/reshape.cpp +13 -6
  173. data/ext/sources/ggml/src/ggml-openvino/openvino/op/rms_norm.cpp +1 -1
  174. data/ext/sources/ggml/src/ggml-openvino/openvino/op/rope.cpp +134 -38
  175. data/ext/sources/ggml/src/ggml-openvino/openvino/op/set_rows.cpp +3 -3
  176. data/ext/sources/ggml/src/ggml-openvino/openvino/op/softmax.cpp +126 -49
  177. data/ext/sources/ggml/src/ggml-openvino/openvino/op/ssm_conv.cpp +59 -0
  178. data/ext/sources/ggml/src/ggml-openvino/openvino/op/sum_rows.cpp +27 -0
  179. data/ext/sources/ggml/src/ggml-openvino/openvino/op/transpose.cpp +32 -1
  180. data/ext/sources/ggml/src/ggml-openvino/openvino/op/unary_silu.cpp +1 -1
  181. data/ext/sources/ggml/src/ggml-openvino/openvino/op/unary_softplus.cpp +38 -0
  182. data/ext/sources/ggml/src/ggml-openvino/openvino/op/view.cpp +90 -25
  183. data/ext/sources/ggml/src/ggml-openvino/openvino/op_table.cpp +41 -23
  184. data/ext/sources/ggml/src/ggml-openvino/openvino/op_table.h +18 -5
  185. data/ext/sources/ggml/src/ggml-openvino/openvino/pass/mark_decompression_convert_constant_folding.h +1 -1
  186. data/ext/sources/ggml/src/ggml-openvino/openvino/translate_session.cpp +43 -40
  187. data/ext/sources/ggml/src/ggml-openvino/openvino/translate_session.h +5 -4
  188. data/ext/sources/ggml/src/ggml-openvino/openvino/utils.cpp +548 -3
  189. data/ext/sources/ggml/src/ggml-openvino/openvino/utils.h +28 -26
  190. data/ext/sources/ggml/src/ggml-openvino/utils.cpp +383 -94
  191. data/ext/sources/ggml/src/ggml-openvino/utils.h +11 -8
  192. data/ext/sources/ggml/src/ggml-quants.c +76 -0
  193. data/ext/sources/ggml/src/ggml-quants.h +3 -0
  194. data/ext/sources/ggml/src/ggml-sycl/CMakeLists.txt +5 -5
  195. data/ext/sources/ggml/src/ggml-sycl/backend.hpp +2 -0
  196. data/ext/sources/ggml/src/ggml-sycl/binbcast.cpp +12 -0
  197. data/ext/sources/ggml/src/ggml-sycl/col2im-1d.cpp +102 -0
  198. data/ext/sources/ggml/src/ggml-sycl/col2im-1d.hpp +8 -0
  199. data/ext/sources/ggml/src/ggml-sycl/common.cpp +6 -8
  200. data/ext/sources/ggml/src/ggml-sycl/common.hpp +19 -2
  201. data/ext/sources/ggml/src/ggml-sycl/concat.cpp +21 -1
  202. data/ext/sources/ggml/src/ggml-sycl/conv2d-dw.cpp +158 -0
  203. data/ext/sources/ggml/src/ggml-sycl/conv2d-dw.hpp +10 -0
  204. data/ext/sources/ggml/src/ggml-sycl/conv2d-transpose.cpp +125 -0
  205. data/ext/sources/ggml/src/ggml-sycl/conv2d-transpose.hpp +10 -0
  206. data/ext/sources/ggml/src/ggml-sycl/conv2d.cpp +150 -0
  207. data/ext/sources/ggml/src/ggml-sycl/conv2d.hpp +10 -0
  208. data/ext/sources/ggml/src/ggml-sycl/conv3d.cpp +224 -0
  209. data/ext/sources/ggml/src/ggml-sycl/conv3d.hpp +8 -0
  210. data/ext/sources/ggml/src/ggml-sycl/convert.cpp +6 -0
  211. data/ext/sources/ggml/src/ggml-sycl/cpy.cpp +706 -0
  212. data/ext/sources/ggml/src/ggml-sycl/cpy.hpp +281 -0
  213. data/ext/sources/ggml/src/ggml-sycl/cross_entropy_loss.cpp +255 -0
  214. data/ext/sources/ggml/src/ggml-sycl/cross_entropy_loss.hpp +7 -0
  215. data/ext/sources/ggml/src/ggml-sycl/dequantize.hpp +15 -0
  216. data/ext/sources/ggml/src/ggml-sycl/dmmv.cpp +492 -319
  217. data/ext/sources/ggml/src/ggml-sycl/dpct/helper.hpp +15 -7
  218. data/ext/sources/ggml/src/ggml-sycl/element_wise.cpp +215 -115
  219. data/ext/sources/ggml/src/ggml-sycl/element_wise.hpp +2 -0
  220. data/ext/sources/ggml/src/ggml-sycl/ggml-sycl.cpp +1006 -336
  221. data/ext/sources/ggml/src/ggml-sycl/mmvq.cpp +252 -67
  222. data/ext/sources/ggml/src/ggml-sycl/mmvq.hpp +17 -0
  223. data/ext/sources/ggml/src/ggml-sycl/norm.cpp +103 -49
  224. data/ext/sources/ggml/src/ggml-sycl/outprod.cpp +45 -9
  225. data/ext/sources/ggml/src/ggml-sycl/pool.cpp +185 -0
  226. data/ext/sources/ggml/src/ggml-sycl/pool.hpp +22 -0
  227. data/ext/sources/ggml/src/ggml-sycl/presets.hpp +3 -1
  228. data/ext/sources/ggml/src/ggml-sycl/set_rows.cpp +10 -2
  229. data/ext/sources/ggml/src/ggml-sycl/softmax.cpp +9 -10
  230. data/ext/sources/ggml/src/ggml-sycl/vecdotq.hpp +35 -0
  231. data/ext/sources/ggml/src/ggml-vulkan/CMakeLists.txt +5 -0
  232. data/ext/sources/ggml/src/ggml-vulkan/ggml-vulkan.cpp +833 -215
  233. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/col2im_1d.comp +61 -0
  234. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/conv2d_mm.comp +1 -1
  235. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/conv3d_mm.comp +431 -0
  236. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/diag.comp +3 -3
  237. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn.comp +1 -0
  238. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_cm1.comp +1 -0
  239. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/generic_unary_head.glsl +21 -19
  240. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/get_rows_back.comp +25 -0
  241. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/glu_head.glsl +23 -4
  242. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/glu_main.glsl +14 -18
  243. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/l2_norm.comp +4 -7
  244. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vecq.comp +21 -24
  245. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm.comp +31 -23
  246. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_cm2.comp +6 -5
  247. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_funcs.glsl +84 -67
  248. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/norm.comp +10 -10
  249. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/repeat_back.comp +3 -3
  250. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/roll.comp +3 -3
  251. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/tri.comp +3 -3
  252. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/unary.comp +168 -0
  253. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp +121 -74
  254. data/ext/sources/ggml/src/ggml-webgpu/ggml-webgpu-shader-lib.hpp +26 -19
  255. data/ext/sources/ggml/src/ggml-webgpu/ggml-webgpu.cpp +31 -36
  256. data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/common_decls.tmpl +16 -2
  257. data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_vec_split.wgsl +7 -7
  258. data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/get_rows.wgsl +21 -0
  259. data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_decls.tmpl +439 -320
  260. data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_id_vec.wgsl +2 -2
  261. data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec.wgsl +45 -39
  262. data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec_acc.tmpl +586 -465
  263. data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec_q_acc.tmpl +63 -69
  264. data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/quantize_q8.wgsl +14 -9
  265. data/ext/sources/ggml/src/ggml.c +36 -14
  266. data/ext/sources/include/whisper.h +21 -0
  267. data/ext/sources/src/whisper.cpp +164 -14
  268. data/lib/whisper/log_settable.rb +5 -8
  269. data/lib/whisper/model/uri.rb +0 -7
  270. data/sig/whisper.rbs +6 -0
  271. data/test/test_vad.rb +9 -0
  272. data/test/test_vad_context.rb +2 -2
  273. data/whispercpp.gemspec +1 -1
  274. metadata +62 -37
  275. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-flash-attn-ops.c +0 -1878
  276. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-matmul-ops.c +0 -2066
  277. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-ops.c +0 -6
  278. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-ops.h +0 -88
  279. data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-profile.h +0 -34
  280. data/ext/sources/ggml/src/ggml-hexagon/htp/vtcm-utils.h +0 -16
  281. data/ext/sources/ggml/src/ggml-openvino/openvino/op/unary_gelu.cpp +0 -25
  282. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/abs.comp +0 -21
  283. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/ceil.comp +0 -22
  284. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/clamp.comp +0 -17
  285. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/cos.comp +0 -17
  286. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/elu.comp +0 -27
  287. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/exp.comp +0 -20
  288. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/floor.comp +0 -22
  289. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/gelu.comp +0 -25
  290. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/gelu_erf.comp +0 -39
  291. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/gelu_quick.comp +0 -23
  292. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/hardsigmoid.comp +0 -22
  293. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/hardswish.comp +0 -22
  294. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/leaky_relu.comp +0 -22
  295. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/neg.comp +0 -20
  296. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/relu.comp +0 -21
  297. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/round.comp +0 -29
  298. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/sgn.comp +0 -21
  299. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/sigmoid.comp +0 -20
  300. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/silu.comp +0 -22
  301. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/sin.comp +0 -17
  302. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/softplus.comp +0 -23
  303. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/sqrt.comp +0 -17
  304. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/square.comp +0 -17
  305. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/step.comp +0 -22
  306. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/tanh.comp +0 -20
  307. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/trunc.comp +0 -22
  308. data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/xielu.comp +0 -35
@@ -905,11 +905,12 @@ struct ggml_webgpu_mul_mat_vec_pipeline_key {
905
905
  ggml_type src0_type;
906
906
  ggml_type src1_type;
907
907
  int vectorized;
908
+ uint32_t num_cols;
908
909
  bool use_mmvq;
909
910
 
910
911
  bool operator==(const ggml_webgpu_mul_mat_vec_pipeline_key & other) const {
911
912
  return src0_type == other.src0_type && src1_type == other.src1_type && vectorized == other.vectorized &&
912
- use_mmvq == other.use_mmvq;
913
+ num_cols == other.num_cols && use_mmvq == other.use_mmvq;
913
914
  }
914
915
  };
915
916
 
@@ -919,6 +920,7 @@ struct ggml_webgpu_mul_mat_vec_pipeline_key_hash {
919
920
  ggml_webgpu_hash_combine(seed, key.src0_type);
920
921
  ggml_webgpu_hash_combine(seed, key.src1_type);
921
922
  ggml_webgpu_hash_combine(seed, key.vectorized);
923
+ ggml_webgpu_hash_combine(seed, key.num_cols);
922
924
  ggml_webgpu_hash_combine(seed, key.use_mmvq);
923
925
  return seed;
924
926
  }
@@ -993,11 +995,12 @@ struct ggml_webgpu_mul_mat_id_pipeline_key {
993
995
  ggml_type src0_type;
994
996
  ggml_type src1_type;
995
997
  uint32_t n_experts;
998
+ uint32_t num_cols;
996
999
  int vectorized;
997
1000
 
998
1001
  bool operator==(const ggml_webgpu_mul_mat_id_pipeline_key & other) const {
999
1002
  return src0_type == other.src0_type && src1_type == other.src1_type && n_experts == other.n_experts &&
1000
- vectorized == other.vectorized;
1003
+ num_cols == other.num_cols && vectorized == other.vectorized;
1001
1004
  }
1002
1005
  };
1003
1006
 
@@ -1007,6 +1010,7 @@ struct ggml_webgpu_mul_mat_id_pipeline_key_hash {
1007
1010
  ggml_webgpu_hash_combine(seed, key.src0_type);
1008
1011
  ggml_webgpu_hash_combine(seed, key.src1_type);
1009
1012
  ggml_webgpu_hash_combine(seed, key.n_experts);
1013
+ ggml_webgpu_hash_combine(seed, key.num_cols);
1010
1014
  ggml_webgpu_hash_combine(seed, key.vectorized);
1011
1015
  return seed;
1012
1016
  }
@@ -1107,7 +1111,7 @@ inline bool ggml_webgpu_can_use_mmvq(const ggml_tensor * src0,
1107
1111
  const ggml_tensor * src1,
1108
1112
  bool supports_dot_product,
1109
1113
  const std::string & vendor) {
1110
- if (src1->ne[1] == 1) {
1114
+ if (src1->ne[1] <= 4) {
1111
1115
  bool supports_dp4a = vendor == "amd" || vendor == "intel" || vendor == "nvidia";
1112
1116
  if (supports_dp4a && supports_dot_product) {
1113
1117
  switch (src1->type) {
@@ -1559,6 +1563,7 @@ class ggml_webgpu_shader_lib {
1559
1563
  case GGML_TYPE_IQ1_S:
1560
1564
  case GGML_TYPE_IQ4_NL:
1561
1565
  case GGML_TYPE_MXFP4:
1566
+ case GGML_TYPE_NVFP4:
1562
1567
  {
1563
1568
  // Quantized types using u32 buffers for portability.
1564
1569
  defines.push_back("SRC_TYPE=u32");
@@ -1589,6 +1594,8 @@ class ggml_webgpu_shader_lib {
1589
1594
  } else if ((key.src_type >= GGML_TYPE_Q4_0 && key.src_type <= GGML_TYPE_Q8_1) ||
1590
1595
  key.src_type == GGML_TYPE_IQ4_NL || key.src_type == GGML_TYPE_MXFP4) {
1591
1596
  defines.push_back("BLOCK_SIZE=32u");
1597
+ } else if (key.src_type == GGML_TYPE_NVFP4) {
1598
+ defines.push_back("BLOCK_SIZE=64u");
1592
1599
  } else if (key.src_type >= GGML_TYPE_Q2_K) {
1593
1600
  defines.push_back("BLOCK_SIZE=256u");
1594
1601
  } else {
@@ -1889,6 +1896,7 @@ class ggml_webgpu_shader_lib {
1889
1896
  (context.src0->type == GGML_TYPE_F32 || context.src0->type == GGML_TYPE_F16)) ?
1890
1897
  1 :
1891
1898
  0;
1899
+ key.num_cols = context.dst->ne[1];
1892
1900
  key.use_mmvq =
1893
1901
  ggml_webgpu_can_use_mmvq(context.src0, context.src1, context.supports_dot_product, context.vendor);
1894
1902
 
@@ -1955,6 +1963,7 @@ class ggml_webgpu_shader_lib {
1955
1963
  defines.push_back(type_upper + "_TABLES");
1956
1964
  break;
1957
1965
  case GGML_TYPE_MXFP4:
1966
+ case GGML_TYPE_NVFP4:
1958
1967
  defines.push_back(type_upper + "_LUT");
1959
1968
  break;
1960
1969
  default:
@@ -2004,6 +2013,7 @@ class ggml_webgpu_shader_lib {
2004
2013
  if (key.vectorized) {
2005
2014
  variant += "_vectorized";
2006
2015
  }
2016
+ defines.push_back(std::string("NUM_COLS=") + std::to_string(key.num_cols));
2007
2017
 
2008
2018
  auto processed = preprocessor.preprocess(shader_src, defines);
2009
2019
  auto decisions = std::make_shared<ggml_webgpu_mul_mat_vec_shader_decisions>();
@@ -2097,6 +2107,7 @@ class ggml_webgpu_shader_lib {
2097
2107
  defines.push_back(type_upper + "_TABLES");
2098
2108
  break;
2099
2109
  case GGML_TYPE_MXFP4:
2110
+ case GGML_TYPE_NVFP4:
2100
2111
  defines.push_back(type_upper + "_LUT");
2101
2112
  break;
2102
2113
  default:
@@ -2268,6 +2279,7 @@ class ggml_webgpu_shader_lib {
2268
2279
  defines.push_back(type_upper + "_TABLES");
2269
2280
  break;
2270
2281
  case GGML_TYPE_MXFP4:
2282
+ case GGML_TYPE_NVFP4:
2271
2283
  defines.push_back(type_upper + "_LUT");
2272
2284
  break;
2273
2285
  default:
@@ -2388,6 +2400,7 @@ class ggml_webgpu_shader_lib {
2388
2400
  defines.push_back(type_upper + "_TABLES");
2389
2401
  break;
2390
2402
  case GGML_TYPE_MXFP4:
2403
+ case GGML_TYPE_NVFP4:
2391
2404
  defines.push_back(type_upper + "_LUT");
2392
2405
  break;
2393
2406
  default:
@@ -2421,6 +2434,7 @@ class ggml_webgpu_shader_lib {
2421
2434
  if (key.vectorized) {
2422
2435
  variant += "_vectorized";
2423
2436
  }
2437
+ defines.push_back(std::string("NUM_COLS=1"));
2424
2438
 
2425
2439
  defines.push_back(std::string("N_EXPERTS=") + std::to_string(key.n_experts));
2426
2440
 
@@ -2807,23 +2821,16 @@ class ggml_webgpu_shader_lib {
2807
2821
  variant.resize(variant.size() - (sizeof("_mask") - 1));
2808
2822
  variant += "_mask_blk";
2809
2823
  }
2810
- uint32_t vec_ne = 1u;
2811
- if (key.common.k_type == GGML_TYPE_F16 && key.common.v_type == GGML_TYPE_F16 &&
2812
- key.common.head_dim_qk == key.common.head_dim_v) {
2813
- switch (key.common.head_dim_qk) {
2814
- case 64:
2815
- case 192:
2816
- case 576:
2817
- vec_ne = 2u;
2818
- break;
2819
- case 96:
2820
- vec_ne = 4u;
2821
- break;
2822
- default:
2823
- break;
2824
- }
2824
+
2825
+ uint32_t d_split = context.min_subgroup_size;
2826
+ if (key.common.k_type == GGML_TYPE_F16 && key.common.v_type == GGML_TYPE_F16) {
2827
+ const uint32_t D = key.common.head_dim_qk | key.common.head_dim_v;
2828
+ const uint32_t D_lsb = D & (~(D - 1u));
2829
+ d_split = std::min(std::min(context.min_subgroup_size, 4u), std::max(D_lsb / 4u, 1u));
2825
2830
  }
2826
- defines.push_back(std::string("VEC_NE=") + std::to_string(vec_ne) + "u");
2831
+
2832
+ defines.push_back(std::string("D_SPLIT=") + std::to_string(d_split));
2833
+ variant += "_dsplit" + std::to_string(d_split);
2827
2834
 
2828
2835
  auto pipeline_decisions = std::make_shared<ggml_webgpu_flash_attn_vec_decisions>(decisions);
2829
2836
  webgpu_pipeline pipeline =
@@ -1418,15 +1418,17 @@ static void ggml_webgpu_quantize_q8_dispatch(webgpu_context &
1418
1418
  const size_t dst_offset = ggml_webgpu_tensor_offset(dst);
1419
1419
  const size_t q8_src1_align_offset = ROUNDUP_POW2(
1420
1420
  dst_offset + ggml_nbytes(dst), ctx->global_ctx->capabilities.limits.minStorageBufferOffsetAlignment);
1421
- const size_t q8_src1_binding_size =
1422
- ROUNDUP_POW2(src1->ne[3] * src1->ne[2] * (36 /* sizeof(q8_1) */ * (src1->ne[0] / /* block_size */ 32)),
1423
- WEBGPU_STORAGE_BUF_BINDING_MULT);
1421
+ const size_t q8_src1_binding_size = ROUNDUP_POW2(
1422
+ src1->ne[3] * src1->ne[2] * src1->ne[1] * (36 /* sizeof(q8_1) */ * (src1->ne[0] / /* block_size */ 32)),
1423
+ WEBGPU_STORAGE_BUF_BINDING_MULT);
1424
1424
 
1425
1425
  std::vector<uint32_t> q8_params = {
1426
1426
  (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
1427
+ (uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
1427
1428
  (uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
1428
1429
  (uint32_t) (src1->nb[3] / ggml_type_size(src1->type)),
1429
1430
  (uint32_t) src1->ne[0],
1431
+ (uint32_t) src1->ne[1],
1430
1432
  (uint32_t) src1->ne[2],
1431
1433
  (uint32_t) src1->ne[3],
1432
1434
  };
@@ -1442,7 +1444,7 @@ static void ggml_webgpu_quantize_q8_dispatch(webgpu_context &
1442
1444
  uint32_t q8_wg_x = 1;
1443
1445
  uint32_t q8_wg_y = 1;
1444
1446
  const uint32_t wg_per_vec = (src0->ne[0] / 4 + (q8_wg_size - 1)) / q8_wg_size;
1445
- const uint32_t q8_total_wg = src1->ne[2] * src1->ne[3] * wg_per_vec;
1447
+ const uint32_t q8_total_wg = src1->ne[1] * src1->ne[2] * src1->ne[3] * wg_per_vec;
1446
1448
  const uint32_t max_wg_per_dim = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension;
1447
1449
  compute_2d_workgroups(q8_total_wg, max_wg_per_dim, q8_wg_x, q8_wg_y);
1448
1450
 
@@ -1456,7 +1458,7 @@ static webgpu_encoded_op ggml_webgpu_mul_mat(webgpu_context & ctx,
1456
1458
  ggml_tensor * src1,
1457
1459
  ggml_tensor * dst) {
1458
1460
  // Determine if this is a mat-vec operation
1459
- bool is_vec = (dst->ne[1] == 1);
1461
+ bool use_mat_vec = (dst->ne[1] <= 4);
1460
1462
 
1461
1463
  // use MMVQ path for mat-vec
1462
1464
  bool use_mmvq = ggml_webgpu_can_use_mmvq(src0, src1, ctx->global_ctx->capabilities.supports_dot_product,
@@ -1482,7 +1484,7 @@ static webgpu_encoded_op ggml_webgpu_mul_mat(webgpu_context & ctx,
1482
1484
  webgpu_pipeline pipeline;
1483
1485
  std::vector<webgpu_dispatch_desc> dispatches;
1484
1486
 
1485
- if (is_vec) {
1487
+ if (use_mat_vec) {
1486
1488
  if (use_mmvq) {
1487
1489
  ggml_webgpu_quantize_q8_dispatch(ctx, src0, src1, dst, dispatches);
1488
1490
  }
@@ -1529,7 +1531,7 @@ static webgpu_encoded_op ggml_webgpu_mul_mat(webgpu_context & ctx,
1529
1531
  uint32_t wg_y = 1;
1530
1532
  const uint32_t max_wg_per_dim = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension;
1531
1533
 
1532
- if (is_vec) {
1534
+ if (use_mat_vec) {
1533
1535
  auto * decisions = static_cast<ggml_webgpu_mul_mat_vec_shader_decisions *>(pipeline.context.get());
1534
1536
 
1535
1537
  uint32_t batches = dst->ne[2] * dst->ne[3];
@@ -3691,8 +3693,8 @@ static size_t ggml_backend_webgpu_buffer_type_get_alloc_size(ggml_backend_buffer
3691
3693
  ggml_webgpu_can_use_mmvq(src0, src1, ctx->webgpu_global_ctx->capabilities.supports_dot_product,
3692
3694
  ctx->webgpu_global_ctx->vendor);
3693
3695
  if (use_mmvq) {
3694
- const size_t q8_src1_size =
3695
- src1->ne[3] * src1->ne[2] * (36 /* sizeof(q8_1) */ * (src1->ne[0] / /* block_size */ 32));
3696
+ const size_t q8_src1_size = src1->ne[3] * src1->ne[2] * src1->ne[1] *
3697
+ (36 /* sizeof(q8_1) */ * (src1->ne[0] / /* block_size */ 32));
3696
3698
  res = ROUNDUP_POW2(res + q8_src1_size +
3697
3699
  ctx->webgpu_global_ctx->capabilities.limits.minStorageBufferOffsetAlignment,
3698
3700
  WEBGPU_STORAGE_BUF_BINDING_MULT);
@@ -3788,7 +3790,7 @@ static void ggml_webgpu_init_memset_pipeline(webgpu_global_context & ctx) {
3788
3790
  ctx->memset_pipeline = ggml_webgpu_create_pipeline(ctx->device, wgsl_memset, "memset", constants);
3789
3791
  }
3790
3792
 
3791
- static void create_webgpu_device(ggml_backend_webgpu_reg_context * ctx) {
3793
+ static void ggml_backend_webgpu_request_adapter(wgpu::Instance & instance, wgpu::Adapter & adapter) {
3792
3794
  wgpu::RequestAdapterOptions options = {};
3793
3795
 
3794
3796
  #ifndef __EMSCRIPTEN__
@@ -3800,17 +3802,20 @@ static void create_webgpu_device(ggml_backend_webgpu_reg_context * ctx) {
3800
3802
  options.nextInChain = &adapterTogglesDesc;
3801
3803
  #endif
3802
3804
 
3803
- ctx->webgpu_global_ctx->instance.WaitAny(
3804
- ctx->webgpu_global_ctx->instance.RequestAdapter(
3805
- &options, wgpu::CallbackMode::AllowSpontaneous,
3806
- [&ctx](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, const char * message) {
3807
- if (status != wgpu::RequestAdapterStatus::Success) {
3808
- GGML_LOG_ERROR("ggml_webgpu: Failed to get an adapter: %s\n", message);
3809
- return;
3810
- }
3811
- ctx->webgpu_global_ctx->adapter = std::move(adapter);
3812
- }),
3813
- UINT64_MAX);
3805
+ instance.WaitAny(instance.RequestAdapter(
3806
+ &options, wgpu::CallbackMode::AllowSpontaneous,
3807
+ [&adapter](wgpu::RequestAdapterStatus status, wgpu::Adapter _adapter, const char * message) {
3808
+ if (status != wgpu::RequestAdapterStatus::Success) {
3809
+ GGML_LOG_ERROR("ggml_webgpu: Failed to get an adapter: %s\n", message);
3810
+ return;
3811
+ }
3812
+ adapter = std::move(_adapter);
3813
+ }),
3814
+ UINT64_MAX);
3815
+ }
3816
+
3817
+ static void create_webgpu_device(ggml_backend_webgpu_reg_context * ctx) {
3818
+ ggml_backend_webgpu_request_adapter(ctx->webgpu_global_ctx->instance, ctx->webgpu_global_ctx->adapter);
3814
3819
  GGML_ASSERT(ctx->webgpu_global_ctx->adapter != nullptr);
3815
3820
 
3816
3821
  ctx->webgpu_global_ctx->adapter.GetLimits(&ctx->webgpu_global_ctx->capabilities.limits);
@@ -4051,6 +4056,7 @@ static bool ggml_webgpu_supported_qtype(ggml_type type) {
4051
4056
  case GGML_TYPE_IQ4_NL:
4052
4057
  case GGML_TYPE_IQ4_XS:
4053
4058
  case GGML_TYPE_MXFP4:
4059
+ case GGML_TYPE_NVFP4:
4054
4060
  return true;
4055
4061
  default:
4056
4062
  return false;
@@ -4151,6 +4157,7 @@ static bool ggml_backend_webgpu_device_supports_op(ggml_backend_dev_t dev, const
4151
4157
  case GGML_TYPE_IQ4_NL:
4152
4158
  case GGML_TYPE_IQ4_XS:
4153
4159
  case GGML_TYPE_MXFP4:
4160
+ case GGML_TYPE_NVFP4:
4154
4161
  supports_op = true;
4155
4162
  break;
4156
4163
  default:
@@ -4191,6 +4198,7 @@ static bool ggml_backend_webgpu_device_supports_op(ggml_backend_dev_t dev, const
4191
4198
  case GGML_TYPE_IQ4_NL:
4192
4199
  case GGML_TYPE_IQ4_XS:
4193
4200
  case GGML_TYPE_MXFP4:
4201
+ case GGML_TYPE_NVFP4:
4194
4202
  supports_op = true;
4195
4203
  break;
4196
4204
  default:
@@ -4265,7 +4273,7 @@ static bool ggml_backend_webgpu_device_supports_op(ggml_backend_dev_t dev, const
4265
4273
  case GGML_OP_RMS_NORM:
4266
4274
  case GGML_OP_NORM:
4267
4275
  case GGML_OP_L2_NORM:
4268
- supports_op = op->type == GGML_TYPE_F32 && src0->type == GGML_TYPE_F32;
4276
+ supports_op = (op->type == GGML_TYPE_F32 && src0->type == GGML_TYPE_F32) && ggml_is_contiguous_rows(src0);
4269
4277
  break;
4270
4278
  case GGML_OP_ROPE:
4271
4279
  supports_op = op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16;
@@ -4543,20 +4551,7 @@ ggml_backend_reg_t ggml_backend_webgpu_reg() {
4543
4551
  // Probe for adapter support
4544
4552
  wgpu::Adapter adapter;
4545
4553
  if (ctx->webgpu_global_ctx->instance != nullptr) {
4546
- wgpu::RequestAdapterOptions options = {};
4547
-
4548
- // probe for adapter support
4549
- ctx->webgpu_global_ctx->instance.WaitAny(
4550
- ctx->webgpu_global_ctx->instance.RequestAdapter(
4551
- &options, wgpu::CallbackMode::AllowSpontaneous,
4552
- [&adapter](wgpu::RequestAdapterStatus status, wgpu::Adapter _adapter, const char * message) {
4553
- if (status != wgpu::RequestAdapterStatus::Success) {
4554
- GGML_LOG_ERROR("ggml_webgpu: Failed to get an adapter: %s\n", message);
4555
- return;
4556
- }
4557
- adapter = std::move(_adapter);
4558
- }),
4559
- UINT64_MAX);
4554
+ ggml_backend_webgpu_request_adapter(ctx->webgpu_global_ctx->instance, adapter);
4560
4555
  }
4561
4556
 
4562
4557
  // WebGPU backend requires f16 support and, on native, implicit device synchronization.
@@ -896,9 +896,23 @@ const kvalues_iq4nl = array<i32, 16>(
896
896
 
897
897
  #endif
898
898
 
899
- #ifdef MXFP4_LUT
899
+ #if defined(MXFP4_LUT) || defined(NVFP4_LUT)
900
900
  const kvalues_mxfp4 = array<i32, 16>(
901
901
  0, 1, 2, 3, 4, 6, 8, 12, 0, -1, -2, -3, -4, -6, -8, -12
902
902
  );
903
- #endif
903
+ #endif // MXFP4_LUT || NVFP4_LUT
904
904
 
905
+ #ifdef NVFP4_LUT
906
+ fn ue4m3_to_fp32(u: u32) -> f32 {
907
+ if (u == 0u || u == 127u) {
908
+ return 0.0;
909
+ }
910
+ let exp = (u >> 3u) & 15u;
911
+ let man = u & 7u;
912
+ if (exp == 0u) {
913
+ return f32(man) * (1.0 / 512.0);
914
+ }
915
+ let bits = ((exp + 120u) << 23u) | (man << 20u);
916
+ return bitcast<f32>(bits);
917
+ }
918
+ #endif // NVFP4_LUT
@@ -39,9 +39,6 @@ enable subgroups;
39
39
  #define KV_GRANULARITY 8
40
40
  #define KV_TILE 16
41
41
  #define WG_SIZE 64
42
- #ifndef VEC_NE
43
- #define VEC_NE 4u
44
- #endif
45
42
 
46
43
  #define KV_BLOCKS (KV_TILE / KV_GRANULARITY)
47
44
 
@@ -367,11 +364,11 @@ fn main(@builtin(workgroup_id) wg_id: vec3<u32>,
367
364
 
368
365
  // accumulate q block * k block into registers across the entire KV tile
369
366
  if (!skip_tile) {
370
- let num_of_threads = subgroup_size / VEC_NE;
367
+ let num_of_threads:u32 = D_SPLIT;
371
368
  let tx = sg_inv_id % num_of_threads;
372
369
  let ty = sg_inv_id / num_of_threads;
373
370
  if (subgroup_id == 0u && q_row_start < params.seq_len_q) {
374
- for (var kv_base : u32 = 0u; kv_base < KV_TILE; kv_base += VEC_NE) {
371
+ for (var kv_base : u32 = 0u; kv_base < KV_TILE; kv_base += subgroup_size / D_SPLIT) {
375
372
  let kv_idx = kv_base + ty;
376
373
  var partial_sum: f32 = 0.0;
377
374
  let kv_valid = kv_idx < KV_TILE && (kv_tile + kv_idx) < params.seq_len_kv;
@@ -486,15 +483,18 @@ fn main(@builtin(workgroup_id) wg_id: vec3<u32>,
486
483
  if (!skip_tile) {
487
484
  // we have P (KV_TILE) in inter_shmem and V (KV_TILE x head_dim_v) in kv_shmem
488
485
  // we want to compute O += P * V across the full KV tile
489
- let ne_threads : u32 = VEC_NE;
486
+ let ne_threads : u32 = subgroup_size / D_SPLIT;
490
487
  let nl_threads = max(1u, subgroup_size / ne_threads);
491
488
  let tx_pv = sg_inv_id % nl_threads;
492
489
  let ty_pv = sg_inv_id / nl_threads;
493
490
  if (subgroup_id == 0u && q_row_start < params.seq_len_q) {
494
491
  for (var vec_col = tx_pv; vec_col < (HEAD_DIM_V / 4u); vec_col += nl_threads) {
495
492
  var lo = vec4<f32>(0.0, 0.0, 0.0, 0.0);
496
- for (var cc = 0u; cc < KV_TILE / ne_threads; cc += 1u) {
493
+ for (var cc = 0u; cc * ne_threads < KV_TILE; cc += 1u) {
497
494
  let kv_idx = cc * ne_threads + ty_pv;
495
+ if (kv_idx >= KV_TILE) {
496
+ continue;
497
+ }
498
498
  let v_row = kv_tile + kv_idx;
499
499
  if (v_row >= params.seq_len_kv) {
500
500
  continue;
@@ -672,6 +672,27 @@ fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
672
672
  }
673
673
  #endif
674
674
 
675
+ #ifdef NVFP4
676
+ fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
677
+ let block_byte_base = (src_base + offset) * 36;
678
+ let d_word = load_u32_at_src(block_byte_base);
679
+ for (var sub: u32 = 0u; sub < 4; sub++) {
680
+ let d = ue4m3_to_fp32(get_byte(d_word, sub)) * 0.5;
681
+ for (var j: u32 = 0u; j < 2; j++) {
682
+ let q_packed = load_u32_at_src(block_byte_base + 4 + sub * 8 + j * 4);
683
+ for (var k: u32 = 0; k < 4; k++) {
684
+ let q_byte = get_byte(q_packed, k);
685
+ let q_lo = f32(kvalues_mxfp4[q_byte & 0xFu]) * d;
686
+ let q_hi = f32(kvalues_mxfp4[(q_byte >> 4) & 0xF]) * d;
687
+ let dst_offset = dst_base + offset * 64 + sub * 16 + j * 4 + k;
688
+ dst[dst_offset] = q_lo;
689
+ dst[dst_offset + 8u] = q_hi;
690
+ }
691
+ }
692
+ }
693
+ }
694
+ #endif
695
+
675
696
 
676
697
  @group(0) @binding(0)
677
698
  var<storage, read_write> src: array<SRC_TYPE>;