diff --git a/nixos/modules/services/home-automation/wyoming/faster-whisper.nix b/nixos/modules/services/home-automation/wyoming/faster-whisper.nix index 928104c497e5..2d67bf8c8e5e 100644 --- a/nixos/modules/services/home-automation/wyoming/faster-whisper.nix +++ b/nixos/modules/services/home-automation/wyoming/faster-whisper.nix @@ -18,10 +18,6 @@ let types ; - inherit (builtins) - toString - ; - inherit (utils) escapeSystemdExecArgs ; @@ -36,230 +32,261 @@ in description = '' Attribute set of wyoming-faster-whisper instances to spawn. ''; - type = attrsOf (submodule { - options = { - enable = mkEnableOption "Wyoming faster-whisper server"; + type = attrsOf ( + submodule ( + { name, ... }: + { + options = { + enable = mkEnableOption "Wyoming faster-whisper server"; - model = mkOption { - type = str; - default = "tiny-int8"; - example = "Systran/faster-distil-whisper-small.en"; - # https://github.com/home-assistant/addons/blob/master/whisper/DOCS.md#option-model - description = '' - Name of the voice model to use. Can also be a HuggingFace model ID or a path to - a custom model directory. + zeroconf = { + enable = mkEnableOption "zeroconf discovery" // { + default = true; + }; - With {option}`useTranformers` enabled, a HuggingFace transformers Whisper model - ID from HuggingFace like `openai/whisper-tiny.en` must be used. + name = mkOption { + type = str; + default = "faster-whisper-${name}"; + description = '' + The advertised name for zeroconf discovery. + ''; + }; + }; - Compressed models (`int8`) are slightly less accurate, but smaller and faster. - Distilled models are uncompressed and faster and smaller than non-distilled models. + sttLibrary = mkOption { + type = enum [ + "auto" + "faster-whisper" + "onnx-asr" + "sherpa" + "transformers" + ]; + default = "auto"; + example = "sherpa"; + description = '' + Library used for speech-to-text process. - Available models: - - `tiny-int8` (compressed) - - `tiny` - - `tiny.en` (English only) - - `base-int8` (compressed) - - `base` - - `base.en` (English only) - - `small-int8` (compressed) - - `distil-small.en` (distilled, English only) - - `small` - - `small.en` (English only) - - `medium-int8` (compressed) - - `distil-medium.en` (distilled, English only) - - `medium` - - `medium.en` (English only) - - `large` - - `large-v1` - - `distil-large-v2` (distilled, English only) - - `large-v2` - - `distil-large-v3` (distilled, English only) - - `large-v3` - - `turbo` (faster than large-v3) - ''; - }; + When set to `auto` picks a default based on the {option}`language`. + ''; + }; - useTransformers = mkOption { - type = bool; - default = false; - description = '' - Whether to provide the dependencies to allow using transformer models. - ''; - }; + model = mkOption { + type = str; + default = "auto"; + example = "sherpa-onnx-nemo-parakeet-tdt-0.6b-v3-int8"; + # https://github.com/home-assistant/addons/blob/master/whisper/DOCS.md#option-model + description = '' + Name of the voice model to use. Can also be a HuggingFace model ID or a path to + a custom model directory. - uri = mkOption { - type = strMatching "^(tcp|unix)://.*$"; - example = "tcp://0.0.0.0:10300"; - description = '' - URI to bind the wyoming server to. - ''; - }; + When set to `auto` picks a default based on the {option}`language`, - device = mkOption { - # https://opennmt.net/CTranslate2/python/ctranslate2.models.Whisper.html# - type = enum [ - "cpu" - "cuda" - "auto" - ]; - default = "cpu"; - description = '' - Determines the platform faster-whisper is run on. CPU works everywhere, CUDA requires a compatible NVIDIA GPU. - ''; - }; + With {option}`sttLibrary` set to `transformers`, a HuggingFace transformers Whisper model + ID from HuggingFace like `openai/whisper-tiny` or `openai/whisper-base` must be used. - language = mkOption { - type = enum [ - # https://github.com/home-assistant/addons/blob/master/whisper/config.yaml#L20 - "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" - "yue" - "yo" - "zh" - ]; - example = "en"; - description = '' - The language used to to parse words and sentences. - ''; - }; + Compressed models (`int8`) are slightly less accurate, but smaller and faster. + Distilled models are uncompressed and faster and smaller than non-distilled models. - initialPrompt = mkOption { - type = nullOr str; - default = null; - # https://github.com/home-assistant/addons/blob/master/whisper/DOCS.md#option-custom_model_type - example = '' - The following conversation takes place in the universe of - Wizard of Oz. Key terms include 'Yellow Brick Road' (the path - to follow), 'Emerald City' (the ultimate goal), and 'Ruby - Slippers' (the magical tools to succeed). Keep these in mind as - they guide the journey. - ''; - description = '' - Optional text to provide as a prompt for the first window. This can be used to provide, or - "prompt-engineer" a context for transcription, e.g. custom vocabularies or proper nouns - to make it more likely to predict those word correctly. + Available models for faster-whisper: + - `tiny-int8` (compressed) + - `tiny` + - `tiny.en` (English only) + - `base-int8` (compressed) + - `base` + - `base.en` (English only) + - `small-int8` (compressed) + - `distil-small.en` (distilled, English only) + - `small` + - `small.en` (English only) + - `medium-int8` (compressed) + - `distil-medium.en` (distilled, English only) + - `medium` + - `medium.en` (English only) + - `large` + - `large-v1` + - `distil-large-v2` (distilled, English only) + - `large-v2` + - `distil-large-v3` (distilled, English only) + - `large-v3` + - `turbo` (faster than large-v3) + ''; + }; - Not supported when the {option}`customModelType` is `transformers`. - ''; - }; + uri = mkOption { + type = strMatching "^(tcp|unix)://.*$"; + example = "tcp://0.0.0.0:10300"; + description = '' + URI to bind the wyoming server to. + ''; + }; - beamSize = mkOption { - type = ints.unsigned; - default = 0; - example = 5; - description = '' - The number of beams to use in beam search. - Use `0` to automatically select a value based on the CPU. - ''; - apply = toString; - }; + device = mkOption { + # https://opennmt.net/CTranslate2/python/ctranslate2.models.Whisper.html# + type = enum [ + "cpu" + "cuda" + "auto" + ]; + default = "cpu"; + description = '' + Determines the platform faster-whisper is run on. CPU works everywhere, CUDA requires a compatible NVIDIA GPU. + ''; + }; - extraArgs = mkOption { - type = listOf str; - default = [ ]; - description = '' - Extra arguments to pass to the server commandline. - ''; - }; - }; - }); + language = mkOption { + type = enum [ + # https://github.com/home-assistant/addons/blob/master/whisper/config.yaml#L20 + "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" + "yue" + "yo" + "zh" + ]; + example = "en"; + description = '' + The language used to to parse words and sentences. + ''; + }; + + initialPrompt = mkOption { + type = nullOr str; + default = null; + # https://github.com/home-assistant/addons/blob/master/whisper/DOCS.md#option-custom_model_type + example = '' + The following conversation takes place in the universe of + Wizard of Oz. Key terms include 'Yellow Brick Road' (the path + to follow), 'Emerald City' (the ultimate goal), and 'Ruby + Slippers' (the magical tools to succeed). Keep these in mind as + they guide the journey. + ''; + description = '' + Optional text to provide as a prompt for the first window. This can be used to provide, or + "prompt-engineer" a context for transcription, e.g. custom vocabularies or proper nouns + to make it more likely to predict those word correctly. + + Only supported when the {option}`sttLibrary` is `faster-whisper`. + ''; + }; + + beamSize = mkOption { + type = ints.unsigned; + default = 0; + example = 5; + description = '' + The number of beams to use in beam search. + + The default (`0`) will use 1 beam on ARM systems (assumes an ARM SBC) and 5 everywhere else. + ''; + apply = toString; + }; + + extraArgs = mkOption { + type = listOf str; + default = [ ]; + description = '' + Extra arguments to pass to the server commandline. + ''; + }; + }; + } + ) + ); }; }; @@ -273,8 +300,8 @@ in in mkIf (cfg.servers != { }) { assertions = mapAttrsToList (server: options: { - assertion = options.useTransformers -> options.initialPrompt == null; - message = "wyoming-faster-whisper/${server}: Transformer models (`useTransformers`) do not currently support an `initialPrompt`."; + assertion = options.sttLibrary != "faster-whisper" -> options.initialPrompt == null; + message = "wyoming-faster-whisper/${server}: Initial prompt is only supported when using `faster-whisper` as `sttLibrary`."; }) cfg.servers; systemd.services = mapAttrs' ( @@ -283,8 +310,14 @@ in finalPackage = cfg.package.overridePythonAttrs (oldAttrs: { dependencies = oldAttrs.dependencies - # for transformer model support - ++ optionals options.useTransformers oldAttrs.optional-dependencies.transformers; + ++ optionals options.zeroconf.enable oldAttrs.optional-dependencies.zeroconf + ++ optionals ( + options.sttLibrary == "onnx-asr" || options.sttLibrary == "auto" && options.language == "ru" + ) oldAttrs.optional-dependencies.onnx_asr + ++ optionals ( + options.sttLibrary == "sherpa-onnx" || options.sttLibrary == "auto" && options.language == "en" + ) oldAttrs.optional-dependencies.sherpa + ++ optionals (options.sttLibrary == "transformers") oldAttrs.optional-dependencies.transformers; }); in nameValuePair "wyoming-faster-whisper-${server}" { @@ -316,6 +349,8 @@ in options.uri "--device" options.device + "--stt-library" + options.sttLibrary "--model" options.model "--language" @@ -323,8 +358,9 @@ in "--beam-size" options.beamSize ] - ++ lib.optionals options.useTransformers [ - "--use-transformers" + ++ lib.optionals options.zeroconf.enable [ + "--zeroconf" + options.zeroconf.name ] ++ lib.optionals (options.initialPrompt != null) [ "--initial-prompt" @@ -366,6 +402,10 @@ in "AF_INET" "AF_INET6" "AF_UNIX" + ] + ++ lib.optionals options.zeroconf.enable [ + # Zeroconf support require network interface enumeration + "AF_NETLINK" ]; RestrictNamespaces = true; RestrictRealtime = true; diff --git a/nixos/modules/services/home-automation/wyoming/piper.nix b/nixos/modules/services/home-automation/wyoming/piper.nix index 2252772d9f68..e4c1971830f3 100644 --- a/nixos/modules/services/home-automation/wyoming/piper.nix +++ b/nixos/modules/services/home-automation/wyoming/piper.nix @@ -37,7 +37,7 @@ in ''; type = types.attrsOf ( types.submodule ( - { ... }: + { name, ... }: { options = { enable = mkEnableOption "Wyoming Piper server"; @@ -49,7 +49,7 @@ in name = mkOption { type = str; - default = "piper"; + default = "piper-${name}"; description = '' The advertised name for zeroconf discovery. ''; @@ -205,8 +205,11 @@ in RestrictAddressFamilies = [ "AF_INET" "AF_INET6" - "AF_NETLINK" "AF_UNIX" + ] + ++ lib.optionals options.zeroconf.enable [ + # Zeroconf support require network interface enumeration + "AF_NETLINK" ]; RestrictNamespaces = true; RestrictRealtime = true; diff --git a/pkgs/by-name/wy/wyoming-faster-whisper/package.nix b/pkgs/by-name/wy/wyoming-faster-whisper/package.nix index 47447bc6bccd..65ddaad79125 100644 --- a/pkgs/by-name/wy/wyoming-faster-whisper/package.nix +++ b/pkgs/by-name/wy/wyoming-faster-whisper/package.nix @@ -6,14 +6,14 @@ python3Packages.buildPythonApplication (finalAttrs: { pname = "wyoming-faster-whisper"; - version = "2.5.0"; + version = "3.1.0"; pyproject = true; src = fetchFromGitHub { owner = "rhasspy"; repo = "wyoming-faster-whisper"; tag = "v${finalAttrs.version}"; - hash = "sha256-MKB6gZdGdAYoNK8SRiDHG8xtMZ5mXdaSn+bH4T6o/K4="; + hash = "sha256-p1FCyj/D7ndKJD1/V5YzhT0xlkg61DSx2m3DCELmPO8="; }; build-system = with python3Packages; [ @@ -25,18 +25,33 @@ python3Packages.buildPythonApplication (finalAttrs: { "wyoming" ]; + pythonRemoveDeps = [ + # https://github.com/rhasspy/wyoming-faster-whisper/pull/81 + "requests" + ]; + dependencies = with python3Packages; [ faster-whisper wyoming ]; - optional-dependencies = { - transformers = - with python3Packages; - [ - transformers - ] - ++ transformers.optional-dependencies.torch; + optional-dependencies = with python3Packages; { + transformers = [ + transformers + ] + ++ transformers.optional-dependencies.torch; + sherpa = [ + sherpa-onnx + ]; + onnx_asr = [ + onnx-asr + ] + ++ onnx-asr.optional-dependencies.cpu + ++ onnx-asr.optional-dependencies.hub; + zeroconf = [ + wyoming + ] + ++ wyoming.optional-dependencies.zeroconf; }; pythonImportsCheck = [