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

音声合成の処理を丸ごとスレッド分離して実行する #692

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/voicevox_core/src/__internal.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod doctest_fixtures;
pub mod interop;

// VOICEVOX CORE内のラッパー向けの実装
// FIXME: 要議論: https://github.com/VOICEVOX/voicevox_core/issues/595
Expand Down
1 change: 1 addition & 0 deletions crates/voicevox_core/src/__internal/interop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub use crate::synthesizer::PerformInference;
8 changes: 3 additions & 5 deletions crates/voicevox_core/src/engine/open_jtalk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl OpenJtalk {
pub async fn new(open_jtalk_dict_dir: impl AsRef<Path>) -> crate::result::Result<Self> {
let open_jtalk_dict_dir = open_jtalk_dict_dir.as_ref().to_owned();

tokio::task::spawn_blocking(move || {
crate::task::asyncify(move || {
let mut s = Self::new_without_dic();
s.load(open_jtalk_dict_dir).map_err(|()| {
// FIXME: 「システム辞書を読もうとしたけど読めなかった」というエラーをちゃんと用意する
Expand All @@ -61,7 +61,6 @@ impl OpenJtalk {
Ok(s)
})
.await
.unwrap()
}

// 先に`load`を呼ぶ必要がある。
Expand All @@ -80,7 +79,7 @@ impl OpenJtalk {

let words = user_dict.to_mecab_format();

let result = tokio::task::spawn_blocking(move || -> crate::Result<_> {
let result = crate::task::asyncify(move || -> crate::Result<_> {
// ユーザー辞書用のcsvを作成
let mut temp_csv =
NamedTempFile::new().map_err(|e| ErrorRepr::UseUserDict(e.into()))?;
Expand Down Expand Up @@ -111,8 +110,7 @@ impl OpenJtalk {

Ok(mecab.load_with_userdic(dict_dir.as_ref(), Some(Path::new(&temp_dict_path))))
})
.await
.unwrap()?;
.await?;

if !result {
return Err(ErrorRepr::UseUserDict(anyhow!("辞書のコンパイルに失敗しました")).into());
Expand Down
13 changes: 8 additions & 5 deletions crates/voicevox_core/src/infer/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,16 @@ impl<R: InferenceRuntime, D: InferenceDomain> Status<R, D> {
self.is_loaded_model_by_style_id(style_id)
}

/// 推論を実行する。
///
/// # Performance
///
/// CPU/GPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

すみません! 前にもみたいなこと聞いたかもなのですが、これって何ででしたっけ 🙇

非同期ランタイムはRustの文脈(というよりtokio?)でグローバルにたった1つだけしかなく、別の非同期処理(ファイルI/Oなど)が実行されなくなるから、とかでしたっけ

///
/// # Panics
///
/// `self`が`model_id`を含んでいないとき、パニックする。
pub(crate) async fn run_session<I>(
pub(crate) fn run_session<I>(
&self,
model_id: &VoiceModelId,
input: I,
Expand All @@ -103,10 +109,7 @@ impl<R: InferenceRuntime, D: InferenceDomain> Status<R, D> {
I::Signature: InferenceSignature<Domain = D>,
{
let sess = self.loaded_models.lock().unwrap().get(model_id);

tokio::task::spawn_blocking(move || sess.run(input))
.await
.unwrap()
sess.run(input)
}
}

Expand Down
6 changes: 4 additions & 2 deletions crates/voicevox_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ mod metas;
mod numerics;
mod result;
mod synthesizer;
mod task;
mod user_dict;
mod version;
mod voice_model;

#[doc(hidden)]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ、ここ手元でcargo docで確認するときに外して、そのまま忘れてgit addしてしまったやつですね...

pub mod __internal;

#[cfg(test)]
Expand All @@ -31,7 +31,9 @@ pub use self::result::*;
pub use self::voice_model::*;
pub use devices::*;
pub use manifest::*;
pub use synthesizer::*;
pub use synthesizer::{
AccelerationMode, InitializeOptions, SynthesisOptions, Synthesizer, TtsOptions,
};
pub use user_dict::*;
pub use version::*;

Expand Down
Loading
Loading