Conversation
There was a problem hiding this comment.
Pull request overview
Refactors several TTS engine classes to pre-resolve language-specific model metadata (samplerate/model path) and reuse it during engine loading, alongside Docker usage documentation tweaks and a small environment-variable default fix in app.py.
Changes:
- Move language/sub checkpoint resolution from
load_engine()into__init__()for multiple TTS engines and reuseself.model_pathinload_engine(). - Update CLI help / README Docker command examples and WSL env var default handling.
- Minor formatting/indentation adjustment in JetPack detection messaging.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/classes/tts_engines/vits.py | Moves model path + samplerate resolution into __init__, uses self.model_path in load_engine(). |
| lib/classes/tts_engines/tortoise.py | Same refactor: resolves model path in __init__, reuses it in load_engine(). |
| lib/classes/tts_engines/tacotron.py | Same refactor with fallback resolution behavior for iso_dir. |
| lib/classes/tts_engines/glowtts.py | Same refactor: resolves model path in __init__, reuses it in load_engine(). |
| lib/classes/device_installer.py | Adjusts JetPack 6.x “unrecognized” message indentation/placement. |
| app.py | Changes DOCKER_IN_WSL default to a string '0' and adjusts embedded help text formatting. |
| README.md | Re-formats Docker run/compose instructions and updates some image references. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| msg = 'Unrecognized JetPack 6.x version. Falling back to CPU.' | ||
| return ('unknown', msg) |
There was a problem hiding this comment.
This assignment is unreachable: every branch above returns (l4t_major < 35, l4t_major == 35, and both rev_major branches). Either remove the dead code, or adjust the branching so an actually-unrecognized JetPack 6.x revision falls through here (e.g., explicitly handle known revisions and return ('unknown', msg) otherwise).
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --rm -it -p 7860:7860 ebook2audiobook:cpu --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | ||
| CUDA: | ||
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --gpus all --rm -it -p 7860:7860 ebook2audiobook:cu[118/122/124/126 etc..] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | ||
| ROCM: | ||
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --device=/dev/kfd --device=/dev/dri --rm -it -p 7860:7860 ebook2audiobook:rocm[6.0/6.1/6.4 etc.] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | ||
| XPU: | ||
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --device=/dev/dri --rm -it -p 7860:7860 ebook2audiobook:xpu --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | ||
| JETSON: | ||
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --runtime nvidia --rm -it -p 7860:7860 ebook2audiobook:jetson[51/60/61 etc.] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] |
There was a problem hiding this comment.
The README mixes image names: Gradio examples use athomasson2/ebook2audiobook:* but the headless examples still use ebook2audiobook:* (local image). This is confusing for users following the "run the container" section. Either update the headless commands to use the same published image, or explicitly note that headless examples assume a locally built image tag.
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --rm -it -p 7860:7860 ebook2audiobook:cpu --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | |
| CUDA: | |
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --gpus all --rm -it -p 7860:7860 ebook2audiobook:cu[118/122/124/126 etc..] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | |
| ROCM: | |
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --device=/dev/kfd --device=/dev/dri --rm -it -p 7860:7860 ebook2audiobook:rocm[6.0/6.1/6.4 etc.] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | |
| XPU: | |
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --device=/dev/dri --rm -it -p 7860:7860 ebook2audiobook:xpu --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | |
| JETSON: | |
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --runtime nvidia --rm -it -p 7860:7860 ebook2audiobook:jetson[51/60/61 etc.] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | |
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --rm -it -p 7860:7860 athomasson2/ebook2audiobook:cpu --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | |
| CUDA: | |
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --gpus all --rm -it -p 7860:7860 athomasson2/ebook2audiobook:cu[118/122/124/126 etc..] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | |
| ROCM: | |
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --device=/dev/kfd --device=/dev/dri --rm -it -p 7860:7860 athomasson2/ebook2audiobook:rocm[6.0/6.1/6.4 etc.] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | |
| XPU: | |
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --device=/dev/dri --rm -it -p 7860:7860 athomasson2/ebook2audiobook:xpu --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] | |
| JETSON: | |
| docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --runtime nvidia --rm -it -p 7860:7860 athomasson2/ebook2audiobook:jetson[51/60/61 etc.] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..] |
| self.engine = self.load_engine() | ||
| self.engine_zs = self._load_engine_zs() | ||
| iso_dir = default_engine_settings[self.session['tts_engine']]['languages'][self.session['language']] | ||
| sub_dict = self.models[self.session['fine_tuned']]['sub'] | ||
| sub = next((key for key, lang_list in sub_dict.items() if iso_dir in lang_list), None) |
There was a problem hiding this comment.
self.load_engine() is called before self.model_path is assigned, but load_engine() now uses self.model_path to set self.tts_key and call _load_api(). This will raise AttributeError during initialization. Move the language/sub resolution and self.model_path assignment above the self.engine = self.load_engine() line (or revert to resolving the path inside load_engine()).
| self.engine = self.load_engine() | ||
| iso_dir = default_engine_settings[self.session['tts_engine']]['languages'][self.session['language']] | ||
| sub_dict = self.models[self.session['fine_tuned']]['sub'] | ||
| sub = next((key for key, lang_list in sub_dict.items() if iso_dir in lang_list), None) | ||
| if sub is None: |
There was a problem hiding this comment.
self.load_engine() runs before self.model_path is computed, but load_engine() now depends on self.model_path for self.tts_key and _load_api(). This will crash with AttributeError in __init__. Resolve iso_dir/sub and set self.model_path before calling load_engine() (or keep the resolution logic inside load_engine()).
| self.amp_dtype = self._apply_gpu_policy(enough_vram=enough_vram, seed=seed) | ||
| self.xtts_speakers = self._load_xtts_builtin_list() | ||
| self.engine = self.load_engine() | ||
| self.engine_zs = self._load_engine_zs() | ||
| iso_dir = default_engine_settings[self.session['tts_engine']]['languages'][self.session['language']] |
There was a problem hiding this comment.
__init__ invokes self.load_engine() before self.model_path is computed, but load_engine() now relies on self.model_path to set self.tts_key and call _load_api(). This makes initialization crash with AttributeError. Resolve iso_dir/sub and set self.model_path (and samplerate) before calling load_engine(), or revert to resolving inside load_engine().
| self.engine = self.load_engine() | ||
| self.engine_zs = self._load_engine_zs() | ||
| iso_dir = default_engine_settings[self.session['tts_engine']]['languages'][self.session['language']] | ||
| sub_dict = self.models[self.session['fine_tuned']]['sub'] | ||
| sub = next((key for key, lang_list in sub_dict.items() if iso_dir in lang_list), None) | ||
| if sub is None: |
There was a problem hiding this comment.
self.load_engine() is invoked before self.model_path is set, but load_engine() now uses self.model_path for the cache key and _load_api() path. As written, initialization will fail with AttributeError. Compute self.model_path (and samplerate) before calling load_engine(), or move the model-path resolution back into load_engine().
No description provided.