価格

アーキテクチャ概要(全体像)

関連ソースファイル

このページの内容は以下のソースファイルに基づいて生成されています:

VibeVoiceは、Microsoftによって開発された音声生成・認識のためのオープンソースプロジェクトである。本プロジェクトは、大規模言語モデル(LLM)をバックボーンとし、音声トークナイザーと拡散モデルを組み合わせることで、テキストから音声への変換(TTS)や音声認識(ASR)などのタスクを実現する。アーキテクチャはモジュラー設計を採用しており、各コンポーネントが明確な責任境界を持つ。

全体アーキテクチャの構成要素

VibeVoiceのアーキテクチャは、主に4つのコアコンポーネントで構成される:LLMバックボーン(Qwen2.5ベース)、Speech Tokenizer(Acoustic & Semantic)、Diffusion Head、そしてText Tokenizerである。これらのコンポーネントは疎結合されており、設定ファイルを通じて柔軟に構成可能である。

正在加载图表渲染器...

アーキテクチャ図の解説:

  1. 入力層:テキストはText Tokenizer(Qwen2ベース)によりトークン化され、音声はSpeech Tokenizerにより特徴量ベクトルに変換される
  2. Speech Connector:音声特徴量の次元をLLMの隠れ層サイズ(3584次元)に合わせるための変換モジュール(modeling_vibevoice.py:59-70
  3. LLMバックボーン:Qwen2.5-7Bをベースとし、32Kコンテキスト長をサポート(qwen2.5_7b_32k.json:49-64
  4. Diffusion Head:LLMの隠れ状態から音声波形を生成する拡散モデルベースのデコーダ

モジュールのエントリーポイントは vibevoice/modular/init.py:1-14 で定義されており、主要クラス(Model, Config, Inference, Streamer)の依存関係が明示されている。具体的なモデル構成パラメータは qwen2.5_7b_32k.json:39-78 に記載されている。

Speech Tokenizer (Acoustic Semantic)

Speech Tokenizerは、音声信号を離散的なトークン表現に変換するエンコーダーである。VibeVoiceでは、音響的特徴と意味的特徴を別々に抽出する2種類のTokenizerを採用している。

Acoustic Tokenizer

Acoustic Tokenizerは、音声の音響的特性(ピッチ、音色、韻律など)を捉えるためのVAEベースのエンコーダーである。設定は configuration_vibevoice.py:31-91 で定義されている。

主要な設定パラメータ:

パラメータデフォルト値説明
vae_dim64VAEの潜在空間次元
encoder_ratios[8,5,5,4,2,2]エンコーダーのダウンサンプリング比率
encoder_depths"3-3-3-3-3-3-8"各エンコーダーレイヤーの深さ
std_dist_type'gaussian'潜在分布のタイプ
causalTrue因果的畳み込みの使用

Semantic Tokenizer

Semantic Tokenizerは、音声の意味的コンテンツ(話される言葉の内容)を抽出する。設定は configuration_vibevoice.py:94-145 で定義されている。Acoustic Tokenizerとの主な違いは、fix_stdが0に設定され、std_dist_typeが'none'である点である。

正規化層の実装

Tokenizer内部では、畳み込みフレンドリーな正規化層が使用される。 modular_vibevoice_tokenizer.py:38-90 では、ConvLayerNormConvRMSNormの2種類が実装されている:

python
1class ConvRMSNorm(RMSNorm):
2    def forward(self, x):
3        x = x.transpose(1, 2)  # b ... t -> b t ...
4        if (not APEX_AVAILABLE) or (not self.elementwise_affine):
5            output = self._norm(x.float()).type_as(x)
6            if self.weight is not None:
7                output = output * self.weight
8        else:
9            output = fused_rms_norm_affine(x, self.weight, self.weight.shape, self.eps)
10        output = output.transpose(1, 2)  # b t ... -> b ... t
11        return output

この実装では、APEXが利用可能な場合に融合RMS正規化を使用し、そうでない場合はネイティブ実装にフォールバックする。

LLM Backbone (Qwen2.5ベース)

VibeVoiceは、Qwen2.5-7Bを言語モデルのバックボーンとして採用している。この選択により、32Kトークンのコンテキスト長と多言語対応が可能になっている。

Speech Connector

Speech Connectorは、Speech Tokenizerからの出力(64次元)をLLMの隠れ層サイズ(3584次元)に変換するアダプターモジュールである。実装は modeling_vibevoice.py:59-70 にある:

python
1class SpeechConnector(nn.Module):
2    def __init__(self, input_dim, output_dim):
3        super().__init__()
4        self.fc1 = nn.Linear(input_dim, output_dim)
5        self.norm = LlamaRMSNorm(output_dim, eps=1e-6)
6        self.fc2 = nn.Linear(output_dim, output_dim)
7
8    def forward(self, features, **kwargs):    
9        x = self.fc1(features)
10        x = self.norm(x)
11        x = self.fc2(x)
12        return x

ストリーミング版でも同様の構造が modeling_vibevoice_streaming.py:44-55 で再定義されている。

Text Tokenizer

テキスト処理には、Qwen2Tokenizerをベースとしたカスタムトークナイザーを使用する。 modular_vibevoice_text_tokenizer.py:12-109 では、音声生成用の特殊トークンが追加されている:

python
1def _add_vibevoice_special_tokens(self):
2    """Add VibeVoice-specific special tokens."""
3    special_tokens = {
4        "additional_special_tokens": [
5            "<|vision_start|>",  # Speech start (reusing vision tokens)
6            "<|vision_end|>",  # Speech end
7            "<|vision_pad|>",  # Speech diffusion pad
8        ]
9    }
10    num_added = self.add_special_tokens(special_tokens)

ASR(音声認識)用のトークナイザーでは、異なる特殊トークンセット(<|object_ref_start|>, <|object_ref_end|>, <|box_start|>)が使用される(modular_vibevoice_text_tokenizer.py:264-283)。

Diffusion Head (音声生成)

Diffusion Headは、LLMの隠れ状態から音声波形を生成する拡散モデルベースのデコーダである。DDPM(Denoising Diffusion Probabilistic Models)を使用し、v-prediction方式を採用している。

正規化層

Diffusion Head内では、RMSNormが使用される。 modular_vibevoice_diffusion_head.py:20-41 の実装:

python
1class RMSNorm(nn.Module):
2    def __init__(self, dim: int, eps: float = 1e-6, elementwise_affine=True, memory_efficient=False):
3        super().__init__()
4        self.dim = dim
5        self.eps = eps
6        self.elementwise_affine = elementwise_affine
7        if self.elementwise_affine:
8            self.weight = nn.Parameter(torch.ones(dim))
9
10    def _norm(self, x):
11        return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)
12
13    def forward(self, x):
14        output = self._norm(x.float()).type_as(x)
15        if self.weight is not None:
16            output = output * self.weight
17        return output

タイムステップ埋め込み

拡散プロセスのタイムステップを埋め込みベクトルに変換するために、サイン・コサイン埋め込みが使用される。 modular_vibevoice_diffusion_head.py:48-93

python
1class TimestepEmbedder(nn.Module):
2    def __init__(self, hidden_size, frequency_embedding_size=256):
3        super().__init__()
4        self.mlp = nn.Sequential(
5            nn.Linear(frequency_embedding_size, hidden_size, bias=False),
6            ACT2FN['silu'],
7            nn.Linear(hidden_size, hidden_size, bias=False),
8        )
9
10    @staticmethod
11    def timestep_embedding(t, dim, max_period=10000):
12        half = dim // 2
13        freqs = torch.exp(
14            -math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half
15        ).to(t.device)
16        args = t[:, None].float() * freqs[None]
17        embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
18        return embedding.to(t.dtype)

Diffusion Head設定

qwen2.5_7b_32k.json:66-78 から、主要な設定パラメータを確認できる:

パラメータ説明
ddpm_num_steps1000拡散ステップ数(学習時)
ddpm_num_inference_steps20推論時のステップ数
ddpm_beta_schedule"cosine"ノイズスケジュール
prediction_type"v_prediction"予測タイプ
head_layers4ヘッドのレイヤー数
latent_size64潜在ベクトルサイズ

データフローと出力形式

VibeVoiceのデータフローは、入力から出力まで一貫したテンソルフローとして設計されている。

出力データ構造

modeling_vibevoice.py:34-57 では、2種類の出力構造が定義されている:

python
1class VibeVoiceCausalLMOutputWithPast(ModelOutput):
2    loss: Optional[torch.FloatTensor] = None
3    diffusion_loss: Optional[torch.FloatTensor] = None
4    speech_token_num: Optional[int] = None
5    logits: torch.FloatTensor = None
6    past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None
7    hidden_states: Optional[Tuple[torch.FloatTensor, ...]] = None
8    attentions: Optional[Tuple[torch.FloatTensor, ...]] = None
9
10class VibeVoiceGenerationOutput(ModelOutput):
11    sequences: torch.LongTensor = None
12    speech_outputs: Optional[List[torch.FloatTensor]] = None

ストリーミング推論のキャッシュ管理

ストリーミング推論時は、KVキャッシュの効率的な管理が重要である。 modeling_vibevoice_streaming_inference.py:38-138 では、transformers 4.57以降との互換性を確保するためのMockCacheLayerが実装されている:

python
1class MockCacheLayer:
2    def __init__(self, key_cache, value_cache, parent_cache=None, layer_idx=0):
3        self.key_cache = key_cache
4        self.value_cache = value_cache
5        self._parent_cache = parent_cache
6        self._layer_idx = layer_idx
7
8    def update(self, key_states, value_states, cache_kwargs=None):
9        if self._parent_cache is None:
10            return self.key_cache, self.value_cache
11        
12        parent = self._parent_cache
13        idx = self._layer_idx
14        
15        if parent.key_cache[idx] is not None:
16            parent.key_cache[idx] = torch.cat([parent.key_cache[idx], key_states], dim=2)
17            parent.value_cache[idx] = torch.cat([parent.value_cache[idx], value_states], dim=2)
18        else:
19            parent.key_cache[idx] = key_states
20            parent.value_cache[idx] = value_states

エンドツーエンドのデータフロー

正在加载图表渲染器...

データフローの解説:

  1. テキスト処理:入力テキストはText Tokenizerによりトークン化され、トークンID列に変換される
  2. 音声処理:参照音声(話者クローン用)はSpeech Tokenizerにより64次元の特徴量ベクトルに変換される
  3. 次元調整:Speech Connectorが音声特徴量をLLMの隠れ層サイズ(3584次元)に拡張する
  4. LLM推論:Qwen2.5がテキストと音声コンテキストを統合的に処理し、次トークンの隠れ状態を生成
  5. 音声生成:Diffusion Headが隠れ状態から20ステップの拡散逆プロセスで音声波形を生成

モジュール依存関係

VibeVoiceのモジュール依存関係は、明確な階層構造を持つ。

正在加载图表渲染器...

依存関係のポイント:

  1. 設定層:全てのコンポーネントは設定クラスに依存し、設定クラスはJSONファイルからパラメータを読み込む
  2. コンポーネント層:各コンポーネントは独立してテスト可能
  3. モデル層:コンポーネントを組み合わせて完全なモデルを構成
  4. 推論層:モデル層の上に構築され、ストリーミングやバッチ推論を最適化

技術選定と設計判断

VibeVoiceのアーキテクチャにおける主要な技術選定とその理由を以下の表にまとめる。

技術用途選定理由代替案
Qwen2.5-7BLLMバックボーン32Kコンテキスト、多言語対応、効率的な推論Llama 3, Mistral
VAESpeech Tokenizer潜在空間での滑らかな補間、再構成品質VQ-VAE, Wav2Vec
DDPM音声生成高品質な生成、安定した学習Flow Matching, GAN
v-prediction拡散予測タイプ数値安定性、高速収束epsilon-prediction
Cosine Scheduleノイズスケジュール滑らかなノイズ除去、高周波成分の保持Linear Schedule
RMSNorm正規化計算効率、LayerNormと同等の性能LayerNorm
BFloat16精度メモリ効率と数値安定性のバランスFloat16, Float32
24kHzサンプリングレート音声品質と計算コストのバランス16kHz, 48kHz

設計上の制約とトレードオフ

  1. メモリ使用量:7BパラメータのLLMと拡散モデルの組み合わせにより、GPUメモリ要件が高い(最低16GB推奨)
  2. レイテンシ:拡散モデルの20ステップ推論は、リアルタイム性を損なう可能性がある
  3. 特殊トークンの再利用<|vision_start|>などのトークンを音声用に再利用しており、将来的な拡張で競合する可能性がある

起動フローと初期化

VibeVoiceの初期化プロセスは、設定の読み込みからモデルのロードまで段階的に行われる。

Webアプリケーションの起動フロー

demo/web/app.py:41-67 から、StreamingTTSServiceの初期化フローを確認できる:

python
1class StreamingTTSService:
2    def __init__(
3        self,
4        model_path: str,
5        device: str = "cuda",
6        inference_steps: int = 5,
7    ) -> None:
8        self.model_path = model_path
9        self.inference_steps = inference_steps
10        self.sample_rate = SAMPLE_RATE  # 24_000
11
12        self.processor: Optional[VibeVoiceStreamingProcessor] = None
13        self.model: Optional[VibeVoiceStreamingForConditionalGenerationInference] = None
14        self.voice_presets: Dict[str, Path] = {}
15        
16        if device == "mps" and not torch.backends.mps.is_available():
17            print("Warning: MPS not available. Falling back to CPU.")
18            device = "cpu"
19        self.device = device

設定の読み込み

設定ファイル(JSON)からモデル構成が読み込まれる。 qwen2.5_7b_32k.json:39-78 には、Acoustic Tokenizer、Decoder、Diffusion Headの3つのセクションが含まれている。設定クラスは configuration_vibevoice.py:14-28 で定義される_convert_dtype_to_string関数を通じて、torch.dtypeを文字列表現に変換し、JSONシリアライゼーション問題を回避している。