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
@@ -51,10 +51,7 @@ fn repack_b_dm(block: u32) -> B_DS_TYPE {
51
51
  fn get_dm(block_byte_base: u32) -> f32 {
52
52
  return f32(load_f16_at_src0(block_byte_base));
53
53
  }
54
- fn mul_q8_1(row_sum: i32, da: f32, b_ds: B_DS_TYPE) -> f32 {
55
- return f32(row_sum) * (da * b_ds.x) - 8.0 * da * b_ds.y / THREADS_PER_BLOCK;
56
- }
57
- #endif
54
+ #endif // MUL_ACC_Q4_0
58
55
 
59
56
  #ifdef MUL_ACC_Q4_1
60
57
  #define BLOCK_SIZE_BYTES 20
@@ -85,10 +82,7 @@ fn get_dm(block_byte_base: u32) -> vec2<f32> {
85
82
  f32(load_f16_at_src0(block_byte_base + 2u))
86
83
  );
87
84
  }
88
- fn mul_q8_1(row_sum: i32, dma: vec2<f32>, b_ds: B_DS_TYPE) -> f32 {
89
- return f32(row_sum) * (dma.x * b_ds.x) + dma.y * b_ds.y / THREADS_PER_BLOCK;
90
- }
91
- #endif
85
+ #endif // MUL_ACC_Q4_1
92
86
 
93
87
  #ifdef MUL_ACC_Q8_0
94
88
  #define BLOCK_SIZE_BYTES 34
@@ -111,46 +105,48 @@ fn repack_b_dm(block: u32) -> B_DS_TYPE {
111
105
  fn get_dm(block_byte_base: u32) -> f32 {
112
106
  return f32(load_f16_at_src0(block_byte_base));
113
107
  }
114
- fn mul_q8_1(row_sum: i32, da: f32, b_ds: B_DS_TYPE) -> f32 {
115
- return f32(row_sum) * (da * b_ds);
116
- }
117
- #endif
108
+ #endif // MUL_ACC_Q8_0
118
109
 
119
- #ifdef LEGACY_QUANTS
120
- fn mmvq_dot_product(a_byte_base: u32, b_inner_id: u32, b_repacked: vec2<u32>, b_ds: B_DS_TYPE) -> f32 {
121
- var row_sum = 0;
122
- let a_repacked = repack_a(a_byte_base, b_inner_id);
123
-
124
- row_sum += dot4I8Packed(a_repacked[0], b_repacked[0]);
125
- row_sum += dot4I8Packed(a_repacked[1], b_repacked[1]);
126
-
127
- return mul_q8_1(row_sum, get_dm(a_byte_base), b_ds);
128
- }
129
-
130
- fn accumulate_vec_q_dot(thread_id: u32, row_base: u32, src0_batch_offset: u32, src1q_idx_base: u32) -> array<f32, OUTPUTS_PER_WG> {
131
- var acc: array<f32, OUTPUTS_PER_WG>;
110
+ #if defined(LEGACY_QUANTS)
111
+ fn accumulate_vec_q_dot(thread_id: u32, row_base: u32, src0_batch_offset: u32, src1q_idx_base: u32) -> array<array<f32, OUTPUTS_PER_WG>, NUM_COLS> {
112
+ var acc: array<array<f32, OUTPUTS_PER_WG>, NUM_COLS>;
132
113
 
133
114
  let num_blocks = params.k / BLOCK_SIZE;
134
115
 
135
116
  for (var block = thread_id / THREADS_PER_BLOCK; block < num_blocks; block += WG_SIZE / THREADS_PER_BLOCK) {
136
- let b_inner_id = thread_id % THREADS_PER_BLOCK;
137
- let b_block_idx = src1q_idx_base + block;
138
-
139
- let b_repacked = repack_b_qs(b_block_idx, b_inner_id);
140
- let b_ds = repack_b_dm(b_block_idx);
141
-
117
+ let inner_id = thread_id % THREADS_PER_BLOCK;
142
118
  for (var row = 0u; row < OUTPUTS_PER_WG; row++) {
143
119
  let output_row = row_base + row;
144
120
  if (output_row < params.m) {
145
121
  let block_byte_base = (src0_batch_offset + output_row * params.stride_01 + block) * BLOCK_SIZE_BYTES;
146
- acc[row] += mmvq_dot_product(block_byte_base, b_inner_id, b_repacked, b_ds);
122
+ let a_repacked = repack_a(block_byte_base, inner_id);
123
+ let da = get_dm(block_byte_base);
124
+ for (var col = 0u;col < NUM_COLS;col += 1) {
125
+ let src1q_idx = src1q_idx_base + col * (params.k / Q8_BLOCK_SIZE) + block;
126
+ let b_repacked = repack_b_qs(src1q_idx, inner_id);
127
+ let b_ds = repack_b_dm(src1q_idx);
128
+
129
+ let row_sum = dot4I8Packed(a_repacked[0], b_repacked[0]) + dot4I8Packed(a_repacked[1], b_repacked[1]);
130
+
131
+ #if defined(MUL_ACC_Q4_0)
132
+ acc[col][row] += f32(row_sum) * (da * b_ds.x) - 8.0 * da * b_ds.y / THREADS_PER_BLOCK;
133
+ #endif // MUL_ACC_Q4_0
134
+
135
+ #if defined(MUL_ACC_Q4_1)
136
+ acc[col][row] += f32(row_sum) * (da.x * b_ds.x) + da.y * b_ds.y / THREADS_PER_BLOCK;
137
+ #endif // MUL_ACC_Q4_1
138
+
139
+ #if defined(MUL_ACC_Q8_0)
140
+ acc[col][row] += f32(row_sum) * (da * b_ds);
141
+ #endif // MUL_ACC_Q8_0
142
+ }
147
143
  }
148
144
  }
149
145
  }
150
146
 
151
147
  return acc;
152
148
  }
153
- #endif
149
+ #endif // LEGACY_QUANTS
154
150
 
155
151
  #ifdef MUL_ACC_Q2_K
156
152
  #define BLOCK_SIZE_BYTES 84
@@ -191,22 +187,7 @@ fn get_scale_min(block_byte_base: u32, tid: u32) -> vec2<f32> {
191
187
  let scale = byte_of(load_u32_at_src0_aligned(scale_byte), scale_byte & 3u);
192
188
  return vec2<f32>(f32(scale & 0xFu), f32(scale >> 4u));
193
189
  }
194
- fn mmvq_dot_product(a_byte_base: u32, tid: u32, b_repacked: vec4<u32>, b_ds: B_DS_TYPE) -> f32 {
195
- let a_repacked = repack_a(a_byte_base, tid);
196
- let dm = get_dm(a_byte_base);
197
- let scale_min = get_scale_min(a_byte_base, tid);
198
-
199
- let scale_q = i32(scale_min.x);
200
- let scale_m_i8x4 = u32(scale_min.y) * 0x01010101u;
201
-
202
- let row_sum_d = (dot4I8Packed(b_repacked[0], a_repacked[0]) + dot4I8Packed(b_repacked[1], a_repacked[1])
203
- + dot4I8Packed(b_repacked[2], a_repacked[2]) + dot4I8Packed(b_repacked[3], a_repacked[3])) * scale_q;
204
- let row_sum_m = dot4I8Packed(b_repacked[0], scale_m_i8x4) + dot4I8Packed(b_repacked[1], scale_m_i8x4)
205
- + dot4I8Packed(b_repacked[2], scale_m_i8x4) + dot4I8Packed(b_repacked[3], scale_m_i8x4);
206
-
207
- return b_ds * (dm.x * f32(row_sum_d) - dm.y * f32(row_sum_m));
208
- }
209
- #endif
190
+ #endif // MUL_ACC_Q2_K
210
191
 
211
192
  #ifdef MUL_ACC_Q4_K
212
193
  #define BLOCK_SIZE_BYTES 144
@@ -265,39 +246,52 @@ fn get_scale_min(block_byte_base: u32, tid: u32) -> vec2<f32> {
265
246
 
266
247
  return vec2<f32>(scale, min_val);
267
248
  }
268
- fn mmvq_dot_product(a_byte_base: u32, tid: u32, b_repacked: vec4<u32>, b_ds: B_DS_TYPE) -> f32 {
269
- let a_repacked = repack_a(a_byte_base, tid);
270
- let dm = get_dm(a_byte_base);
271
- let scale_min = get_scale_min(a_byte_base, tid);
272
-
273
- let row_sum = dot4I8Packed(a_repacked[0], b_repacked[0]) + dot4I8Packed(a_repacked[1], b_repacked[1])
274
- + dot4I8Packed(a_repacked[2], b_repacked[2]) + dot4I8Packed(a_repacked[3], b_repacked[3]);
275
-
276
- // Each thread covers half of the Q8_1 block, so add only b_ds.y/2.
277
- return b_ds.x * dm.x * scale_min.x * f32(row_sum) - dm.y * scale_min.y * (b_ds.y / (Q8_BLOCK_SIZE / ELEMS_PER_THREAD));
278
- }
279
- #endif
249
+ #endif // MUL_ACC_Q4_K
280
250
 
281
251
  #ifdef K_QUANTS
282
- fn accumulate_vec_q_dot(thread_id: u32, row_base: u32, src0_batch_offset: u32, src1q_idx_base: u32) -> array<f32, OUTPUTS_PER_WG> {
283
- var acc: array<f32, OUTPUTS_PER_WG>;
252
+ fn accumulate_vec_q_dot(thread_id: u32, row_base: u32, src0_batch_offset: u32, src1q_idx_base: u32) -> array<array<f32, OUTPUTS_PER_WG>, NUM_COLS> {
253
+ var acc: array<array<f32, OUTPUTS_PER_WG>, NUM_COLS>;
284
254
 
285
255
  let tid = thread_id % THREADS_PER_BLOCK;
286
256
 
287
257
  for (var block = thread_id / THREADS_PER_BLOCK; block < params.k / BLOCK_SIZE; block += WG_SIZE / THREADS_PER_BLOCK) {
288
- let src1q_idx = src1q_idx_base + (block * BLOCK_SIZE + ELEMS_PER_THREAD * tid) / Q8_BLOCK_SIZE;
289
- let b_repacked = repack_b_qs(src1q_idx, tid);
290
- let b_ds = repack_b_dm(src1q_idx);
291
-
292
258
  for (var row = 0u; row < OUTPUTS_PER_WG; row++) {
293
259
  let output_row = row_base + row;
294
260
  if (output_row < params.m) {
295
261
  let block_byte_base = (src0_batch_offset + output_row * params.stride_01 + block) * BLOCK_SIZE_BYTES;
296
- acc[row] += mmvq_dot_product(block_byte_base, tid, b_repacked, b_ds);
262
+ let a_repacked = repack_a(block_byte_base, tid);
263
+ let dm = get_dm(block_byte_base);
264
+ let scale_min = get_scale_min(block_byte_base, tid);
265
+ for (var col = 0u;col < NUM_COLS;col += 1) {
266
+ let src1q_idx = src1q_idx_base + col * (params.k / Q8_BLOCK_SIZE) + (block * BLOCK_SIZE + ELEMS_PER_THREAD * tid) / Q8_BLOCK_SIZE;
267
+ let b_repacked = repack_b_qs(src1q_idx, tid);
268
+ let b_ds = repack_b_dm(src1q_idx);
269
+
270
+ #if defined(MUL_ACC_Q2_K)
271
+ let scale_q = i32(scale_min.x);
272
+ let scale_m_i8x4 = u32(scale_min.y) * 0x01010101u;
273
+
274
+ let row_sum_d = (dot4I8Packed(b_repacked[0], a_repacked[0]) + dot4I8Packed(b_repacked[1], a_repacked[1])
275
+ + dot4I8Packed(b_repacked[2], a_repacked[2]) + dot4I8Packed(b_repacked[3], a_repacked[3])) * scale_q;
276
+ let row_sum_m = dot4I8Packed(b_repacked[0], scale_m_i8x4) + dot4I8Packed(b_repacked[1], scale_m_i8x4)
277
+ + dot4I8Packed(b_repacked[2], scale_m_i8x4) + dot4I8Packed(b_repacked[3], scale_m_i8x4);
278
+
279
+ acc[col][row] += b_ds * (dm.x * f32(row_sum_d) - dm.y * f32(row_sum_m));
280
+ #endif // MUL_ACC_Q2_K
281
+
282
+ #if defined(MUL_ACC_Q4_K)
283
+ let row_sum = dot4I8Packed(a_repacked[0], b_repacked[0]) + dot4I8Packed(a_repacked[1], b_repacked[1])
284
+ + dot4I8Packed(a_repacked[2], b_repacked[2]) + dot4I8Packed(a_repacked[3], b_repacked[3]);
285
+
286
+ // Each thread covers half of the Q8_1 block, so add only b_ds.y/2.
287
+ acc[col][row] += b_ds.x * dm.x * scale_min.x * f32(row_sum) - dm.y * scale_min.y * (b_ds.y / (Q8_BLOCK_SIZE / ELEMS_PER_THREAD));
288
+ #endif // MUL_ACC_Q4_K
289
+
290
+ }
297
291
  }
298
292
  }
299
293
  }
300
294
 
301
295
  return acc;
302
296
  }
303
- #endif
297
+ #endif // K_QUANTS
@@ -9,9 +9,11 @@ requires packed_4x8_integer_dot_product;
9
9
 
10
10
  struct Params {
11
11
  offset_src1: u32,
12
+ stride_11: u32,
12
13
  stride_12: u32,
13
14
  stride_13: u32,
14
15
  ne0: u32,
16
+ ne1: u32,
15
17
  ne2: u32,
16
18
  ne3: u32,
17
19
  };
@@ -57,25 +59,28 @@ fn main(
57
59
  @builtin(num_workgroups) num_wg: vec3<u32>
58
60
  ) {
59
61
  let thread_id = local_id.x;
60
- let num_vec4 = params.ne0 / 4u;
62
+ let ne0_vec4 = params.ne0 / 4u;
61
63
 
62
- let wg_per_vec = (num_vec4 + (WG_SIZE - 1u)) / WG_SIZE;
63
- let total_batches = wg_per_vec * params.ne2 * params.ne3;
64
+ let wg_per_vec = (ne0_vec4 + (WG_SIZE - 1u)) / WG_SIZE;
65
+ let total_batches = wg_per_vec * params.ne1 * params.ne2 * params.ne3;
64
66
 
65
67
  let wg_linear = wg_id.y * num_wg.x + wg_id.x;
66
68
  if (wg_linear >= total_batches) {
67
69
  return;
68
70
  }
69
71
 
70
- let src13_idx = wg_linear / (params.ne2 * wg_per_vec);
71
- let src12_idx = (wg_linear - src13_idx * (params.ne2 * wg_per_vec)) / wg_per_vec;
72
- let src11_wg_idx = wg_linear % wg_per_vec;
73
- let src1_idx_base = params.offset_src1 + src13_idx * params.stride_13 + src12_idx * params.stride_12;
72
+ let vec_idx = wg_linear / wg_per_vec;
73
+ let src13_idx = vec_idx / (params.ne2 * params.ne1);
74
+ let vec_ne12_num = vec_idx % (params.ne2 * params.ne1);
75
+ let src12_idx = vec_ne12_num / params.ne1;
76
+ let src11_idx = vec_ne12_num % params.ne1;
77
+ let src1_idx_base = params.offset_src1 + src13_idx * params.stride_13 + src12_idx * params.stride_12 + src11_idx * params.stride_11;
74
78
  let src1_idx_vec4_base = src1_idx_base / 4u;
75
79
 
76
80
  let blocks_per_row = params.ne0 / 32u;
77
81
  let blocks_per_wg = (WG_SIZE * 4u) / 32u;
78
- let src1q_idx_base = (src13_idx * params.ne2 + src12_idx) * blocks_per_row;
82
+ let src1q_idx_base = ((src13_idx * params.ne2 + src12_idx) * params.ne1 + src11_idx) * blocks_per_row;
83
+ let src11_wg_idx = wg_linear % wg_per_vec;
79
84
  let src1q_idx = src1q_idx_base + src11_wg_idx * blocks_per_wg + thread_id / 8u;
80
85
  let qs_idx = thread_id % 8u;
81
86
 
@@ -85,7 +90,7 @@ fn main(
85
90
  var thread_amax = 0.0;
86
91
 
87
92
  let src11_vec4_idx = src11_wg_idx * WG_SIZE + thread_id;
88
- let is_valid = src11_vec4_idx < num_vec4;
93
+ let is_valid = src11_vec4_idx < ne0_vec4;
89
94
 
90
95
  #ifdef USE_SUBGROUP_REDUCTION
91
96
 
@@ -525,7 +525,11 @@ const char * ggml_commit(void) {
525
525
 
526
526
  #if defined(_MSC_VER) || defined(__MINGW32__)
527
527
  static int64_t timer_freq, timer_start;
528
- void ggml_time_init(void) {
528
+ static BOOL CALLBACK ggml_time_init_once(PINIT_ONCE once, PVOID param, PVOID *ctx) {
529
+ UNUSED(once);
530
+ UNUSED(param);
531
+ UNUSED(ctx);
532
+
529
533
  LARGE_INTEGER t;
530
534
  QueryPerformanceFrequency(&t);
531
535
  timer_freq = t.QuadPart;
@@ -535,6 +539,12 @@ void ggml_time_init(void) {
535
539
  // We subtract the program start time to reduce the likelihood of that happening.
536
540
  QueryPerformanceCounter(&t);
537
541
  timer_start = t.QuadPart;
542
+
543
+ return TRUE;
544
+ }
545
+ void ggml_time_init(void) {
546
+ static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
547
+ InitOnceExecuteOnce(&once, ggml_time_init_once, NULL, NULL);
538
548
  }
539
549
  int64_t ggml_time_ms(void) {
540
550
  LARGE_INTEGER t;
@@ -600,18 +610,15 @@ FILE * ggml_fopen(const char * fname, const char * mode) {
600
610
  // convert fname (UTF-8)
601
611
  wchar_t * wfname = ggml_mbstowcs(fname);
602
612
  if (wfname) {
603
- // convert mode (ANSI)
604
- wchar_t * wmode = GGML_MALLOC((strlen(mode) + 1) * sizeof(wchar_t));
605
- wchar_t * wmode_p = wmode;
606
- do {
607
- *wmode_p++ = (wchar_t)*mode;
608
- } while (*mode++);
609
-
610
- // open file
611
- file = _wfopen(wfname, wmode);
613
+ // convert mode (UTF-8)
614
+ wchar_t * wmode = ggml_mbstowcs(mode);
615
+ if (wmode) {
616
+ // open file
617
+ file = _wfopen(wfname, wmode);
618
+ GGML_FREE(wmode);
619
+ }
612
620
 
613
621
  GGML_FREE(wfname);
614
- GGML_FREE(wmode);
615
622
  }
616
623
 
617
624
  return file;
@@ -674,6 +681,14 @@ static const struct ggml_type_traits type_traits[GGML_TYPE_COUNT] = {
674
681
  .to_float = (ggml_to_float_t) dequantize_row_q1_0,
675
682
  .from_float_ref = (ggml_from_float_t) quantize_row_q1_0_ref,
676
683
  },
684
+ [GGML_TYPE_Q2_0] = {
685
+ .type_name = "q2_0",
686
+ .blck_size = QK2_0,
687
+ .type_size = sizeof(block_q2_0),
688
+ .is_quantized = true,
689
+ .to_float = (ggml_to_float_t) dequantize_row_q2_0,
690
+ .from_float_ref = (ggml_from_float_t) quantize_row_q2_0_ref,
691
+ },
677
692
  [GGML_TYPE_Q4_0] = {
678
693
  .type_name = "q4_0",
679
694
  .blck_size = QK4_0,
@@ -1410,6 +1425,7 @@ enum ggml_type ggml_ftype_to_ggml_type(enum ggml_ftype ftype) {
1410
1425
  case GGML_FTYPE_MOSTLY_Q4_0: wtype = GGML_TYPE_Q4_0; break;
1411
1426
  case GGML_FTYPE_MOSTLY_Q4_1: wtype = GGML_TYPE_Q4_1; break;
1412
1427
  case GGML_FTYPE_MOSTLY_Q1_0: wtype = GGML_TYPE_Q1_0; break;
1428
+ case GGML_FTYPE_MOSTLY_Q2_0: wtype = GGML_TYPE_Q2_0; break;
1413
1429
  case GGML_FTYPE_MOSTLY_Q5_0: wtype = GGML_TYPE_Q5_0; break;
1414
1430
  case GGML_FTYPE_MOSTLY_Q5_1: wtype = GGML_TYPE_Q5_1; break;
1415
1431
  case GGML_FTYPE_MOSTLY_Q8_0: wtype = GGML_TYPE_Q8_0; break;
@@ -3910,7 +3926,7 @@ struct ggml_tensor * ggml_set_rows(
3910
3926
  GGML_ASSERT(b->ne[2] % c->ne[1] == 0);
3911
3927
  GGML_ASSERT(b->ne[3] % c->ne[2] == 0);
3912
3928
  GGML_ASSERT(c->ne[3] == 1);
3913
- GGML_ASSERT(b->type == GGML_TYPE_F32);
3929
+ GGML_ASSERT(b->type == GGML_TYPE_F32 || b->type == GGML_TYPE_F16);
3914
3930
  GGML_ASSERT(c->type == GGML_TYPE_I64 || c->type == GGML_TYPE_I32);
3915
3931
 
3916
3932
  GGML_ASSERT(ggml_is_contiguous_rows(a));
@@ -7412,6 +7428,10 @@ static int ggml_node_list_find_tensor(const struct ggml_cgraph * cgraph,
7412
7428
  return -1;
7413
7429
  }
7414
7430
 
7431
+ static bool ggml_is_constant(const struct ggml_tensor * tensor) {
7432
+ return tensor->buffer != NULL && ggml_backend_buffer_get_usage(tensor->buffer) == GGML_BACKEND_BUFFER_USAGE_WEIGHTS && (tensor->flags & GGML_TENSOR_FLAG_PARAM) == 0;
7433
+ }
7434
+
7415
7435
  bool ggml_can_fuse_subgraph_ext(const struct ggml_cgraph * cgraph,
7416
7436
  const int * node_idxs,
7417
7437
  int count,
@@ -7457,10 +7477,11 @@ bool ggml_can_fuse_subgraph_ext(const struct ggml_cgraph * cgraph,
7457
7477
  return false;
7458
7478
  }
7459
7479
 
7460
- // if node is a view, check if the view_src and all it's parent view_srcs are within the subgraph
7480
+ // if node is a view, check if the view_src and all its parent view_srcs are within the subgraph.
7481
+ // external view sources are allowed only for weight tensors, which are constant for this graph execution.
7461
7482
  struct ggml_tensor * view_src = node->view_src;
7462
7483
  while (view_src) {
7463
- if (ggml_node_list_find_tensor(cgraph, node_idxs, count, view_src) == -1) {
7484
+ if (ggml_node_list_find_tensor(cgraph, node_idxs, count, view_src) == -1 && !ggml_is_constant(view_src)) {
7464
7485
  return false;
7465
7486
  }
7466
7487
  view_src = view_src->view_src;
@@ -7732,6 +7753,7 @@ size_t ggml_quantize_chunk(
7732
7753
 
7733
7754
  switch (type) {
7734
7755
  case GGML_TYPE_Q1_0: result = quantize_q1_0 (src + start, (char *) dst + start_row * row_size, nrows, n_per_row, imatrix); break;
7756
+ case GGML_TYPE_Q2_0: result = quantize_q2_0 (src + start, (char *) dst + start_row * row_size, nrows, n_per_row, imatrix); break;
7735
7757
  case GGML_TYPE_Q4_0: result = quantize_q4_0 (src + start, (char *) dst + start_row * row_size, nrows, n_per_row, imatrix); break;
7736
7758
  case GGML_TYPE_Q4_1: result = quantize_q4_1 (src + start, (char *) dst + start_row * row_size, nrows, n_per_row, imatrix); break;
7737
7759
  case GGML_TYPE_Q5_0: result = quantize_q5_0 (src + start, (char *) dst + start_row * row_size, nrows, n_per_row, imatrix); break;
@@ -667,10 +667,31 @@ extern "C" {
667
667
  WHISPER_API whisper_token_data whisper_full_get_token_data (struct whisper_context * ctx, int i_segment, int i_token);
668
668
  WHISPER_API whisper_token_data whisper_full_get_token_data_from_state(struct whisper_state * state, int i_segment, int i_token);
669
669
 
670
+ // Get the start/end time of the specified token, in centiseconds. When VAD is enabled
671
+ // these are mapped back to the original audio timeline (a token landing in a removed
672
+ // inter-segment silence snaps to the nearest speech boundary), unlike
673
+ // whisper_full_get_token_data().t0/t1 which stay in VAD-processed time. Without VAD the
674
+ // raw token times are returned unchanged.
675
+ WHISPER_API int64_t whisper_full_get_token_t0 (struct whisper_context * ctx, int i_segment, int i_token);
676
+ WHISPER_API int64_t whisper_full_get_token_t0_from_state(struct whisper_state * state, int i_segment, int i_token);
677
+ WHISPER_API int64_t whisper_full_get_token_t1 (struct whisper_context * ctx, int i_segment, int i_token);
678
+ WHISPER_API int64_t whisper_full_get_token_t1_from_state(struct whisper_state * state, int i_segment, int i_token);
679
+
670
680
  // Get the probability of the specified token in the specified segment
671
681
  WHISPER_API float whisper_full_get_token_p (struct whisper_context * ctx, int i_segment, int i_token);
672
682
  WHISPER_API float whisper_full_get_token_p_from_state(struct whisper_state * state, int i_segment, int i_token);
673
683
 
684
+ // Access the speech segments detected by the internal VAD (only when params.vad = true).
685
+ // Times are on the original audio timeline, in centiseconds. The count is 0 when VAD was
686
+ // not used, so callers can reuse whisper's own speech boundaries instead of running a
687
+ // separate VAD pass.
688
+ WHISPER_API int whisper_full_n_vad_segments (struct whisper_context * ctx);
689
+ WHISPER_API int whisper_full_n_vad_segments_from_state (struct whisper_state * state);
690
+ WHISPER_API int64_t whisper_full_get_vad_segment_t0 (struct whisper_context * ctx, int i);
691
+ WHISPER_API int64_t whisper_full_get_vad_segment_t0_from_state(struct whisper_state * state, int i);
692
+ WHISPER_API int64_t whisper_full_get_vad_segment_t1 (struct whisper_context * ctx, int i);
693
+ WHISPER_API int64_t whisper_full_get_vad_segment_t1_from_state(struct whisper_state * state, int i);
694
+
674
695
  //
675
696
  // Voice Activity Detection (VAD)
676
697
  //
@@ -8075,6 +8075,94 @@ struct whisper_token_data whisper_full_get_token_data(struct whisper_context * c
8075
8075
  return ctx->state->result_all[i_segment].tokens[i_token];
8076
8076
  }
8077
8077
 
8078
+ // map a token time (centiseconds) from the VAD-processed timeline back to the original
8079
+ // audio. a token inside a speech segment is interpolated within that segment; a token that
8080
+ // falls in the silence removed between two segments snaps to the nearer boundary, so it
8081
+ // never ends up in the middle of a cut-out gap (which a single global interpolation over
8082
+ // the whole mapping table would do).
8083
+ static int64_t whisper_map_token_time_segment_aware(
8084
+ int64_t t,
8085
+ const std::vector<whisper_state::vad_segment_info> & segs) {
8086
+ if (segs.empty()) {
8087
+ return t;
8088
+ }
8089
+ if (t <= segs.front().vad_start) {
8090
+ return segs.front().orig_start;
8091
+ }
8092
+ if (t >= segs.back().vad_end) {
8093
+ return segs.back().orig_end;
8094
+ }
8095
+ for (size_t i = 0; i < segs.size(); ++i) {
8096
+ const auto & s = segs[i];
8097
+ if (t >= s.vad_start && t <= s.vad_end) {
8098
+ const int64_t vd = s.vad_end - s.vad_start;
8099
+ const int64_t od = s.orig_end - s.orig_start;
8100
+ if (vd <= 0) {
8101
+ return s.orig_start;
8102
+ }
8103
+ return s.orig_start + (t - s.vad_start) * od / vd;
8104
+ }
8105
+ if (i + 1 < segs.size() && t > s.vad_end && t < segs[i + 1].vad_start) {
8106
+ const int64_t mid = (s.vad_end + segs[i + 1].vad_start) / 2;
8107
+ return (t <= mid) ? s.orig_end : segs[i + 1].orig_start;
8108
+ }
8109
+ }
8110
+ return t;
8111
+ }
8112
+
8113
+ int64_t whisper_full_get_token_t0_from_state(struct whisper_state * state, int i_segment, int i_token) {
8114
+ const int64_t t0 = state->result_all[i_segment].tokens[i_token].t0;
8115
+ if (!state->has_vad_segments || state->vad_segments.empty()) {
8116
+ return t0;
8117
+ }
8118
+ return whisper_map_token_time_segment_aware(t0, state->vad_segments);
8119
+ }
8120
+
8121
+ int64_t whisper_full_get_token_t0(struct whisper_context * ctx, int i_segment, int i_token) {
8122
+ return whisper_full_get_token_t0_from_state(ctx->state, i_segment, i_token);
8123
+ }
8124
+
8125
+ int64_t whisper_full_get_token_t1_from_state(struct whisper_state * state, int i_segment, int i_token) {
8126
+ const int64_t t1 = state->result_all[i_segment].tokens[i_token].t1;
8127
+ if (!state->has_vad_segments || state->vad_segments.empty()) {
8128
+ return t1;
8129
+ }
8130
+ const int64_t orig_t0 = whisper_full_get_token_t0_from_state(state, i_segment, i_token);
8131
+ int64_t orig_t1 = whisper_map_token_time_segment_aware(t1, state->vad_segments);
8132
+ if (orig_t1 < orig_t0 + 1) {
8133
+ orig_t1 = orig_t0 + 1; // keep a strictly positive duration after snapping
8134
+ }
8135
+ return orig_t1;
8136
+ }
8137
+
8138
+ int64_t whisper_full_get_token_t1(struct whisper_context * ctx, int i_segment, int i_token) {
8139
+ return whisper_full_get_token_t1_from_state(ctx->state, i_segment, i_token);
8140
+ }
8141
+
8142
+ int whisper_full_n_vad_segments_from_state(struct whisper_state * state) {
8143
+ return (int) state->vad_segments.size();
8144
+ }
8145
+
8146
+ int whisper_full_n_vad_segments(struct whisper_context * ctx) {
8147
+ return (int) ctx->state->vad_segments.size();
8148
+ }
8149
+
8150
+ int64_t whisper_full_get_vad_segment_t0_from_state(struct whisper_state * state, int i) {
8151
+ return state->vad_segments[i].orig_start;
8152
+ }
8153
+
8154
+ int64_t whisper_full_get_vad_segment_t0(struct whisper_context * ctx, int i) {
8155
+ return ctx->state->vad_segments[i].orig_start;
8156
+ }
8157
+
8158
+ int64_t whisper_full_get_vad_segment_t1_from_state(struct whisper_state * state, int i) {
8159
+ return state->vad_segments[i].orig_end;
8160
+ }
8161
+
8162
+ int64_t whisper_full_get_vad_segment_t1(struct whisper_context * ctx, int i) {
8163
+ return ctx->state->vad_segments[i].orig_end;
8164
+ }
8165
+
8078
8166
  float whisper_full_get_token_p_from_state(struct whisper_state * state, int i_segment, int i_token) {
8079
8167
  return state->result_all[i_segment].tokens[i_token].p;
8080
8168
  }
@@ -8397,24 +8485,86 @@ static int64_t sample_to_timestamp(int i_sample) {
8397
8485
 
8398
8486
  // a cost-function / heuristic that is high for text that takes longer to pronounce
8399
8487
  // obviously, can be improved
8488
+ //
8489
+ // iterate over utf-8 code points rather than raw bytes: a CJK glyph is 3 bytes, so the
8490
+ // old per-byte loop counted every Han/kana/hangul character ~3x and never matched
8491
+ // full-width punctuation, skewing how a segment's time is shared between its tokens for
8492
+ // Chinese/Japanese. full-width punctuation gets the same weight as its ASCII form and
8493
+ // pure-ASCII text decodes to the same weights as before.
8400
8494
  static float voice_length(const std::string & text) {
8401
8495
  float res = 0.0f;
8402
8496
 
8403
- for (char c : text) {
8404
- if (c == ' ') {
8405
- res += 0.01f;
8406
- } else if (c == ',') {
8407
- res += 2.00f;
8408
- } else if (c == '.') {
8409
- res += 3.00f;
8410
- } else if (c == '!') {
8411
- res += 3.00f;
8412
- } else if (c == '?') {
8413
- res += 3.00f;
8414
- } else if (c >= '0' && c <= '9') {
8415
- res += 3.00f;
8497
+ const unsigned char * s = (const unsigned char *) text.data();
8498
+ const size_t n = text.size();
8499
+
8500
+ for (size_t i = 0; i < n; ) {
8501
+ const unsigned char c = s[i];
8502
+ uint32_t cp = c;
8503
+ int len = 1;
8504
+ if (c < 0x80) {
8505
+ len = 1;
8506
+ } else if ((c >> 5) == 0x6) {
8507
+ cp = c & 0x1F;
8508
+ len = 2;
8509
+ } else if ((c >> 4) == 0xE) {
8510
+ cp = c & 0x0F;
8511
+ len = 3;
8512
+ } else if ((c >> 3) == 0x1E) {
8513
+ cp = c & 0x07;
8514
+ len = 4;
8515
+ } else {
8516
+ cp = c; // stray continuation / invalid lead byte
8517
+ len = 1;
8518
+ }
8519
+ if (i + (size_t) len <= n) {
8520
+ bool ok = true;
8521
+ for (int k = 1; k < len; ++k) {
8522
+ const unsigned char cc = s[i + k];
8523
+ if ((cc & 0xC0) != 0x80) {
8524
+ ok = false;
8525
+ break;
8526
+ }
8527
+ cp = (cp << 6) | (cc & 0x3F);
8528
+ }
8529
+ if (!ok) {
8530
+ cp = c;
8531
+ len = 1;
8532
+ }
8416
8533
  } else {
8417
- res += 1.00f;
8534
+ cp = c;
8535
+ len = 1;
8536
+ }
8537
+ i += (size_t) len;
8538
+
8539
+ switch (cp) {
8540
+ case ' ':
8541
+ case 0x3000: // ideographic space
8542
+ res += 0.01f;
8543
+ break;
8544
+ case ',':
8545
+ case 0xFF0C: // ,
8546
+ case 0x3001: // 、
8547
+ case 0xFF1B: // ;
8548
+ case 0xFF1A: // :
8549
+ res += 2.00f;
8550
+ break;
8551
+ case '.':
8552
+ case '!':
8553
+ case '?':
8554
+ case 0x3002: // 。
8555
+ case 0xFF0E: // .
8556
+ case 0xFF01: // !
8557
+ case 0xFF1F: // ?
8558
+ case 0x2026: // …
8559
+ res += 3.00f;
8560
+ break;
8561
+ default:
8562
+ if ((cp >= '0' && cp <= '9') || (cp >= 0xFF10 && cp <= 0xFF19)) {
8563
+ res += 3.00f; // half/full-width digits
8564
+ } else {
8565
+ res += 1.00f; // letters, CJK ideographs, kana, hangul, ...
8566
+ }
8567
+ break;
8418
8568
  }
8419
8569
  }
8420
8570
 
@@ -1,13 +1,5 @@
1
- require "mutex_m"
2
-
3
1
  module Whisper
4
2
  module LogSettable
5
- class << self
6
- def extended(base)
7
- base.extend Mutex_m
8
- end
9
- end
10
-
11
3
  private
12
4
 
13
5
  def start_log_callback_thread
@@ -32,5 +24,10 @@ module Whisper
32
24
  end
33
25
  }
34
26
  end
27
+
28
+ def synchronize(&block)
29
+ @mutex ||= Thread::Mutex.new
30
+ @mutex.synchronize &block
31
+ end
35
32
  end
36
33
  end
@@ -44,7 +44,6 @@ module Whisper
44
44
  return path if cache_path.exist?
45
45
 
46
46
  headers = {}
47
- headers["if-modified-since"] = path.mtime.httpdate if path.exist?
48
47
  request @uri, headers
49
48
  path
50
49
  end
@@ -54,17 +53,11 @@ module Whisper
54
53
  request = Net::HTTP::Get.new(uri, headers)
55
54
  http.request request do |response|
56
55
  case response
57
- when Net::HTTPNotModified
58
- # noop
59
56
  when Net::HTTPOK
60
- return if !response.key?("last-modified") && cache_path.exist?
61
-
62
57
  download response
63
58
  when Net::HTTPRedirection
64
59
  request URI(response["location"]), headers
65
60
  else
66
- return if headers.key?("if-modified-since") # Use cache file
67
-
68
61
  raise "#{response.code} #{response.message}\n#{response.body}"
69
62
  end
70
63
  end
data/sig/whisper.rbs CHANGED
@@ -131,6 +131,12 @@ module Whisper
131
131
 
132
132
  def full_get_segment_no_speech_prob: (Integer) -> Float
133
133
 
134
+ def full_n_vad_segments: () -> Integer
135
+
136
+ def full_get_vad_segment_t0: (Integer) -> Integer
137
+
138
+ def full_get_vad_segment_t1: (Integer) -> Integer
139
+
134
140
  # Run the entire model: PCM -> log mel spectrogram -> encoder -> decoder -> text
135
141
  # Not thread safe for same context
136
142
  # Uses the specified decoding strategy to obtain the text.