grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / home-automation / wyoming / faster-whisper.nix
blob45664103665f71a49a29c69bab3a0ba3f9e977c8
1 { config
2 , lib
3 , pkgs
4 , ...
5 }:
7 let
8   cfg = config.services.wyoming.faster-whisper;
10   inherit (lib)
11     escapeShellArgs
12     mkOption
13     mkEnableOption
14     mkPackageOption
15     types
16     ;
18   inherit (builtins)
19     toString
20     ;
25   options.services.wyoming.faster-whisper = with types; {
26     package = mkPackageOption pkgs "wyoming-faster-whisper" { };
28     servers = mkOption {
29       default = {};
30       description = ''
31         Attribute set of faster-whisper instances to spawn.
32       '';
33       type = types.attrsOf (types.submodule (
34         { ... }: {
35           options = {
36             enable = mkEnableOption "Wyoming faster-whisper server";
38             model = mkOption {
39               type = str;
40               default = "tiny-int8";
41               example = "Systran/faster-distil-whisper-small.en";
42               description = ''
43                 Name of the voice model to use.
45                 Check the [2.0.0 release notes](https://github.com/rhasspy/wyoming-faster-whisper/releases/tag/v2.0.0) for possible values.
46               '';
47             };
49             uri = mkOption {
50               type = strMatching "^(tcp|unix)://.*$";
51               example = "tcp://0.0.0.0:10300";
52               description = ''
53                 URI to bind the wyoming server to.
54               '';
55             };
57             device = mkOption {
58               # https://opennmt.net/CTranslate2/python/ctranslate2.models.Whisper.html#
59               type = types.enum [
60                 "cpu"
61                 "cuda"
62                 "auto"
63               ];
64               default = "cpu";
65               description = ''
66                 Determines the platform faster-whisper is run on. CPU works everywhere, CUDA requires a compatible NVIDIA GPU.
67               '';
68             };
70             language = mkOption {
71               type = enum [
72                 # https://github.com/home-assistant/addons/blob/master/whisper/config.yaml#L20
73                 "auto" "af" "am" "ar" "as" "az" "ba" "be" "bg" "bn" "bo" "br" "bs" "ca" "cs" "cy" "da" "de" "el" "en" "es" "et" "eu" "fa" "fi" "fo" "fr" "gl" "gu" "ha" "haw" "he" "hi" "hr" "ht" "hu" "hy" "id" "is" "it" "ja" "jw" "ka" "kk" "km" "kn" "ko" "la" "lb" "ln" "lo" "lt" "lv" "mg" "mi" "mk" "ml" "mn" "mr" "ms" "mt" "my" "ne" "nl" "nn" "no" "oc" "pa" "pl" "ps" "pt" "ro" "ru" "sa" "sd" "si" "sk" "sl" "sn" "so" "sq" "sr" "su" "sv" "sw" "ta" "te" "tg" "th" "tk" "tl" "tr" "tt" "uk" "ur" "uz" "vi" "yi" "yo" "zh"
74               ];
75               example = "en";
76               description = ''
77                 The language used to to parse words and sentences.
78               '';
79             };
81             beamSize = mkOption {
82               type = ints.unsigned;
83               default = 1;
84               example = 5;
85               description = ''
86                 The number of beams to use in beam search.
87               '';
88               apply = toString;
89             };
91             extraArgs = mkOption {
92               type = listOf str;
93               default = [ ];
94               description = ''
95                 Extra arguments to pass to the server commandline.
96               '';
97               apply = escapeShellArgs;
98             };
99           };
100         }
101       ));
102     };
103   };
105   config = let
106     inherit (lib)
107       mapAttrs'
108       mkIf
109       nameValuePair
110     ;
111   in mkIf (cfg.servers != {}) {
112     systemd.services = mapAttrs' (server: options:
113       nameValuePair "wyoming-faster-whisper-${server}" {
114         inherit (options) enable;
115         description = "Wyoming faster-whisper server instance ${server}";
116         wants = [
117           "network-online.target"
118         ];
119         after = [
120           "network-online.target"
121         ];
122         wantedBy = [
123           "multi-user.target"
124         ];
125         # https://github.com/rhasspy/wyoming-faster-whisper/issues/27
126         environment."HF_HUB_CACHE" = "/tmp";
127         serviceConfig = {
128           DynamicUser = true;
129           User = "wyoming-faster-whisper";
130           StateDirectory = "wyoming/faster-whisper";
131           # https://github.com/home-assistant/addons/blob/master/whisper/rootfs/etc/s6-overlay/s6-rc.d/whisper/run
132           ExecStart = ''
133             ${cfg.package}/bin/wyoming-faster-whisper \
134               --data-dir $STATE_DIRECTORY \
135               --download-dir $STATE_DIRECTORY \
136               --uri ${options.uri} \
137               --device ${options.device} \
138               --model ${options.model} \
139               --language ${options.language} \
140               --beam-size ${options.beamSize} ${options.extraArgs}
141           '';
142           CapabilityBoundingSet = "";
143           DeviceAllow = if builtins.elem options.device [ "cuda" "auto" ] then [
144             # https://docs.nvidia.com/dgx/pdf/dgx-os-5-user-guide.pdf
145             # CUDA not working? Check DeviceAllow and PrivateDevices first!
146             "/dev/nvidia0"
147             "/dev/nvidia1"
148             "/dev/nvidia2"
149             "/dev/nvidia3"
150             "/dev/nvidia4"
151             "/dev/nvidia-caps/nvidia-cap1"
152             "/dev/nvidia-caps/nvidia-cap2"
153             "/dev/nvidiactl"
154             "/dev/nvidia-modeset"
155             "/dev/nvidia-uvm"
156             "/dev/nvidia-uvm-tools"
157           ] else "";
158           DevicePolicy = "closed";
159           LockPersonality = true;
160           MemoryDenyWriteExecute = true;
161           PrivateUsers = true;
162           ProtectHome = true;
163           ProtectHostname = true;
164           ProtectKernelLogs = true;
165           ProtectKernelModules = true;
166           ProtectKernelTunables = true;
167           ProtectControlGroups = true;
168           ProtectProc = "invisible";
169           ProcSubset = "pid";
170           RestrictAddressFamilies = [
171             "AF_INET"
172             "AF_INET6"
173             "AF_UNIX"
174           ];
175           RestrictNamespaces = true;
176           RestrictRealtime = true;
177           SystemCallArchitectures = "native";
178           SystemCallFilter = [
179             "@system-service"
180             "~@privileged"
181           ];
182           UMask = "0077";
183         };
184       }) cfg.servers;
185   };