14 # needed for audio-to-text
26 # apply feature parameter names according to
27 # https://github.com/NixOS/rfcs/pull/169
32 enable_avx512 ? stdenv.hostPlatform.avx512Support,
36 with_openblas ? false,
39 with_cublas ? config.cudaSupport,
47 with_tinydream ? false, # do not compile with cublas
50 with_stablediffusion ? true,
71 else if with_cublas then
73 else if with_clblas then
78 inherit (cudaPackages)
86 go-llama = effectiveStdenv.mkDerivation {
88 src = fetchFromGitHub {
90 repo = "go-llama.cpp";
91 rev = "2b57a8ae43e4699d3dc5d1496a1ccd42922993be";
92 hash = "sha256-D6SEg5pPcswGyKAmF4QTJP6/Y1vjRr7m7REguag+too=";
93 fetchSubmodules = true;
97 "BUILD_TYPE=${BUILD_TYPE}"
102 ++ lib.optionals with_cublas [
107 ++ lib.optionals with_clblas [
112 ++ lib.optionals with_openblas [ openblas.dev ];
114 nativeBuildInputs = [ cmake ] ++ lib.optionals with_cublas [ cuda_nvcc ];
116 dontUseCmakeConfigure = true;
120 tar cf - --exclude=build --exclude=CMakeFiles --exclude="*.o" . \
126 (llama-cpp-grpc.overrideAttrs (prev: {
127 name = "llama-cpp-rpc";
128 cmakeFlags = prev.cmakeFlags ++ [
129 (lib.cmakeBool "GGML_AVX" false)
130 (lib.cmakeBool "GGML_AVX2" false)
131 (lib.cmakeBool "GGML_AVX512" false)
132 (lib.cmakeBool "GGML_FMA" false)
133 (lib.cmakeBool "GGML_F16C" false)
138 openclSupport = false;
144 (llama-cpp.overrideAttrs (
146 name = "llama-cpp-grpc";
147 src = fetchFromGitHub {
150 rev = "fc54ef0d1c138133a01933296d50a36a1ab64735";
151 hash = "sha256-o87EhrA2Oa98pwyb6GSUgwERY0/GWJiX7kvlxDv4zb4=";
152 fetchSubmodules = true;
158 cp -r --no-preserve=mode ${src}/backend/cpp/llama grpc-server
159 cp llava/clip.* llava/llava.* grpc-server
160 printf "\nadd_subdirectory(grpc-server)" >> CMakeLists.txt
162 cp ${src}/backend/backend.proto grpc-server
163 sed -i grpc-server/CMakeLists.txt \
164 -e '/get_filename_component/ s;[.\/]*backend/;;' \
165 -e '$a\install(TARGETS ''${TARGET} RUNTIME)'
168 cmakeFlags = prev.cmakeFlags ++ [
169 (lib.cmakeBool "BUILD_SHARED_LIBS" false)
170 (lib.cmakeBool "GGML_AVX" enable_avx)
171 (lib.cmakeBool "GGML_AVX2" enable_avx2)
172 (lib.cmakeBool "GGML_AVX512" enable_avx512)
173 (lib.cmakeBool "GGML_FMA" enable_fma)
174 (lib.cmakeBool "GGML_F16C" enable_f16c)
176 buildInputs = prev.buildInputs ++ [
177 protobuf # provides also abseil_cpp as propagated build input
184 cudaSupport = with_cublas;
186 openclSupport = with_clblas;
187 blasSupport = with_openblas;
190 espeak-ng' = espeak-ng.overrideAttrs (self: {
192 inherit (go-piper) src;
193 sourceRoot = "${go-piper.src.name}/espeak";
195 nativeBuildInputs = [ cmake ];
196 cmakeFlags = (self.cmakeFlags or [ ]) ++ [
197 (lib.cmakeBool "BUILD_SHARED_LIBS" true)
198 (lib.cmakeBool "USE_ASYNC" false)
199 (lib.cmakeBool "USE_MBROLA" false)
200 (lib.cmakeBool "USE_LIBPCAUDIO" false)
201 (lib.cmakeBool "USE_KLATT" false)
202 (lib.cmakeBool "USE_SPEECHPLAYER" false)
203 (lib.cmakeBool "USE_LIBSONIC" false)
204 (lib.cmakeBool "CMAKE_POSITION_INDEPENDENT_CODE" true)
210 piper-phonemize = stdenv.mkDerivation {
211 name = "piper-phonemize";
212 inherit (go-piper) src;
213 sourceRoot = "${go-piper.src.name}/piper-phonemize";
218 nativeBuildInputs = [
223 (lib.cmakeFeature "ONNXRUNTIME_DIR" "${onnxruntime.dev}")
224 (lib.cmakeFeature "ESPEAK_NG_DIR" "${espeak-ng'}")
226 passthru.espeak-ng = espeak-ng';
229 piper-tts' = (piper-tts.override { inherit piper-phonemize; }).overrideAttrs (self: {
231 inherit (go-piper) src;
232 sourceRoot = "${go-piper.src.name}/piper";
235 cp CMakeFiles/piper.dir/src/cpp/piper.cpp.o $out/piper.o
239 mv piper piper_phonemize bin/
240 rm -rf cmake pkgconfig espeak-ng-data *.ort
244 go-piper = stdenv.mkDerivation {
246 src = fetchFromGitHub {
249 rev = "9d0100873a7dbb0824dfea40e8cec70a1b110759";
250 hash = "sha256-Yv9LQkWwGpYdOS0FvtP0vZ0tRyBAx27sdmziBR4U4n8=";
251 fetchSubmodules = true;
254 cp -r --no-preserve=mode ${piper-tts'}/* source
258 -e '/CXXFLAGS *= / s;$; -DSPDLOG_FMT_EXTERNAL=1;'
260 buildFlags = [ "libpiper_binding.a" ];
271 cp -r --no-preserve=mode $src $out
272 mkdir -p $out/piper-phonemize/pi
273 cp -r --no-preserve=mode ${piper-phonemize}/share $out/piper-phonemize/pi
278 go-rwkv = stdenv.mkDerivation {
280 src = fetchFromGitHub {
282 repo = "go-rwkv.cpp";
283 rev = "661e7ae26d442f5cfebd2a0881b44e8c55949ec6";
284 hash = "sha256-byTNZQSnt7qpBMng3ANJmpISh3GJiz+F15UqfXaz6nQ=";
285 fetchSubmodules = true;
287 buildFlags = [ "librwkv.a" ];
288 dontUseCmakeConfigure = true;
289 nativeBuildInputs = [ cmake ];
291 cp -r --no-preserve=mode $src $out
296 # try to merge with openai-whisper-cpp in future
297 whisper-cpp = effectiveStdenv.mkDerivation {
298 name = "whisper-cpp";
299 src = fetchFromGitHub {
301 repo = "whisper.cpp";
302 rev = "9e3c5345cd46ea718209db53464e426c3fe7a25e";
303 hash = "sha256-JOptyveuaKRLzeZ6GuB3A70IM7dk4we95g5o25XVXJI=";
306 nativeBuildInputs = [
309 ] ++ lib.optionals with_cublas [ cuda_nvcc ];
313 ++ lib.optionals with_cublas [
319 ++ lib.optionals with_clblas [
324 ++ lib.optionals with_openblas [ openblas.dev ];
327 (lib.cmakeBool "WHISPER_CUDA" with_cublas)
328 (lib.cmakeBool "WHISPER_CLBLAST" with_clblas)
329 (lib.cmakeBool "WHISPER_OPENBLAS" with_openblas)
330 (lib.cmakeBool "WHISPER_NO_AVX" (!enable_avx))
331 (lib.cmakeBool "WHISPER_NO_AVX2" (!enable_avx2))
332 (lib.cmakeBool "WHISPER_NO_FMA" (!enable_fma))
333 (lib.cmakeBool "WHISPER_NO_F16C" (!enable_f16c))
334 (lib.cmakeBool "BUILD_SHARED_LIBS" false)
337 install -Dt $out/bin bin/*
341 go-bert = stdenv.mkDerivation {
343 src = fetchFromGitHub {
345 repo = "go-bert.cpp";
346 rev = "710044b124545415f555e4260d16b146c725a6e4";
347 hash = "sha256-UNrs3unYjvSzCVaVISFFBDD+s37lmN6/7ajmGNcYgrU=";
348 fetchSubmodules = true;
350 buildFlags = [ "libgobert.a" ];
351 dontUseCmakeConfigure = true;
352 nativeBuildInputs = [ cmake ];
353 env.NIX_CFLAGS_COMPILE = "-Wformat";
355 cp -r --no-preserve=mode $src $out
360 go-stable-diffusion = stdenv.mkDerivation {
361 name = "go-stable-diffusion";
362 src = fetchFromGitHub {
364 repo = "go-stable-diffusion";
365 rev = "4a3cd6aeae6f66ee57eae9a0075f8c58c3a6a38f";
366 hash = "sha256-KXUvMP6cDyWib4rG0RmVRm3pgrdsfKXaH3k0v5/mTe8=";
367 fetchSubmodules = true;
369 buildFlags = [ "libstablediffusion.a" ];
370 dontUseCmakeConfigure = true;
371 nativeBuildInputs = [ cmake ];
372 buildInputs = [ opencv ];
373 env.NIX_CFLAGS_COMPILE = " -isystem ${opencv}/include/opencv4";
376 tar cf - --exclude=CMakeFiles --exclude="*.o" --exclude="*.so" --exclude="*.so.*" . \
381 go-tiny-dream-ncnn = ncnn.overrideAttrs (self: {
382 name = "go-tiny-dream-ncnn";
383 inherit (go-tiny-dream) src;
384 sourceRoot = "${go-tiny-dream.src.name}/ncnn";
385 cmakeFlags = self.cmakeFlags ++ [
386 (lib.cmakeBool "NCNN_SHARED_LIB" false)
387 (lib.cmakeBool "NCNN_OPENMP" false)
388 (lib.cmakeBool "NCNN_VULKAN" false)
389 (lib.cmakeBool "NCNN_AVX" enable_avx)
390 (lib.cmakeBool "NCNN_AVX2" enable_avx2)
391 (lib.cmakeBool "NCNN_AVX512" enable_avx512)
392 (lib.cmakeBool "NCNN_FMA" enable_fma)
393 (lib.cmakeBool "NCNN_F16C" enable_f16c)
397 go-tiny-dream = effectiveStdenv.mkDerivation {
398 name = "go-tiny-dream";
399 src = fetchFromGitHub {
401 repo = "go-tiny-dream";
402 rev = "c04fa463ace9d9a6464313aa5f9cd0f953b6c057";
403 hash = "sha256-uow3vbAI4F/fTGjYOKOLqTpKq7NgGYSZhGlEhn7h6s0=";
404 fetchSubmodules = true;
408 mkdir -p source/ncnn/build/src
409 cp -r --no-preserve=mode ${go-tiny-dream-ncnn}/lib/. ${go-tiny-dream-ncnn}/include/. source/ncnn/build/src
411 buildFlags = [ "libtinydream.a" ];
414 tar cf - --exclude="*.o" . \
417 meta.broken = lib.versionOlder go-tiny-dream.stdenv.cc.version "13";
421 lib.optional with_tinydream "tinydream"
422 ++ lib.optional with_tts "tts"
423 ++ lib.optional with_stablediffusion "stablediffusion";
427 # It's necessary to consistently use backendStdenv when building with CUDA support,
428 # otherwise we get libstdc++ errors downstream.
429 cudaPackages.backendStdenv
435 src = fetchFromGitHub {
439 hash = "sha256-FeZZC0Tg9JT9Yj0e27GOLSdHEtWl17AHK3j7epwPyY8=";
444 cp = "cp -r --no-preserve=mode,ownership";
448 ${cp} ${go-llama} sources/go-llama.cpp
449 ${cp} ${if with_tts then go-piper else go-piper.src} sources/go-piper
450 ${cp} ${go-rwkv} sources/go-rwkv.cpp
451 ${cp} ${whisper-cpp.src} sources/whisper.cpp
452 cp ${whisper-cpp}/lib/lib*.a sources/whisper.cpp
453 ${cp} ${go-bert} sources/go-bert.cpp
455 if with_stablediffusion then go-stable-diffusion else go-stable-diffusion.src
456 } sources/go-stable-diffusion
457 ${cp} ${if with_tinydream then go-tiny-dream else go-tiny-dream.src} sources/go-tiny-dream
460 self = buildGoModule.override { stdenv = effectiveStdenv; } {
461 inherit pname version src;
463 vendorHash = "sha256-mDxp5frUIECSHKjxaJVqIP7mnIusvdT45Xlxc9+P5tE=";
465 env.NIX_CFLAGS_COMPILE = lib.optionalString with_stablediffusion " -isystem ${opencv}/include/opencv4";
470 -e '/mod download/ d' \
471 -e '/^ALL_GRPC_BACKENDS+=backend-assets\/grpc\/llama-cpp-fallback/ d' \
472 -e '/^ALL_GRPC_BACKENDS+=backend-assets\/grpc\/llama-cpp-avx/ d' \
473 -e '/^ALL_GRPC_BACKENDS+=backend-assets\/grpc\/llama-cpp-cuda/ d' \
476 + lib.optionalString with_cublas ''
478 -e '/^CGO_LDFLAGS_WHISPER?=/ s;$;-L${libcufft}/lib -L${cuda_cudart}/lib;'
485 mkdir -p backend-assets/grpc
486 cp ${llama-cpp-grpc}/bin/grpc-server backend-assets/grpc/llama-cpp-avx2
487 cp ${llama-cpp-rpc}/bin/grpc-server backend-assets/grpc/llama-cpp-grpc
489 mkdir -p backend/cpp/llama/llama.cpp
491 mkdir -p backend-assets/util
492 cp ${llama-cpp-rpc}/bin/llama-rpc-server backend-assets/util/llama-cpp-rpc-server
494 # avoid rebuild of prebuilt make targets
495 touch backend-assets/grpc/* backend-assets/util/* sources/**/lib*.a
500 ++ lib.optionals with_cublas [
505 ++ lib.optionals with_clblas [
510 ++ lib.optionals with_openblas [ openblas.dev ]
511 ++ lib.optionals with_stablediffusion go-stable-diffusion.buildInputs
512 ++ lib.optionals with_tts go-piper.buildInputs;
514 nativeBuildInputs = [
521 ] ++ lib.optional enable_upx upx ++ lib.optionals with_cublas [ cuda_nvcc ];
523 enableParallelBuilding = false;
534 # should be passed as makeFlags, but build system failes with strings
536 env.GO_TAGS = builtins.concatStringsSep " " GO_TAGS;
540 "VERSION=v${version}"
541 "BUILD_TYPE=${BUILD_TYPE}"
543 ++ lib.optional with_cublas "CUDA_LIBPATH=${cuda_cudart}/lib"
544 ++ lib.optional with_tts "PIPER_CGO_CXXFLAGS=-DSPDLOG_FMT_EXTERNAL=1";
550 ''${enableParallelBuilding:+-j''${NIX_BUILD_CORES}}
553 concatTo flagsArray makeFlags makeFlagsArray buildFlags buildFlagsArray
554 echoCmd 'build flags' "''${flagsArray[@]}"
555 make build "''${flagsArray[@]}"
564 install -Dt $out/bin ${pname}
569 # patching rpath with patchelf doens't work. The execuable
570 # raises an segmentation fault
575 ++ lib.optionals with_cublas [
576 # driverLink has to be first to avoid loading the stub version of libcuda.so
577 # https://github.com/NixOS/nixpkgs/issues/320145#issuecomment-2190319327
578 addDriverRunpath.driverLink
579 (lib.getLib libcublas)
582 ++ lib.optionals with_clblas [
586 ++ lib.optionals with_openblas [ openblas ]
587 ++ lib.optionals with_tts [ piper-phonemize ]
588 ++ lib.optionals (with_tts && enable_upx) [
594 wrapProgram $out/bin/${pname} \
595 --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath LD_LIBRARY_PATH}" \
596 --prefix PATH : "${ffmpeg}/bin"
599 passthru.local-packages = {
616 passthru.features = {
627 passthru.tests = callPackages ./tests.nix { inherit self; };
628 passthru.lib = callPackages ./lib.nix { };
631 description = "OpenAI alternative to run local LLMs, image and audio generation";
632 homepage = "https://localai.io";
633 license = licenses.mit;
634 maintainers = with maintainers; [
638 platforms = platforms.linux;