Skip to main content

native/whisper_ct2_native/Cargo.toml

[package]
name = "whisper_ct2_native"
version = "0.5.0"
edition = "2024"
rust-version = "1.85"

[lib]
name = "whisper_ct2_native"
crate-type = ["cdylib"]

[dependencies]
rustler = "0.37.3"
ct2rs = { version = "0.9.18", features = ["whisper"] }
# Versions pinned to match ct2rs 0.9.18 so duplicate crates collapse during build.
mel_spec = "0.3"
ndarray = "0.16"
tokenizers = "0.22"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
# Used directly for the per-chunk center-padded STFT that matches
# faster-whisper's FeatureExtractor. `mel_spec`'s streaming Spectrogram
# can't express center=True with reflect padding, so we plan the FFT
# ourselves.
rustfft = "6.4"
# `parking_lot::Mutex` avoids `std::sync::Mutex`'s poisoning behaviour
# (a panic under the lock would otherwise brick the loaded model for the
# rest of its lifetime). `ct2rs::sys::Whisper` is internally thread-safe;
# this mutex only serialises our own non-Sync handle.
parking_lot = "0.12"

[features]
# Build-time choices, selected via mix:
#   WHISPER_CT2_FEATURES="dnnl cuda-dynamic" mix compile
#
# === GPU ===
# `cuda`         - CTranslate2 with statically linked CUDA kernels; libcudart
#                  must be present at NIF load time.
# `cuda-dynamic` - same kernels, but libcudart is loaded lazily; one binary
#                  runs on CPU-only hosts and gracefully uses CUDA when
#                  available. Preferred for shipping.
#
# === CPU SGEMM backend ===
# Exactly one should normally be enabled. Defaults to ct2rs's `ruy` if none.
# `mkl`        - Intel oneMKL. Fastest on Intel x86; deliberately slow on AMD.
# `dnnl`       - oneDNN. Strong on both Intel and AMD x86. Best single-binary
#                choice for x86_64-linux when targeting mixed CPU vendors.
# `openblas`   - portable OpenBLAS link.
# `accelerate` - Apple Accelerate framework (Apple Silicon / macOS only).
default = []
cuda = ["ct2rs/cuda"]
cuda-dynamic = ["ct2rs/cuda-dynamic-loading"]
mkl = ["ct2rs/mkl"]
dnnl = ["ct2rs/dnnl"]
openblas = ["ct2rs/openblas"]
accelerate = ["ct2rs/accelerate"]

[lints.rust]
# `deny` rather than `forbid`: ndarray's `s!` macro emits internal
# `#[allow(unsafe_code)]` attributes that `forbid` would reject. Any unsafe
# block we write ourselves still triggers a hard error.
unsafe_code = "deny"
missing_docs = "warn"
unreachable_pub = "warn"

[lints.clippy]
pedantic = { level = "warn", priority = -1 }
module_name_repetitions = "allow"
missing_errors_doc = "allow"
missing_panics_doc = "allow"
# Doc-style nits we prefer not to enforce on prose comments.
doc_markdown = "allow"
doc_overindented_list_items = "allow"

[profile.release]
opt-level = 3
lto = "thin"
codegen-units = 1