Skip to content

Commit 24193f9

Browse files
committed
limit py scan on flatpak to speed up start
1 parent 23c232a commit 24193f9

File tree

6 files changed

+128
-44
lines changed

6 files changed

+128
-44
lines changed

desktop/qml/SettingsAdvancedPage.qml

+29-13
Original file line numberDiff line numberDiff line change
@@ -257,26 +257,42 @@ ColumnLayout {
257257
text: qsTranslate("SettingsPage", "Libraries")
258258
}
259259

260-
CheckBox {
261-
checked: _settings.py_feature_scan
262-
text: qsTranslate("SettingsPage", "Use Python libriaries")
263-
onCheckedChanged: {
264-
_settings.py_feature_scan = checked
265-
}
266-
267-
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
268-
ToolTip.visible: hovered
269-
ToolTip.text: qsTranslate("SettingsPage", "Check the presence of the required Python libraries.") + " " +
270-
qsTranslate("SettingsPage", "Disable this option if you observe problems when launching the application.")
271-
hoverEnabled: true
260+
ComboBoxForm {
261+
id: pyScanModeCombo
272262

263+
label.text: qsTranslate("SettingsPage", "Detection of Python libraries")
264+
toolTip: qsTranslate("SettingsPage", "Determine how and whether Python libraries are detected when the application is launched.")
265+
comboBox {
266+
currentIndex: {
267+
if (_settings.py_scan_mode === Settings.PyScanOn) return 0
268+
if (_settings.py_scan_mode === Settings.PyScanOffAllEnabled) return 1
269+
if (_settings.py_scan_mode === Settings.PyScanOffAllDisabled) return 2
270+
return _settings.is_xcb() ? 1 : 2
271+
}
272+
model: [
273+
qsTranslate("SettingsPage", "On"),
274+
qsTranslate("SettingsPage", "Off (Assume all are available)"),
275+
qsTranslate("SettingsPage", "Off (Assume none are available)"),
276+
]
277+
onActivated: {
278+
if (index === 0) {
279+
_settings.py_scan_mode = Settings.PyScanOn
280+
} else if (index === 1) {
281+
_settings.py_scan_mode = Settings.PyScanOffAllEnabled
282+
} else if (index === 2) {
283+
_settings.py_scan_mode = Settings.PyScanOffAllDisabled
284+
} else {
285+
_settings.py_scan_mode = Settings.PyScanOn;
286+
}
287+
}
288+
}
273289
}
274290

275291
TextFieldForm {
276292
id: pyTextField
277293

278294
indends: 1
279-
visible: _settings.py_feature_scan
295+
visible: _settings.py_scan_mode === Settings.PyScanOn || _settings.py_scan_mode === Settings.PyScanOffAllEnabled
280296
label.text: qsTranslate("SettingsPage", "Location of Python libraries (version: %1)").arg(app.py_version.length === 0 ? "0.0.0" : app.py_version)
281297
toolTip: qsTranslate("SettingsPage", "Python libraries directory (%1).").arg("<i>PYTHONPATH</i>") + " " +
282298
qsTranslate("SettingsPage", "Leave blank to use the default value.") + " " +

src/py_executor.cpp

+19-6
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,25 @@ void py_executor::loop() {
106106
try {
107107
m_py_interpreter.emplace();
108108

109-
if (settings::instance()->py_feature_scan()) {
110-
libs_availability = py_tools::libs_availability();
111-
} else {
112-
LOGW("py scan is off");
113-
libs_availability = py_tools::libs_availability_t{};
114-
}
109+
#ifdef USE_PY
110+
libs_availability = py_tools::libs_availability(
111+
[scan_type = settings::instance()->py_scan_mode()] {
112+
switch (scan_type) {
113+
case settings::py_scan_mode_t::PyScanOn:
114+
LOGD("py scan mode: on");
115+
return py_tools::libs_scan_type_t::on;
116+
case settings::py_scan_mode_t::PyScanOffAllEnabled:
117+
LOGD("py scan mode: off-all-enabled");
118+
return py_tools::libs_scan_type_t::off_all_enabled;
119+
case settings::py_scan_mode_t::PyScanOffAllDisabled:
120+
LOGD("py scan mode: off-all-disabled");
121+
return py_tools::libs_scan_type_t::off_all_disabled;
122+
}
123+
LOGF("invalid py scan mode");
124+
}());
125+
#else
126+
libs_availability = py_tools::libs_availability_t{};
127+
#endif
115128

116129
while (!m_shutting_down) {
117130
std::unique_lock<std::mutex> lock{m_mutex};

src/py_tools.cpp

+51-12
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,43 @@ std::ostream& operator<<(std::ostream& os,
6161
}
6262

6363
namespace py_tools {
64-
libs_availability_t libs_availability() {
64+
libs_availability_t libs_availability(libs_scan_type_t scan_type) {
6565
// run only in py thread
6666

6767
libs_availability_t availability{};
6868

69+
switch (scan_type) {
70+
case libs_scan_type_t::on:
71+
break;
72+
case libs_scan_type_t::off_all_enabled:
73+
if (cpu_tools::cpuinfo().feature_flags &
74+
cpu_tools::feature_flags_t::avx) {
75+
availability.coqui_tts = true;
76+
availability.whisperspeech_tts = true;
77+
availability.parler_tts = true;
78+
availability.f5_tts = true;
79+
availability.kokoro_tts = true;
80+
availability.kokoro_ja = true;
81+
availability.kokoro_zh = true;
82+
}
83+
availability.faster_whisper = true;
84+
availability.mimic3_tts = true;
85+
availability.transformers = true;
86+
availability.unikud = true;
87+
availability.gruut_de = true;
88+
availability.gruut_es = true;
89+
availability.gruut_fa = true;
90+
availability.gruut_fr = true;
91+
availability.gruut_it = true;
92+
availability.gruut_nl = true;
93+
availability.gruut_ru = true;
94+
availability.gruut_sw = true;
95+
availability.mecab = true;
96+
break;
97+
case libs_scan_type_t::off_all_disabled:
98+
return availability;
99+
}
100+
69101
#ifdef USE_PY
70102
namespace py = pybind11;
71103
using namespace pybind11::literals;
@@ -103,7 +135,25 @@ libs_availability_t libs_availability() {
103135
} catch (const std::exception& err) {
104136
LOGD("torch cuda check py error: " << err.what());
105137
}
138+
}
139+
140+
try {
141+
LOGD("checking: ctranslate2-cuda");
142+
auto ct2 = py::module_::import("ctranslate2");
143+
LOGD("ctranslate2 version: "
144+
<< ct2.attr("__version__").cast<std::string>());
145+
availability.ctranslate2_cuda =
146+
py::len(ct2.attr("get_supported_compute_types")("cuda")) > 0;
147+
} catch (const std::exception& err) {
148+
LOGD("ctranslate2-cuda check py error: " << err.what());
149+
}
106150

151+
if (scan_type == libs_scan_type_t::off_all_enabled ||
152+
scan_type == libs_scan_type_t::off_all_disabled) {
153+
return availability;
154+
}
155+
156+
if (cpu_tools::cpuinfo().feature_flags & cpu_tools::feature_flags_t::avx) {
107157
try {
108158
LOGD("checking: coqui tts");
109159
py::module_::import("TTS");
@@ -170,17 +220,6 @@ libs_availability_t libs_availability() {
170220
LOGD("faster-whisper check py error: " << err.what());
171221
}
172222

173-
try {
174-
LOGD("checking: ctranslate2-cuda");
175-
auto ct2 = py::module_::import("ctranslate2");
176-
LOGD("ctranslate2 version: "
177-
<< ct2.attr("__version__").cast<std::string>());
178-
availability.ctranslate2_cuda =
179-
py::len(ct2.attr("get_supported_compute_types")("cuda")) > 0;
180-
} catch (const std::exception& err) {
181-
LOGD("ctranslate2-cuda check py error: " << err.what());
182-
}
183-
184223
try {
185224
LOGD("checking: transformers");
186225
py::module_::import("transformers");

src/py_tools.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <iostream>
1212

1313
namespace py_tools {
14+
enum class libs_scan_type_t { on, off_all_disabled, off_all_enabled };
1415
inline static const auto python_site_path = "python/site-packages";
1516

1617
struct py_version_t {
@@ -46,7 +47,7 @@ struct libs_availability_t {
4647
bool mecab = false;
4748
};
4849

49-
libs_availability_t libs_availability();
50+
libs_availability_t libs_availability(libs_scan_type_t scan_type);
5051
bool init_module();
5152
} // namespace py_tools
5253

src/settings.cpp

+15-7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <thread>
2828

2929
#include "config.h"
30+
#include "cpu_tools.hpp"
3031
#include "gpu_tools.hpp"
3132
#include "logger.hpp"
3233
#include "module_tools.hpp"
@@ -2104,14 +2105,21 @@ void settings::set_tts_tag_mode(tts_tag_mode_t value) {
21042105
}
21052106
}
21062107

2107-
bool settings::py_feature_scan() const {
2108-
return value(QStringLiteral("service/py_feature_scan"), true).toBool();
2108+
settings::py_scan_mode_t settings::py_scan_mode() const {
2109+
return static_cast<py_scan_mode_t>(
2110+
value(QStringLiteral("service/py_scan_mode"),
2111+
static_cast<int>(is_flatpak() && cpu_tools::arch() ==
2112+
cpu_tools::arch_t::x86_64
2113+
? py_scan_mode_t::PyScanOffAllEnabled
2114+
: py_scan_mode_t::PyScanOn))
2115+
.toInt());
21092116
}
21102117

2111-
void settings::set_py_feature_scan(bool value) {
2112-
if (value != py_feature_scan()) {
2113-
setValue(QStringLiteral("service/py_feature_scan"), value);
2114-
emit py_feature_scan_changed();
2118+
void settings::set_py_scan_mode(py_scan_mode_t value) {
2119+
if (value != py_scan_mode()) {
2120+
setValue(QStringLiteral("service/py_scan_mode"),
2121+
static_cast<int>(value));
2122+
emit py_scan_mode_changed();
21152123

21162124
set_restart_required(true);
21172125
}
@@ -2218,7 +2226,7 @@ void settings::disable_hw_scan() {
22182226
}
22192227

22202228
void settings::disable_py_scan() {
2221-
set_py_feature_scan(false);
2229+
set_py_scan_mode(py_scan_mode_t::PyScanOffAllDisabled);
22222230
set_restart_required(false);
22232231
}
22242232

src/settings.h

+12-5
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,8 @@ class settings : public QSettings, public singleton<settings> {
351351
set_default_mnt_out_lang NOTIFY default_mnt_out_lang_changed)
352352
Q_PROPERTY(QString audio_input_device READ audio_input_device WRITE
353353
set_audio_input_device NOTIFY audio_input_device_changed)
354-
Q_PROPERTY(bool py_feature_scan READ py_feature_scan WRITE
355-
set_py_feature_scan NOTIFY py_feature_scan_changed)
354+
Q_PROPERTY(py_scan_mode_t py_scan_mode READ py_scan_mode WRITE
355+
set_py_scan_mode NOTIFY py_scan_mode_changed)
356356
Q_PROPERTY(
357357
cache_audio_format_t cache_audio_format READ cache_audio_format WRITE
358358
set_cache_audio_format NOTIFY cache_audio_format_changed)
@@ -646,6 +646,13 @@ class settings : public QSettings, public singleton<settings> {
646646
};
647647
Q_ENUM(voice_profile_type_t)
648648

649+
enum class py_scan_mode_t {
650+
PyScanOn = 0,
651+
PyScanOffAllDisabled = 1,
652+
PyScanOffAllEnabled = 2
653+
};
654+
Q_ENUM(py_scan_mode_t)
655+
649656
struct voice_profile_prompt_t {
650657
QString name;
651658
QString desc;
@@ -907,8 +914,8 @@ class settings : public QSettings, public singleton<settings> {
907914
void set_enabled_models(const QStringList &value);
908915
QString audio_input_device() const;
909916
void set_audio_input_device(const QString &value);
910-
bool py_feature_scan() const;
911-
void set_py_feature_scan(bool value);
917+
py_scan_mode_t py_scan_mode() const;
918+
void set_py_scan_mode(py_scan_mode_t value);
912919
int num_threads() const;
913920
void set_num_threads(int value);
914921
QString py_path() const;
@@ -1053,7 +1060,7 @@ class settings : public QSettings, public singleton<settings> {
10531060
void default_mnt_lang_changed();
10541061
void default_mnt_out_lang_changed();
10551062
void audio_input_device_changed();
1056-
void py_feature_scan_changed();
1063+
void py_scan_mode_changed();
10571064
void cache_audio_format_changed();
10581065
void cache_policy_changed();
10591066
void num_threads_changed();

0 commit comments

Comments
 (0)