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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +21 -0
- data/LICENSE.txt +201 -0
- data/NOTICE +5 -0
- data/README.md +265 -0
- data/THIRD_PARTY_NOTICES.md +67 -0
- data/exe/cohere-transcribe +8 -0
- data/exe/cohere-transcribe-doctor +8 -0
- data/ext/cohere_transcribe_native/CMakeLists.txt +262 -0
- data/ext/cohere_transcribe_native/README.md +26 -0
- data/ext/cohere_transcribe_native/audio_abi.cpp +1416 -0
- data/ext/cohere_transcribe_native/audio_exports.macos +5 -0
- data/ext/cohere_transcribe_native/audio_exports.map +10 -0
- data/ext/cohere_transcribe_native/cohere_abi.cpp +1209 -0
- data/ext/cohere_transcribe_native/exports.macos +40 -0
- data/ext/cohere_transcribe_native/exports.map +45 -0
- data/ext/cohere_transcribe_native/extconf.rb +89 -0
- data/ext/cohere_transcribe_native/test/abi_smoke.rb +232 -0
- data/ext/cohere_transcribe_native/test/audio_matrix_smoke.cpp +121 -0
- data/ext/cohere_transcribe_native/test/audio_reliability_smoke.cpp +198 -0
- data/ext/cohere_transcribe_native/test/native_abi_reliability_smoke.cpp +186 -0
- data/ext/cohere_transcribe_native/test/native_batch_projection_probe.rb +81 -0
- data/ext/cohere_transcribe_native/test/native_cancellation_smoke.cpp +194 -0
- data/lib/cohere/transcribe/alignment/ATTRIBUTION.md +23 -0
- data/lib/cohere/transcribe/alignment/LICENSE.ctc-forced-aligner +407 -0
- data/lib/cohere/transcribe/alignment/LICENSE.torchaudio +25 -0
- data/lib/cohere/transcribe/alignment/LICENSE.uroman +26 -0
- data/lib/cohere/transcribe/alignment/aligner.rb +476 -0
- data/lib/cohere/transcribe/alignment/ctc.rb +224 -0
- data/lib/cohere/transcribe/alignment/text.rb +237 -0
- data/lib/cohere/transcribe/alignment/uroman_data.rb +4950 -0
- data/lib/cohere/transcribe/api.rb +173 -0
- data/lib/cohere/transcribe/asr/batching.rb +472 -0
- data/lib/cohere/transcribe/asr/failure_policy.rb +112 -0
- data/lib/cohere/transcribe/asr/native.rb +676 -0
- data/lib/cohere/transcribe/audio/ATTRIBUTION.md +8 -0
- data/lib/cohere/transcribe/audio/LICENSE.auditok +21 -0
- data/lib/cohere/transcribe/audio/decoder.rb +315 -0
- data/lib/cohere/transcribe/audio/ffmpeg_native.rb +248 -0
- data/lib/cohere/transcribe/audio/segmentation.rb +260 -0
- data/lib/cohere/transcribe/cli.rb +727 -0
- data/lib/cohere/transcribe/configuration.rb +282 -0
- data/lib/cohere/transcribe/constants.rb +14 -0
- data/lib/cohere/transcribe/dense_converter.rb +548 -0
- data/lib/cohere/transcribe/doctor.rb +576 -0
- data/lib/cohere/transcribe/errors.rb +57 -0
- data/lib/cohere/transcribe/gguf_writer.rb +268 -0
- data/lib/cohere/transcribe/hub.rb +436 -0
- data/lib/cohere/transcribe/input.rb +110 -0
- data/lib/cohere/transcribe/licenses/crispasr.txt +21 -0
- data/lib/cohere/transcribe/loader.rb +128 -0
- data/lib/cohere/transcribe/model_identity.rb +440 -0
- data/lib/cohere/transcribe/output/publication.rb +1118 -0
- data/lib/cohere/transcribe/output/rendering.rb +105 -0
- data/lib/cohere/transcribe/output/timing.rb +86 -0
- data/lib/cohere/transcribe/python_text.rb +70 -0
- data/lib/cohere/transcribe/pytorch_checkpoint.rb +1180 -0
- data/lib/cohere/transcribe/runtime/engine.rb +1676 -0
- data/lib/cohere/transcribe/runtime/model_provider.rb +390 -0
- data/lib/cohere/transcribe/runtime/precision.rb +57 -0
- data/lib/cohere/transcribe/runtime/preparation.rb +215 -0
- data/lib/cohere/transcribe/runtime/resources.rb +165 -0
- data/lib/cohere/transcribe/runtime/word_pipeline.rb +364 -0
- data/lib/cohere/transcribe/safetensors.rb +579 -0
- data/lib/cohere/transcribe/state/checkpoint.rb +224 -0
- data/lib/cohere/transcribe/state/contracts.rb +141 -0
- data/lib/cohere/transcribe/state/io.rb +727 -0
- data/lib/cohere/transcribe/state/locking.rb +211 -0
- data/lib/cohere/transcribe/state/manifest.rb +155 -0
- data/lib/cohere/transcribe/state.rb +7 -0
- data/lib/cohere/transcribe/types.rb +535 -0
- data/lib/cohere/transcribe/vad/ATTRIBUTION.md +14 -0
- data/lib/cohere/transcribe/vad/LICENSE.faster-whisper +21 -0
- data/lib/cohere/transcribe/vad/LICENSE.silero-vad +21 -0
- data/lib/cohere/transcribe/vad/silero.rb +344 -0
- data/lib/cohere/transcribe/vad/silero_vad_v6.onnx +0 -0
- data/lib/cohere/transcribe/vad/timestamps.rb +219 -0
- data/lib/cohere/transcribe/version.rb +7 -0
- data/lib/cohere/transcribe.rb +26 -0
- data/sig/cohere/transcribe.rbs +250 -0
- data/vendor/crispasr/AUTHORS +510 -0
- data/vendor/crispasr/LICENSE +21 -0
- data/vendor/crispasr/UPSTREAM.md +9 -0
- data/vendor/crispasr/VERSION +1 -0
- data/vendor/crispasr/ggml/AUTHORS +335 -0
- data/vendor/crispasr/ggml/CMakeLists.txt +512 -0
- data/vendor/crispasr/ggml/LICENSE +21 -0
- data/vendor/crispasr/ggml/README.md +49 -0
- data/vendor/crispasr/ggml/cmake/FindNCCL.cmake +36 -0
- data/vendor/crispasr/ggml/cmake/GitVars.cmake +22 -0
- data/vendor/crispasr/ggml/cmake/common.cmake +50 -0
- data/vendor/crispasr/ggml/cmake/ggml-config.cmake.in +191 -0
- data/vendor/crispasr/ggml/ggml.pc.in +10 -0
- data/vendor/crispasr/ggml/include/ggml-alloc.h +85 -0
- data/vendor/crispasr/ggml/include/ggml-backend.h +431 -0
- data/vendor/crispasr/ggml/include/ggml-blas.h +25 -0
- data/vendor/crispasr/ggml/include/ggml-cann.h +123 -0
- data/vendor/crispasr/ggml/include/ggml-cpp.h +39 -0
- data/vendor/crispasr/ggml/include/ggml-cpu.h +151 -0
- data/vendor/crispasr/ggml/include/ggml-cuda.h +50 -0
- data/vendor/crispasr/ggml/include/ggml-hexagon.h +19 -0
- data/vendor/crispasr/ggml/include/ggml-metal.h +61 -0
- data/vendor/crispasr/ggml/include/ggml-opencl.h +26 -0
- data/vendor/crispasr/ggml/include/ggml-openvino.h +37 -0
- data/vendor/crispasr/ggml/include/ggml-opt.h +256 -0
- data/vendor/crispasr/ggml/include/ggml-rpc.h +35 -0
- data/vendor/crispasr/ggml/include/ggml-sycl.h +49 -0
- data/vendor/crispasr/ggml/include/ggml-virtgpu.h +14 -0
- data/vendor/crispasr/ggml/include/ggml-vulkan.h +29 -0
- data/vendor/crispasr/ggml/include/ggml-webgpu.h +19 -0
- data/vendor/crispasr/ggml/include/ggml-zdnn.h +17 -0
- data/vendor/crispasr/ggml/include/ggml-zendnn.h +22 -0
- data/vendor/crispasr/ggml/include/ggml.h +2887 -0
- data/vendor/crispasr/ggml/include/gguf.h +204 -0
- data/vendor/crispasr/ggml/src/CMakeLists.txt +493 -0
- data/vendor/crispasr/ggml/src/ggml-alloc.c +1323 -0
- data/vendor/crispasr/ggml/src/ggml-backend-dl.cpp +48 -0
- data/vendor/crispasr/ggml/src/ggml-backend-dl.h +44 -0
- data/vendor/crispasr/ggml/src/ggml-backend-impl.h +275 -0
- data/vendor/crispasr/ggml/src/ggml-backend-meta.cpp +2145 -0
- data/vendor/crispasr/ggml/src/ggml-backend-reg.cpp +586 -0
- data/vendor/crispasr/ggml/src/ggml-backend.cpp +2437 -0
- data/vendor/crispasr/ggml/src/ggml-common.h +1900 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/CMakeLists.txt +718 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/amx/amx.cpp +249 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/amx/amx.h +8 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/amx/common.h +115 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/amx/mmq.cpp +2512 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/amx/mmq.h +10 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/arm/cpu-feats.cpp +98 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/arm/quants.c +4244 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/arm/repack.cpp +5156 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/loongarch/quants.c +2158 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/powerpc/cpu-feats.cpp +82 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/powerpc/quants.c +2304 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/riscv/cpu-feats.cpp +38 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/riscv/quants.c +4455 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/riscv/repack.cpp +1703 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/s390/cpu-feats.cpp +50 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/s390/quants.c +1465 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/wasm/quants.c +1220 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/x86/cpu-feats.cpp +327 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/x86/quants.c +3970 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch/x86/repack.cpp +6407 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/arch-fallback.h +349 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/binary-ops.cpp +154 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/binary-ops.h +16 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/cmake/FindSIMD.cmake +100 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/common.h +95 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/ggml-cpu-impl.h +539 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/ggml-cpu.c +3791 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/ggml-cpu.cpp +703 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/hbm.cpp +55 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/hbm.h +8 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/kleidiai/kernels.cpp +939 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/kleidiai/kernels.h +90 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/kleidiai/kleidiai.cpp +1513 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/kleidiai/kleidiai.h +17 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/llamafile/sgemm.cpp +4051 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/llamafile/sgemm.h +25 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/ops.cpp +11662 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/ops.h +121 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/quants.c +1288 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/quants.h +103 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/repack.cpp +4836 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/repack.h +245 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/simd-gemm.h +226 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/simd-mappings.h +1329 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/spacemit/ime.cpp +1025 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/spacemit/ime.h +13 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/spacemit/ime1_kernels.cpp +3196 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/spacemit/ime_kernels.h +26 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/traits.cpp +36 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/traits.h +38 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/unary-ops.cpp +336 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/unary-ops.h +35 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/vec.cpp +681 -0
- data/vendor/crispasr/ggml/src/ggml-cpu/vec.h +1606 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/CMakeLists.txt +272 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/acc.cu +61 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/acc.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/add-id.cu +58 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/add-id.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/arange.cu +34 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/arange.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/argmax.cu +91 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/argmax.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/argsort.cu +265 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/argsort.cuh +19 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/binbcast.cu +534 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/binbcast.cuh +12 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/clamp.cu +45 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/clamp.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/col2im-1d.cu +81 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/col2im-1d.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/common.cuh +1489 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/concat.cu +204 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/concat.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/conv-transpose-1d.cu +97 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/conv-transpose-1d.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/conv2d-dw.cu +161 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/conv2d-dw.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/conv2d-transpose.cu +115 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/conv2d-transpose.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/conv2d.cu +166 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/conv2d.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/convert.cu +892 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/convert.cuh +66 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/count-equal.cu +64 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/count-equal.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/cp-async.cuh +57 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/cpy-utils.cuh +217 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/cpy.cu +581 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/cpy.cuh +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/cross-entropy-loss.cu +177 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/cross-entropy-loss.cuh +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/cumsum.cu +307 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/cumsum.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/dequantize.cuh +99 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/diag.cu +77 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/diag.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/diagmask.cu +40 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/diagmask.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fattn-common.cuh +1212 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fattn-mma-f16.cuh +1860 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fattn-tile.cu +57 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fattn-tile.cuh +1309 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fattn-vec.cuh +600 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fattn-wmma-f16.cu +696 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fattn-wmma-f16.cuh +51 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fattn.cu +620 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fattn.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fill.cu +37 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/fill.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/gated_delta_net.cu +273 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/gated_delta_net.cuh +4 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/getrows.cu +332 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/getrows.cuh +15 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/ggml-cuda.cu +5580 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/gla.cu +93 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/gla.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/im2col.cu +274 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/im2col.cuh +6 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mean.cu +75 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mean.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mma.cuh +1333 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmf.cu +191 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmf.cuh +908 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmid.cu +164 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmid.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmq.cu +372 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmq.cuh +4175 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmvf.cu +862 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmvf.cuh +14 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmvq.cu +1161 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/mmvq.cuh +16 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/norm.cu +756 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/norm.cuh +20 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/opt-step-adamw.cu +78 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/opt-step-adamw.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/opt-step-sgd.cu +49 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/opt-step-sgd.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/out-prod.cu +68 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/out-prod.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/pad.cu +106 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/pad.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/pad_reflect_1d.cu +91 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/pad_reflect_1d.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/pool2d.cu +94 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/pool2d.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/quantize.cu +443 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/quantize.cuh +41 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/reduce_rows.cuh +39 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/roll.cu +67 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/roll.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/rope.cu +665 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/rope.cuh +9 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/scale.cu +34 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/scale.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/set-rows.cu +330 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/set-rows.cuh +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/set.cu +39 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/set.cuh +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/softcap.cu +34 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/softcap.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/softmax.cu +472 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/softmax.cuh +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/solve_tri.cu +275 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/solve_tri.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/ssm-conv.cu +197 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/ssm-conv.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/ssm-scan.cu +342 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/ssm-scan.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/sum.cu +41 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/sum.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/sumrows.cu +43 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/sumrows.cuh +4 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_16.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_32.cu +6 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_8.cu +11 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_1.cu +10 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_2.cu +10 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_4.cu +12 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_16.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_32.cu +6 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_4.cu +12 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_8.cu +11 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_32-ncols2_1.cu +10 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_32-ncols2_2.cu +10 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_16.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_2.cu +10 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_4.cu +12 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_8.cu +11 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_64-ncols2_1.cu +10 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_1.cu +10 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_2.cu +10 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_4.cu +12 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_8.cu +11 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq112-dv112.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq128-dv128.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq256-dv256.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq320-dv256.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq40-dv40.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq512-dv512.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq576-dv512.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq64-dv64.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq72-dv72.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq80-dv80.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq96-dv96.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-bf16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-f16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q4_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q4_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q5_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q5_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q8_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-bf16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-f16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q4_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q4_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q5_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q5_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q8_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-bf16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-f16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q4_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q4_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q5_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q5_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q8_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-bf16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-f16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q4_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q4_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q5_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q5_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q8_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-bf16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-f16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q4_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q4_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q5_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q5_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q8_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-bf16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-f16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q4_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q4_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q5_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q5_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q8_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-bf16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-f16.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q4_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q4_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q5_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q5_1.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q8_0.cu +7 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_1.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_10.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_11.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_12.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_13.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_14.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_15.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_16.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_2.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_3.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_4.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_5.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_6.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_7.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_8.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_9.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq1_s.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_s.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_xs.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_xxs.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq3_s.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq3_xxs.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq4_nl.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-iq4_xs.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-mxfp4.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-nvfp4.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q1_0.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q2_k.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q3_k.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q4_0.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q4_1.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q4_k.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q5_0.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q5_1.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q5_k.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q6_k.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/template-instances/mmq-instance-q8_0.cu +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/top-k.cu +95 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/top-k.cuh +3 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/topk-moe.cu +415 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/topk-moe.cuh +27 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/tri.cu +136 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/tri.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/tsembd.cu +47 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/tsembd.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/unary.cu +644 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/unary.cuh +116 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/upscale.cu +293 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/upscale.cuh +5 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/vecdotq.cuh +1317 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/vendors/cuda.h +28 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/vendors/hip.h +306 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/vendors/musa.h +148 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/wkv.cu +199 -0
- data/vendor/crispasr/ggml/src/ggml-cuda/wkv.cuh +7 -0
- data/vendor/crispasr/ggml/src/ggml-impl.h +783 -0
- data/vendor/crispasr/ggml/src/ggml-metal/CMakeLists.txt +124 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-common.cpp +457 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-common.h +52 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-context.h +41 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-context.m +778 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-device.cpp +2117 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-device.h +299 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-device.m +2093 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-impl.h +1267 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-ops.cpp +5023 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal-ops.h +111 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal.cpp +954 -0
- data/vendor/crispasr/ggml/src/ggml-metal/ggml-metal.metal +11756 -0
- data/vendor/crispasr/ggml/src/ggml-opt.cpp +1094 -0
- data/vendor/crispasr/ggml/src/ggml-quants.c +5491 -0
- data/vendor/crispasr/ggml/src/ggml-quants.h +112 -0
- data/vendor/crispasr/ggml/src/ggml-threading.cpp +12 -0
- data/vendor/crispasr/ggml/src/ggml-threading.h +14 -0
- data/vendor/crispasr/ggml/src/ggml.c +7925 -0
- data/vendor/crispasr/ggml/src/ggml.cpp +26 -0
- data/vendor/crispasr/ggml/src/gguf.cpp +1556 -0
- data/vendor/crispasr/src/cohere-arch.h +137 -0
- data/vendor/crispasr/src/cohere.cpp +5642 -0
- data/vendor/crispasr/src/cohere.h +327 -0
- data/vendor/crispasr/src/cohere_batch_planner.h +82 -0
- data/vendor/crispasr/src/cohere_chunking.h +64 -0
- data/vendor/crispasr/src/cohere_decoder_batch_layout.h +60 -0
- data/vendor/crispasr/src/cohere_encoder_padded_layout.h +27 -0
- data/vendor/crispasr/src/cohere_frontend.cpp +189 -0
- data/vendor/crispasr/src/cohere_frontend.h +31 -0
- data/vendor/crispasr/src/cohere_ragged_controller.h +149 -0
- data/vendor/crispasr/src/cohere_token_renderer.h +181 -0
- data/vendor/crispasr/src/core/attention.h +924 -0
- data/vendor/crispasr/src/core/audio_chunking.h +97 -0
- data/vendor/crispasr/src/core/beam_decode.h +486 -0
- data/vendor/crispasr/src/core/cpu_ops.h +135 -0
- data/vendor/crispasr/src/core/gguf_loader.cpp +1021 -0
- data/vendor/crispasr/src/core/gguf_loader.h +216 -0
- data/vendor/crispasr/src/core/gpu_backend_pref.h +119 -0
- data/vendor/crispasr/src/core/mel.cpp +519 -0
- data/vendor/crispasr/src/core/mel.h +265 -0
- data/vendor/crispasr/src/core/ngram_loop_fix.h +173 -0
- data/vendor/crispasr/src/core/repetition_loop_guard.h +54 -0
- data/vendor/crispasr/src/crispasr_imatrix.cpp +255 -0
- data/vendor/crispasr/src/crispasr_imatrix.h +38 -0
- 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
|