1. はじめに
前回(Part1)では「なぜTF-Locoformerが必要だったか」という背景と問題設定を解説しました。
ポイントを振り返ってみましょう。
- TFドメインモデルはSTFTで長い時間窓を使えるため、残響対策に構造的に有利
- 当時最強のTF-GridNetはRNN(ローカルモデリング)とSelf-Attention(グローバルモデリング)を組み合わせていた
- しかしRNNは逐次処理しかできず、Transformerの並列化の恩恵を受けられない
- TF-Locoformerの解決策:FFNを「畳み込み付きFFN(ConvSwiGLU)」に変えてローカル性を担保しつつRNNを廃止
Part2では、TF-Locoformerのアーキテクチャについて、詳しく解説していこうと思います。
2. 全体パイプラインを俯瞰する
2.1 入力:STFTとスペクトログラム
TF-Locoformerへの入力は、音声波形をSTFTで変換した「スペクトログラム」です。
まずSTFTとは何かを整理しておきましょう。
音声は1次元の数値列です。16kHzサンプリングなら1秒間に16,000個の数値が並びます。
音声波形(1次元):時刻: 1 2 3 ... 16000値: 0.1 0.3 -0.2 ... 0.05これを2次元の「時間×周波数」表現に変換するのがSTFTです。
【STFTのイメージ】
音声波形の一部を窓で切り取る: [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 元の波形 [●●●●] 窓1(例:16ms分) [●●●●] 窓2(少しずらす) [●●●●] 窓3 [●●●●] 窓4 ...
各窓の中で「どの周波数成分がどれだけ含まれるか」をフーリエ変換で計算 → 1つの窓 → F次元の複素数ベクトル(例:F=257次元) → T枚の窓 → T × F の複素数行列各窓の中で「どの周波数成分がどれだけ含まれるか」をフーリエ変換で計算します。
1つの窓はF次元の複素数ベクトルとなるため、T枚の窓はの複素数行列となります。
この複素数行列をスペクトログラムと言います。
各要素は複素数 a + bi であり、
- 振幅
|a + bi|:その周波数の「強さ」 - 位相
∠(a + bi):その周波数の波のズレ具合
を表します。Conv-TasNetがSTFTを使わず波形を直接扱ったのに対し、TF-Locoformerは複素数スペクトログラムをそのまま入力として使います。位相情報も保持されるため、より精密な分離が可能です。
STFTの窓長は16〜32msが一般的で、残響の遅延(80〜数百ms)をカバーできる長さです。
Conv-TasNetのエンコーダカーネル(約2ms)と比べて、構造的に長期の依存関係を扱いやすいという利点があります。
2.2 TF-Locoformerの全体パイプライン
全体の処理フローを一度に把握しておきましょう。
【TF-Locoformerの全体パイプライン】
混合音声(波形) ↓ 【STFT】混合スペクトログラム X ∈ ℂ^{T × F} ↓ 【実部・虚部を分離 → 線形変換(1×1 Conv)】特徴マップ Z ∈ ℝ^{T × F × D} (D:特徴次元数) ↓ 【Dual-Pathブロック × N(デフォルトN = 8)】 ┌────────────────────────────────────────┐ │ ブロック1:Intra-block(周波数方向) │ │ ブロック2:Inter-block(時間方向) │ │ ブロック3:Intra-block │ │ ...(交互にN回) │ └────────────────────────────────────────┘ ↓精製された特徴マップ Z' ∈ ℝ^{T × F × D} ↓ 【線形変換 → 複素マスク M₁, M₂ ∈ ℂ^{T × F}】 ↓ 【マスクを元のスペクトログラムに適用 Ŷ_c = M_c ⊙ X】各話者のスペクトログラム Ŷ₁, Ŷ₂ ∈ ℂ^{T × F} ↓ 【ISTFT(逆STFT)】各話者の波形 ŝ₁(t), ŝ₂(t)2.2.1 前処理
先ほど、音声をSTFTし複素数として出力することを言いました。
ここで、ニューラルネットワークは実数しか扱えないため、ここでは複素数を実部と虚部に分けて2チャンネルにします。 たとえば画像のRGBが3チャンネルあるのと同じように、「実部チャンネル」と「虚部チャンネル」の2枚を束ねて入力するわけです。
さらに、畳み込みをすることでチャンネル数を2からD次元に増やします。結果として、形が の特徴マップができます。
2.2.2 Dual-Pathブロックで特徴を精製する
ここがTF-Locoformerの心臓部です。特徴マップをN回繰り返し処理して、 どの時間・周波数のマスが度の話者に属するかを見分けられるように特徴を磨いていきます。
ポイントは、1回ごとに見る方向を交互に切り替えることです。
- Intra-block (周波数方向): 時間を固定して、ある瞬間の低い音から高い音までを横断的に見る。 「この瞬間、どの周波数帯が話者Aっぽいか」を判断する。
- Inter-block(時間方向): 周波数を固定して、時間の流れに沿って見る。「この周波数帯の音が、時間的にどうつながっているか」を追う。
なぜ交互にやるかというと、2次元のマップ全体を一度に処理するのは計算コストが非常に大きいからです。
周波数方向と時間方向を分けて交互に処理することで、効率よく2次元全体の情報を捉えます。これがDual-Pathという名前の由来です。
2.2.3 マスクをかけて音声に戻す
精製された特徴マップから、話者ごとの複素マスクを生成します。マスクとは、元のスペクトログラムの各マスに対して「ここは話者Aの成分をどれだけ残すか」を示す重みです。
元のスペクトログラムにマスクを掛け算すると、各話者の成分だけが残ったスペクトログラムが得られます。最後にISTFT(逆STFT)で波形に戻せば、分離された音声の完成です。
3. Dual-Path構造
3.1 なぜDual-Pathが必要なのか
スペクトログラムは「時間×周波数」の2次元データです。たとえば時間方向に125マス、周波数方向に257マスあると、 マスの総数は約32000個になります。
もし全マスを1列に並べてAttentionを書けると回の比較が必要です。 これはメモリも計算時間も現実的ではありません。
そこで考えられたのが、Dual-Pathのアイデアです。これを用いることで、上の例では全展開の約100分の1になります。 精度をほぼ落とさずにこれだけ軽くなるのがDual-Pathの魅力です。
3.2 Dual-Path処理の動作原理
時間5マス×周波数4マスの具体例で説明していきます。
3.2.1 Intra-block (周波数方向に見る)
時間を1行ずつ固定して、その行の中だけでAttentionを書けます。
時刻t1の行 → [f1, f2, f3, f4] の4要素だけで互いの関係を計算時刻t2の行 → [f1, f2, f3, f4] の4要素だけで互いの関係を計算 ...(t5まで同様)これは「ある瞬間に、低音と高音がどのように関係しているか」を学ぶ処理です。 人の声には「フォルマント」と呼ばれる特徴的な周波数のパターンがあり、複数の周波数帯が連動して変化します。 Intra-blockはこういったパターンを捉えます。
計算量は、各行がたった4要素なので回の比較が5行あるので、80回。 20マス全体を一度にやる場合の回より大幅に少ないです。
3.2.2 Inter-block (時間方向に見る)
今度は周波数を1列ずつ固定して、その列の中だけでAttentionをかけます。
周波数f1の列 → [t1, t2, t3, t4, t5] の5要素だけで互いの関係を計算周波数f2の列 → [t1, t2, t3, t4, t5] の5要素だけで互いの関係を計算 ...(f4まで同様)これは「ある周波数帯の音が、時間の流れの中でどう変化しているか」を学ぶ処理です。 たとえば話者Aが一度黙って再び話し始めたとき、離れた時刻の特徴が似ていることを認識できます。
3.2.3 なぜ交互に繰り返すのか
Intra-blockだけだと、各時刻の行は独立に処理されるので「時間の流れ」の情報が一切伝わりません。 逆にInter-blockだけだと「周波数間の関係」がわかりません。
ここが巧妙なところで、交互に繰り返すと情報が間接的に2次元全体に伝播していきます。
わかりやすいたとえとして、教室の座席を想像してください。生徒が5行×4列で座っているとします。
1回目(横方向の相談):各行の中で隣同士が情報交換する。まだ他の行のことは知らない。 2回目(縦方向の相談):各列の中で情報交換する。このとき、1回目で横方向から得た情報も一緒に伝わる。 3回目(また横方向):2回目で縦方向から伝わってきた情報を踏まえて、横方向の理解を更新する。
こうして何回か繰り返すと、教室のどの位置の生徒の情報も、全員に行き渡ります。
TF-Locoformerではこれをデフォルト8回繰り返して、時間×周波数の両方にまたがる複雑なパターンを捉えられるようにしています。
まとめると、Dual-Pathとは2次元のデータを一度に全部処理すると重すぎるので、行方向と列方向を交互に処理して、計算量を抑えつつ全体の情報を統合するということです。
4. Transformerブロックの中身:マカロン構造
前のセクションで、Dual-Pathでは「行方向」と「列方向」を交互にTransformerブロックで処理すると説明しました。 では、そのTransformerブロック自体の中身はどうなっているのかというのがこのセクションのテーマです。
4.1 標準的なTransformerブロックを知る
通常のTransformerブロックは、大きく2つの部品からできています。
- Self-Attention: データ列の中で「どの要素とどの要素が関連しているか」を見つけ出すモジュールです。 列全体を見渡すグローバルな視野を持ちます。
- FFN: 各要素を個別に変換するモジュールです。隣の要素は一切見ず、その要素だけを交換します。
標準では「Attention→FFN」の順に1組だけ並んでいます。
4.2 マカロン構造:FFNでAttentionを挟む
TF-Locoformerでは、この標準構造を少し変えて「FFN→Attention→FFN」という3段構成にしています。 これをマカロン構造と呼びます。グローバルな情報交換の前後にローカルな整理を挟むことで、より深い情報の融合が実現するとでも考えてください。
4.3 各モジュールの役割をもう少し詳しく
4.3.1 Self-Attention
前セクションのDual-Pathの話と直結します。Intra-blockとして使われるときは、ある時刻における周波数ビン同士の関係を計算します。 Inter-blockとして使われるときは、ある周波数ビンにおける時間フレーム同士の関係を計算します。
仕組みを簡単にいうと、入力データから3種類のベクトルを作ります。
- Query:「自分は何を探しているか」を表す
- Key:「自分は何を持っているか」を表す
- Value:「実際に渡す情報の中身」
すべてのQueryとKeyのペアで「どれくらい関連があるか」のスコアを計算し、スコアが高いペアからより多くのValueを受け取る、という仕組みです。 図書館で本を探す比喩でいえば、Queryが「検索キーワード」、Keyが「本の背表紙のラベル」、Valueが「本の中身」に相当します。
4.3.2 ConvSwiGLU
マカロン構造でAttentionの前後に置かれるFFNの部分です。標準的なFFNは各要素を完全に独立に変換しますが、ConvSwiGLUはDepthwise Convolutionを内蔵しており、近傍数個の要素も参照できます。
たとえばカーネルサイズK=4の場合、ある要素の出力を計算するとき、その要素と隣接する3要素の合計4要素を参照します。Self-Attentionが「列全体を見渡す望遠鏡」だとすれば、Depthwise Convは「すぐ隣を確認する虫眼鏡」のようなものです。
音声処理では、隣り合う周波数ビンや隣り合う時間フレームに強い相関があるため、このローカルな情報の取り込みが有効に働きます。
4.3.3 RMSGroupNorm
ニューラルネットワークでは、層を重ねるうちにデータの値の分布が偏ってしまい、学習が不安定になることがあります。 正規化はデータの分布を整えて学習を安定させる操作です。
TF-Locoformerでは、各部品の前に正規化を置く「Pre-Norm」方式を採用しています。 標準的なTransformerでは部品の後に正規化を置く「Post-Norm」方式が使われていましたが、 Pre-Normのほうが深いネットワークでも学習が安定しやすいことがわかっており、近年の大規模言語モデル(LLaMAなど)でも広く使われています。
4.3.4 残差接続(スキップ接続)
これは3つの部品すべてに共通して使われている重要な仕組みです。
処理前の入力を、処理後の出力に直接足し算します。 つまり、各モジュールは「入力をまるごと変換する」のではなく、「入力からの変化分だけを学習する」ことになります。 たとえるなら、文章の校正に似ています。原稿を一から書き直すのではなく、 原稿はそのまま残して「修正点だけ」を赤ペンで追記する方式です。こうすることで、各部品の仕事が軽くなり、深い層を重ねても学習が安定します。 また、逆伝播のとき、残差接続のおかげで勾配が「直通経路」を通って遠くの層まで届きやすくなります。 これがないと、層が深くなるほど勾配が消失して学習が進まなくなる問題(勾配消失)が起きます。
5. Intra-blockとInter-blockの具体的な動作
このセクションでは、Intra-blockとInter-blockの具体的な処理の流れについてみていきます。
5.1 入力テンソルの形
Dual-Pathブロックに入ってくるデータの形はは Z ∈ ℝ^{T × F × D} です。 3次元のテンソルで、それぞれの軸の意味は以下の通りです。
- T: 時間フレーム数
- F: 周波数便数
- D: 各マスに割り当てられた特徴ベクトルの次元数
つまり、スペクトログラムの各マスにD次元の情報ベクトルがぶら下がっているような状態です。
5.2 Intra-block: 周波数方向の処理
目標は、各時刻を独立に周波数方向の系列としてTransformerブロックに渡すことです。
5.2.1 テンソルの見方を変える
Transformerブロックは「N個の要素からなる系列」を入力として受け取ります。 入力の形は(バッチサイズ, 系列長N, 特徴次元D)です。
Intra-blockでは周波数方向に処理したいので、時間軸Tをバッチとして扱います。つまり、T本の系列を並列処理するという見方です。
たとえばT=125、F=257、D=48なら、「257要素の系列が125本」という形でマカロンブロックに渡されます。125本は互いに独立で、GPUで完全に並列処理できます。
処理は「各時刻 t を独立に」実行されます。全T時刻を並列に処理できます。
5.2.2 マカロンブロックの処理
各系列に対して、前セクションで説明したマカロン構造の3段処理が実行されます。
系列 [z_{t,1}, z_{t,2}, ..., z_{t,257}] (各要素はD=48次元ベクトル)
↓ ConvSwiGLU(前FFN):近傍数ビンのローカルな関係を整理 ↓ Self-Attention:257ビン全体の関係を計算(257×257のスコア行列) ↓ ConvSwiGLU(後FFN):Attentionの結果をローカルに統合
出力 [z'_{t,1}, z'_{t,2}, ..., z'_{t,257}]5.2.3 出力の形
出力は入力と同じの形で、 そのまま次のInter-blockに渡されます。
5.3 Inter-block(時間方向)の処理
5.3.1 軸の入れ替え
目標は、各周波数を独立に時間方向の系列としてTransformerブロックに渡すことです。 Inter-blockの入力も Z ∈ ℝ^{T × F × D} です。
T=125、F=257なら、「125要素の系列が257本」という形になります。
5.3.2 Transformerブロックの処理。
各系列(長さT=125)に対して、同じTransformer構造が実行されます。
系列 [z'_{1,f}, z'_{2,f}, ..., z'_{125,f}] (各要素はD=48次元ベクトル)
↓ ConvSwiGLU(前FFN):近傍数フレームのローカルな連続性を整理 ↓ Self-Attention:125フレーム全体の関係を計算(125×125のスコア行列) ↓ ConvSwiGLU(後FFN):Attentionの結果をローカルに統合
出力 [z''_{1,f}, z''_{2,f}, ..., z''_{125,f}]5.3.3 軸を基に戻す
処理が終わったら、transposeで軸を基の の順序に戻します。これで次のIntra-blockにそのまま渡せます。
6. マスク生成とデコーダ
Dual-Pathブロックの出力 Z' ∈ ℝ^{T × F × D} から、各話者の音声を復元するステップです。
6.1 線形変換で次元を変換する
Dual-Pathの出力Z'の各マスはD次元の特徴ベクトルを持っています。 これを線形変換(全結合層)で、必要な出力次元に変換します。 2人の話者を分離する場合、各マスについて「話者1の実部、話者1の虚部、話者2の実部、話者2の虚部」の4つの値が必要です。 したがって、D次元から4次元への変換になります。
6.2 reshapeして複素マスクにする
4次元の出力を、話者ごとに実部と虚部を組み合わせて複素数に戻します。
ℝ^{T × F × 4} ↓ 2つずつペアにして複素数化M₁ ∈ ℂ^{T × F} (話者1のマスク)M₂ ∈ ℂ^{T × F} (話者2のマスク)6.3 マスクを元のスペクトログラムに適用する
混合音の複素スペクトログラムXに、各話者のマスクを要素ごとに掛け算します。
Ŷ₁ = M₁ ⊙ X (話者1の推定スペクトログラム)Ŷ₂ = M₂ ⊙ X (話者2の推定スペクトログラム)ここでの ⊙ は要素ごとの掛け算で、各マスの位置について「マスクの複素数 × 混合音の複素数」を計算します。
6.4 ISTFT(逆STFT)
最後に、各話者の推定スペクトログラムにISTFT(逆短時間フーリエ変換)を適用して、時間領域の波形に変換します。
ISTFTはSTFTの逆操作です。STFTが「波形 → スペクトログラム」の変換だったのに対し、 ISTFTは「スペクトログラム → 波形」の変換です。各時間フレームのスペクトルを逆フーリエ変換で短い波形に戻し、 それらを時間方向に重ね合わせて元の長さの波形を再構成します。
7. 全体のまとめ
Part2ではTF-Locoformerのアーキテクチャ全体を解説しました。
① STFTで音声を「時間×周波数」の2次元マップに変換 → 残響対策に有利な時間窓が使える
② Dual-Path構造(Intra + Interを交互にN回) → T×F全体をAttentionにかけるよりはるかに軽量 → 周波数軸・時間軸の両方向の情報を段階的に統合
③ マカロン型ブロック(ConvSwiGLU → MH-SA → ConvSwiGLU) → Self-Attentionがグローバルな情報を担当 → ConvSwiGLUがローカルな情報を担当(RNNの役割を代替)
④ 複素マスクで振幅と位相を両方修正 → より正確な残響除去・音源分離が可能
⑤ 全処理が並列化可能(RNNなし) → 学習・推論の高速化、Transformerエコシステムの活用
次のPart3では、TF-Locoformerの核心であるConvSwiGLUとRMSGroupNormの技術詳細と、実験結果を解説します。