Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reload --vosk-grammar-file JSON on SIGHUP #88

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

KJ7LNW
Copy link
Contributor

@KJ7LNW KJ7LNW commented Feb 9, 2023

This commit adds support for reloading the grammar configuration on SIGHUP. This is accomplished by moving the recognizer initialization into its own function so that the signal handler can call it on reload.

A reload of the recognizer is fast because it does not reload the model and only applies the grammar.

Signed-off-by: Eric Wheeler [email protected]

@KJ7LNW
Copy link
Contributor Author

KJ7LNW commented Feb 15, 2023

fixed merge conflict

This commit adds support for reloading the grammar configuration on SIGHUP.
This is accomplished by moving the recognizer initialization into its own
function so that the signal handler can call it on reload.

A reload of the recognizer is fast because it does not reload the model and
only applies the grammar.

Signed-off-by: Eric Wheeler <[email protected]>
@KJ7LNW
Copy link
Contributor Author

KJ7LNW commented Feb 15, 2023

Fixed mypy --strict with return type -> None.

BTW, the diff shown by github isn't pretty because of the indented code (whitespace), but the logic change is small:

Here is a diff ignoring whitespace:

# git show -w HEAD
diff --git a/nerd-dictation b/nerd-dictation
index e5d8196..c4adc49 100755
--- a/nerd-dictation
+++ b/nerd-dictation
@@ -944,22 +944,30 @@ def text_from_vosk_pipe(
 
     vosk.SetLogLevel(-1)
 
+    # Allow for loading the model to take some time:
+    if verbose >= 1:
+        sys.stderr.write("Loading model...\n")
+    model = vosk.Model(vosk_model_dir)
+
+    rec = None
+
+    def vosk_load_recognizer() -> None:
+        nonlocal vosk_grammar_file
+        nonlocal rec
+
         if not vosk_grammar_file:
             grammar_json = ""
         else:
             with open(vosk_grammar_file, encoding="utf-8") as fh:
                 grammar_json = fh.read()
 
-    # Allow for loading the model to take some time:
-    if verbose >= 1:
-        sys.stderr.write("Loading model...\n")
-    model = vosk.Model(vosk_model_dir)
-
         if grammar_json == "":
             rec = vosk.KaldiRecognizer(model, sample_rate)
         else:
             rec = vosk.KaldiRecognizer(model, sample_rate, grammar_json)
 
+    vosk_load_recognizer()
+
     if verbose >= 1:
         sys.stderr.write("Model loaded.\n")
 
@@ -1135,6 +1143,7 @@ def text_from_vosk_pipe(
         if verbose >= 1:
             sys.stderr.write("Reload.\n")
         process_fn("")
+        vosk_load_recognizer()
 
     import signal

@KJ7LNW
Copy link
Contributor Author

KJ7LNW commented Feb 15, 2023

@ideasman42,

Just realized I still have mypy issues to work out on this PR, but I'm not sure what to do.

Scoping rec = None outside of the new vosk_load_recognizer() function causes mypy to complain as follows because None is not properly typed:

nerd-dictation:1052: error: Item "None" of "Optional[Any]" has no attribute "FinalResult"
nerd-dictation:1069: error: Item "None" of "Optional[Any]" has no attribute "PartialResult"
nerd-dictation:1100: error: Item "None" of "Optional[Any]" has no attribute "Reset"
nerd-dictation:1208: error: Item "None" of "Optional[Any]" has no attribute "AcceptWaveform"

I tried a few things but I'm not very familiar with Python's typing. For example, changing rec = None to rec = vosk.KaldiRecognizer(model, sample_rate) and then still calling vosk_load_recognizer() to load the JSON grammar "fixes" the typing issue, but the extra call to vosk.KaldiRecognizer() seems unnecessary.

Do you know what should be done here?

@KJ7LNW KJ7LNW marked this pull request as draft February 15, 2023 21:21
@ideasman42
Copy link
Owner

In this case mypy needs to know that it's not None.

  • If there is no chance of it being None, you can do assert rec is not None to quiet the warning.
  • Or if there is no reason for the value to be None, remove the Optional[..] type.

@KJ7LNW
Copy link
Contributor Author

KJ7LNW commented Feb 16, 2023

The only reason I set rec = None is to scope outside of the vosk_load_recognizer() function.

Questions:

  • Is there a way to scope rec without assigning it to None?
  • How do you remove the Optional[..] type?
  • I've pushed a commit with a few assert lines that fix the mypy issue so you can see it. Do you think is the best way to go here? If so then let me know and I will squash+repush.

@KJ7LNW KJ7LNW marked this pull request as ready for review March 27, 2023 21:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants