1{
2 lib,
3 stdenv,
4 cmake,
5 git,
6 apple-sdk_11,
7 ninja,
8 fetchFromGitHub,
9 SDL2,
10 wget,
11 which,
12 autoAddDriverRunpath,
13 makeWrapper,
14
15 metalSupport ? stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64,
16 coreMLSupport ? stdenv.hostPlatform.isDarwin && false, # FIXME currently broken
17
18 config,
19 cudaSupport ? config.cudaSupport,
20 cudaPackages ? { },
21
22 rocmSupport ? config.rocmSupport,
23 rocmPackages ? { },
24 rocmGpuTargets ? builtins.concatStringsSep ";" rocmPackages.clr.gpuTargets,
25
26 vulkanSupport ? false,
27 shaderc,
28 vulkan-headers,
29 vulkan-loader,
30
31 withSDL ? true,
32}:
33
34assert metalSupport -> stdenv.hostPlatform.isDarwin;
35assert coreMLSupport -> stdenv.hostPlatform.isDarwin;
36
37let
38 # It's necessary to consistently use backendStdenv when building with CUDA support,
39 # otherwise we get libstdc++ errors downstream.
40 # cuda imposes an upper bound on the gcc version, e.g. the latest gcc compatible with cudaPackages_11 is gcc11
41 effectiveStdenv = if cudaSupport then cudaPackages.backendStdenv else stdenv;
42 inherit (lib)
43 cmakeBool
44 cmakeFeature
45 optional
46 optionals
47 ;
48
49 darwinBuildInputs = [ apple-sdk_11 ];
50
51 cudaBuildInputs = with cudaPackages; [
52 cuda_cccl # <nv/target>
53
54 # A temporary hack for reducing the closure size, remove once cudaPackages
55 # have stopped using lndir: https://github.com/NixOS/nixpkgs/issues/271792
56 cuda_cudart
57 libcublas
58 ];
59
60 rocmBuildInputs = with rocmPackages; [
61 clr
62 hipblas
63 rocblas
64 ];
65
66 vulkanBuildInputs = [
67 shaderc
68 vulkan-headers
69 vulkan-loader
70 ];
71
72in
73effectiveStdenv.mkDerivation (finalAttrs: {
74 pname = "whisper-cpp";
75 version = "1.7.6";
76
77 src = fetchFromGitHub {
78 owner = "ggml-org";
79 repo = "whisper.cpp";
80 tag = "v${finalAttrs.version}";
81 hash = "sha256-dppBhiCS4C3ELw/Ckx5W0KOMUvOHUiisdZvkS7gkxj4=";
82 };
83
84 # The upstream download script tries to download the models to the
85 # directory of the script, which is not writable due to being
86 # inside the nix store. This patch changes the script to download
87 # the models to the current directory of where it is being run from.
88 patches = [ ./download-models.patch ];
89
90 postPatch = ''
91 for target in examples/{bench,command,cli,quantize,server,stream,talk-llama}/CMakeLists.txt; do
92 if ! grep -q -F 'install('; then
93 echo 'install(TARGETS ''${TARGET} RUNTIME)' >> $target
94 fi
95 done
96 '';
97
98 nativeBuildInputs = [
99 cmake
100 git
101 ninja
102 which
103 makeWrapper
104 ]
105 ++ lib.optionals cudaSupport [
106 cudaPackages.cuda_nvcc
107 autoAddDriverRunpath
108 ];
109
110 buildInputs =
111 optional withSDL SDL2
112 ++ optionals effectiveStdenv.hostPlatform.isDarwin darwinBuildInputs
113 ++ optionals cudaSupport cudaBuildInputs
114 ++ optionals rocmSupport rocmBuildInputs
115 ++ optionals vulkanSupport vulkanBuildInputs;
116
117 cmakeFlags = [
118 (cmakeBool "WHISPER_BUILD_EXAMPLES" true)
119 (cmakeBool "GGML_CUDA" cudaSupport)
120 (cmakeBool "GGML_HIPBLAS" rocmSupport)
121 (cmakeBool "GGML_VULKAN" vulkanSupport)
122 (cmakeBool "WHISPER_SDL2" withSDL)
123 (cmakeBool "GGML_LTO" true)
124 (cmakeBool "GGML_NATIVE" false)
125 (cmakeBool "BUILD_SHARED_LIBS" (!effectiveStdenv.hostPlatform.isStatic))
126 ]
127 ++ optionals (effectiveStdenv.hostPlatform.isx86 && !effectiveStdenv.hostPlatform.isStatic) [
128 (cmakeBool "GGML_BACKEND_DL" true)
129 (cmakeBool "GGML_CPU_ALL_VARIANTS" true)
130 ]
131 ++ optionals cudaSupport [
132 (cmakeFeature "CMAKE_CUDA_ARCHITECTURES" cudaPackages.flags.cmakeCudaArchitecturesString)
133 ]
134 ++ optionals rocmSupport [
135 (cmakeFeature "CMAKE_C_COMPILER" "hipcc")
136 (cmakeFeature "CMAKE_CXX_COMPILER" "hipcc")
137
138 # Build all targets supported by rocBLAS. When updating search for TARGET_LIST_ROCM
139 # in https://github.com/ROCmSoftwarePlatform/rocBLAS/blob/develop/CMakeLists.txt
140 # and select the line that matches the current nixpkgs version of rocBLAS.
141 "-DAMDGPU_TARGETS=${rocmGpuTargets}"
142 ]
143 ++ optionals coreMLSupport [
144 (cmakeBool "WHISPER_COREML" true)
145 (cmakeBool "WHISPER_COREML_ALLOW_FALLBACK" true)
146 ]
147 ++ optionals metalSupport [
148 (cmakeFeature "CMAKE_C_FLAGS" "-D__ARM_FEATURE_DOTPROD=1")
149 (cmakeBool "GGML_METAL" true)
150 (cmakeBool "GGML_METAL_EMBED_LIBRARY" true)
151 ];
152
153 postInstall = ''
154 # Add "whisper-cpp" prefix before every command
155 mv -v "$out/bin/"{quantize,whisper-quantize}
156
157 install -v -D -m755 "$src/models/download-ggml-model.sh" "$out/bin/whisper-cpp-download-ggml-model"
158
159 wrapProgram "$out/bin/whisper-cpp-download-ggml-model" \
160 --prefix PATH : ${lib.makeBinPath [ wget ]}
161 '';
162
163 requiredSystemFeatures = optionals rocmSupport [ "big-parallel" ]; # rocmSupport multiplies build time by the number of GPU targets, which takes arround 30 minutes on a 16-cores system to build
164
165 doInstallCheck = true;
166
167 installCheckPhase = ''
168 runHook preInstallCheck
169 "$out/bin/whisper-cli" --help >/dev/null
170 runHook postInstallCheck
171 '';
172
173 meta = {
174 description = "Port of OpenAI's Whisper model in C/C++";
175 longDescription = ''
176 To download the models as described in the project's readme, you may
177 use the `whisper-cpp-download-ggml-model` binary from this package.
178 '';
179 homepage = "https://github.com/ggerganov/whisper.cpp";
180 license = lib.licenses.mit;
181 mainProgram = "whisper-cli";
182 platforms = lib.platforms.all;
183 broken = coreMLSupport;
184 badPlatforms = optionals cudaSupport lib.platforms.darwin;
185 maintainers = with lib.maintainers; [
186 dit7ya
187 hughobrien
188 aviallon
189 ];
190 };
191})