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,268 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tempfile"
4
+
5
+ module Cohere
6
+ module Transcribe
7
+ # Small GGUF v3 writer tailored to streaming model conversion. Tensor data
8
+ # is supplied by callbacks, so the writer never retains model weights.
9
+ module GGUF
10
+ class Error < StandardError; end
11
+
12
+ MAGIC = "GGUF".b.freeze
13
+ VERSION = 3
14
+ DEFAULT_ALIGNMENT = 32
15
+
16
+ VALUE_TYPES = {
17
+ uint8: 0,
18
+ int8: 1,
19
+ uint16: 2,
20
+ int16: 3,
21
+ uint32: 4,
22
+ int32: 5,
23
+ float32: 6,
24
+ bool: 7,
25
+ string: 8,
26
+ array: 9,
27
+ uint64: 10,
28
+ int64: 11,
29
+ float64: 12
30
+ }.freeze
31
+
32
+ TENSOR_TYPES = {
33
+ f32: 0,
34
+ f16: 1,
35
+ bf16: 30
36
+ }.freeze
37
+ TENSOR_WIDTHS = {
38
+ f32: 4,
39
+ f16: 2,
40
+ bf16: 2
41
+ }.freeze
42
+
43
+ Metadata = Data.define(:type, :value, :element_type)
44
+ Tensor = Data.define(:name, :shape, :dtype, :nbytes, :write_data)
45
+
46
+ # Produces a GGUF v3 document from metadata and streaming tensor writers.
47
+ class Writer
48
+ attr_reader :metadata, :tensors, :alignment
49
+
50
+ def initialize(alignment: DEFAULT_ALIGNMENT)
51
+ unless alignment.is_a?(Integer) && alignment.positive? && alignment.nobits?(alignment - 1)
52
+ raise ArgumentError, "GGUF alignment must be a positive power of two"
53
+ end
54
+
55
+ @alignment = alignment
56
+ @metadata = {}
57
+ @tensors = []
58
+ add_uint32("general.alignment", alignment) unless alignment == DEFAULT_ALIGNMENT
59
+ end
60
+
61
+ def add_string(key, value)
62
+ add_metadata(key, :string, String(value))
63
+ end
64
+
65
+ def add_uint32(key, value)
66
+ add_metadata(key, :uint32, unsigned_integer(value, bits: 32))
67
+ end
68
+
69
+ def add_uint64(key, value)
70
+ add_metadata(key, :uint64, unsigned_integer(value, bits: 64))
71
+ end
72
+
73
+ def add_float32(key, value)
74
+ add_metadata(key, :float32, Float(value))
75
+ end
76
+
77
+ def add_bool(key, value)
78
+ raise ArgumentError, "GGUF bool metadata must be true or false" unless [true, false].include?(value)
79
+
80
+ add_metadata(key, :bool, value)
81
+ end
82
+
83
+ def add_string_array(key, values)
84
+ values = values.map { |value| String(value) }.freeze
85
+ raise ArgumentError, "GGUF arrays must not be empty" if values.empty?
86
+
87
+ add_metadata(key, :array, values, element_type: :string)
88
+ end
89
+
90
+ def add_tensor(name, shape:, dtype:, &write_data)
91
+ name = String(name)
92
+ raise ArgumentError, "GGUF tensor name must not be empty" if name.empty?
93
+ raise ArgumentError, "GGUF tensor #{name.inspect} has no data writer" unless write_data
94
+ raise ArgumentError, "Duplicate GGUF tensor name #{name.inspect}" if tensors.any? { |tensor| tensor.name == name }
95
+
96
+ shape = Array(shape)
97
+ unless !shape.empty? && shape.all? { |dimension| dimension.is_a?(Integer) && dimension.positive? }
98
+ raise ArgumentError, "GGUF tensor #{name.inspect} has an invalid shape"
99
+ end
100
+
101
+ dtype = dtype.to_sym
102
+ width = TENSOR_WIDTHS[dtype]
103
+ raise ArgumentError, "Unsupported GGUF tensor dtype #{dtype.inspect}" unless width
104
+
105
+ elements = shape.reduce(1, :*)
106
+ tensors << Tensor.new(
107
+ name: name.freeze,
108
+ shape: shape.freeze,
109
+ dtype: dtype,
110
+ nbytes: elements * width,
111
+ write_data: write_data
112
+ )
113
+ self
114
+ end
115
+
116
+ def write(path, overwrite: false, fsync: true)
117
+ output = Pathname(path).expand_path
118
+ raise Error, "Output directory #{output.dirname} does not exist" unless output.dirname.directory?
119
+ raise Error, "Output file #{output} already exists" if output.exist? && !overwrite
120
+
121
+ temporary = Tempfile.new([".#{output.basename}", ".tmp"], output.dirname.to_s)
122
+ temporary.binmode
123
+ begin
124
+ write_to(temporary)
125
+ temporary.flush
126
+ temporary.fsync if fsync
127
+ temporary.close
128
+ raise Error, "Output file #{output} already exists" if output.exist? && !overwrite
129
+
130
+ if overwrite
131
+ File.rename(temporary.path, output)
132
+ else
133
+ # A same-directory hard link is an atomic no-replace publish on
134
+ # POSIX filesystems. It closes the existence-check race where a
135
+ # concurrent writer could otherwise be silently overwritten by
136
+ # rename(2).
137
+ begin
138
+ File.link(temporary.path, output)
139
+ rescue Errno::EEXIST
140
+ raise Error, "Output file #{output} already exists"
141
+ end
142
+ temporary.unlink
143
+ end
144
+ sync_directory(output.dirname) if fsync
145
+ ensure
146
+ temporary.close unless temporary.closed?
147
+ temporary.unlink
148
+ end
149
+ output
150
+ rescue Errno::EACCES, Errno::ENOSPC, Errno::EROFS => e
151
+ raise Error, "Cannot write GGUF file #{output}: #{e.message}"
152
+ end
153
+
154
+ def write_to(io)
155
+ validate_document!
156
+ io.write(MAGIC)
157
+ io.write([VERSION].pack("L<"))
158
+ io.write([tensors.length, metadata.length].pack("Q<Q<"))
159
+ metadata.each do |key, entry|
160
+ write_string(io, key)
161
+ io.write([VALUE_TYPES.fetch(entry.type)].pack("L<"))
162
+ write_value(io, entry.type, entry.value, element_type: entry.element_type)
163
+ end
164
+
165
+ offset = 0
166
+ tensors.each do |tensor|
167
+ write_string(io, tensor.name)
168
+ io.write([tensor.shape.length].pack("L<"))
169
+ io.write(tensor.shape.reverse.pack("Q<*"))
170
+ io.write([TENSOR_TYPES.fetch(tensor.dtype)].pack("L<"))
171
+ io.write([offset].pack("Q<"))
172
+ offset += padded(tensor.nbytes)
173
+ end
174
+
175
+ write_padding(io, io.pos)
176
+ tensors.each do |tensor|
177
+ before = io.pos
178
+ tensor.write_data.call(io)
179
+ actual = io.pos - before
180
+ if actual != tensor.nbytes
181
+ raise Error,
182
+ "Tensor #{tensor.name.inspect} wrote #{actual} bytes; expected #{tensor.nbytes}"
183
+ end
184
+ write_padding(io, tensor.nbytes)
185
+ end
186
+ io
187
+ end
188
+
189
+ private
190
+
191
+ def sync_directory(path)
192
+ File.open(path, File::RDONLY, &:fsync)
193
+ rescue Errno::EINVAL, Errno::ENOTSUP, Errno::EISDIR
194
+ nil
195
+ end
196
+
197
+ def unsigned_integer(value, bits:)
198
+ integer = begin
199
+ Integer(value)
200
+ rescue ArgumentError, TypeError
201
+ raise ArgumentError, "GGUF uint#{bits} metadata must be an integer"
202
+ end
203
+ return integer if integer.between?(0, (1 << bits) - 1)
204
+
205
+ raise ArgumentError, "GGUF uint#{bits} metadata is outside its representable range"
206
+ end
207
+
208
+ def add_metadata(key, type, value, element_type: nil)
209
+ key = String(key)
210
+ raise ArgumentError, "GGUF metadata key must not be empty" if key.empty?
211
+ raise ArgumentError, "Duplicate GGUF metadata key #{key.inspect}" if metadata.key?(key)
212
+
213
+ metadata[key.freeze] = Metadata.new(type: type, value: value, element_type: element_type)
214
+ self
215
+ end
216
+
217
+ def validate_document!
218
+ raise Error, "GGUF document contains no tensors" if tensors.empty?
219
+ return if metadata.key?("general.architecture")
220
+
221
+ raise Error, "GGUF document is missing general.architecture"
222
+ end
223
+
224
+ def write_value(io, type, value, element_type: nil)
225
+ case type
226
+ when :uint8 then io.write([value].pack("C"))
227
+ when :int8 then io.write([value].pack("c"))
228
+ when :uint16 then io.write([value].pack("S<"))
229
+ when :int16 then io.write([value].pack("s<"))
230
+ when :uint32 then io.write([value].pack("L<"))
231
+ when :int32 then io.write([value].pack("l<"))
232
+ when :float32 then io.write([value].pack("e"))
233
+ when :bool then io.write([value ? 1 : 0].pack("C"))
234
+ when :string then write_string(io, value)
235
+ when :uint64 then io.write([value].pack("Q<"))
236
+ when :int64 then io.write([value].pack("q<"))
237
+ when :float64 then io.write([value].pack("E"))
238
+ when :array
239
+ io.write([VALUE_TYPES.fetch(element_type)].pack("L<"))
240
+ io.write([value.length].pack("Q<"))
241
+ value.each { |item| write_value(io, element_type, item) }
242
+ else
243
+ raise Error, "Unsupported GGUF metadata type #{type.inspect}"
244
+ end
245
+ end
246
+
247
+ def write_string(io, value)
248
+ encoded = value.encode(Encoding::UTF_8)
249
+ raise Error, "GGUF strings must contain valid UTF-8" unless encoded.valid_encoding?
250
+
251
+ io.write([encoded.bytesize].pack("Q<"))
252
+ io.write(encoded.b)
253
+ rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError => e
254
+ raise Error, "Cannot encode GGUF string as UTF-8: #{e.message}"
255
+ end
256
+
257
+ def padded(bytes)
258
+ ((bytes + alignment - 1) / alignment) * alignment
259
+ end
260
+
261
+ def write_padding(io, bytes)
262
+ count = padded(bytes) - bytes
263
+ io.write("\0".b * count) if count.positive?
264
+ end
265
+ end
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,436 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "digest"
5
+ require "json"
6
+ require "net/http"
7
+ require "tempfile"
8
+ require "uri"
9
+
10
+ module Cohere
11
+ module Transcribe
12
+ # Minimal Hugging Face Hub client used by the native Ruby runtime. It uses
13
+ # the standard Hub cache layout, so artifacts already fetched by other Hub
14
+ # clients are reused without copying multi-gigabyte model weights.
15
+ class Hub
16
+ class Error < StandardError; end
17
+ class AuthenticationError < Error; end
18
+ class NotFoundError < Error; end
19
+
20
+ COMMIT_PATTERN = /\A[0-9a-f]{40}\z/i
21
+ DEFAULT_ENDPOINT = "https://huggingface.co"
22
+
23
+ attr_reader :cache_dir, :endpoint
24
+
25
+ def initialize(cache_dir: nil, endpoint: nil, token: nil)
26
+ hf_home = ENV.fetch("HF_HOME", File.expand_path("~/.cache/huggingface"))
27
+ @cache_dir = Pathname(cache_dir || ENV.fetch("HF_HUB_CACHE", File.join(hf_home, "hub"))).expand_path
28
+ @endpoint = (endpoint || ENV.fetch("HF_ENDPOINT", DEFAULT_ENDPOINT)).sub(%r{/+\z}, "")
29
+ @endpoint_uri = URI(@endpoint)
30
+ @token = token || ENV["HF_TOKEN"] || cached_token(hf_home)
31
+ end
32
+
33
+ def resolve_revision(repo_id, revision = nil, filename: "config.json")
34
+ validate_repo_id!(repo_id)
35
+ requested = revision || "main"
36
+ validate_revision!(requested)
37
+ return requested.downcase if COMMIT_PATTERN.match?(requested)
38
+
39
+ if (cached = cached_revision(repo_id, requested, filename: filename))
40
+ return cached
41
+ end
42
+
43
+ encoded_repo = repo_id.split("/").map { |part| URI.encode_www_form_component(part) }.join("/")
44
+ encoded_revision = URI.encode_www_form_component(requested)
45
+ response = request(URI("#{endpoint}/api/models/#{encoded_repo}/revision/#{encoded_revision}"))
46
+ payload = JSON.parse(response.body)
47
+ commit = payload["sha"]
48
+ unless commit.is_a?(String) && COMMIT_PATTERN.match?(commit)
49
+ raise Error, "Hub returned no immutable commit for #{repo_id.inspect} at #{requested.inspect}"
50
+ end
51
+
52
+ write_ref(repo_id, requested, commit.downcase)
53
+ commit.downcase
54
+ rescue JSON::ParserError => e
55
+ raise Error, "Invalid Hub response while resolving #{repo_id.inspect}: #{e.message}"
56
+ end
57
+
58
+ def download(repo_id, filename, revision: nil)
59
+ validate_filename!(filename)
60
+ commit = resolve_revision(repo_id, revision, filename: filename)
61
+ repository = cache_dir.join(cache_repo_name(repo_id))
62
+ destination = repository.join("snapshots", commit, filename)
63
+ return destination if safe_cached_file(repository, destination)
64
+
65
+ prepare_cache_directory!(repository, destination.dirname)
66
+ encoded_repo = repo_id.split("/").map { |part| URI.encode_www_form_component(part) }.join("/")
67
+ encoded_filename = filename.split("/").map { |part| URI.encode_www_form_component(part) }.join("/")
68
+ uri = URI("#{endpoint}/#{encoded_repo}/resolve/#{commit}/#{encoded_filename}")
69
+
70
+ open_download_lock(download_lock_path(destination)) do |lock|
71
+ raise Error, "Cannot acquire Hub download lock for #{destination}" unless lock.flock(File::LOCK_EX)
72
+ return destination if safe_cached_file(repository, destination)
73
+
74
+ cleanup_download_temporaries(destination)
75
+ Tempfile.create(
76
+ [download_temporary_prefix(destination), ".download"],
77
+ destination.dirname.to_s,
78
+ binmode: true
79
+ ) do |temporary|
80
+ request(uri, stream: temporary)
81
+ temporary.flush
82
+ temporary.fsync
83
+ temporary.close
84
+ File.rename(temporary.path, destination)
85
+ end
86
+ sync_directory(destination.dirname)
87
+ end
88
+ destination
89
+ rescue Errno::EACCES, Errno::ENOSPC, Errno::EROFS => e
90
+ raise Error, "Cannot cache #{repo_id}/#{filename}: #{e.message}"
91
+ end
92
+
93
+ def list_files(repo_id, revision: nil)
94
+ commit = resolve_revision(repo_id, revision)
95
+ encoded_repo = repo_id.split("/").map { |part| URI.encode_www_form_component(part) }.join("/")
96
+ response = request(URI("#{endpoint}/api/models/#{encoded_repo}/revision/#{commit}"))
97
+ payload = JSON.parse(response.body)
98
+ siblings = payload["siblings"]
99
+ raise Error, "Hub returned no repository file list for #{repo_id}@#{commit}" unless siblings.is_a?(Array)
100
+
101
+ siblings.filter_map do |item|
102
+ name = item.is_a?(Hash) ? item["rfilename"] : nil
103
+ name if name.is_a?(String)
104
+ end.freeze
105
+ rescue JSON::ParserError => e
106
+ raise Error, "Invalid Hub response while listing #{repo_id.inspect}: #{e.message}"
107
+ end
108
+
109
+ def snapshot_path(repo_id, commit)
110
+ validate_repo_id!(repo_id)
111
+ raise ArgumentError, "Invalid immutable Hub commit: #{commit.inspect}" unless commit.is_a?(String) && COMMIT_PATTERN.match?(commit)
112
+
113
+ cache_dir.join(cache_repo_name(repo_id), "snapshots", commit)
114
+ end
115
+
116
+ def cached_file(repo_id, filename, revision: nil)
117
+ validate_repo_id!(repo_id)
118
+ validate_filename!(filename)
119
+ validate_revision!(revision) if revision
120
+ commit = if revision && COMMIT_PATTERN.match?(revision)
121
+ revision.downcase
122
+ else
123
+ cached_revision(repo_id, revision || "main", filename: filename)
124
+ end
125
+ return unless commit
126
+
127
+ repository = cache_dir.join(cache_repo_name(repo_id))
128
+ path = repository.join("snapshots", commit, filename)
129
+ safe_cached_file(repository, path)
130
+ end
131
+
132
+ private
133
+
134
+ def request(uri, stream: nil, redirects: 0)
135
+ raise Error, "Too many redirects while fetching #{uri}" if redirects > 8
136
+
137
+ request = Net::HTTP::Get.new(uri)
138
+ request["Authorization"] = "Bearer #{@token}" if @token && !@token.empty? && trusted_authorization_origin?(uri)
139
+ # Keep Content-Length comparable to the bytes written below. Net::HTTP
140
+ # otherwise permits transparent content decoding.
141
+ request["Accept-Encoding"] = "identity"
142
+ request["User-Agent"] = "cohere-transcribe-ruby/#{Cohere::Transcribe::VERSION}"
143
+ response = Net::HTTP.start(
144
+ uri.host,
145
+ uri.port,
146
+ use_ssl: uri.scheme == "https",
147
+ open_timeout: 30,
148
+ read_timeout: 300
149
+ ) do |http|
150
+ if stream
151
+ http.request(request) do |incoming|
152
+ case incoming
153
+ when Net::HTTPSuccess
154
+ written = 0
155
+ incoming.read_body do |chunk|
156
+ count = stream.write(chunk)
157
+ unless count == chunk.bytesize
158
+ raise Error,
159
+ "Cannot write the complete Hub response body for #{uri}: " \
160
+ "wrote #{count.inspect} of #{chunk.bytesize} bytes"
161
+ end
162
+ written += count
163
+ end
164
+ expected = response_content_length(incoming, uri)
165
+ if expected && written != expected
166
+ raise Error,
167
+ "Hub returned an incomplete response body for #{uri}: " \
168
+ "received #{written} bytes, expected #{expected}"
169
+ end
170
+ when Net::HTTPRedirection
171
+ return request(resolve_redirect(uri, incoming), stream: stream, redirects: redirects + 1)
172
+ else
173
+ raise_http_error!(incoming, uri)
174
+ end
175
+ end
176
+ else
177
+ http.request(request)
178
+ end
179
+ end
180
+
181
+ return response if stream
182
+ return response if response.is_a?(Net::HTTPSuccess)
183
+ return request(resolve_redirect(uri, response), redirects: redirects + 1) if response.is_a?(Net::HTTPRedirection)
184
+
185
+ raise_http_error!(response, uri)
186
+ rescue Timeout::Error, SocketError, SystemCallError, EOFError,
187
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, OpenSSL::SSL::SSLError => e
188
+ raise Error, "Cannot reach Hugging Face Hub at #{uri}: #{e.class}: #{e.message}"
189
+ end
190
+
191
+ def response_content_length(response, uri)
192
+ value = response["content-length"]
193
+ return unless value
194
+ return Integer(value, 10) if value.match?(/\A[0-9]+\z/)
195
+
196
+ raise Error, "Hub returned an invalid Content-Length for #{uri}: #{value.inspect}"
197
+ end
198
+
199
+ def resolve_redirect(base, response)
200
+ location = response["location"]
201
+ raise Error, "Hub redirect from #{base} did not include a location" unless location
202
+
203
+ URI.join(base.to_s, location)
204
+ end
205
+
206
+ def trusted_authorization_origin?(uri)
207
+ uri.scheme == @endpoint_uri.scheme && uri.host == @endpoint_uri.host &&
208
+ uri.port == @endpoint_uri.port
209
+ end
210
+
211
+ def raise_http_error!(response, uri)
212
+ detail = begin
213
+ parsed = JSON.parse(response.body.to_s)
214
+ parsed["error"] || parsed["message"]
215
+ rescue JSON::ParserError
216
+ nil
217
+ end
218
+ detail ||= response.message
219
+ message = "Hugging Face request failed (#{response.code}) for #{uri}: #{detail}"
220
+ case response.code.to_i
221
+ when 401, 403 then raise AuthenticationError, message
222
+ when 404 then raise NotFoundError, message
223
+ else raise Error, message
224
+ end
225
+ end
226
+
227
+ def cached_revision(repo_id, revision, filename:)
228
+ repository = cache_dir.join(cache_repo_name(repo_id))
229
+ candidates = []
230
+ ref = revision_path(repository, revision)
231
+ cached_ref = safe_cached_file(repository, ref)
232
+ candidates << cached_ref.read.strip if cached_ref
233
+ candidates << revision if COMMIT_PATTERN.match?(revision)
234
+ candidates.find do |candidate|
235
+ COMMIT_PATTERN.match?(candidate) &&
236
+ safe_cached_file(repository, repository.join("snapshots", candidate, filename))
237
+ end
238
+ rescue SystemCallError
239
+ nil
240
+ end
241
+
242
+ def write_ref(repo_id, revision, commit)
243
+ repository = cache_dir.join(cache_repo_name(repo_id))
244
+ path = revision_path(repository, revision)
245
+ prepare_cache_directory!(repository, path.dirname)
246
+ # Resolution can happen concurrently in separate Transcriber facades.
247
+ # A PID-only temporary name lets those threads truncate or rename the
248
+ # same file out from under one another. Each writer instead publishes a
249
+ # complete, durable ref from its own file; every competing value is an
250
+ # immutable commit, so the final atomic rename remains consistent.
251
+ Tempfile.create([".cohere-transcribe-ref-", ".tmp"], path.dirname.to_s) do |temporary|
252
+ temporary.write("#{commit}\n")
253
+ temporary.flush
254
+ temporary.fsync
255
+ temporary.close
256
+ File.rename(temporary.path, path)
257
+ end
258
+ sync_directory(path.dirname)
259
+ end
260
+
261
+ def safe_cached_file(repository, path)
262
+ return unless path.file?
263
+
264
+ cache_root = cache_dir.realpath
265
+ repository_stat = repository.lstat
266
+ return if repository_stat.symlink? || !repository_stat.directory?
267
+ return unless repository.parent.realpath == cache_root
268
+
269
+ repository_root = repository.realpath
270
+ resolved = path.realpath
271
+ return unless resolved.file? && within_directory?(resolved, repository_root)
272
+
273
+ path
274
+ rescue SystemCallError
275
+ nil
276
+ end
277
+
278
+ def download_cache_key(destination)
279
+ Digest::SHA256.hexdigest(destination.basename.to_s)[0, 24]
280
+ end
281
+
282
+ def download_lock_path(destination)
283
+ destination.dirname.join(".cohere-transcribe-#{download_cache_key(destination)}.download.lock")
284
+ end
285
+
286
+ def download_temporary_prefix(destination)
287
+ "cohere-transcribe-#{download_cache_key(destination)}-"
288
+ end
289
+
290
+ def cleanup_download_temporaries(destination)
291
+ pattern = destination.dirname.join("#{download_temporary_prefix(destination)}*.download")
292
+ Dir.glob(pattern.to_s).each do |path|
293
+ File.unlink(path)
294
+ rescue Errno::ENOENT
295
+ nil
296
+ end
297
+ end
298
+
299
+ def open_download_lock(path)
300
+ flags = File::RDWR | File::CREAT
301
+ flags |= File::NOFOLLOW if defined?(File::NOFOLLOW)
302
+ flags |= File::CLOEXEC if defined?(File::CLOEXEC)
303
+ descriptor = ::IO.sysopen(path.to_s, flags, 0o600)
304
+ lock = File.new(descriptor, "r+", autoclose: true)
305
+ descriptor = nil
306
+ opened = lock.stat
307
+ current = path.lstat
308
+ unless opened.file? && !current.symlink? && opened.dev == current.dev && opened.ino == current.ino
309
+ raise Error, "Hub download lock changed while it was being opened or is not regular: #{path}"
310
+ end
311
+
312
+ yield lock
313
+ rescue Errno::ELOOP, Errno::EISDIR, Errno::ENXIO => e
314
+ raise Error, "Hub download lock is not a regular file: #{path}", cause: e
315
+ ensure
316
+ lock&.close
317
+ ::IO.new(descriptor).close if descriptor
318
+ end
319
+
320
+ # Build each repository subdirectory only after proving that its parent is
321
+ # still inside this repository. This prevents a poisoned snapshots/refs
322
+ # symlink from redirecting a Tempfile and rename outside the cache.
323
+ def prepare_cache_directory!(repository, directory)
324
+ FileUtils.mkdir_p(cache_dir)
325
+ cache_root = cache_dir.realpath
326
+ begin
327
+ Dir.mkdir(repository, 0o755)
328
+ rescue Errno::EEXIST
329
+ nil
330
+ end
331
+
332
+ repository_stat = repository.lstat
333
+ unless repository_stat.directory? && !repository_stat.symlink? &&
334
+ repository.parent.realpath == cache_root
335
+ raise Error, "Hub cache repository is not a regular directory: #{repository}"
336
+ end
337
+
338
+ repository_root = repository.realpath
339
+ relative = directory.relative_path_from(repository)
340
+ if relative.absolute? || relative.each_filename.any? { |part| part == ".." }
341
+ raise Error, "Hub cache path #{directory} escapes its repository cache #{repository}"
342
+ end
343
+
344
+ current = repository
345
+ relative.each_filename do |part|
346
+ next if part == "."
347
+
348
+ current = current.join(part)
349
+ begin
350
+ Dir.mkdir(current, 0o755)
351
+ rescue Errno::EEXIST
352
+ nil
353
+ end
354
+ resolved = current.realpath
355
+ unless resolved.directory? && within_directory?(resolved, repository_root)
356
+ raise Error, "Hub cache path #{current} escapes its repository cache #{repository}"
357
+ end
358
+ end
359
+ directory
360
+ rescue Error
361
+ raise
362
+ rescue SystemCallError => e
363
+ raise Error, "Cannot prepare Hub cache directory #{directory}: #{e.message}"
364
+ end
365
+
366
+ def within_directory?(path, directory)
367
+ path_text = path.to_s
368
+ directory_text = directory.to_s
369
+ path_text == directory_text || path_text.start_with?("#{directory_text}#{File::SEPARATOR}")
370
+ end
371
+
372
+ def sync_directory(path)
373
+ File.open(path, File::RDONLY, &:fsync)
374
+ rescue Errno::EINVAL, Errno::ENOTSUP, Errno::EISDIR
375
+ nil
376
+ end
377
+
378
+ def cached_token(hf_home)
379
+ token_path = File.join(hf_home, "token")
380
+ File.file?(token_path) ? File.read(token_path).strip : nil
381
+ rescue Errno::EACCES
382
+ nil
383
+ end
384
+
385
+ def cache_repo_name(repo_id)
386
+ "models--#{repo_id.gsub("/", "--")}"
387
+ end
388
+
389
+ def validate_repo_id!(repo_id)
390
+ valid = if repo_id.is_a?(String) && repo_id.length.between?(1, 96) && repo_id.count("/") <= 1 &&
391
+ !repo_id.include?("..") && !repo_id.include?("--") && !repo_id.end_with?(".git")
392
+ repo_id.split("/").all? do |part|
393
+ part.match?(/\A[[:alnum:]_](?:[[:alnum:]_.-]*[[:alnum:]_])?\z/)
394
+ end
395
+ else
396
+ false
397
+ end
398
+ raise ArgumentError, "Invalid Hugging Face model repository ID: #{repo_id.inspect}" unless valid
399
+ end
400
+
401
+ def validate_filename!(filename)
402
+ raise ArgumentError, "Invalid Hub filename: #{filename.inspect}" unless filename.is_a?(String)
403
+
404
+ path = Pathname(filename)
405
+ safe_components = path.each_filename.none? do |part|
406
+ part == "." || part == ".." || part.empty?
407
+ end
408
+ valid = !filename.empty? && !filename.include?("\0") && !path.absolute? &&
409
+ !filename.start_with?("/") && !filename.end_with?("/") &&
410
+ safe_components
411
+ raise ArgumentError, "Invalid Hub filename: #{filename.inspect}" unless valid
412
+ end
413
+
414
+ def validate_revision!(revision)
415
+ safe_components = revision.is_a?(String) && Pathname(revision).each_filename.none? do |part|
416
+ part == "." || part == ".." || part.empty?
417
+ end
418
+ valid = revision.is_a?(String) && !revision.empty? && !revision.include?("\0") &&
419
+ revision == revision.strip && !Pathname(revision).absolute? &&
420
+ !revision.start_with?("/") && !revision.end_with?("/") &&
421
+ safe_components
422
+ raise ArgumentError, "Invalid Hugging Face revision: #{revision.inspect}" unless valid
423
+ end
424
+
425
+ def revision_path(repository, revision)
426
+ validate_revision!(revision)
427
+ refs = repository.join("refs").expand_path
428
+ path = refs.join(revision).expand_path
429
+ prefix = "#{refs}#{File::SEPARATOR}"
430
+ raise ArgumentError, "Invalid Hugging Face revision: #{revision.inspect}" unless path.to_s.start_with?(prefix)
431
+
432
+ path
433
+ end
434
+ end
435
+ end
436
+ end