cohere-transcribe 0.1.0

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 (480) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +21 -0
  3. data/LICENSE.txt +201 -0
  4. data/NOTICE +5 -0
  5. data/README.md +265 -0
  6. data/THIRD_PARTY_NOTICES.md +67 -0
  7. data/exe/cohere-transcribe +8 -0
  8. data/exe/cohere-transcribe-doctor +8 -0
  9. data/ext/cohere_transcribe_native/CMakeLists.txt +262 -0
  10. data/ext/cohere_transcribe_native/README.md +26 -0
  11. data/ext/cohere_transcribe_native/audio_abi.cpp +1416 -0
  12. data/ext/cohere_transcribe_native/audio_exports.macos +5 -0
  13. data/ext/cohere_transcribe_native/audio_exports.map +10 -0
  14. data/ext/cohere_transcribe_native/cohere_abi.cpp +1209 -0
  15. data/ext/cohere_transcribe_native/exports.macos +40 -0
  16. data/ext/cohere_transcribe_native/exports.map +45 -0
  17. data/ext/cohere_transcribe_native/extconf.rb +89 -0
  18. data/ext/cohere_transcribe_native/test/abi_smoke.rb +232 -0
  19. data/ext/cohere_transcribe_native/test/audio_matrix_smoke.cpp +121 -0
  20. data/ext/cohere_transcribe_native/test/audio_reliability_smoke.cpp +198 -0
  21. data/ext/cohere_transcribe_native/test/native_abi_reliability_smoke.cpp +186 -0
  22. data/ext/cohere_transcribe_native/test/native_batch_projection_probe.rb +81 -0
  23. data/ext/cohere_transcribe_native/test/native_cancellation_smoke.cpp +194 -0
  24. data/lib/cohere/transcribe/alignment/ATTRIBUTION.md +23 -0
  25. data/lib/cohere/transcribe/alignment/LICENSE.ctc-forced-aligner +407 -0
  26. data/lib/cohere/transcribe/alignment/LICENSE.torchaudio +25 -0
  27. data/lib/cohere/transcribe/alignment/LICENSE.uroman +26 -0
  28. data/lib/cohere/transcribe/alignment/aligner.rb +476 -0
  29. data/lib/cohere/transcribe/alignment/ctc.rb +224 -0
  30. data/lib/cohere/transcribe/alignment/text.rb +237 -0
  31. data/lib/cohere/transcribe/alignment/uroman_data.rb +4950 -0
  32. data/lib/cohere/transcribe/api.rb +173 -0
  33. data/lib/cohere/transcribe/asr/batching.rb +472 -0
  34. data/lib/cohere/transcribe/asr/failure_policy.rb +112 -0
  35. data/lib/cohere/transcribe/asr/native.rb +676 -0
  36. data/lib/cohere/transcribe/audio/ATTRIBUTION.md +8 -0
  37. data/lib/cohere/transcribe/audio/LICENSE.auditok +21 -0
  38. data/lib/cohere/transcribe/audio/decoder.rb +315 -0
  39. data/lib/cohere/transcribe/audio/ffmpeg_native.rb +248 -0
  40. data/lib/cohere/transcribe/audio/segmentation.rb +260 -0
  41. data/lib/cohere/transcribe/cli.rb +727 -0
  42. data/lib/cohere/transcribe/configuration.rb +282 -0
  43. data/lib/cohere/transcribe/constants.rb +14 -0
  44. data/lib/cohere/transcribe/dense_converter.rb +548 -0
  45. data/lib/cohere/transcribe/doctor.rb +576 -0
  46. data/lib/cohere/transcribe/errors.rb +57 -0
  47. data/lib/cohere/transcribe/gguf_writer.rb +268 -0
  48. data/lib/cohere/transcribe/hub.rb +436 -0
  49. data/lib/cohere/transcribe/input.rb +110 -0
  50. data/lib/cohere/transcribe/licenses/crispasr.txt +21 -0
  51. data/lib/cohere/transcribe/loader.rb +128 -0
  52. data/lib/cohere/transcribe/model_identity.rb +440 -0
  53. data/lib/cohere/transcribe/output/publication.rb +1118 -0
  54. data/lib/cohere/transcribe/output/rendering.rb +105 -0
  55. data/lib/cohere/transcribe/output/timing.rb +86 -0
  56. data/lib/cohere/transcribe/python_text.rb +70 -0
  57. data/lib/cohere/transcribe/pytorch_checkpoint.rb +1180 -0
  58. data/lib/cohere/transcribe/runtime/engine.rb +1676 -0
  59. data/lib/cohere/transcribe/runtime/model_provider.rb +390 -0
  60. data/lib/cohere/transcribe/runtime/precision.rb +57 -0
  61. data/lib/cohere/transcribe/runtime/preparation.rb +215 -0
  62. data/lib/cohere/transcribe/runtime/resources.rb +165 -0
  63. data/lib/cohere/transcribe/runtime/word_pipeline.rb +364 -0
  64. data/lib/cohere/transcribe/safetensors.rb +579 -0
  65. data/lib/cohere/transcribe/state/checkpoint.rb +224 -0
  66. data/lib/cohere/transcribe/state/contracts.rb +141 -0
  67. data/lib/cohere/transcribe/state/io.rb +727 -0
  68. data/lib/cohere/transcribe/state/locking.rb +211 -0
  69. data/lib/cohere/transcribe/state/manifest.rb +155 -0
  70. data/lib/cohere/transcribe/state.rb +7 -0
  71. data/lib/cohere/transcribe/types.rb +535 -0
  72. data/lib/cohere/transcribe/vad/ATTRIBUTION.md +14 -0
  73. data/lib/cohere/transcribe/vad/LICENSE.faster-whisper +21 -0
  74. data/lib/cohere/transcribe/vad/LICENSE.silero-vad +21 -0
  75. data/lib/cohere/transcribe/vad/silero.rb +344 -0
  76. data/lib/cohere/transcribe/vad/silero_vad_v6.onnx +0 -0
  77. data/lib/cohere/transcribe/vad/timestamps.rb +219 -0
  78. data/lib/cohere/transcribe/version.rb +7 -0
  79. data/lib/cohere/transcribe.rb +26 -0
  80. data/sig/cohere/transcribe.rbs +250 -0
  81. data/vendor/crispasr/AUTHORS +510 -0
  82. data/vendor/crispasr/LICENSE +21 -0
  83. data/vendor/crispasr/UPSTREAM.md +9 -0
  84. data/vendor/crispasr/VERSION +1 -0
  85. data/vendor/crispasr/ggml/AUTHORS +335 -0
  86. data/vendor/crispasr/ggml/CMakeLists.txt +512 -0
  87. data/vendor/crispasr/ggml/LICENSE +21 -0
  88. data/vendor/crispasr/ggml/README.md +49 -0
  89. data/vendor/crispasr/ggml/cmake/FindNCCL.cmake +36 -0
  90. data/vendor/crispasr/ggml/cmake/GitVars.cmake +22 -0
  91. data/vendor/crispasr/ggml/cmake/common.cmake +50 -0
  92. data/vendor/crispasr/ggml/cmake/ggml-config.cmake.in +191 -0
  93. data/vendor/crispasr/ggml/ggml.pc.in +10 -0
  94. data/vendor/crispasr/ggml/include/ggml-alloc.h +85 -0
  95. data/vendor/crispasr/ggml/include/ggml-backend.h +431 -0
  96. data/vendor/crispasr/ggml/include/ggml-blas.h +25 -0
  97. data/vendor/crispasr/ggml/include/ggml-cann.h +123 -0
  98. data/vendor/crispasr/ggml/include/ggml-cpp.h +39 -0
  99. data/vendor/crispasr/ggml/include/ggml-cpu.h +151 -0
  100. data/vendor/crispasr/ggml/include/ggml-cuda.h +50 -0
  101. data/vendor/crispasr/ggml/include/ggml-hexagon.h +19 -0
  102. data/vendor/crispasr/ggml/include/ggml-metal.h +61 -0
  103. data/vendor/crispasr/ggml/include/ggml-opencl.h +26 -0
  104. data/vendor/crispasr/ggml/include/ggml-openvino.h +37 -0
  105. data/vendor/crispasr/ggml/include/ggml-opt.h +256 -0
  106. data/vendor/crispasr/ggml/include/ggml-rpc.h +35 -0
  107. data/vendor/crispasr/ggml/include/ggml-sycl.h +49 -0
  108. data/vendor/crispasr/ggml/include/ggml-virtgpu.h +14 -0
  109. data/vendor/crispasr/ggml/include/ggml-vulkan.h +29 -0
  110. data/vendor/crispasr/ggml/include/ggml-webgpu.h +19 -0
  111. data/vendor/crispasr/ggml/include/ggml-zdnn.h +17 -0
  112. data/vendor/crispasr/ggml/include/ggml-zendnn.h +22 -0
  113. data/vendor/crispasr/ggml/include/ggml.h +2887 -0
  114. data/vendor/crispasr/ggml/include/gguf.h +204 -0
  115. data/vendor/crispasr/ggml/src/CMakeLists.txt +493 -0
  116. data/vendor/crispasr/ggml/src/ggml-alloc.c +1323 -0
  117. data/vendor/crispasr/ggml/src/ggml-backend-dl.cpp +48 -0
  118. data/vendor/crispasr/ggml/src/ggml-backend-dl.h +44 -0
  119. data/vendor/crispasr/ggml/src/ggml-backend-impl.h +275 -0
  120. data/vendor/crispasr/ggml/src/ggml-backend-meta.cpp +2145 -0
  121. data/vendor/crispasr/ggml/src/ggml-backend-reg.cpp +586 -0
  122. data/vendor/crispasr/ggml/src/ggml-backend.cpp +2437 -0
  123. data/vendor/crispasr/ggml/src/ggml-common.h +1900 -0
  124. data/vendor/crispasr/ggml/src/ggml-cpu/CMakeLists.txt +718 -0
  125. data/vendor/crispasr/ggml/src/ggml-cpu/amx/amx.cpp +249 -0
  126. data/vendor/crispasr/ggml/src/ggml-cpu/amx/amx.h +8 -0
  127. data/vendor/crispasr/ggml/src/ggml-cpu/amx/common.h +115 -0
  128. data/vendor/crispasr/ggml/src/ggml-cpu/amx/mmq.cpp +2512 -0
  129. data/vendor/crispasr/ggml/src/ggml-cpu/amx/mmq.h +10 -0
  130. data/vendor/crispasr/ggml/src/ggml-cpu/arch/arm/cpu-feats.cpp +98 -0
  131. data/vendor/crispasr/ggml/src/ggml-cpu/arch/arm/quants.c +4244 -0
  132. data/vendor/crispasr/ggml/src/ggml-cpu/arch/arm/repack.cpp +5156 -0
  133. data/vendor/crispasr/ggml/src/ggml-cpu/arch/loongarch/quants.c +2158 -0
  134. data/vendor/crispasr/ggml/src/ggml-cpu/arch/powerpc/cpu-feats.cpp +82 -0
  135. data/vendor/crispasr/ggml/src/ggml-cpu/arch/powerpc/quants.c +2304 -0
  136. data/vendor/crispasr/ggml/src/ggml-cpu/arch/riscv/cpu-feats.cpp +38 -0
  137. data/vendor/crispasr/ggml/src/ggml-cpu/arch/riscv/quants.c +4455 -0
  138. data/vendor/crispasr/ggml/src/ggml-cpu/arch/riscv/repack.cpp +1703 -0
  139. data/vendor/crispasr/ggml/src/ggml-cpu/arch/s390/cpu-feats.cpp +50 -0
  140. data/vendor/crispasr/ggml/src/ggml-cpu/arch/s390/quants.c +1465 -0
  141. data/vendor/crispasr/ggml/src/ggml-cpu/arch/wasm/quants.c +1220 -0
  142. data/vendor/crispasr/ggml/src/ggml-cpu/arch/x86/cpu-feats.cpp +327 -0
  143. data/vendor/crispasr/ggml/src/ggml-cpu/arch/x86/quants.c +3970 -0
  144. data/vendor/crispasr/ggml/src/ggml-cpu/arch/x86/repack.cpp +6407 -0
  145. data/vendor/crispasr/ggml/src/ggml-cpu/arch-fallback.h +349 -0
  146. data/vendor/crispasr/ggml/src/ggml-cpu/binary-ops.cpp +154 -0
  147. data/vendor/crispasr/ggml/src/ggml-cpu/binary-ops.h +16 -0
  148. data/vendor/crispasr/ggml/src/ggml-cpu/cmake/FindSIMD.cmake +100 -0
  149. data/vendor/crispasr/ggml/src/ggml-cpu/common.h +95 -0
  150. data/vendor/crispasr/ggml/src/ggml-cpu/ggml-cpu-impl.h +539 -0
  151. data/vendor/crispasr/ggml/src/ggml-cpu/ggml-cpu.c +3791 -0
  152. data/vendor/crispasr/ggml/src/ggml-cpu/ggml-cpu.cpp +703 -0
  153. data/vendor/crispasr/ggml/src/ggml-cpu/hbm.cpp +55 -0
  154. data/vendor/crispasr/ggml/src/ggml-cpu/hbm.h +8 -0
  155. data/vendor/crispasr/ggml/src/ggml-cpu/kleidiai/kernels.cpp +939 -0
  156. data/vendor/crispasr/ggml/src/ggml-cpu/kleidiai/kernels.h +90 -0
  157. data/vendor/crispasr/ggml/src/ggml-cpu/kleidiai/kleidiai.cpp +1513 -0
  158. data/vendor/crispasr/ggml/src/ggml-cpu/kleidiai/kleidiai.h +17 -0
  159. data/vendor/crispasr/ggml/src/ggml-cpu/llamafile/sgemm.cpp +4051 -0
  160. data/vendor/crispasr/ggml/src/ggml-cpu/llamafile/sgemm.h +25 -0
  161. data/vendor/crispasr/ggml/src/ggml-cpu/ops.cpp +11662 -0
  162. data/vendor/crispasr/ggml/src/ggml-cpu/ops.h +121 -0
  163. data/vendor/crispasr/ggml/src/ggml-cpu/quants.c +1288 -0
  164. data/vendor/crispasr/ggml/src/ggml-cpu/quants.h +103 -0
  165. data/vendor/crispasr/ggml/src/ggml-cpu/repack.cpp +4836 -0
  166. data/vendor/crispasr/ggml/src/ggml-cpu/repack.h +245 -0
  167. data/vendor/crispasr/ggml/src/ggml-cpu/simd-gemm.h +226 -0
  168. data/vendor/crispasr/ggml/src/ggml-cpu/simd-mappings.h +1329 -0
  169. data/vendor/crispasr/ggml/src/ggml-cpu/spacemit/ime.cpp +1025 -0
  170. data/vendor/crispasr/ggml/src/ggml-cpu/spacemit/ime.h +13 -0
  171. data/vendor/crispasr/ggml/src/ggml-cpu/spacemit/ime1_kernels.cpp +3196 -0
  172. data/vendor/crispasr/ggml/src/ggml-cpu/spacemit/ime_kernels.h +26 -0
  173. data/vendor/crispasr/ggml/src/ggml-cpu/traits.cpp +36 -0
  174. data/vendor/crispasr/ggml/src/ggml-cpu/traits.h +38 -0
  175. data/vendor/crispasr/ggml/src/ggml-cpu/unary-ops.cpp +336 -0
  176. data/vendor/crispasr/ggml/src/ggml-cpu/unary-ops.h +35 -0
  177. data/vendor/crispasr/ggml/src/ggml-cpu/vec.cpp +681 -0
  178. data/vendor/crispasr/ggml/src/ggml-cpu/vec.h +1606 -0
  179. data/vendor/crispasr/ggml/src/ggml-cuda/CMakeLists.txt +272 -0
  180. data/vendor/crispasr/ggml/src/ggml-cuda/acc.cu +61 -0
  181. data/vendor/crispasr/ggml/src/ggml-cuda/acc.cuh +5 -0
  182. data/vendor/crispasr/ggml/src/ggml-cuda/add-id.cu +58 -0
  183. data/vendor/crispasr/ggml/src/ggml-cuda/add-id.cuh +3 -0
  184. data/vendor/crispasr/ggml/src/ggml-cuda/arange.cu +34 -0
  185. data/vendor/crispasr/ggml/src/ggml-cuda/arange.cuh +5 -0
  186. data/vendor/crispasr/ggml/src/ggml-cuda/argmax.cu +91 -0
  187. data/vendor/crispasr/ggml/src/ggml-cuda/argmax.cuh +3 -0
  188. data/vendor/crispasr/ggml/src/ggml-cuda/argsort.cu +265 -0
  189. data/vendor/crispasr/ggml/src/ggml-cuda/argsort.cuh +19 -0
  190. data/vendor/crispasr/ggml/src/ggml-cuda/binbcast.cu +534 -0
  191. data/vendor/crispasr/ggml/src/ggml-cuda/binbcast.cuh +12 -0
  192. data/vendor/crispasr/ggml/src/ggml-cuda/clamp.cu +45 -0
  193. data/vendor/crispasr/ggml/src/ggml-cuda/clamp.cuh +5 -0
  194. data/vendor/crispasr/ggml/src/ggml-cuda/col2im-1d.cu +81 -0
  195. data/vendor/crispasr/ggml/src/ggml-cuda/col2im-1d.cuh +3 -0
  196. data/vendor/crispasr/ggml/src/ggml-cuda/common.cuh +1489 -0
  197. data/vendor/crispasr/ggml/src/ggml-cuda/concat.cu +204 -0
  198. data/vendor/crispasr/ggml/src/ggml-cuda/concat.cuh +5 -0
  199. data/vendor/crispasr/ggml/src/ggml-cuda/conv-transpose-1d.cu +97 -0
  200. data/vendor/crispasr/ggml/src/ggml-cuda/conv-transpose-1d.cuh +5 -0
  201. data/vendor/crispasr/ggml/src/ggml-cuda/conv2d-dw.cu +161 -0
  202. data/vendor/crispasr/ggml/src/ggml-cuda/conv2d-dw.cuh +5 -0
  203. data/vendor/crispasr/ggml/src/ggml-cuda/conv2d-transpose.cu +115 -0
  204. data/vendor/crispasr/ggml/src/ggml-cuda/conv2d-transpose.cuh +5 -0
  205. data/vendor/crispasr/ggml/src/ggml-cuda/conv2d.cu +166 -0
  206. data/vendor/crispasr/ggml/src/ggml-cuda/conv2d.cuh +5 -0
  207. data/vendor/crispasr/ggml/src/ggml-cuda/convert.cu +892 -0
  208. data/vendor/crispasr/ggml/src/ggml-cuda/convert.cuh +66 -0
  209. data/vendor/crispasr/ggml/src/ggml-cuda/count-equal.cu +64 -0
  210. data/vendor/crispasr/ggml/src/ggml-cuda/count-equal.cuh +5 -0
  211. data/vendor/crispasr/ggml/src/ggml-cuda/cp-async.cuh +57 -0
  212. data/vendor/crispasr/ggml/src/ggml-cuda/cpy-utils.cuh +217 -0
  213. data/vendor/crispasr/ggml/src/ggml-cuda/cpy.cu +581 -0
  214. data/vendor/crispasr/ggml/src/ggml-cuda/cpy.cuh +7 -0
  215. data/vendor/crispasr/ggml/src/ggml-cuda/cross-entropy-loss.cu +177 -0
  216. data/vendor/crispasr/ggml/src/ggml-cuda/cross-entropy-loss.cuh +7 -0
  217. data/vendor/crispasr/ggml/src/ggml-cuda/cumsum.cu +307 -0
  218. data/vendor/crispasr/ggml/src/ggml-cuda/cumsum.cuh +5 -0
  219. data/vendor/crispasr/ggml/src/ggml-cuda/dequantize.cuh +99 -0
  220. data/vendor/crispasr/ggml/src/ggml-cuda/diag.cu +77 -0
  221. data/vendor/crispasr/ggml/src/ggml-cuda/diag.cuh +5 -0
  222. data/vendor/crispasr/ggml/src/ggml-cuda/diagmask.cu +40 -0
  223. data/vendor/crispasr/ggml/src/ggml-cuda/diagmask.cuh +5 -0
  224. data/vendor/crispasr/ggml/src/ggml-cuda/fattn-common.cuh +1212 -0
  225. data/vendor/crispasr/ggml/src/ggml-cuda/fattn-mma-f16.cuh +1860 -0
  226. data/vendor/crispasr/ggml/src/ggml-cuda/fattn-tile.cu +57 -0
  227. data/vendor/crispasr/ggml/src/ggml-cuda/fattn-tile.cuh +1309 -0
  228. data/vendor/crispasr/ggml/src/ggml-cuda/fattn-vec.cuh +600 -0
  229. data/vendor/crispasr/ggml/src/ggml-cuda/fattn-wmma-f16.cu +696 -0
  230. data/vendor/crispasr/ggml/src/ggml-cuda/fattn-wmma-f16.cuh +51 -0
  231. data/vendor/crispasr/ggml/src/ggml-cuda/fattn.cu +620 -0
  232. data/vendor/crispasr/ggml/src/ggml-cuda/fattn.cuh +5 -0
  233. data/vendor/crispasr/ggml/src/ggml-cuda/fill.cu +37 -0
  234. data/vendor/crispasr/ggml/src/ggml-cuda/fill.cuh +3 -0
  235. data/vendor/crispasr/ggml/src/ggml-cuda/gated_delta_net.cu +273 -0
  236. data/vendor/crispasr/ggml/src/ggml-cuda/gated_delta_net.cuh +4 -0
  237. data/vendor/crispasr/ggml/src/ggml-cuda/getrows.cu +332 -0
  238. data/vendor/crispasr/ggml/src/ggml-cuda/getrows.cuh +15 -0
  239. data/vendor/crispasr/ggml/src/ggml-cuda/ggml-cuda.cu +5580 -0
  240. data/vendor/crispasr/ggml/src/ggml-cuda/gla.cu +93 -0
  241. data/vendor/crispasr/ggml/src/ggml-cuda/gla.cuh +3 -0
  242. data/vendor/crispasr/ggml/src/ggml-cuda/im2col.cu +274 -0
  243. data/vendor/crispasr/ggml/src/ggml-cuda/im2col.cuh +6 -0
  244. data/vendor/crispasr/ggml/src/ggml-cuda/mean.cu +75 -0
  245. data/vendor/crispasr/ggml/src/ggml-cuda/mean.cuh +3 -0
  246. data/vendor/crispasr/ggml/src/ggml-cuda/mma.cuh +1333 -0
  247. data/vendor/crispasr/ggml/src/ggml-cuda/mmf.cu +191 -0
  248. data/vendor/crispasr/ggml/src/ggml-cuda/mmf.cuh +908 -0
  249. data/vendor/crispasr/ggml/src/ggml-cuda/mmid.cu +164 -0
  250. data/vendor/crispasr/ggml/src/ggml-cuda/mmid.cuh +5 -0
  251. data/vendor/crispasr/ggml/src/ggml-cuda/mmq.cu +372 -0
  252. data/vendor/crispasr/ggml/src/ggml-cuda/mmq.cuh +4175 -0
  253. data/vendor/crispasr/ggml/src/ggml-cuda/mmvf.cu +862 -0
  254. data/vendor/crispasr/ggml/src/ggml-cuda/mmvf.cuh +14 -0
  255. data/vendor/crispasr/ggml/src/ggml-cuda/mmvq.cu +1161 -0
  256. data/vendor/crispasr/ggml/src/ggml-cuda/mmvq.cuh +16 -0
  257. data/vendor/crispasr/ggml/src/ggml-cuda/norm.cu +756 -0
  258. data/vendor/crispasr/ggml/src/ggml-cuda/norm.cuh +20 -0
  259. data/vendor/crispasr/ggml/src/ggml-cuda/opt-step-adamw.cu +78 -0
  260. data/vendor/crispasr/ggml/src/ggml-cuda/opt-step-adamw.cuh +5 -0
  261. data/vendor/crispasr/ggml/src/ggml-cuda/opt-step-sgd.cu +49 -0
  262. data/vendor/crispasr/ggml/src/ggml-cuda/opt-step-sgd.cuh +5 -0
  263. data/vendor/crispasr/ggml/src/ggml-cuda/out-prod.cu +68 -0
  264. data/vendor/crispasr/ggml/src/ggml-cuda/out-prod.cuh +3 -0
  265. data/vendor/crispasr/ggml/src/ggml-cuda/pad.cu +106 -0
  266. data/vendor/crispasr/ggml/src/ggml-cuda/pad.cuh +5 -0
  267. data/vendor/crispasr/ggml/src/ggml-cuda/pad_reflect_1d.cu +91 -0
  268. data/vendor/crispasr/ggml/src/ggml-cuda/pad_reflect_1d.cuh +5 -0
  269. data/vendor/crispasr/ggml/src/ggml-cuda/pool2d.cu +94 -0
  270. data/vendor/crispasr/ggml/src/ggml-cuda/pool2d.cuh +5 -0
  271. data/vendor/crispasr/ggml/src/ggml-cuda/quantize.cu +443 -0
  272. data/vendor/crispasr/ggml/src/ggml-cuda/quantize.cuh +41 -0
  273. data/vendor/crispasr/ggml/src/ggml-cuda/reduce_rows.cuh +39 -0
  274. data/vendor/crispasr/ggml/src/ggml-cuda/roll.cu +67 -0
  275. data/vendor/crispasr/ggml/src/ggml-cuda/roll.cuh +5 -0
  276. data/vendor/crispasr/ggml/src/ggml-cuda/rope.cu +665 -0
  277. data/vendor/crispasr/ggml/src/ggml-cuda/rope.cuh +9 -0
  278. data/vendor/crispasr/ggml/src/ggml-cuda/scale.cu +34 -0
  279. data/vendor/crispasr/ggml/src/ggml-cuda/scale.cuh +5 -0
  280. data/vendor/crispasr/ggml/src/ggml-cuda/set-rows.cu +330 -0
  281. data/vendor/crispasr/ggml/src/ggml-cuda/set-rows.cuh +7 -0
  282. data/vendor/crispasr/ggml/src/ggml-cuda/set.cu +39 -0
  283. data/vendor/crispasr/ggml/src/ggml-cuda/set.cuh +7 -0
  284. data/vendor/crispasr/ggml/src/ggml-cuda/softcap.cu +34 -0
  285. data/vendor/crispasr/ggml/src/ggml-cuda/softcap.cuh +5 -0
  286. data/vendor/crispasr/ggml/src/ggml-cuda/softmax.cu +472 -0
  287. data/vendor/crispasr/ggml/src/ggml-cuda/softmax.cuh +7 -0
  288. data/vendor/crispasr/ggml/src/ggml-cuda/solve_tri.cu +275 -0
  289. data/vendor/crispasr/ggml/src/ggml-cuda/solve_tri.cuh +3 -0
  290. data/vendor/crispasr/ggml/src/ggml-cuda/ssm-conv.cu +197 -0
  291. data/vendor/crispasr/ggml/src/ggml-cuda/ssm-conv.cuh +3 -0
  292. data/vendor/crispasr/ggml/src/ggml-cuda/ssm-scan.cu +342 -0
  293. data/vendor/crispasr/ggml/src/ggml-cuda/ssm-scan.cuh +3 -0
  294. data/vendor/crispasr/ggml/src/ggml-cuda/sum.cu +41 -0
  295. data/vendor/crispasr/ggml/src/ggml-cuda/sum.cuh +5 -0
  296. data/vendor/crispasr/ggml/src/ggml-cuda/sumrows.cu +43 -0
  297. data/vendor/crispasr/ggml/src/ggml-cuda/sumrows.cuh +4 -0
  298. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_16.cu +5 -0
  299. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_32.cu +6 -0
  300. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_8.cu +11 -0
  301. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_1.cu +10 -0
  302. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_2.cu +10 -0
  303. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_4.cu +12 -0
  304. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_16.cu +5 -0
  305. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_32.cu +6 -0
  306. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_4.cu +12 -0
  307. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_8.cu +11 -0
  308. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_32-ncols2_1.cu +10 -0
  309. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_32-ncols2_2.cu +10 -0
  310. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_16.cu +5 -0
  311. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_2.cu +10 -0
  312. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_4.cu +12 -0
  313. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_8.cu +11 -0
  314. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_64-ncols2_1.cu +10 -0
  315. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_1.cu +10 -0
  316. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_2.cu +10 -0
  317. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_4.cu +12 -0
  318. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_8.cu +11 -0
  319. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq112-dv112.cu +5 -0
  320. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq128-dv128.cu +5 -0
  321. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq256-dv256.cu +5 -0
  322. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq320-dv256.cu +5 -0
  323. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq40-dv40.cu +5 -0
  324. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq512-dv512.cu +5 -0
  325. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq576-dv512.cu +5 -0
  326. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq64-dv64.cu +5 -0
  327. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq72-dv72.cu +5 -0
  328. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq80-dv80.cu +5 -0
  329. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq96-dv96.cu +5 -0
  330. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-bf16.cu +7 -0
  331. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-f16.cu +7 -0
  332. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q4_0.cu +7 -0
  333. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q4_1.cu +7 -0
  334. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q5_0.cu +7 -0
  335. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q5_1.cu +7 -0
  336. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q8_0.cu +7 -0
  337. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-bf16.cu +7 -0
  338. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-f16.cu +7 -0
  339. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q4_0.cu +7 -0
  340. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q4_1.cu +7 -0
  341. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q5_0.cu +7 -0
  342. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q5_1.cu +7 -0
  343. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q8_0.cu +7 -0
  344. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-bf16.cu +7 -0
  345. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-f16.cu +7 -0
  346. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q4_0.cu +7 -0
  347. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q4_1.cu +7 -0
  348. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q5_0.cu +7 -0
  349. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q5_1.cu +7 -0
  350. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q8_0.cu +7 -0
  351. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-bf16.cu +7 -0
  352. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-f16.cu +7 -0
  353. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q4_0.cu +7 -0
  354. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q4_1.cu +7 -0
  355. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q5_0.cu +7 -0
  356. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q5_1.cu +7 -0
  357. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q8_0.cu +7 -0
  358. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-bf16.cu +7 -0
  359. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-f16.cu +7 -0
  360. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q4_0.cu +7 -0
  361. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q4_1.cu +7 -0
  362. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q5_0.cu +7 -0
  363. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q5_1.cu +7 -0
  364. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q8_0.cu +7 -0
  365. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-bf16.cu +7 -0
  366. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-f16.cu +7 -0
  367. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q4_0.cu +7 -0
  368. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q4_1.cu +7 -0
  369. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q5_0.cu +7 -0
  370. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q5_1.cu +7 -0
  371. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q8_0.cu +7 -0
  372. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-bf16.cu +7 -0
  373. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-f16.cu +7 -0
  374. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q4_0.cu +7 -0
  375. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q4_1.cu +7 -0
  376. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q5_0.cu +7 -0
  377. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q5_1.cu +7 -0
  378. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q8_0.cu +7 -0
  379. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_1.cu +5 -0
  380. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_10.cu +5 -0
  381. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_11.cu +5 -0
  382. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_12.cu +5 -0
  383. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_13.cu +5 -0
  384. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_14.cu +5 -0
  385. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_15.cu +5 -0
  386. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_16.cu +5 -0
  387. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_2.cu +5 -0
  388. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_3.cu +5 -0
  389. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_4.cu +5 -0
  390. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_5.cu +5 -0
  391. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_6.cu +5 -0
  392. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_7.cu +5 -0
  393. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_8.cu +5 -0
  394. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_9.cu +5 -0
  395. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq1_s.cu +5 -0
  396. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_s.cu +5 -0
  397. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_xs.cu +5 -0
  398. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_xxs.cu +5 -0
  399. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq3_s.cu +5 -0
  400. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq3_xxs.cu +5 -0
  401. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq4_nl.cu +5 -0
  402. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq4_xs.cu +5 -0
  403. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-mxfp4.cu +5 -0
  404. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-nvfp4.cu +5 -0
  405. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q1_0.cu +5 -0
  406. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q2_k.cu +5 -0
  407. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q3_k.cu +5 -0
  408. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q4_0.cu +5 -0
  409. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q4_1.cu +5 -0
  410. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q4_k.cu +5 -0
  411. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q5_0.cu +5 -0
  412. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q5_1.cu +5 -0
  413. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q5_k.cu +5 -0
  414. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q6_k.cu +5 -0
  415. data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q8_0.cu +5 -0
  416. data/vendor/crispasr/ggml/src/ggml-cuda/top-k.cu +95 -0
  417. data/vendor/crispasr/ggml/src/ggml-cuda/top-k.cuh +3 -0
  418. data/vendor/crispasr/ggml/src/ggml-cuda/topk-moe.cu +415 -0
  419. data/vendor/crispasr/ggml/src/ggml-cuda/topk-moe.cuh +27 -0
  420. data/vendor/crispasr/ggml/src/ggml-cuda/tri.cu +136 -0
  421. data/vendor/crispasr/ggml/src/ggml-cuda/tri.cuh +5 -0
  422. data/vendor/crispasr/ggml/src/ggml-cuda/tsembd.cu +47 -0
  423. data/vendor/crispasr/ggml/src/ggml-cuda/tsembd.cuh +5 -0
  424. data/vendor/crispasr/ggml/src/ggml-cuda/unary.cu +644 -0
  425. data/vendor/crispasr/ggml/src/ggml-cuda/unary.cuh +116 -0
  426. data/vendor/crispasr/ggml/src/ggml-cuda/upscale.cu +293 -0
  427. data/vendor/crispasr/ggml/src/ggml-cuda/upscale.cuh +5 -0
  428. data/vendor/crispasr/ggml/src/ggml-cuda/vecdotq.cuh +1317 -0
  429. data/vendor/crispasr/ggml/src/ggml-cuda/vendors/cuda.h +28 -0
  430. data/vendor/crispasr/ggml/src/ggml-cuda/vendors/hip.h +306 -0
  431. data/vendor/crispasr/ggml/src/ggml-cuda/vendors/musa.h +148 -0
  432. data/vendor/crispasr/ggml/src/ggml-cuda/wkv.cu +199 -0
  433. data/vendor/crispasr/ggml/src/ggml-cuda/wkv.cuh +7 -0
  434. data/vendor/crispasr/ggml/src/ggml-impl.h +783 -0
  435. data/vendor/crispasr/ggml/src/ggml-metal/CMakeLists.txt +124 -0
  436. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-common.cpp +457 -0
  437. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-common.h +52 -0
  438. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-context.h +41 -0
  439. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-context.m +778 -0
  440. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-device.cpp +2117 -0
  441. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-device.h +299 -0
  442. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-device.m +2093 -0
  443. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-impl.h +1267 -0
  444. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-ops.cpp +5023 -0
  445. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-ops.h +111 -0
  446. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal.cpp +954 -0
  447. data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal.metal +11756 -0
  448. data/vendor/crispasr/ggml/src/ggml-opt.cpp +1094 -0
  449. data/vendor/crispasr/ggml/src/ggml-quants.c +5491 -0
  450. data/vendor/crispasr/ggml/src/ggml-quants.h +112 -0
  451. data/vendor/crispasr/ggml/src/ggml-threading.cpp +12 -0
  452. data/vendor/crispasr/ggml/src/ggml-threading.h +14 -0
  453. data/vendor/crispasr/ggml/src/ggml.c +7925 -0
  454. data/vendor/crispasr/ggml/src/ggml.cpp +26 -0
  455. data/vendor/crispasr/ggml/src/gguf.cpp +1556 -0
  456. data/vendor/crispasr/src/cohere-arch.h +137 -0
  457. data/vendor/crispasr/src/cohere.cpp +5642 -0
  458. data/vendor/crispasr/src/cohere.h +327 -0
  459. data/vendor/crispasr/src/cohere_batch_planner.h +82 -0
  460. data/vendor/crispasr/src/cohere_chunking.h +64 -0
  461. data/vendor/crispasr/src/cohere_decoder_batch_layout.h +60 -0
  462. data/vendor/crispasr/src/cohere_encoder_padded_layout.h +27 -0
  463. data/vendor/crispasr/src/cohere_frontend.cpp +189 -0
  464. data/vendor/crispasr/src/cohere_frontend.h +31 -0
  465. data/vendor/crispasr/src/cohere_ragged_controller.h +149 -0
  466. data/vendor/crispasr/src/cohere_token_renderer.h +181 -0
  467. data/vendor/crispasr/src/core/attention.h +924 -0
  468. data/vendor/crispasr/src/core/audio_chunking.h +97 -0
  469. data/vendor/crispasr/src/core/beam_decode.h +486 -0
  470. data/vendor/crispasr/src/core/cpu_ops.h +135 -0
  471. data/vendor/crispasr/src/core/gguf_loader.cpp +1021 -0
  472. data/vendor/crispasr/src/core/gguf_loader.h +216 -0
  473. data/vendor/crispasr/src/core/gpu_backend_pref.h +119 -0
  474. data/vendor/crispasr/src/core/mel.cpp +519 -0
  475. data/vendor/crispasr/src/core/mel.h +265 -0
  476. data/vendor/crispasr/src/core/ngram_loop_fix.h +173 -0
  477. data/vendor/crispasr/src/core/repetition_loop_guard.h +54 -0
  478. data/vendor/crispasr/src/crispasr_imatrix.cpp +255 -0
  479. data/vendor/crispasr/src/crispasr_imatrix.h +38 -0
  480. metadata +596 -0
@@ -0,0 +1,390 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+ require "fileutils"
5
+ require "json"
6
+ require "tempfile"
7
+
8
+ module Cohere
9
+ module Transcribe
10
+ module Runtime
11
+ # Resolves native Transformers Dense checkpoints, downloads only their
12
+ # required artifacts, converts them once to CrispASR GGUF, and retains no
13
+ # Python-side state.
14
+ class ModelProvider
15
+ # Increment whenever conversion semantics or the native tensor types
16
+ # written to GGUF change. Version 2 adds first-class BF16 artifacts.
17
+ CACHE_LAYOUT_VERSION = 2
18
+
19
+ attr_reader :cache_dir, :hub
20
+
21
+ def initialize(hub: Hub.new, cache_dir: nil, native_session_class: nil,
22
+ converter: nil)
23
+ @hub = hub
24
+ root = cache_dir || ENV["COHERE_TRANSCRIBE_CACHE"] ||
25
+ File.join(ENV.fetch("XDG_CACHE_HOME", File.expand_path("~/.cache")), "cohere-transcribe")
26
+ @cache_dir = Pathname(root).expand_path
27
+ @native_session_class = native_session_class
28
+ @converter = converter
29
+ end
30
+
31
+ # Planning may discover that every requested output can be resumed from
32
+ # a checkpoint. Defer multi-gigabyte weight discovery until #open unless
33
+ # a caller explicitly asks to validate inference artifacts now.
34
+ def resolve(options, verify_model_weights: false)
35
+ identity = ModelIdentity.resolve(
36
+ path_text(options.model),
37
+ options.model_revision,
38
+ path_text(options.adapter),
39
+ options.adapter_revision,
40
+ hub: hub,
41
+ verify_weight_artifacts: verify_model_weights
42
+ )
43
+ unless identity.model_format == :dense
44
+ raise TranscriptionConfigurationError,
45
+ "Saved #{identity.model_format} checkpoints are outside the core Dense Ruby inference path"
46
+ end
47
+ if identity.adapter_id
48
+ raise TranscriptionConfigurationError,
49
+ "PEFT/LoRA adapters are not supported by the native Ruby Dense runtime"
50
+ end
51
+
52
+ identity
53
+ end
54
+
55
+ def open(identity, options)
56
+ ModelIdentity.verify_model_weight_artifacts(identity, hub: hub)
57
+ path = converted_model_path(identity, options)
58
+ (@native_session_class || ASR::NativeSession).new(path, options)
59
+ rescue ArgumentError, TypeError, Hub::Error => e
60
+ raise TranscriptionRuntimeError, e.message
61
+ end
62
+
63
+ def converted_model_path(identity, options)
64
+ model_directory = materialize_source(identity)
65
+ output_type = { "fp32" => :f32, "bf16" => :bf16 }.fetch(options.dtype, :f16)
66
+ fingerprint = source_fingerprint(identity, model_directory, output_type)
67
+ directory = conversion_cache_directory
68
+ output = directory.join("#{fingerprint}-#{output_type}.gguf")
69
+ return output if valid_gguf?(output, fingerprint: fingerprint, output_type: output_type)
70
+
71
+ lock_path = Pathname("#{output}.lock")
72
+ open_conversion_lock(lock_path) do |lock|
73
+ raise TranscriptionRuntimeError, "Cannot acquire Dense conversion lock for #{output}" unless lock.flock(File::LOCK_EX)
74
+ return output if valid_gguf?(output, fingerprint: fingerprint, output_type: output_type)
75
+
76
+ cleanup_conversion_temporaries(output)
77
+ remove_cache_entry(output)
78
+ remove_cache_entry(conversion_marker(output))
79
+ begin
80
+ converter.convert(
81
+ model_dir: model_directory,
82
+ output_path: output,
83
+ output_type: output_type,
84
+ overwrite: false,
85
+ fsync: true
86
+ )
87
+ unless source_fingerprint(identity, model_directory, output_type) == fingerprint
88
+ raise TranscriptionRuntimeError,
89
+ "Dense checkpoint changed during Dense conversion; retry with a stable model directory"
90
+ end
91
+ write_conversion_marker(output, fingerprint: fingerprint, output_type: output_type)
92
+ rescue Exception # rubocop:disable Lint/RescueException -- clean partial artifacts before propagating interrupts
93
+ remove_cache_entry(output)
94
+ remove_cache_entry(conversion_marker(output))
95
+ raise
96
+ end
97
+ end
98
+ unless valid_gguf?(output, fingerprint: fingerprint, output_type: output_type)
99
+ raise TranscriptionRuntimeError,
100
+ "Dense conversion did not produce a valid GGUF file at #{output}"
101
+ end
102
+
103
+ output
104
+ rescue DenseConverter::Error, Safetensors::Error, PyTorchCheckpoint::Error, GGUF::Error => e
105
+ raise TranscriptionRuntimeError, "Cannot convert Dense Cohere checkpoint: #{e.message}"
106
+ rescue Hub::Error => e
107
+ raise TranscriptionRuntimeError, e.message
108
+ rescue SystemCallError => e
109
+ raise TranscriptionRuntimeError, "Cannot prepare native Dense model: #{e.message}"
110
+ end
111
+
112
+ def materialize_source(identity)
113
+ local = Pathname(identity.model_id).expand_path
114
+ return local.realpath if local.directory?
115
+
116
+ revision = identity.model_revision
117
+ raise TranscriptionRuntimeError, "Remote model identity has no immutable revision" unless revision
118
+
119
+ DenseConverter::REQUIRED_ARTIFACT_FILENAMES.each do |filename|
120
+ hub.download(identity.model_id, filename, revision: revision)
121
+ end
122
+ snapshot = hub.snapshot_path(identity.model_id, revision)
123
+ return snapshot if hub.cached_file(identity.model_id, "model.safetensors", revision: revision)
124
+ return snapshot if hub.cached_file(identity.model_id, "pytorch_model.bin", revision: revision)
125
+
126
+ safetensors_index = hub.cached_file(
127
+ identity.model_id, "model.safetensors.index.json", revision: revision
128
+ )
129
+ if safetensors_index
130
+ download_index_shards(identity, safetensors_index, extension: ".safetensors", label: "Safetensors")
131
+ return snapshot
132
+ end
133
+ pytorch_index = hub.cached_file(
134
+ identity.model_id, "pytorch_model.bin.index.json", revision: revision
135
+ )
136
+ if pytorch_index
137
+ download_index_shards(identity, pytorch_index, extension: ".bin", label: "PyTorch")
138
+ return snapshot
139
+ end
140
+
141
+ files = hub.list_files(identity.model_id, revision: revision)
142
+ if files.include?("model.safetensors")
143
+ hub.download(identity.model_id, "model.safetensors", revision: revision)
144
+ elsif files.include?("model.safetensors.index.json")
145
+ index = hub.download(identity.model_id, "model.safetensors.index.json", revision: revision)
146
+ download_index_shards(identity, index, extension: ".safetensors", label: "Safetensors")
147
+ elsif files.include?("pytorch_model.bin")
148
+ hub.download(identity.model_id, "pytorch_model.bin", revision: revision)
149
+ elsif files.include?("pytorch_model.bin.index.json")
150
+ index = hub.download(identity.model_id, "pytorch_model.bin.index.json", revision: revision)
151
+ download_index_shards(identity, index, extension: ".bin", label: "PyTorch")
152
+ else
153
+ raise TranscriptionRuntimeError,
154
+ "#{identity.model_id}@#{revision} has no supported Dense Safetensors or PyTorch weights"
155
+ end
156
+ snapshot
157
+ end
158
+
159
+ private
160
+
161
+ def converter
162
+ @converter ||= DenseConverter
163
+ end
164
+
165
+ def conversion_cache_directory
166
+ FileUtils.mkdir_p(cache_dir)
167
+ cache_root = cache_dir.realpath
168
+ directory = cache_dir.join("dense-v#{CACHE_LAYOUT_VERSION}")
169
+ begin
170
+ Dir.mkdir(directory, 0o700)
171
+ rescue Errno::EEXIST
172
+ nil
173
+ end
174
+ stat = directory.lstat
175
+ unless stat.directory? && !stat.symlink? && directory.parent.realpath == cache_root
176
+ raise TranscriptionRuntimeError,
177
+ "Dense conversion cache directory is not a regular directory: #{directory}"
178
+ end
179
+
180
+ directory
181
+ rescue TranscriptionRuntimeError
182
+ raise
183
+ rescue SystemCallError => e
184
+ raise TranscriptionRuntimeError,
185
+ "Cannot prepare Dense conversion cache directory: #{e.message}"
186
+ end
187
+
188
+ def open_conversion_lock(path)
189
+ flags = File::RDWR | File::CREAT
190
+ flags |= File::NOFOLLOW if defined?(File::NOFOLLOW)
191
+ flags |= File::CLOEXEC if defined?(File::CLOEXEC)
192
+ descriptor = ::IO.sysopen(path.to_s, flags, 0o600)
193
+ lock = File.new(descriptor, "r+", autoclose: true)
194
+ descriptor = nil
195
+ opened = lock.stat
196
+ current = path.lstat
197
+ unless opened.file? && !current.symlink? && opened.dev == current.dev && opened.ino == current.ino
198
+ raise TranscriptionRuntimeError,
199
+ "Dense conversion lock changed while it was being opened or is not regular: #{path}"
200
+ end
201
+
202
+ yield lock
203
+ rescue Errno::ELOOP, Errno::EISDIR, Errno::ENXIO => e
204
+ raise TranscriptionRuntimeError, "Dense conversion lock is not a regular file: #{path}", cause: e
205
+ ensure
206
+ lock&.close
207
+ ::IO.new(descriptor).close if descriptor
208
+ end
209
+
210
+ def path_text(value)
211
+ value.respond_to?(:to_path) ? value.to_path : value
212
+ end
213
+
214
+ def download_index_shards(identity, index_path, extension:, label:)
215
+ payload = JSON.parse(Pathname(index_path).read(encoding: "UTF-8"))
216
+ weights = payload.is_a?(Hash) ? payload["weight_map"] : nil
217
+ unless weights.is_a?(Hash) && !weights.empty? &&
218
+ weights.all? { |name, filename| name.is_a?(String) && !name.empty? && filename.is_a?(String) }
219
+ raise TranscriptionRuntimeError, "#{label} index #{index_path} has an invalid weight_map"
220
+ end
221
+
222
+ filenames = weights.values.uniq
223
+ filenames.each do |filename|
224
+ if filename.empty? || filename.include?("\0")
225
+ raise TranscriptionRuntimeError, "#{label} index contains an invalid shard name: #{filename.inspect}"
226
+ end
227
+
228
+ path = Pathname(filename)
229
+ unless !path.absolute? &&
230
+ path.each_filename.none? { |part| part == ".." } && filename.end_with?(extension)
231
+ raise TranscriptionRuntimeError, "#{label} index contains an invalid shard name: #{filename.inspect}"
232
+ end
233
+
234
+ hub.download(identity.model_id, filename, revision: identity.model_revision)
235
+ end
236
+ rescue JSON::ParserError, EncodingError => e
237
+ raise TranscriptionRuntimeError, "Cannot parse #{label} index #{index_path}: #{e.message}"
238
+ end
239
+
240
+ def source_fingerprint(identity, directory, output_type)
241
+ digest = Digest::SHA256.new
242
+ digest << "cohere-transcribe-dense\0#{CACHE_LAYOUT_VERSION}\0#{output_type}\0"
243
+ digest << identity.model_id.to_s << "\0" << identity.model_revision.to_s << "\0"
244
+ source_files(directory).each do |path|
245
+ stat = path.stat
246
+ digest << path.relative_path_from(directory).to_s << "\0"
247
+ digest << stat.size.to_s << "\0" << stat.mtime.to_r.to_s << "\0"
248
+ # A same-size rewrite can deliberately preserve mtime. ctime is
249
+ # kernel-managed and still invalidates that stale conversion.
250
+ digest << stat.ctime.to_r.to_s << "\0"
251
+ end
252
+ digest.hexdigest
253
+ end
254
+
255
+ def source_files(directory)
256
+ files = DenseConverter::REQUIRED_ARTIFACT_FILENAMES.map { |name| directory.join(name) }
257
+ single = directory.join("model.safetensors")
258
+ if single.file?
259
+ files << single
260
+ elsif directory.join("model.safetensors.index.json").file?
261
+ index = directory.join("model.safetensors.index.json")
262
+ files << index
263
+ payload = JSON.parse(index.read(encoding: "UTF-8"))
264
+ weights = payload.is_a?(Hash) ? payload["weight_map"] : nil
265
+ unless weights.is_a?(Hash) && !weights.empty? &&
266
+ weights.all? { |name, file| name.is_a?(String) && !name.empty? && file.is_a?(String) }
267
+ raise TranscriptionRuntimeError,
268
+ "Cannot fingerprint Dense checkpoint: " \
269
+ "Safetensors index #{index} has an invalid weight_map"
270
+ end
271
+
272
+ shard_names = weights.values.uniq
273
+ shard_names.each do |name|
274
+ next if valid_safetensors_shard_name?(name)
275
+
276
+ raise TranscriptionRuntimeError,
277
+ "Cannot fingerprint Dense checkpoint: " \
278
+ "Safetensors index #{index} contains an invalid shard path #{name.inspect}"
279
+ end
280
+ shard_names.sort.each { |name| files << directory.join(name) }
281
+ elsif directory.join("pytorch_model.bin").file?
282
+ files << directory.join("pytorch_model.bin")
283
+ else
284
+ index = directory.join("pytorch_model.bin.index.json")
285
+ files << index
286
+ tensor_set = PyTorchCheckpoint::TensorSet.from_directory(directory)
287
+ files.concat(tensor_set.readers.map(&:path))
288
+ end
289
+ missing = files.reject(&:file?)
290
+ raise TranscriptionRuntimeError, "Dense checkpoint is missing: #{missing.join(", ")}" unless missing.empty?
291
+
292
+ files.sort_by(&:to_s)
293
+ rescue JSON::ParserError, KeyError => e
294
+ raise TranscriptionRuntimeError, "Cannot fingerprint Dense checkpoint: #{e.message}"
295
+ end
296
+
297
+ def valid_safetensors_shard_name?(name)
298
+ return false if name.empty? || name.include?("\0")
299
+
300
+ candidate = Pathname(name)
301
+ !candidate.absolute? && candidate.each_filename.none? { |part| part == ".." }
302
+ end
303
+
304
+ def conversion_marker(path)
305
+ Pathname("#{path}.complete.json")
306
+ end
307
+
308
+ def remove_cache_entry(path)
309
+ path.delete
310
+ rescue Errno::ENOENT
311
+ nil
312
+ end
313
+
314
+ def cleanup_conversion_temporaries(output)
315
+ [output, conversion_marker(output)].each do |target|
316
+ pattern = target.dirname.join(".#{target.basename}*.tmp")
317
+ Dir.glob(pattern.to_s).each do |path|
318
+ File.unlink(path)
319
+ rescue Errno::ENOENT
320
+ nil
321
+ end
322
+ end
323
+ end
324
+
325
+ def valid_gguf?(path, fingerprint:, output_type:)
326
+ stat = path.lstat
327
+ return false unless stat.file? && !stat.symlink? && stat.size > 32
328
+ return false unless path.open("rb") { |file| file.read(4) == "GGUF" }
329
+
330
+ marker = conversion_marker(path)
331
+ marker_stat = marker.lstat
332
+ return false unless marker_stat.file? && !marker_stat.symlink? && marker_stat.size.between?(1, 16_384)
333
+
334
+ payload = JSON.parse(marker.read(encoding: "UTF-8"))
335
+ payload == conversion_marker_payload(
336
+ stat,
337
+ fingerprint: fingerprint,
338
+ output_type: output_type
339
+ )
340
+ rescue JSON::ParserError, EncodingError, SystemCallError
341
+ false
342
+ end
343
+
344
+ def write_conversion_marker(path, fingerprint:, output_type:)
345
+ stat = path.lstat
346
+ unless stat.file? && !stat.symlink? && stat.size > 32 &&
347
+ path.open("rb") { |file| file.read(4) == "GGUF" }
348
+ raise TranscriptionRuntimeError, "Dense conversion produced an invalid GGUF file at #{path}"
349
+ end
350
+
351
+ marker = conversion_marker(path)
352
+ payload = conversion_marker_payload(
353
+ stat,
354
+ fingerprint: fingerprint,
355
+ output_type: output_type
356
+ )
357
+ Tempfile.create([".#{marker.basename}", ".tmp"], marker.dirname, binmode: true) do |temporary|
358
+ temporary.chmod(0o600)
359
+ temporary.write(JSON.generate(payload))
360
+ temporary.write("\n")
361
+ temporary.flush
362
+ temporary.fsync
363
+ temporary.close
364
+ File.rename(temporary.path, marker)
365
+ end
366
+ begin
367
+ File.open(marker.dirname, File::RDONLY, &:fsync)
368
+ rescue Errno::EINVAL, Errno::ENOTSUP, Errno::EISDIR
369
+ nil
370
+ end
371
+ marker
372
+ end
373
+
374
+ def conversion_marker_payload(stat, fingerprint:, output_type:)
375
+ {
376
+ "schema_version" => 1,
377
+ "cache_layout_version" => CACHE_LAYOUT_VERSION,
378
+ "source_fingerprint" => fingerprint,
379
+ "output_type" => output_type.to_s,
380
+ "device" => stat.dev,
381
+ "inode" => stat.ino,
382
+ "size" => stat.size,
383
+ "mtime_ns" => (stat.mtime.to_i * 1_000_000_000) + stat.mtime.nsec,
384
+ "ctime_ns" => (stat.ctime.to_i * 1_000_000_000) + stat.ctime.nsec
385
+ }
386
+ end
387
+ end
388
+ end
389
+ end
390
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fiddle"
4
+
5
+ module Cohere
6
+ module Transcribe
7
+ module Runtime
8
+ # Resolves public device/precision requests against the native runtime
9
+ # before any input is decoded. The returned options describe what will
10
+ # actually execute; an unavailable explicit accelerator is never allowed
11
+ # to fall through to ggml's command-line-oriented CPU fallback.
12
+ module Precision
13
+ module_function
14
+
15
+ def resolve(options, native_library: nil)
16
+ library = native_library
17
+ device = if options.device == "cpu"
18
+ "cpu"
19
+ else
20
+ library ||= ASR::NativeLibrary.load
21
+ library.resolve_device(options.device)
22
+ end
23
+ dtype = resolved_dtype(options.dtype, device, library)
24
+ if options.alignment == "word" && options.align_dtype == "fp16" && device != "cuda"
25
+ raise TranscriptionRuntimeError,
26
+ "--align-dtype fp16 is supported only with CUDA"
27
+ end
28
+
29
+ vad_engine = options.vad == "silero" ? "onnx" : options.vad_engine
30
+ options.with(device: device, dtype: dtype, vad_engine: vad_engine)
31
+ rescue TranscriptionError
32
+ raise
33
+ rescue Fiddle::DLError, LoadError, SystemCallError => e
34
+ raise TranscriptionRuntimeError,
35
+ "Cannot resolve the native inference device: #{e.class}: #{e.message}"
36
+ end
37
+
38
+ def resolved_dtype(requested, device, native_library)
39
+ return "fp32" if device == "cpu"
40
+
41
+ resolved = if requested == "auto"
42
+ device == "cuda" && native_library&.supports_bf16?(device) ? "bf16" : "fp16"
43
+ else
44
+ requested
45
+ end
46
+ if resolved == "bf16" && !native_library&.supports_bf16?(device)
47
+ label = device == "mps" ? "MPS device/runtime" : "CUDA device"
48
+ raise TranscriptionRuntimeError,
49
+ "This #{label} does not support BF16; use --dtype fp16"
50
+ end
51
+ resolved
52
+ end
53
+ private_class_method :resolved_dtype
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,215 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "etc"
4
+
5
+ require_relative "../audio/ffmpeg_native"
6
+
7
+ module Cohere
8
+ module Transcribe
9
+ module Runtime
10
+ module Preparation
11
+ MAX_PIPELINE_GROUP_BYTES = 512 * (1024**2)
12
+ MAX_GROUP_JOBS = 128
13
+
14
+ # The result of decode and VAD preparation. Timings are accumulated by
15
+ # the engine on the consuming thread, keeping statistics deterministic.
16
+ PreparedEntry = Data.define(
17
+ :item,
18
+ :snapshot,
19
+ :decoded,
20
+ :duration,
21
+ :segment_times,
22
+ :speech_spans,
23
+ :vad_details,
24
+ :decode_seconds,
25
+ :vad_seconds,
26
+ :error
27
+ )
28
+
29
+ # Bounded ordered preparation with at most one group ahead of ASR.
30
+ #
31
+ # A pipelined group receives at most half of the configured decoded-PCM
32
+ # budget (and never more than 512 MiB). Jobs inside it divide that cap,
33
+ # so the current and one in-flight next group cannot together exceed the
34
+ # configured PCM budget. Native decoder implementation transients are
35
+ # outside this retained-PCM accounting, as they are in the Python path.
36
+ class Pipeline
37
+ include Enumerable
38
+
39
+ class WorkerPool
40
+ STOP = Object.new.freeze
41
+
42
+ def initialize(size, &prepare)
43
+ @prepare = prepare
44
+ @queues = Array.new(size) { Queue.new }
45
+ @threads = @queues.each_with_index.map do |queue, slot|
46
+ Thread.new do
47
+ Thread.current.name = "cohere-audio-prep-#{slot}" if Thread.current.respond_to?(:name=)
48
+ loop do
49
+ task = queue.pop
50
+ break if task.equal?(STOP)
51
+
52
+ item, limit, response = task
53
+ begin
54
+ response << [:ok, @prepare.call(item, limit, slot)]
55
+ rescue Exception => e # rubocop:disable Lint/RescueException -- transport fatal worker errors
56
+ response << [:error, e]
57
+ end
58
+ end
59
+ end.tap { |thread| thread.report_on_exception = false }
60
+ end
61
+ end
62
+
63
+ def prepare(group, per_file_limit)
64
+ responses = group.each_with_index.map do |item, slot|
65
+ response = Queue.new
66
+ @queues.fetch(slot) << [item, per_file_limit, response]
67
+ response
68
+ end
69
+ responses.map do |response|
70
+ status, value = response.pop
71
+ raise value if status == :error
72
+
73
+ value
74
+ end
75
+ end
76
+
77
+ def close(cancel:)
78
+ if cancel
79
+ Audio::FFmpegNative.cancel_active!
80
+ @threads.each { |thread| thread.kill if thread.alive? }
81
+ else
82
+ @queues.each { |queue| queue << STOP }
83
+ end
84
+ @threads.each(&:join)
85
+ end
86
+ end
87
+ private_constant :WorkerPool
88
+
89
+ attr_reader :effective_workers, :group_byte_limit, :memory_byte_limit, :wait_seconds
90
+
91
+ def initialize(items, memory_byte_limit:, requested_workers:, enabled:, worker_limit: nil, &prepare)
92
+ raise ArgumentError, "prepare block is required" unless prepare
93
+
94
+ @items = items.to_a.freeze
95
+ @memory_byte_limit = Integer(memory_byte_limit)
96
+ raise ArgumentError, "memory_byte_limit must be positive" unless @memory_byte_limit.positive?
97
+
98
+ @prepare = prepare
99
+ @wait_seconds = 0.0
100
+ @enabled = enabled && @items.length > 1
101
+ @worker_limit = worker_limit.nil? ? nil : Integer(worker_limit)
102
+ raise ArgumentError, "worker_limit must be positive" if @worker_limit && !@worker_limit.positive?
103
+
104
+ @group_byte_limit = if @enabled
105
+ [[@memory_byte_limit / 2, 1].max, MAX_PIPELINE_GROUP_BYTES].min
106
+ else
107
+ @memory_byte_limit
108
+ end
109
+ @effective_workers = resolve_workers(requested_workers)
110
+ end
111
+
112
+ def pipelined?
113
+ @enabled
114
+ end
115
+
116
+ def each(&block)
117
+ return enum_for(__method__) unless block
118
+ return if @items.empty?
119
+
120
+ unless pipelined?
121
+ @items.each { |item| block.call(@prepare.call(item, @memory_byte_limit, 0)) }
122
+ return
123
+ end
124
+
125
+ groups = @items.each_slice(@effective_workers).to_a
126
+ pool = WorkerPool.new(@effective_workers, &@prepare)
127
+ pending = submit(groups.first, 0, pool)
128
+ groups.each_with_index do |_group, group_index|
129
+ prepared = resolve(pending)
130
+ pending = nil
131
+ pending = submit(groups.fetch(group_index + 1), group_index + 1, pool) if group_index + 1 < groups.length
132
+ consume(prepared, &block)
133
+ end
134
+ completed = true
135
+ ensure
136
+ cancel(pending) if defined?(pending) && pending
137
+ pool&.close(cancel: !completed) if defined?(pool) && pool
138
+ end
139
+
140
+ private
141
+
142
+ def resolve_workers(requested)
143
+ return 1 if @items.empty?
144
+
145
+ processors = Etc.nprocessors
146
+ processors = 1 unless processors.is_a?(Integer) && processors.positive?
147
+ automatic = if @items.length == 1
148
+ 1
149
+ else
150
+ [2, @items.length, [processors / 2, 1].max].min
151
+ end
152
+ value = requested.nil? ? automatic : Integer(requested)
153
+ raise ArgumentError, "requested_workers must be positive" unless value.positive?
154
+
155
+ return 1 unless @enabled
156
+
157
+ limits = [value, @items.length, processors, MAX_GROUP_JOBS, @group_byte_limit]
158
+ limits << @worker_limit if @worker_limit
159
+ limits.min
160
+ rescue SystemCallError
161
+ value = requested.nil? ? 2 : Integer(requested)
162
+ limits = [value, @items.length, MAX_GROUP_JOBS, @group_byte_limit]
163
+ limits << @worker_limit if @worker_limit
164
+ limits.min
165
+ end
166
+
167
+ def submit(group, group_index, pool)
168
+ Thread.new do
169
+ Thread.current.name = "cohere-audio-group-#{group_index}" if Thread.current.respond_to?(:name=)
170
+ prepare_group(group, pool)
171
+ end.tap { |thread| thread.report_on_exception = false }
172
+ end
173
+
174
+ def resolve(thread)
175
+ started = monotonic
176
+ thread.value
177
+ ensure
178
+ @wait_seconds += monotonic - started if started
179
+ end
180
+
181
+ def prepare_group(group, pool)
182
+ per_file_limit = [@group_byte_limit / group.length, 1].max
183
+ pool.prepare(group, per_file_limit)
184
+ end
185
+
186
+ def consume(prepared, &block)
187
+ prepared.each_index do |index|
188
+ entry = prepared.fetch(index)
189
+ begin
190
+ block.call(entry)
191
+ ensure
192
+ prepared[index] = nil
193
+ end
194
+ end
195
+ ensure
196
+ prepared&.clear
197
+ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true)
198
+ end
199
+
200
+ def cancel(thread)
201
+ Audio::FFmpegNative.cancel_active!
202
+ thread.kill if thread.alive?
203
+ thread.join
204
+ rescue Exception # rubocop:disable Lint/RescueException -- preserve the caller's active exception
205
+ nil
206
+ end
207
+
208
+ def monotonic
209
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end